// Copyright 2021 Aaron Hance // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. { Driver->Storage->StorageManagment Storage Managment System DEPRECATED unit @author(Aaron Hance ah@aaronhance.me) } unit storagemanagement; interface uses util, drivertypes, console, terminal, drivermanagement, lmemorymanager, strings, lists, tracer, rtc, MBR, volumemanager, storagetypes; type TDirectory_Entry_Type = (directoryEntry, fileEntry, mountEntry); APStorage_Volume = array[0..10] of PStorage_volume; byteArray8 = array[0..7] of char; PByteArray8 = ^byteArray8; PDirectory_Entry = ^TDirectory_Entry; PPWriteHook = procedure(volume : PStorage_volume; directory : pchar; entry : PDirectory_Entry; byteCount : uint32; buffer : puint32; statusOut : puint32); PPReadHook = function(volume : PStorage_Volume; directory : pchar; fileName : pchar; fileExtension : pchar; buffer : puint32; bytecount : puint32) : uint32; 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; 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; APStorage_Device = array[0..255] of PStorage_device; { Generic directory entry } TDirectory_Entry = record { Contains filename and optionally file extension, seperated by the last period.} fileName : pchar; entryType : TDirectory_Entry_Type; creationT : TDateTime; modifiedT : TDateTime; end; var storageDevices : PLinkedListBase; //index in this array is global drive id fileSystems : PLinkedListBase; rootVolume : PStorage_Volume = PStorage_Volume(0); procedure init(); procedure register_device(device : PStorage_Device); function get_device_list() : PLinkedListBase; implementation function controller_type_2_string(controllerType : TControllerType) : pchar; begin case controllerType of ControllerIDE : controller_type_2_string:= 'IDE'; ControllerUSB : controller_type_2_string:= 'USB'; ControllerAHCI : controller_type_2_string:= 'ACHI (SATA)'; ControllerNET : controller_type_2_string:= 'Net'; end; end; { Disk subcommand for listing drives } procedure ls_command(params : PParamList); var i : uint16; begin push_trace('storagemanagment.ls_command'); //if no storage device print none found if LL_Size(storageDevices) < 1 then begin console.writestringlnWnd('No storage devices found.', getTerminalHWND()); exit; end; //print number of storage devices console.writeintwnd(LL_Size(storageDevices), getTerminalHWND()); console.writestringlnWnd(' devices found', getTerminalHWND()); for i:=0 to LL_Size(storageDevices)-1 do begin //print device id and type console.writeintwnd(i, getTerminalHWND()); console.writestringwnd(' - Device type: ', getTerminalHWND()); console.writestringwnd(controller_type_2_string(PStorage_Device(LL_Get(storageDevices, i))^.controller), getTerminalHWND()); console.writestringwnd(', ', getTerminalHWND()); //print device capcity console.writestringwnd(' Capacity: ', getTerminalHWND()); console.writeintwnd((( PStorage_Device(LL_Get(storageDevices, i))^.maxSectorCount * PStorage_Device(LL_Get(storageDevices, i))^.sectorSize) DIV 1024) DIV 1024, getTerminalHWND()); console.writestringlnWnd('MB', getTerminalHWND()); end; end; { Disk subcommand for formatting drives } procedure format_command(params : PParamList); var driveIndex : uint16; drive : PStorage_Device; filesystemString : pchar; spc : puint32; sectorCount : uint32; volumeId : uint8; mb : PMaster_Boot_Record; i : uint32 = 0; begin //format spc:= puint32(kalloc(4)); spc^:= 1; driveIndex:= stringToInt( getParam(1, params) ); drive:= PStorage_Device(LL_Get(storageDevices, driveIndex)); filesystemString := getParam(2, params); sectorCount := stringToInt( getParam(4, params) ); // if sector count is 0, use full drive if sectorCount = 0 then begin sectorCount := drive^.maxSectorCount - 10; end; //create MBR if none, and partition table mb := PMaster_Boot_Record(kalloc(sizeof(TMaster_Boot_Record))); drive^.readCallback(drive, 0, 1, PuInt32(mb)); //check if MBR exists if not mb^.boot_sector = $55AA then begin //create MBR mb^.signature := $A570 + drive^.id; mb^.boot_sector := $55AA; //create partition table mbr.setup_partition(@mb^.partition[0], 2, sectorCount); //write MBR drive^.writeCallback(drive, 0, 1, puint32(mb)); end; kfree(puint32(mb)); //setup volume volumemanager.create_volume(drive, filesystemString, 2, sectorCount); writestringWnd('Drive ', getTerminalHWND); writeintWnd(driveIndex, getTerminalHWND); writestringlnWnd(' formatted.', getTerminalHWND); end; { Command for managing and getting information from disks. } procedure disk_command(params : PParamList); var i : uint16; drive : uint16; subcmd : pchar; begin push_trace('StorageManagment.disk_command'); //check if params wehre supplied if paramCount(params) = 0 then begin writestringlnWnd('Incorrect number of params.', getTerminalHWND); exit; end; subcmd:= getParam(0, params); //ls for listing storage devices if stringEquals(subcmd, 'ls') then begin ls_command(params); exit; end; //format command for clearing a disk and make a new volume if stringEquals(subcmd, 'format') then begin format_command(params); end; pop_trace(); end; { Initialise the storage manager } procedure init(); begin push_trace('StorageManagment.init'); setworkingdirectory('.'); storageDevices:= ll_new(sizeof(TStorage_Device)); terminal.registerCommand('DISK', @disk_command, 'Disk utility'); end; { Register a new drive with the storage manager } procedure register_device(device : PStorage_device); var i : uint8; elm : void; begin push_trace('StorageManagment.register_device'); //add the drive to the list of storage devices. elm:= LL_Add(storageDevices); PStorage_device(elm)^ := device^; //create empty volume list for drive PStorage_Device(LL_Get(storageDevices, LL_Size(storageDevices) - 1))^.volumes := LL_New(sizeof(TStorage_Volume)); //check for volumes pop_trace(); end; function get_device_list() : PLinkedListBase; begin get_device_list:= storageDevices; end; end.