Asuro/src/driver/storage/storagemanagement.pas

258 lines
7.6 KiB
ObjectPascal

// 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 <DRIVE_ID> <FILESYSTEM> <size>
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.