git-svn-id: https://spexeah.com:8443/svn/Asuro@727 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c

This commit is contained in:
aaron 2018-05-12 15:18:04 +00:00
parent 1f56595625
commit 24027a3109
2 changed files with 281 additions and 127 deletions

View File

@ -127,7 +127,7 @@ 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
@ -135,9 +135,9 @@ begin
end;
break;
end else begin
if (str[i] = '/') or (str[i] = ',') then begin
//status^:= 3;
end;
// if (str[i] = '/') or (str[i] = ',') then begin
// status:= 3;
// end;
cleanString[i]:= str[i];
end;
end;
@ -163,6 +163,7 @@ var
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;
@ -182,6 +183,7 @@ var
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;
@ -239,7 +241,7 @@ var
dirElm : puint32;
begin
push_trace('fat32.findFreeClusters');
clusters := LL_New(sizeof(uint32));
clusters := LL_New(8);
while true do begin
@ -247,6 +249,11 @@ begin
currentClusterValue:= readFat(volume, i, bootRecord);
console.writeintlnWND(i, getTerminalHWND());
redrawWindows();
if currentClusterValue = 0 then begin
dirElm:= LL_add(clusters);
dirElm^:= i;
@ -312,11 +319,44 @@ begin
compareByteArray8:= false;
break;
end;
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^.fileExtension:= 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?
function readDirectory(volume : PStorage_volume; directory : pchar; status : puint32) : PLinkedListBase; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = invalid name, 4= already exists
function readDirectory(volume : PStorage_volume; directory : pchar; statusOut : puint32) : PLinkedListBase; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = invalid name, 4= already exists
var
bootRecord : PBootRecord;
directoryStrings : PLinkedListBase;
@ -325,7 +365,9 @@ var
i : uint32;
ii : uint32 = 0;
dirEntry : PDirectory;
status : puint32;
begin
status:= puint32(kalloc(sizeof(uint32)));
push_trace('fat32.readDirectory');
status^:= 0;
bootRecord:= readBootRecord(volume);
@ -333,13 +375,13 @@ begin
directories:= getDirEntries(volume, bootRecord^.rootCluster, bootRecord);
if LL_size(directoryStrings) > 0 then begin
for i:=0 to LL_Size(directoryStrings) do begin
for i:=0 to (LL_Size(directoryStrings) - 1) do begin /// maybe -1 will work
ii:=0;
while true do begin
if ii > LL_Size(directories) - 1 then begin
status^:= 1;
break;
status^:= 1;
break;
end;
dirEntry:= PDirectory(LL_Get(directories, ii));
@ -353,7 +395,7 @@ begin
if status^ <> 0 then break;
LL_Free(directories); //TODO need to really free the things
LL_Free(directories);
directories:= getDirEntries(volume, cluster, bootRecord);
if i = LL_Size(directoryStrings) - 1 then break;
@ -368,12 +410,18 @@ begin
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
procedure writeDirectory(volume : PStorage_volume; directory : pchar; dirName : pchar; attributes : uint32; var statusO : puint32); // need to handle parent table cluster overflow, need to take attributes
procedure writeDirectory(volume : PStorage_volume; directory : pchar; dirName : pchar; attributes : uint32; statusOut : puint32); // need to handle parent table cluster overflow, need to take attributes
var
directories : PLinkedListBase;
parentDirectory : PDirectory;
@ -394,24 +442,48 @@ var
status : puint32;
begin
push_trace('fat32.writeDirectory');
status:= puint32(kalloc(sizeof(uint32)));
status^:= 0;
directories:= readDirectory(volume, directory, status);
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;
console.writestringlnWND('1', getTerminalHWND());
redrawWindows();
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;
console.writestringlnWND('2', getTerminalHWND());
redrawWindows();
bootRecord:= readBootRecord(volume);
datastart:= volume^.sectorStart + 1 + bootRecord^.FATSize + bootRecord^.rsvSectors;
console.writestringlnWND('3', getTerminalHWND());
console.writeintlnWND(status^, getTerminalHWND());
redrawWindows();
if status^ = 0 then begin
console.writestringlnWND('3.1', getTerminalHWND());
redrawWindows();
parentDirectory:= PDirectory(LL_Get(directories, 0));
parentCluster:= uint32(parentDirectory^.clusterlow) or uint32(parentDirectory^.clusterhigh shl 16);
clusters:= findFreeClusters(volume, 1, bootRecord);
cluster:= uint32(LL_Get(clusters, 0)^);
LL_Free(clusters);
console.writestringlnWND('3.2', getTerminalHWND());
redrawWindows();
if attributes = $10 then begin // if directory
buffer:= puint32(kalloc(bootRecord^.sectorSize));
@ -433,16 +505,24 @@ begin
volume^.device^.writecallback(volume^.device, dataStart + (cluster * bootRecord^.spc), 1, buffer);
//write fat
writeFat(volume, cluster, $FFFFFFF8, bootRecord); //TODO check if working
writeFat(volume, cluster, $FFFFFFF8, bootRecord);
end;
push_trace('1');
memset(uint32(buffer), 0, bootRecord^.sectorSize);
push_trace('2');
console.writestringlnWND('3.5', getTerminalHWND());
redrawWindows();
//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);
@ -452,10 +532,11 @@ begin
//write to disk
volume^.device^.writecallback(volume^.device, dataStart + sectorLocation, 1, buffer);
kfree(buffer);
end;
statusO^:= status^;
statusOut^:= status^;
kfree(puint32(bootRecord));
LL_Free(directories);
end;
@ -609,7 +690,7 @@ procedure init();
begin
push_trace('fat32.init()');
filesystem.sName:= 'FAT32';
filesystem.readDirCallback:= @readDirectory;
filesystem.readDirCallback:= @readDirectoryGen;
filesystem.createDirCallback:= @writeDirectory;
filesystem.createcallback:= @create_volume;
filesystem.detectcallback:= @detect_volumes;

