From 24027a31095c8c55f19202de66d9fa0b76e0703b Mon Sep 17 00:00:00 2001 From: aaron Date: Sat, 12 May 2018 15:18:04 +0000 Subject: [PATCH] git-svn-id: https://spexeah.com:8443/svn/Asuro@727 6dbc8c32-bb84-406f-8558-d1cf31a0ab0c --- src/driver/storage/fat32.pas | 119 ++++++++-- src/driver/storage/storagemanagement.pas | 289 ++++++++++++++--------- 2 files changed, 281 insertions(+), 127 deletions(-) diff --git a/src/driver/storage/fat32.pas b/src/driver/storage/fat32.pas index 2df20825..2a059132 100644 --- a/src/driver/storage/fat32.pas +++ b/src/driver/storage/fat32.pas @@ -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; diff --git a/src/driver/storage/storagemanagement.pas b/src/driver/storage/storagemanagement.pas index b472b9d9..aa7d3f46 100644 --- a/src/driver/storage/storagemanagement.pas +++ b/src/driver/storage/storagemanagement.pas @@ -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 ', 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 ', 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. \ No newline at end of file