Work on storage and flat file system
This commit is contained in:
@ -25,7 +25,13 @@ interface
|
||||
uses
|
||||
tracer,
|
||||
strings,
|
||||
volumemanager;
|
||||
volumemanager,
|
||||
lists,
|
||||
console,
|
||||
terminal,
|
||||
storagetypes,
|
||||
lmemorymanager,
|
||||
util;
|
||||
|
||||
type
|
||||
|
||||
@ -35,14 +41,15 @@ type
|
||||
version: uint16;
|
||||
sectorCount : uint16;
|
||||
fileCount : uint16;
|
||||
signature : uint32 = $0B00B1E5;
|
||||
signature : uint32;
|
||||
end;
|
||||
PDisk_Info = ^TDisk_Info;
|
||||
|
||||
TFile_Entry = packed record
|
||||
name: array[0..59] of char;
|
||||
size: uint16;
|
||||
start : uint16;
|
||||
TFile_Entry = bitpacked record
|
||||
attribues : uint8; // 0x00 = does not exsist, 0x01 = file, 0x02 = hidden, 0x04 = system/read only, 0x10 = directory, 0x20 = archive
|
||||
name: array[0..54] of char; //max file name length is 55
|
||||
size: uint32;
|
||||
start : uint32;
|
||||
end;
|
||||
PFile_Entry = ^TFile_Entry;
|
||||
|
||||
@ -51,11 +58,344 @@ var
|
||||
|
||||
|
||||
procedure init;
|
||||
procedure create_volume(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
|
||||
procedure create_volume(volume : PStorage_Volume; sectors : uint32; start : uint32; config : puint32);
|
||||
procedure detect_volumes(disk : PStorage_Device);
|
||||
|
||||
function read_directory(volume : PStorage_Volume; directory : pchar; status : PuInt32) : PLinkedListBase;
|
||||
|
||||
implementation
|
||||
|
||||
procedure create_volume(volume : PStorage_Volume; sectors : uint32; start : uint32; config : puint32);
|
||||
var
|
||||
info : PDisk_Info;
|
||||
entryTable : PFile_Entry;
|
||||
i : uint32;
|
||||
|
||||
directories : PLinkedListBase;
|
||||
status : PuInt32;
|
||||
|
||||
const
|
||||
asuroArray : array[0..7] of char = 'ASURO';
|
||||
systemArray : array[0..6] of char = '/system';
|
||||
programsArray : array[0..8] of char = '/programs';
|
||||
userArray : array[0..4] of char = '/user';
|
||||
begin
|
||||
|
||||
info := PDisk_Info(Kalloc(512));
|
||||
memset(uint32(info), 0, 512);
|
||||
|
||||
info^.jmp2boot := $0;
|
||||
info^.OEMName := asuroArray;
|
||||
info^.version := 1;
|
||||
info^.sectorCount := sectors;
|
||||
info^.fileCount := 1000;
|
||||
info^.signature := $0B00B1E5;
|
||||
|
||||
if config^ <> 0 then begin
|
||||
info^.fileCount := config^;
|
||||
end;
|
||||
|
||||
volume^.device^.writeCallback(volume^.device, start, 1, PuInt32(info));// what happens if buffer is smaller than 512?
|
||||
|
||||
// create file table
|
||||
entryTable := PFile_Entry(Kalloc(126 * 512));
|
||||
memset(uint32(entryTable), 0, 126 * 512);
|
||||
|
||||
//create system folders
|
||||
entryTable[0].attribues := $10;
|
||||
memcpy(uint32(@systemArray), uint32(@entryTable[0].name), 7);
|
||||
entryTable[0].size := 0;
|
||||
entryTable[0].start := 0;
|
||||
|
||||
entryTable[1].attribues := $10;
|
||||
memcpy(uint32(@programsArray), uint32(@entryTable[1].name), 9);
|
||||
entryTable[1].size := 0;
|
||||
entryTable[1].start := 0;
|
||||
|
||||
entryTable[2].attribues := $10;
|
||||
memcpy(uint32(@userArray), uint32(@entryTable[2].name), 5);
|
||||
entryTable[2].size := 0;
|
||||
entryTable[2].start := 0;
|
||||
|
||||
//write file table
|
||||
// volume^.device^.writeCallback(volume^.device, start + 1, ((sizeof(TFile_Entry) * info^.fileCount) div 512), puint32(entryTable));
|
||||
volume^.device^.writeCallback(volume^.device, start + 1, 1, puint32(entryTable));
|
||||
|
||||
//temp read
|
||||
status := PuInt32(Kalloc(sizeof(uint32)));
|
||||
directories := read_directory(volume, '/', status);
|
||||
end;
|
||||
|
||||
procedure write_directory(volume : PStorage_Volume; directory : pchar; status : PuInt32);
|
||||
var
|
||||
directories : PLinkedListBase;
|
||||
i : uint32;
|
||||
|
||||
fileEntry : PFile_Entry;
|
||||
buffer : PuInt32;
|
||||
|
||||
position : uint32;
|
||||
offset : uint32;
|
||||
|
||||
const
|
||||
fileCount : uint32 = 1000;
|
||||
begin
|
||||
status^ = 0;
|
||||
|
||||
directories := read_directory(volume, directory, status);
|
||||
|
||||
if status^ = 0 then begin
|
||||
for i := 0 to fileCount - 1 do begin
|
||||
fileEntry := PFile_Entry(LL_Get(directories, i));
|
||||
|
||||
if fileEntry^.attribues = 0 then begin
|
||||
fileEntry^.attribues := $10;
|
||||
fileEntry^.size := 0;
|
||||
fileEntry^.start := 0;
|
||||
memcpy(uint32(@fileEntry^.name), uint32(@directory), strlen(directory));
|
||||
|
||||
//write file table
|
||||
buffer := PuInt32(Kalloc(512));
|
||||
memset(uint32(buffer), 0, 512);
|
||||
|
||||
//read file table cointaining entry of interest
|
||||
position := (i * sizeof(TFile_Entry)) div 512;
|
||||
volume^.device^.readCallback(volume^.device, sectorStart + 1 + position, 1, buffer);
|
||||
|
||||
//calculate entry offset into sector
|
||||
offset := (i * sizeof(TFile_Entry)) mod 512;
|
||||
offset := offset div sizeof(TFile_Entry);
|
||||
|
||||
//set entry in buffer
|
||||
PFile_Entry(buffer)[offset] := fileEntry^;
|
||||
|
||||
//write updated file table sector
|
||||
volume^.device^.writeCallback(volume^.device, sectorStart + 1 + position, 1, buffer);
|
||||
|
||||
Kfree(buffer);
|
||||
|
||||
break;
|
||||
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if fileEntry^.attribues = 0 then begin
|
||||
status^ := 1;
|
||||
end;
|
||||
|
||||
LL_Destroy(directories);
|
||||
end;
|
||||
|
||||
function read_directory(volume : PStorage_Volume; directory : pchar; status : PuInt32) : PLinkedListBase;
|
||||
var
|
||||
directories : PLinkedListBase;
|
||||
fileEntrys : PFile_Entry;
|
||||
i : uint32;
|
||||
|
||||
compString : PChar;
|
||||
afterString : PChar;
|
||||
compStringLength : uint32;
|
||||
|
||||
fileCount : uint32 = 1000;
|
||||
|
||||
begin
|
||||
|
||||
compString := pchar(kalloc(60));
|
||||
memset(uint32(compString), 0, 60);
|
||||
|
||||
afterString := pchar(kalloc(60));
|
||||
memset(uint32(afterString), 0, 60);
|
||||
|
||||
directories := STRLL_New();
|
||||
|
||||
fileEntrys := PFile_Entry(Kalloc(sizeof(TFile_Entry) * fileCount));
|
||||
volume^.device^.readCallback(volume^.device, volume^.sectorStart + 1, sizeof(TFile_Entry) * fileCount div 512, puint32(fileEntrys));
|
||||
|
||||
for i := 0 to fileCount - 1 do begin
|
||||
// if fileEntrys[i].attribues and $10 = $10 then begin
|
||||
|
||||
writestringlnWND(fileEntrys[i].name, getterminalhwnd());
|
||||
|
||||
compString := stringSub(fileEntrys[i].name, 0, stringSize(directory));
|
||||
afterString := stringSub(fileEntrys[i].name, stringSize(directory), stringSize(fileEntrys[i].name)-1);
|
||||
|
||||
if stringEquals(compString, directory) and
|
||||
(not stringContains(afterString, '/')) then begin
|
||||
|
||||
console.writestringlnWND(afterString, getTerminalHWND());
|
||||
STRLL_Add(directories, afterString);
|
||||
end;
|
||||
|
||||
// end;
|
||||
end;
|
||||
|
||||
Kfree(puint32(fileEntrys));
|
||||
|
||||
read_directory := directories;
|
||||
end;
|
||||
|
||||
procedure quicksort_start(list : PFile_Entry; begining : uint32; stop : uint32);
|
||||
var
|
||||
pivot : uint32;
|
||||
i : uint32;
|
||||
j : uint32;
|
||||
temp : PLinkedListBase;
|
||||
|
||||
tempFileEntry : PFile_Entry;
|
||||
begin
|
||||
|
||||
i:=begining;
|
||||
j:=stop;
|
||||
|
||||
pivot := list[(begining + stop) div 2].start;
|
||||
|
||||
while i <= j do begin
|
||||
while list[i].start < pivot do begin
|
||||
i := i + 1;
|
||||
end;
|
||||
|
||||
while list[j].start > pivot do begin
|
||||
j := j - 1;
|
||||
end;
|
||||
|
||||
if i <= j then begin
|
||||
tempFileEntry := list[i];
|
||||
list[i] := list[j];
|
||||
list[j] := tempFileEntry;
|
||||
|
||||
i := i + 1;
|
||||
j := j - 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
if begining < j then begin
|
||||
quicksort_start(list, begining, j);
|
||||
end;
|
||||
|
||||
if i < stop then begin
|
||||
quicksort_start(list, i, stop);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function find_free_space(volume : PStorage_Volume; size : uint32; status : PuInt32) : uint32;
|
||||
var
|
||||
fileEntrys : PFile_Entry;
|
||||
fileEntry : TFile_Entry;
|
||||
i : uint32;
|
||||
fileCount : uint32 = 1000;
|
||||
begin
|
||||
fileEntrys := PFile_Entry(Kalloc(sizeof(TFile_Entry) * fileCount));
|
||||
volume^.device^.readCallback(volume^.device, volume^.sectorStart + 1, sizeof(TFile_Entry) * fileCount div 512, puint32(fileEntrys));
|
||||
|
||||
//sort file table by start address using quicksort
|
||||
quicksort(fileEntrys, 0, fileCount - 1);
|
||||
|
||||
//find free space big enough to fit size
|
||||
for i := 0 to fileCount - 1 do begin
|
||||
if fileEntrys[i+1].start - (fileEntrys[i].start + fileEntrys[i].size) > size+1 then begin
|
||||
find_free_space := fileEntrys[i].start + fileEntrys[i].size;
|
||||
status^ := 0;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
Kfree(puint32(fileEntrys));
|
||||
|
||||
find_free_space := freeSpace;
|
||||
end;
|
||||
|
||||
procedure write_file(volume : PStorage_Volume; fileName : pchar; data : PuInt32; size : uint32; status : PuInt32);
|
||||
var
|
||||
directories : PLinkedListBase;
|
||||
i : uint32;
|
||||
|
||||
fileEntry : PFile_Entry;
|
||||
buffer : PuInt32;
|
||||
|
||||
position : uint32;
|
||||
offset : uint32;
|
||||
|
||||
fileCount : uint32 = 1000;
|
||||
|
||||
exsists : boolean;
|
||||
begin
|
||||
|
||||
//load file table
|
||||
directories := read_directory(volume, '/', status);
|
||||
|
||||
|
||||
//check if file exists else find free entry
|
||||
for i := 0 to fileCount - 1 do begin
|
||||
fileEntry := PFile_Entry(LL_Get(directories, i));
|
||||
|
||||
if stringEquals(fileEntry^.name, fileName) then begin
|
||||
exsists := true;
|
||||
break;
|
||||
end;
|
||||
|
||||
if fileEntry^.attribues = 0 then begin
|
||||
exsists := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
//if entry is directory then exit
|
||||
if fileEntry^.attribues and $10 = $10 then begin
|
||||
status^ := 1;
|
||||
exit;
|
||||
end;
|
||||
|
||||
//allocate file table
|
||||
buffer := PuInt32(Kalloc(512));
|
||||
memset(uint32(buffer), 0, 512);
|
||||
|
||||
//read file table cointaining entry of interest
|
||||
position := (i * sizeof(TFile_Entry)) div 512;
|
||||
volume^.device^.readCallback(volume^.device, sectorStart + 1 + position, 1, buffer);
|
||||
|
||||
//calculate entry offset into sector
|
||||
offset := (i * sizeof(TFile_Entry)) mod 512;
|
||||
offset := offset div sizeof(TFile_Entry);
|
||||
|
||||
//if file exists update entry else create new entry
|
||||
if exsists then do begin
|
||||
//check if size is greater than current size
|
||||
if size > fileEntry^.size then begin
|
||||
//find free space
|
||||
fileEntry^.start := find_free_space(volume, size);
|
||||
fileEntry^.size := size;
|
||||
end else begin
|
||||
//update size
|
||||
fileEntry^.size := size;
|
||||
end;
|
||||
|
||||
end else begin
|
||||
//find free space
|
||||
fileEntry^.start := find_free_space(volume, size);
|
||||
fileEntry^.size := size;
|
||||
fileEntry^.attribues := $01;
|
||||
|
||||
//add file name
|
||||
fileEntry^.name := fileName;
|
||||
|
||||
//add file to table
|
||||
LL_Add(directories, fileEntry);
|
||||
end;
|
||||
|
||||
//write file table
|
||||
volume^.device^.writeCallback(volume^.device, sectorStart + 1 + position, 1, buffer);
|
||||
|
||||
//write file
|
||||
volume^.device^.writeCallback(volume^.device, fileEntry^.start, size div 512 + 1, data);
|
||||
|
||||
//free buffer
|
||||
Kfree(puint32(buffer));
|
||||
|
||||
//free directories
|
||||
LL_Free(directories);
|
||||
end;
|
||||
|
||||
procedure detect_volumes(disk : PStorage_Device);
|
||||
var
|
||||
buffer : puint32;
|
||||
@ -92,14 +432,14 @@ end;
|
||||
procedure init();
|
||||
begin
|
||||
push_trace('flatfs.init()');
|
||||
filesystem.sName:= 'FlatFS';
|
||||
filesystem.sName:= 'flatfs';
|
||||
filesystem.system_id:= $02;
|
||||
filesystem.readDirCallback:= @readDirectoryGen;
|
||||
filesystem.createDirCallback:= @writeDirectoryGen;
|
||||
filesystem.readDirCallback:= @read_directory;
|
||||
// filesystem.createDirCallback:= @writeDirectoryGen;
|
||||
filesystem.createcallback:= @create_volume;
|
||||
filesystem.detectcallback:= @detect_volumes;
|
||||
filesystem.writecallback:= @writeFile;
|
||||
filesystem.readcallback := @readFile;
|
||||
// filesystem.writecallback:= @writeFile;
|
||||
// filesystem.readcallback := @readFile;
|
||||
// filesystem.formatVolumeCallback := @create_volume;
|
||||
|
||||
volumemanager.register_filesystem(@filesystem);
|
||||
|
Reference in New Issue
Block a user