View File

@ -20,12 +20,13 @@ uses
lmemorymanager,
strings,
lists,
tracer;
tracer,
rtc;
type
TControllerType = (ControllerIDE, ControllerUSB, ControllerAHCI, ControllerNET);
TDirectory_Entry_Type = (Directory, Data, Executable, Mounted);
TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry);
PStorage_volume = ^TStorage_Volume;
PStorage_device = ^TStorage_Device;
APStorage_Volume = array[0..10] of PStorage_volume;
@ -36,7 +37,7 @@ type
PPHIOHook = procedure(volume : PStorage_device; addr : uint32; sectors : uint32; buffer : puint32);
PPCreateHook = procedure(disk : PStorage_Device; sectors : uint32; start : uint32; config : puint32);
PPDetectHook = procedure(disk : PStorage_Device);
PPCreateDirHook = procedure(volume : PStorage_volume; directory : pchar; dirname : pchar; attributes : uint32; var status : puint32);
PPCreateDirHook = procedure(volume : PStorage_volume; directory : pchar; dirname : pchar; attributes : uint32; status : puint32);
PPReadDirHook = function(volume : PStorage_volume; directory : pchar; status : puint32) : PLinkedListBase; //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error //returns: 0 = success, 1 = dir not exsist, 2 = not directory, 3 = error
PPHIOHook_ = procedure;
@ -80,14 +81,16 @@ type
TDirectory_Entry = record //TODO implement dtae.time stuff
fileName : pchar;
extension : pchar;
volume : PStorage_Volume;
entryType : TDirectory_Entry_Type;
creationT : TDateTime;
modifiedT : TDateTime;
end;
PDirectory_Entry = ^TDirectory_Entry;
var
storageDevices : PLinkedListBase; //index in this array is global drive id
fileSystems : PLinkedListBase;
rootVolume : PStorage_Volume = PStorage_Volume(0);
procedure init();
@ -102,24 +105,6 @@ procedure register_volume(device : PStorage_Device; volume : PStorage_Volume);
implementation
procedure test_command(params : PParamList);
var
i : uint32;
elm : puint32;
str : pchar;
list : PLinkedListBase;
begin
str := getParam(0, params);
list := LL_fromString(str, '/');
for i:=0 to LL_Size(list) - 1 do begin
elm:= puint32(LL_Get(list, i));
str := pchar(elm^);
console.writestringln(str);
end;
end;
procedure disk_command(params : PParamList);
var
i : uint8;
@ -165,89 +150,6 @@ begin
pop_trace;
end;
procedure mkdir_command(params : PParamList);
var
dir : pchar;
temp : pchar;
dirName : pbyteArray8;
device : PStorage_Device;
volume : PStorage_Volume;
error : puint32;
i : uint32;
begin
push_trace('mkdir');
error := puint32(kalloc(8));
error^ := 0;
if paramCount(params) > 0 then begin
dir := getParam(0, params);
temp:= getParam(1, params);
//for i:=0 to 7 do begin
// dirname[i]:= pbyteArray8(temp)[i];
//end;
//console.writestringlnWND(pchar(dirname), getTerminalHWND());
device:= PStorage_Device(LL_Get(storageDevices, 0));
volume:= PStorage_Volume(LL_Get(device^.volumes, 0));
volume^.filesystem^.createDirCallback(volume, dir, temp, $10, error);
//if error <> 1 then console.writestringln('ERROR');
end;
kfree(error);
end;
procedure ls_command(params : PParamList);
type
TDirectory = bitpacked 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;
var
dirs : PLinkedListBase;
dir : pchar;
dirp : PDirectory;
device : PStorage_Device;
volume : PStorage_Volume;
error : puint32;
i : uint32;
begin
push_trace('ls');
error:= puint32(kalloc(4));
if paramCount(params) > 0 then begin
dir := getParam(0, params);
device:= PStorage_Device(LL_Get(storageDevices, 0));
volume:= PStorage_Volume(LL_Get(device^.volumes, 0));
dirs:= volume^.filesystem^.readDirCallback(volume, dir, error);
//if error <> 1 then console.writestringln('ERROR');
for i:=2 to LL_Size(dirs) - 1 do begin
console.writestringWND(' /', getTerminalHWND);
dirp:= PDirectory(LL_Get(dirs, i));
console.writestringlnWND(pchar(dirp^.fileName), getTerminalHWND);
end;
pop_trace();
end else begin
console.writestringlnWND('Specifiy a folder', getTerminalHWND);
end;
end;
procedure volume_command(params : PParamList);
var
i : uint32;
@ -274,16 +176,185 @@ begin
end;
end;
function padWithSpaces(str : pchar; length : uint16) : pchar;
var
i : uint32;
ii : uint32;
begin
for i:=0 to length do begin
if str[i] = ' ' then begin
for ii:=i to length do begin
padWithSpaces[i]:= ' ';
end;
end else begin
if str[i] = char(0) then exit;
padWithSpaces[i]:= str[i];
end;
end;
end;
function allButLast(str : pchar; delim : char) : pchar;
var
strings : PLinkedListBase;
i : uint32;
begin
strings:= STRLL_FromString(str, delim);
if STRLL_Size(strings) > 2 then begin
for i:=0 to STRLL_Size(strings) - 2 do begin
stringConcat(allButLast, STRLL_Get(strings, i));
end;
end else begin
if STRLL_Size(strings) = 2 then begin
allButLast:= STRLL_Get(strings, 0);
end else begin
allButLast:= str;
end;
end;
console.writestringlnWND(allButLast, getTerminalHWND());
STRLL_Clear(strings);
STRLL_Free(strings);
end;
procedure list_command(params : PParamList);
var
dirEntries : PLinkedListBase;
i : uint32;
ii : uint32;
error : puint32;
nli : uint32 = 0;
begin
error := puint32(kalloc(4));
if paramCount(params) > 1 then begin
console.writestringlnWND('', getTerminalHWND());
console.writestringlnWND('Lists the files and directories in working directory, or optionaly, the specified directory.', getTerminalHWND());
console.writestringlnWND('', getTerminalHWND());
console.writestringlnWND('Usage:', getTerminalHWND());
console.writestringlnWND('ls <directory>', getTerminalHWND());
end else begin
if paramCount(params) = 1 then begin
dirEntries:= rootVolume^.filesystem^.readDirCallback(rootVolume, pchar(getParam(0, params)), error);
end else begin
dirEntries:= rootVolume^.filesystem^.readDirCallback(rootVolume, getWorkingDirectory(), error);
end;
//loop and print dirs
for i:=2 to LL_Size(dirEntries) - 1 do begin
console.writestringWND(' /', getTerminalHWND);
console.writestringWND( PDirectory_Entry(LL_Get(dirEntries, i ))^.fileName , getTerminalHWND());
if nli > 3 then begin
console.writestringlnWND('',getTerminalHWND());
nli:= 0;
end else begin
nli+=1;
end;
end;
console.writestringlnWND('',getTerminalHWND());
end;
kfree(error);
end;
procedure change_dir_command(params : PParamList);
var
targetDirectory : pchar;
dirEntries : PLinkedListBase;
lastString : pchar;
entry : PDirectory_Entry;
error : puint32;
begin
error := puint32(kalloc(4));
if paramCount(params) = 1 then begin
if (pchar(getParam(0, params))[0] = '/') then begin //search from root
targetDirectory:= pchar(getParam(0,params));
dirEntries:= rootVolume^.filesystem^.readDirCallback(rootVolume, pchar( getParam(0, params)), error);
console.writestringlnWND('from root', getTerminalHWND());
end else begin //search from working directory
//concat current dir and param
targetDirectory:= stringConcat(getWorkingDirectory, '/');
targetDirectory:= stringConcat(targetDirectory, pchar(getParam(0,params)) ); //do i need pad with space?
dirEntries:= rootVolume^.filesystem^.readDirCallback(rootVolume, targetDirectory, error); // need to be able to supply attributes for list conversion method
end;
if error^ = 0 then begin
setworkingdirectory(targetDirectory); // need to clean ..
end;
kfree(puint32(dirEntries));
end else begin
console.writestringlnWND('', getTerminalHWND());
console.writestringlnWND('Changes the current working directory, this is the context wich other commands rely on.', getTerminalHWND());
console.writestringlnWND('', getTerminalHWND());
console.writestringlnWND('Usage:', getTerminalHWND());
console.writestringlnWND('cd <directory>', getTerminalHWND());
end;
kfree(error);
end;
procedure mkdir_command(params : PParamList);
var
directories : PLinkedListBase;
targetDirectory : pchar;
temp : pchar;
target : pchar;
device : PStorage_Device;
volume : PStorage_Volume;
status : uint32;
error : puint32;
i : uint32;
isRoot : boolean = false;
begin
error:= @status;
error^ := 0;
if paramCount(params) = 1 then begin
directories:= STRLL_FromString(getParam(0, params), '/');
if LL_Size(directories) > 1 then begin
temp := allbutlast(getParam(0, params), '/');
end else begin
temp:= '/';
end;
target:= STRLL_Get(directories, LL_Size(directories)-1);
if (getParam(0, params)[0] = '/') then begin //search from root
targetDirectory:= temp;
end else begin //search from working directory
targetDirectory:= stringConcat(getWorkingDirectory, '/');
targetDirectory:= stringConcat(targetDirectory, temp ); //do i need pad with space?
end;
console.writestringlnWND(targetDirectory, getTerminalHWND());
console.writestringlnWND(target, getTerminalHWND());
device:= PStorage_Device(LL_Get(storageDevices, 0));
volume:= PStorage_Volume(LL_Get(device^.volumes, 0));
volume^.filesystem^.createDirCallback(volume, targetDirectory, target, $10, error);
if error^ <> 0 then console.writestringlnWND('ERROR', getTerminalHWND());
end; // else print out help
end;
procedure init();
begin
push_trace('storagemanagement.init');
setworkingdirectory('.');
storageDevices:= ll_New(sizeof(TStorage_Device));
fileSystems:= ll_New(sizeof(TFilesystem));
terminal.registerCommand('DISK', @disk_command, 'Disk utility');
terminal.registerCommand('VOLUME', @volume_command, 'Volume utility');
terminal.registerCommandEx('mkdir', @mkdir_command, 'Volume utility', true);
terminal.registerCommandEx('ls', @ls_command, 'Volume utility', true);
terminal.registerCommandEx('mkdir', @mkdir_command, 'Make Directory', true);
terminal.registerCommandEx('ls', @list_command, 'List contents of directory', true);
terminal.registerCommandEx('cd', @change_dir_command, 'Chae the working directory', true);
pop_trace();
end;
@ -324,6 +395,8 @@ begin
push_trace('storagemanagement.register_volume');
elm := LL_Add(device^.volumes);
PStorage_volume(elm)^:= volume^;
if rootVolume = PStorage_Volume(0) then rootVolume:= volume;
end;
end.