mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 13:28:41 +00:00
First part of the work on DiskManager
- plugged DriveInfo - added tests for DriveInfo - added to VFS a new method RegisterFilesystem()
This commit is contained in:
parent
fee00817a0
commit
d2ecdfdeee
15 changed files with 761 additions and 99 deletions
136
Tests/Cosmos.Kernel.Tests.Fat/System.IO/DriveInfoTest.cs
Normal file
136
Tests/Cosmos.Kernel.Tests.Fat/System.IO/DriveInfoTest.cs
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
using System.IO;
|
||||
using Cosmos.TestRunner;
|
||||
using Cosmos.Debug.Kernel;
|
||||
using System;
|
||||
|
||||
namespace Cosmos.Kernel.Tests.Fat.System.IO
|
||||
{
|
||||
public class DriveInfoTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests System.IO.DriveInfo plugs.
|
||||
/// </summary>
|
||||
public static void Execute(Debugger mDebugger)
|
||||
{
|
||||
string driveName = @"0:\";
|
||||
var MyDrive = new DriveInfo(driveName);
|
||||
|
||||
mDebugger.Send("START TEST: Get Name");
|
||||
|
||||
Assert.IsTrue(MyDrive.Name == driveName, "DriveInfo.Name failed drive has wrong name");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Get TotalSize");
|
||||
long MyDriveSize = MyDrive.TotalSize;
|
||||
|
||||
mDebugger.Send($"Size is {MyDriveSize}");
|
||||
|
||||
Assert.IsTrue(MyDriveSize > 0, "DriveInfo.TotalSize failed: invalid size");
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Get AvailableFreeSpace");
|
||||
long MyDriveAvailableFreeSpace = MyDrive.AvailableFreeSpace;
|
||||
|
||||
mDebugger.Send($"AvailableFreeSpace {MyDriveAvailableFreeSpace}");
|
||||
|
||||
Assert.IsTrue(MyDriveAvailableFreeSpace >= 0, "DriveInfo.AvailableFreeSpace failed: invalid size");
|
||||
|
||||
Assert.IsFalse(MyDriveAvailableFreeSpace > MyDrive.TotalSize, "DriveInfo.AvailableFreeSpace failed: more than TotalSize");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Get TotalFreeSpace");
|
||||
long MyDriveTotalFreeSpace = MyDrive.TotalFreeSpace;
|
||||
|
||||
mDebugger.Send($"TotalFreeSpace {MyDriveTotalFreeSpace}");
|
||||
|
||||
Assert.IsTrue(MyDriveTotalFreeSpace >= 0, "DriveInfo.TotalFreeSpace failed: invalid size");
|
||||
|
||||
Assert.IsFalse(MyDriveTotalFreeSpace > MyDrive.TotalSize, "DriveInfo.TotalFreeSpace failed: more than TotalSize");
|
||||
|
||||
/*
|
||||
* If disk quotas are enabled AvailableFreeSpace and TotalFreeSpace could be different numbers but TotalFreeSpace
|
||||
* should be always >= of AvailableFreeSpace
|
||||
*/
|
||||
Assert.IsTrue(MyDriveTotalFreeSpace >= MyDriveAvailableFreeSpace, "DriveInfo.MyDriveTotalFreeSpace failed: less than AvailableFreeSpace");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Get RootDirectory");
|
||||
|
||||
var xDi = MyDrive.RootDirectory;
|
||||
|
||||
Assert.IsTrue(xDi.Name == MyDrive.Name, "RootDirectory failed");
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Get DriveFormat");
|
||||
|
||||
Assert.IsTrue(MyDrive.DriveFormat == "FAT32", "DriveFormat failed");
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Get VolumeLabel");
|
||||
|
||||
string OriginalVolumeLabel = MyDrive.VolumeLabel;
|
||||
|
||||
mDebugger.Send($"Volume Label of {MyDrive.Name} is {MyDrive.VolumeLabel}");
|
||||
|
||||
Assert.IsTrue(OriginalVolumeLabel == "COSMOS", "VolumeLabel Get failed not the expected value");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Set VolumeLabel to <TEST>");
|
||||
// Now try to change it...
|
||||
String NewVolumeLabel = "TEST";
|
||||
mDebugger.Send($"Changing Volume Label to {NewVolumeLabel}...");
|
||||
MyDrive.VolumeLabel = NewVolumeLabel;
|
||||
|
||||
string SetVolumeLabel = MyDrive.VolumeLabel;
|
||||
|
||||
mDebugger.Send($"Volume Label of {MyDrive.Name} is {SetVolumeLabel}");
|
||||
|
||||
Assert.IsTrue(SetVolumeLabel == NewVolumeLabel, "VolumeLabel Set failed: not the expected value");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Set VolumeLabel (restoring original label)");
|
||||
// Now try to change it...
|
||||
mDebugger.Send($"Changing Volume Label to {OriginalVolumeLabel}...");
|
||||
MyDrive.VolumeLabel = OriginalVolumeLabel;
|
||||
|
||||
SetVolumeLabel = MyDrive.VolumeLabel;
|
||||
|
||||
mDebugger.Send($"Volume Label of {MyDrive.Name} is {SetVolumeLabel}");
|
||||
|
||||
Assert.IsTrue(SetVolumeLabel == OriginalVolumeLabel, "VolumeLabel Set failed: not the expected value");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Testing isReady status of the Drive");
|
||||
|
||||
Assert.IsTrue(MyDrive.IsReady, "IsReady failed drive not ready");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Testing DriveType");
|
||||
|
||||
Assert.IsTrue(MyDrive.DriveType == DriveType.Fixed, "DriveType failed drive not of Fixed type");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
|
||||
mDebugger.Send("START TEST: Getting all drives info");
|
||||
|
||||
DriveInfo[] xDrives = DriveInfo.GetDrives();
|
||||
|
||||
Assert.IsFalse(xDrives == null, "GetDrives failed: null array returned");
|
||||
|
||||
// I suppose that at least a drive is recognized by Cosmos
|
||||
Assert.IsTrue(xDrives.Length > 0, "GetDrives failed: no drive recognized");
|
||||
|
||||
/* Check that only the Name property of the first one is the same of driveName */
|
||||
Assert.IsTrue(xDrives[0].Name == driveName, "GetDrives failed: first drive is not the same of MyDrive (0:)");
|
||||
|
||||
mDebugger.Send("END TEST");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ namespace Cosmos.Kernel.Tests.Fat2
|
|||
mDebugger.Send("Run");
|
||||
|
||||
FileTest.Execute(mDebugger);
|
||||
DriveInfoTest.Execute(mDebugger);
|
||||
|
||||
TestController.Completed();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,9 @@ namespace Cosmos.System.FileSystem
|
|||
public class CosmosVFS : VFSBase
|
||||
{
|
||||
private List<Partition> mPartitions;
|
||||
|
||||
|
||||
private List<FileSystem> mFileSystems;
|
||||
|
||||
|
||||
private FileSystem mCurrentFileSystem;
|
||||
private List<FileSystemFactory> mRegisteredFileSystems;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the virtual file system.
|
||||
|
|
@ -33,6 +30,9 @@ namespace Cosmos.System.FileSystem
|
|||
{
|
||||
mPartitions = new List<Partition>();
|
||||
mFileSystems = new List<FileSystem>();
|
||||
mRegisteredFileSystems = new List<FileSystemFactory>();
|
||||
|
||||
RegisterFileSystem(new FatFileSystemFactory());
|
||||
|
||||
InitializePartitions();
|
||||
if (mPartitions.Count > 0)
|
||||
|
|
@ -41,6 +41,12 @@ namespace Cosmos.System.FileSystem
|
|||
}
|
||||
}
|
||||
|
||||
public override void RegisterFileSystem(FileSystemFactory aFileSystemFactory)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Registering filesystem {aFileSystemFactory.Name}");
|
||||
mRegisteredFileSystems.Add(aFileSystemFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new file.
|
||||
/// </summary>
|
||||
|
|
@ -400,14 +406,15 @@ namespace Cosmos.System.FileSystem
|
|||
{
|
||||
string xRootPath = string.Concat(i, VolumeSeparatorChar, DirectorySeparatorChar);
|
||||
var xSize = (long)(mPartitions[i].BlockCount * mPartitions[i].BlockSize / 1024 / 1024);
|
||||
switch (FileSystem.GetFileSystemType(mPartitions[i]))
|
||||
|
||||
// We 'probe' the partition <i> with all the FileSystem registered until we find a Filesystem that can read / write to it
|
||||
foreach (var fs in mRegisteredFileSystems)
|
||||
{
|
||||
case FileSystemType.FAT:
|
||||
if (fs.IsType(mPartitions[i]))
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Partion {i} has a {fs.Name} filesystem");
|
||||
mFileSystems.Add(new FatFileSystem(mPartitions[i], xRootPath, xSize));
|
||||
break;
|
||||
default:
|
||||
global::System.Console.WriteLine("Unknown filesystem type!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mFileSystems.Count > 0) && (mFileSystems[mFileSystems.Count - 1].mRootPath == xRootPath))
|
||||
|
|
@ -547,5 +554,70 @@ namespace Cosmos.System.FileSystem
|
|||
|
||||
return aFS.GetRootDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies if driveId is a valid id for a drive.
|
||||
/// </summary>
|
||||
/// <param name="driveId">The id of the drive.</param>
|
||||
/// <returns>true if the drive id is valid, false otherwise.</returns>
|
||||
public override bool IsValidDriveId(string driveId)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"driveId is {driveId} after normalization");
|
||||
|
||||
/* We need to remove ':\' to get only the numeric value */
|
||||
driveId = driveId.Remove(driveId.Length - 2);
|
||||
Global.mFileSystemDebugger.SendInternal($"driveId is now {driveId}");
|
||||
|
||||
/*
|
||||
* Cosmos Drive name is really similar to DOS / Windows but a number instead of a letter is used, it is not limited
|
||||
* to 1 character but any number is valid
|
||||
*/
|
||||
|
||||
bool isOK = Int32.TryParse(driveId, out int val);
|
||||
Global.mFileSystemDebugger.SendInternal($"isOK is {isOK}");
|
||||
|
||||
return isOK;
|
||||
}
|
||||
|
||||
public override long GetTotalSize(string aDriveId)
|
||||
{
|
||||
var xFs = GetFileSystemFromPath(aDriveId);
|
||||
|
||||
return xFs.mSize;
|
||||
}
|
||||
|
||||
public override long GetAvailableFreeSpace(string aDriveId)
|
||||
{
|
||||
var xFs = GetFileSystemFromPath(aDriveId);
|
||||
|
||||
return xFs.mAvailableFreeSpace;
|
||||
}
|
||||
|
||||
public override long GetTotalFreeSpace(string aDriveId)
|
||||
{
|
||||
var xFs = GetFileSystemFromPath(aDriveId);
|
||||
|
||||
return xFs.mTotalFreeSpace;
|
||||
}
|
||||
|
||||
public override string GetFileSystemType(string aDriveId)
|
||||
{
|
||||
var xFs = GetFileSystemFromPath(aDriveId);
|
||||
|
||||
return xFs.mType;
|
||||
}
|
||||
|
||||
public override string GetFileSystemLabel(string aDriveId)
|
||||
{
|
||||
var xFs = GetFileSystemFromPath(aDriveId);
|
||||
|
||||
return xFs.mLabel;
|
||||
}
|
||||
|
||||
public override void SetFileSystemLabel(string aDriveId, string aLabel)
|
||||
{
|
||||
var xFs = GetFileSystemFromPath(aDriveId);
|
||||
xFs.mLabel = aLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -353,6 +353,24 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
|
||||
private readonly Fat[] mFats;
|
||||
|
||||
public override string mType
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (mFatType)
|
||||
{
|
||||
case FatTypeEnum.Fat12:
|
||||
return "FAT12";
|
||||
case FatTypeEnum.Fat16:
|
||||
return "FAT16";
|
||||
case FatTypeEnum.Fat32:
|
||||
return "FAT32";
|
||||
default:
|
||||
throw new Exception("Unknown FAT file system type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FatFileSystem"/> class.
|
||||
/// </summary>
|
||||
|
|
@ -587,7 +605,7 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
}
|
||||
|
||||
var result = new List<DirectoryEntry>();
|
||||
var xEntry = (FatDirectoryEntry)baseDirectory;
|
||||
var xEntry = (FatDiretoryEntry)baseDirectory;
|
||||
var fatListing = xEntry.ReadDirectoryContents();
|
||||
|
||||
for (int i = 0; i < fatListing.Count; i++)
|
||||
|
|
@ -601,7 +619,7 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
{
|
||||
Global.mFileSystemDebugger.SendInternal("-- FatFileSystem.GetRootDirectory --");
|
||||
|
||||
var xRootEntry = new FatDirectoryEntry(this, null, mRootPath, mSize, mRootPath, RootCluster);
|
||||
var xRootEntry = new FatDiretoryEntry(this, null, mRootPath, mSize, mRootPath, RootCluster);
|
||||
return xRootEntry;
|
||||
}
|
||||
|
||||
|
|
@ -623,7 +641,7 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
throw new ArgumentNullException(nameof(aNewDirectory));
|
||||
}
|
||||
|
||||
var xParentDirectory = (FatDirectoryEntry)aParentDirectory;
|
||||
var xParentDirectory = (FatDiretoryEntry)aParentDirectory;
|
||||
var xDirectoryEntryToAdd = xParentDirectory.AddDirectoryEntry(aNewDirectory, DirectoryEntryTypeEnum.Directory);
|
||||
return xDirectoryEntryToAdd;
|
||||
}
|
||||
|
|
@ -646,7 +664,8 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
throw new ArgumentNullException(nameof(aNewFile));
|
||||
}
|
||||
|
||||
var xParentDirectory = (FatDirectoryEntry)aParentDirectory;
|
||||
var xParentDirectory = (FatDiretoryEntry)aParentDirectory;
|
||||
|
||||
var xDirectoryEntryToAdd = xParentDirectory.AddDirectoryEntry(aNewFile, DirectoryEntryTypeEnum.File);
|
||||
return xDirectoryEntryToAdd;
|
||||
}
|
||||
|
|
@ -658,7 +677,7 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
throw new ArgumentNullException(nameof(aDirectoryEntry));
|
||||
}
|
||||
|
||||
var xDirectoryEntry = (FatDirectoryEntry)aDirectoryEntry;
|
||||
var xDirectoryEntry = (FatDiretoryEntry)aDirectoryEntry;
|
||||
|
||||
xDirectoryEntry.DeleteDirectoryEntry();
|
||||
}
|
||||
|
|
@ -670,7 +689,7 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
throw new ArgumentNullException(nameof(aDirectoryEntry));
|
||||
}
|
||||
|
||||
var xDirectoryEntry = (FatDirectoryEntry)aDirectoryEntry;
|
||||
var xDirectoryEntry = (FatDiretoryEntry)aDirectoryEntry;
|
||||
|
||||
var entries = xDirectoryEntry.GetFatTable();
|
||||
|
||||
|
|
@ -682,6 +701,64 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
xDirectoryEntry.DeleteDirectoryEntry();
|
||||
}
|
||||
|
||||
public override string mLabel
|
||||
{
|
||||
/*
|
||||
* In the FAT filesystem the name field of RootDirectory is - in reality - the Volume Label
|
||||
*/
|
||||
get
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal("-- FatFileSystem.mLabel --");
|
||||
var RootDirectory = (FatDiretoryEntry) GetRootDirectory();
|
||||
|
||||
var VolumeId = RootDirectory.FindVolumeId();
|
||||
if (VolumeId == null)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal("No VolumeID, returning drive name");
|
||||
return RootDirectory.mName;
|
||||
}
|
||||
|
||||
Global.mFileSystemDebugger.SendInternal($"Volume label is {VolumeId.mName}");
|
||||
return VolumeId.mName;
|
||||
}
|
||||
set
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Setting Volume label to {value}");
|
||||
|
||||
var RootDirectory = (FatDiretoryEntry) GetRootDirectory();
|
||||
|
||||
var VolumeId = RootDirectory.FindVolumeId();
|
||||
if (VolumeId != null)
|
||||
{
|
||||
VolumeId.SetName(value);
|
||||
return;
|
||||
}
|
||||
|
||||
Global.mFileSystemDebugger.SendInternal("No VolumeID found, let's create it!");
|
||||
|
||||
VolumeId = RootDirectory.CreateVolumeId(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override long mAvailableFreeSpace
|
||||
{
|
||||
get
|
||||
{
|
||||
var RootDirectory = (FatDiretoryEntry)GetRootDirectory();
|
||||
// We do not support "user quotas" for now so this is effectively the same then mTotalFreeSpace
|
||||
return mSize - RootDirectory.GetUsedSpace();
|
||||
}
|
||||
}
|
||||
|
||||
public override long mTotalFreeSpace
|
||||
{
|
||||
get
|
||||
{
|
||||
var RootDirectory = (FatDiretoryEntry)GetRootDirectory();
|
||||
return mSize - RootDirectory.GetUsedSpace();
|
||||
}
|
||||
}
|
||||
|
||||
private enum FatTypeEnum
|
||||
{
|
||||
Unknown,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
|
||||
protected long mPosition;
|
||||
|
||||
private readonly FatDirectoryEntry mDirectoryEntry;
|
||||
private readonly FatDiretoryEntry mDirectoryEntry;
|
||||
|
||||
private readonly FatFileSystem mFS;
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ namespace Cosmos.System.FileSystem.FAT
|
|||
|
||||
private long mSize;
|
||||
|
||||
public FatStream(FatDirectoryEntry aEntry)
|
||||
public FatStream(FatDiretoryEntry aEntry)
|
||||
{
|
||||
if (aEntry == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using Cosmos.System.FileSystem.Listing;
|
|||
|
||||
namespace Cosmos.System.FileSystem.FAT.Listing
|
||||
{
|
||||
internal class FatDirectoryEntry : DirectoryEntry
|
||||
internal class FatDiretoryEntry : DirectoryEntry
|
||||
{
|
||||
private readonly uint mEntryHeaderDataOffset;
|
||||
|
||||
|
|
@ -18,9 +18,9 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
|
||||
// Size is UInt32 because FAT doesn't support bigger.
|
||||
// Don't change to UInt64
|
||||
public FatDirectoryEntry(
|
||||
public FatDiretoryEntry(
|
||||
FatFileSystem aFileSystem,
|
||||
FatDirectoryEntry aParent,
|
||||
FatDiretoryEntry aParent,
|
||||
string aFullPath,
|
||||
string aName,
|
||||
long aSize,
|
||||
|
|
@ -31,6 +31,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
{
|
||||
if (aFirstCluster < aFileSystem.RootCluster)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"aFirstCluster {aFirstCluster} < aFileSystem.RootCluster {aFileSystem.RootCluster}");
|
||||
throw new ArgumentOutOfRangeException(nameof(aFirstCluster));
|
||||
}
|
||||
|
||||
|
|
@ -38,9 +39,9 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
mEntryHeaderDataOffset = aEntryHeaderDataOffset;
|
||||
}
|
||||
|
||||
public FatDirectoryEntry(
|
||||
public FatDiretoryEntry(
|
||||
FatFileSystem aFileSystem,
|
||||
FatDirectoryEntry aParent,
|
||||
FatDiretoryEntry aParent,
|
||||
string aFullPath,
|
||||
long aSize,
|
||||
string aName,
|
||||
|
|
@ -143,7 +144,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
GetFatTable();
|
||||
}
|
||||
|
||||
public FatDirectoryEntry AddDirectoryEntry(string aName, DirectoryEntryTypeEnum aEntryType)
|
||||
public FatDiretoryEntry AddDirectoryEntry(string aName, DirectoryEntryTypeEnum aEntryType)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.AddDirectoryEntry --");
|
||||
Global.mFileSystemDebugger.SendInternal("aName =");
|
||||
|
|
@ -203,7 +204,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
}
|
||||
|
||||
int n = 1;
|
||||
List<FatDirectoryEntry> xDirectoryEntries = ReadDirectoryContents(true);
|
||||
List<FatDiretoryEntry> xDirectoryEntries = ReadDirectoryContents(true);
|
||||
string[] xShortFilenames = new string[xDirectoryEntries.Count];
|
||||
|
||||
for (int i = 0; i < xDirectoryEntries.Count; i++)
|
||||
|
|
@ -279,7 +280,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
Global.mFileSystemDebugger.SendInternal("xEntryHeaderDataOffset =");
|
||||
Global.mFileSystemDebugger.SendInternal(xEntryHeaderDataOffset);
|
||||
|
||||
var xNewEntry = new FatDirectoryEntry((FatFileSystem)mFileSystem, this, xFullPath, aName, 0, xFirstCluster, xEntryHeaderDataOffset, aEntryType);
|
||||
var xNewEntry = new FatDiretoryEntry((FatFileSystem)mFileSystem, this, xFullPath, aName, 0, xFirstCluster, xEntryHeaderDataOffset, aEntryType);
|
||||
|
||||
xNewEntry.AllocateDirectoryEntry(xShortName);
|
||||
|
||||
|
|
@ -289,6 +290,8 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
throw new ArgumentOutOfRangeException(nameof(aEntryType), "Unknown directory entry type.");
|
||||
}
|
||||
|
||||
private bool IsRootDirectory() => (mParent == null) ? true : false;
|
||||
|
||||
public void DeleteDirectoryEntry()
|
||||
{
|
||||
if (mEntryType == DirectoryEntryTypeEnum.Unknown)
|
||||
|
|
@ -296,25 +299,23 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
if (mParent != null)
|
||||
if (IsRootDirectory())
|
||||
{
|
||||
var xData = ((FatDirectoryEntry)mParent).GetDirectoryEntryData();
|
||||
|
||||
var xEntryOffset = mEntryHeaderDataOffset - 32;
|
||||
|
||||
while (xData[xEntryOffset + 11] == FatDirectoryEntryAttributeConsts.LongName)
|
||||
{
|
||||
xData[xEntryOffset] = FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry;
|
||||
xEntryOffset -= 32;
|
||||
}
|
||||
|
||||
((FatDirectoryEntry)mParent).SetDirectoryEntryData(xData);
|
||||
throw new Exception("Root directory can not be deleted");
|
||||
}
|
||||
else
|
||||
|
||||
var xData = ((FatDiretoryEntry)mParent).GetDirectoryEntryData();
|
||||
|
||||
var xEntryOffset = mEntryHeaderDataOffset - 32;
|
||||
|
||||
while (xData[xEntryOffset + 11] == FatDirectoryEntryAttributeConsts.LongName)
|
||||
{
|
||||
throw new Exception("Parent directory is null");
|
||||
xData[xEntryOffset] = FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry;
|
||||
xEntryOffset -= 32;
|
||||
}
|
||||
|
||||
((FatDiretoryEntry)mParent).SetDirectoryEntryData(xData);
|
||||
|
||||
SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata.FirstByte, FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry);
|
||||
|
||||
// GetFatTable calls GetFatChain, which "refreshes" the FAT table and clusters
|
||||
|
|
@ -322,16 +323,16 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a <see cref="List{T}"/> of <see cref="FatDirectoryEntry"/> objects that represent the Directory Entries inside this Directory
|
||||
/// Retrieves a <see cref="List{T}"/> of <see cref="FatDiretoryEntry"/> objects that represent the Directory Entries inside this Directory
|
||||
/// </summary>
|
||||
/// <returns>Returns a <see cref="List{T}"/> of the Directory Entries inside this Directory</returns>
|
||||
public List<FatDirectoryEntry> ReadDirectoryContents(bool aReturnShortFilenames = false)
|
||||
public List<FatDiretoryEntry> ReadDirectoryContents(bool aReturnShortFilenames = false)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.ReadDirectoryContents --");
|
||||
|
||||
var xData = GetDirectoryEntryData();
|
||||
var xResult = new List<FatDirectoryEntry>();
|
||||
FatDirectoryEntry xParent = this;
|
||||
var xResult = new List<FatDiretoryEntry>();
|
||||
FatDiretoryEntry xParent = this;
|
||||
|
||||
//TODO: Change xLongName to StringBuilder
|
||||
string xLongName = "";
|
||||
|
|
@ -474,7 +475,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
}
|
||||
|
||||
string xFullPath = Path.Combine(mFullPath, xName);
|
||||
var xEntry = new FatDirectoryEntry(((FatFileSystem)mFileSystem), xParent, xFullPath, xName, xSize, xFirstCluster, i, DirectoryEntryTypeEnum.File);
|
||||
var xEntry = new FatDiretoryEntry(((FatFileSystem)mFileSystem), xParent, xFullPath, xName, xSize, xFirstCluster, i, DirectoryEntryTypeEnum.File);
|
||||
xResult.Add(xEntry);
|
||||
Global.mFileSystemDebugger.SendInternal(xEntry.mName + " - " + xEntry.mSize + " bytes");
|
||||
}
|
||||
|
|
@ -482,7 +483,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
{
|
||||
string xFullPath = Path.Combine(mFullPath, xName);
|
||||
uint xSize = xData.ToUInt32(i + 28);
|
||||
var xEntry = new FatDirectoryEntry(((FatFileSystem)mFileSystem), xParent, xFullPath, xName, xSize, xFirstCluster, i, DirectoryEntryTypeEnum.Directory);
|
||||
var xEntry = new FatDiretoryEntry(((FatFileSystem)mFileSystem), xParent, xFullPath, xName, xSize, xFirstCluster, i, DirectoryEntryTypeEnum.Directory);
|
||||
Global.mFileSystemDebugger.SendInternal(xEntry.mName + " <DIR> " + xEntry.mSize + " bytes : Attrib = " + xAttrib + ", Status = " + xStatus);
|
||||
xResult.Add(xEntry);
|
||||
}
|
||||
|
|
@ -502,6 +503,62 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
return xResult;
|
||||
}
|
||||
|
||||
public FatDiretoryEntry FindVolumeId()
|
||||
{
|
||||
if (!IsRootDirectory())
|
||||
{
|
||||
throw new Exception("VolumeId can be found only in Root Directory");
|
||||
}
|
||||
|
||||
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.FindVolumeId --");
|
||||
|
||||
var xData = GetDirectoryEntryData();
|
||||
FatDiretoryEntry xParent = this;
|
||||
|
||||
FatDiretoryEntry xResult = null;
|
||||
for (uint i = 0; i < xData.Length; i = i + 32)
|
||||
{
|
||||
byte xAttrib = xData[i + 11];
|
||||
|
||||
//if ((xAttrib & FatDirectoryEntryAttributeConsts.VolumeID) != FatDirectoryEntryAttributeConsts.VolumeID)
|
||||
if (xAttrib != FatDirectoryEntryAttributeConsts.VolumeID)
|
||||
continue;
|
||||
|
||||
Global.mFileSystemDebugger.SendInternal("VolumeID Found");
|
||||
/* The Label in FAT could be only a shortName (limited to 11 characters) so it is more easy */
|
||||
string xName = xData.GetAsciiString(i, 11).TrimEnd();
|
||||
string xFullPath = Path.Combine(mFullPath, xName);
|
||||
/* Probably can be OK to hardcode 0 here */
|
||||
uint xSize = xData.ToUInt32(i + 28);
|
||||
//uint xFirstCluster = (uint)(xData.ToUInt16(i + 20) << 16 | xData.ToUInt16(i + 26));
|
||||
uint xFirstCluster = xParent.mFirstClusterNum;
|
||||
|
||||
Global.mFileSystemDebugger.SendInternal($"VolumeID Found xName {xName} xFullPath {xFullPath} xSize {xSize} xFirstCluster {xFirstCluster}");
|
||||
|
||||
xResult = new FatDiretoryEntry(((FatFileSystem)mFileSystem), xParent, xFullPath, xName, xSize, xFirstCluster, i, DirectoryEntryTypeEnum.File);
|
||||
break;
|
||||
}
|
||||
|
||||
if (xResult == null)
|
||||
Global.mFileSystemDebugger.SendInternal($"VolumeID not found, returning null");
|
||||
|
||||
return xResult;
|
||||
}
|
||||
|
||||
public FatDiretoryEntry CreateVolumeId(string name)
|
||||
{
|
||||
if (!IsRootDirectory())
|
||||
{
|
||||
throw new Exception("VolumeId can be created only in Root Directory");
|
||||
}
|
||||
|
||||
// VolumeId is really a special type of File with attribute 'VolumeID' set
|
||||
var VolumeId = AddDirectoryEntry(name, DirectoryEntryTypeEnum.File);
|
||||
VolumeId.SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata.Attributes, FatDirectoryEntryAttributeConsts.VolumeID);
|
||||
|
||||
return VolumeId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find an empty space for a directory entry and returns the offset to that space if successful, otherwise throws an exception.
|
||||
/// </summary>
|
||||
|
|
@ -614,23 +671,21 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
Global.mFileSystemDebugger.SendInternal("aValue =");
|
||||
Global.mFileSystemDebugger.SendInternal(aValue);
|
||||
|
||||
if (mParent != null)
|
||||
{
|
||||
var xData = ((FatDirectoryEntry)mParent).GetDirectoryEntryData();
|
||||
|
||||
if (xData.Length > 0)
|
||||
{
|
||||
var xValue = new byte[aEntryMetadata.DataLength];
|
||||
xValue.SetUInt32(0, aValue);
|
||||
uint offset = mEntryHeaderDataOffset + aEntryMetadata.DataOffset;
|
||||
Array.Copy(xValue, 0, xData, offset, aEntryMetadata.DataLength);
|
||||
((FatDirectoryEntry)mParent).SetDirectoryEntryData(xData);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (IsRootDirectory())
|
||||
{
|
||||
throw new Exception("Root directory metadata can not be changed using the file stream.");
|
||||
}
|
||||
|
||||
var xData = ((FatDiretoryEntry)mParent).GetDirectoryEntryData();
|
||||
|
||||
if (xData.Length > 0)
|
||||
{
|
||||
var xValue = new byte[aEntryMetadata.DataLength];
|
||||
xValue.SetUInt32(0, aValue);
|
||||
uint offset = mEntryHeaderDataOffset + aEntryMetadata.DataOffset;
|
||||
Array.Copy(xValue, 0, xData, offset, aEntryMetadata.DataLength);
|
||||
((FatDiretoryEntry)mParent).SetDirectoryEntryData(xData);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, long aValue)
|
||||
|
|
@ -639,25 +694,23 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
Global.mFileSystemDebugger.SendInternal("aValue =");
|
||||
Global.mFileSystemDebugger.SendInternal(aValue);
|
||||
|
||||
if (mParent != null)
|
||||
{
|
||||
var xData = ((FatDirectoryEntry)mParent).GetDirectoryEntryData();
|
||||
|
||||
if (xData.Length > 0)
|
||||
{
|
||||
var xValue = new byte[aEntryMetadata.DataLength];
|
||||
xValue.SetUInt32(0, (uint)aValue);
|
||||
uint offset = mEntryHeaderDataOffset + aEntryMetadata.DataOffset;
|
||||
Global.mFileSystemDebugger.SendInternal("offset =");
|
||||
Global.mFileSystemDebugger.SendInternal(offset);
|
||||
Array.Copy(xValue, 0, xData, offset, aEntryMetadata.DataLength);
|
||||
((FatDirectoryEntry)mParent).SetDirectoryEntryData(xData);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (IsRootDirectory())
|
||||
{
|
||||
throw new Exception("Root directory metadata can not be changed using the file stream.");
|
||||
}
|
||||
|
||||
var xData = ((FatDiretoryEntry)mParent).GetDirectoryEntryData();
|
||||
|
||||
if (xData.Length > 0)
|
||||
{
|
||||
var xValue = new byte[aEntryMetadata.DataLength];
|
||||
xValue.SetUInt32(0, (uint)aValue);
|
||||
uint offset = mEntryHeaderDataOffset + aEntryMetadata.DataOffset;
|
||||
Global.mFileSystemDebugger.SendInternal("offset =");
|
||||
Global.mFileSystemDebugger.SendInternal(offset);
|
||||
Array.Copy(xValue, 0, xData, offset, aEntryMetadata.DataLength);
|
||||
((FatDiretoryEntry)mParent).SetDirectoryEntryData(xData);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, string aValue)
|
||||
|
|
@ -666,7 +719,12 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
Global.mFileSystemDebugger.SendInternal("aValue =");
|
||||
Global.mFileSystemDebugger.SendInternal(aValue);
|
||||
|
||||
var xData = ((FatDirectoryEntry)mParent).GetDirectoryEntryData();
|
||||
if (IsRootDirectory())
|
||||
{
|
||||
throw new Exception("Root directory metadata can not be changed using the file stream.");
|
||||
}
|
||||
|
||||
var xData = ((FatDiretoryEntry)mParent).GetDirectoryEntryData();
|
||||
|
||||
if (xData.Length > 0)
|
||||
{
|
||||
|
|
@ -676,7 +734,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
uint offset = mEntryHeaderDataOffset + aEntryMetadata.DataOffset;
|
||||
Array.Copy(xValue, 0, xData, offset, aEntryMetadata.DataLength);
|
||||
|
||||
((FatDirectoryEntry)mParent).SetDirectoryEntryData(xData);
|
||||
((FatDiretoryEntry)mParent).SetDirectoryEntryData(xData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -791,5 +849,100 @@ namespace Cosmos.System.FileSystem.FAT.Listing
|
|||
|
||||
return xChecksum;
|
||||
}
|
||||
|
||||
private long GetDirectoryEntrySize(byte[] DirectoryEntryData)
|
||||
{
|
||||
long xResult = 0;
|
||||
|
||||
for (uint i = 0; i < DirectoryEntryData.Length; i = i + 32)
|
||||
{
|
||||
byte xAttrib = DirectoryEntryData[i + 11];
|
||||
byte xStatus = DirectoryEntryData[i];
|
||||
|
||||
if (xAttrib == FatDirectoryEntryAttributeConsts.LongName)
|
||||
{
|
||||
//Global.mFileSystemDebugger.SendInternal($"-- FatDirectoryEntry.GetDirectoryEntrySize() LongName DirEntry skipped!");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (xStatus == 0x00)
|
||||
{
|
||||
//Global.mFileSystemDebugger.SendInternal("<EOF> : Attrib = " + xAttrib + ", Status = " + xStatus);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (xStatus)
|
||||
{
|
||||
case 0x05:
|
||||
// Japanese characters - We dont handle these
|
||||
continue;
|
||||
case 0x2E:
|
||||
// Dot entry
|
||||
continue;
|
||||
case FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry:
|
||||
// Empty slot, skip it
|
||||
continue;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int xTest = xAttrib & (FatDirectoryEntryAttributeConsts.Directory | FatDirectoryEntryAttributeConsts.VolumeID);
|
||||
|
||||
switch (xTest)
|
||||
{
|
||||
// Normal file
|
||||
case 0:
|
||||
uint xSize = DirectoryEntryData.ToUInt32(i + 28);
|
||||
xResult += xSize;
|
||||
break;
|
||||
|
||||
case FatDirectoryEntryAttributeConsts.Directory:
|
||||
//Global.mFileSystemDebugger.SendInternal($"-- FatDirectoryEntry.GetDirectoryEntrySize() found directory: recursing!");
|
||||
|
||||
uint xFirstCluster = (uint)(DirectoryEntryData.ToUInt16(i + 20) << 16 | DirectoryEntryData.ToUInt16(i + 26));
|
||||
byte[] xDirData;
|
||||
((FatFileSystem)mFileSystem).Read(xFirstCluster, out xDirData);
|
||||
|
||||
xResult += GetDirectoryEntrySize(xDirData);
|
||||
break;
|
||||
|
||||
case FatDirectoryEntryAttributeConsts.VolumeID:
|
||||
//Global.mFileSystemDebugger.SendInternal("<VOLUME ID>: skipped");
|
||||
continue;
|
||||
|
||||
default:
|
||||
//Global.mFileSystemDebugger.SendInternal("<INVALID ENTRY>: skipped");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//Global.mFileSystemDebugger.SendInternal($"-- FatDirectoryEntry.GetDirectoryEntrySize() is {xResult} bytes");
|
||||
return xResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* Please note that this could become slower and slower as the partion becomes greater this could be optimized in two ways:
|
||||
* 1. Compute the value using this function on FS inizialization and write the difference between TotalSpace and the computed
|
||||
* value to the specif field of 'FS Information Sector' of FAT32
|
||||
* 2. Compute the value using this function on FS inizialization and write the difference between TotalSpace and the computed
|
||||
* value in a sort of memory cache in VFS itself
|
||||
*
|
||||
* In any case if one of this two methods will be used in the future when a file is removed or new data are written on it,
|
||||
* the value on the field should be always updated.
|
||||
*/
|
||||
public override long GetUsedSpace()
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"-- FatDirectoryEntry.GetUsedSpace() on Directory {mName} ---");
|
||||
|
||||
long xResult = 0;
|
||||
|
||||
var xData = GetDirectoryEntryData();
|
||||
|
||||
xResult += GetDirectoryEntrySize(xData);
|
||||
|
||||
Global.mFileSystemDebugger.SendInternal($"-- FatDirectoryEntry.GetUsedSpace() is {xResult} bytes");
|
||||
return xResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
23
source/Cosmos.System2/FileSystem/FatFileSystemFactory.cs
Normal file
23
source/Cosmos.System2/FileSystem/FatFileSystemFactory.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using Cosmos.HAL.BlockDevice;
|
||||
using Cosmos.System.FileSystem.FAT;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Cosmos.System.FileSystem
|
||||
{
|
||||
public class FatFileSystemFactory : FileSystemFactory
|
||||
{
|
||||
public override string Name { get => "FAT"; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FatFileSystem"/> class.
|
||||
/// </summary>
|
||||
/// <param name="aDevice">The partition.</param>
|
||||
/// <param name="aRootPath">The root path.</param>
|
||||
/// <exception cref="Exception">FAT signature not found.</exception>
|
||||
public override FileSystem Create(Partition aDevice, string aRootPath, long aSize) => new FatFileSystem(aDevice, aRootPath, aSize);
|
||||
|
||||
public override bool IsType(Partition aDevice) => FatFileSystem.IsDeviceFat(aDevice);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,16 +16,6 @@ namespace Cosmos.System.FileSystem
|
|||
mSize = aSize;
|
||||
}
|
||||
|
||||
public static FileSystemType GetFileSystemType(Partition aDevice)
|
||||
{
|
||||
if (FatFileSystem.IsDeviceFat(aDevice))
|
||||
{
|
||||
return FileSystemType.FAT;
|
||||
}
|
||||
|
||||
return FileSystemType.Unknown;
|
||||
}
|
||||
|
||||
public abstract void DisplayFileSystemInfo();
|
||||
|
||||
public abstract List<DirectoryEntry> GetDirectoryListing(DirectoryEntry baseDirectory);
|
||||
|
|
@ -45,5 +35,13 @@ namespace Cosmos.System.FileSystem
|
|||
public string mRootPath { get; }
|
||||
|
||||
public long mSize { get; }
|
||||
|
||||
public abstract long mAvailableFreeSpace { get; }
|
||||
|
||||
public abstract long mTotalFreeSpace { get; }
|
||||
|
||||
public abstract string mType { get; }
|
||||
|
||||
public abstract string mLabel { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
source/Cosmos.System2/FileSystem/FileSystemFactory.cs
Normal file
16
source/Cosmos.System2/FileSystem/FileSystemFactory.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using Cosmos.HAL.BlockDevice;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Cosmos.System.FileSystem
|
||||
{
|
||||
public class FileSystemFactory
|
||||
{
|
||||
public virtual string Name { get; private set; }
|
||||
|
||||
public virtual FileSystem Create(Partition aDevice, string aRootPath, long aSize) => null;
|
||||
|
||||
public virtual bool IsType(Partition aDevice) => false;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
public enum FileSystemType
|
||||
{
|
||||
Unknown = 0,
|
||||
FAT,
|
||||
Unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,5 +79,7 @@ namespace Cosmos.System.FileSystem.Listing
|
|||
public abstract void SetSize(long aSize);
|
||||
|
||||
public abstract Stream GetFileStream();
|
||||
|
||||
public abstract long GetUsedSpace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ namespace Cosmos.System.FileSystem.VFS
|
|||
{
|
||||
public abstract void Initialize();
|
||||
|
||||
public abstract void RegisterFileSystem(FileSystemFactory aFileSystemFactory);
|
||||
|
||||
public abstract DirectoryEntry CreateFile(string aPath);
|
||||
|
||||
public abstract DirectoryEntry CreateDirectory(string aPath);
|
||||
|
|
@ -37,5 +39,19 @@ namespace Cosmos.System.FileSystem.VFS
|
|||
public static char AltDirectorySeparatorChar { get { return '/'; } }
|
||||
|
||||
public static char VolumeSeparatorChar { get { return ':'; } }
|
||||
|
||||
public abstract bool IsValidDriveId(string driveId);
|
||||
|
||||
public abstract long GetTotalSize(string aDriveId);
|
||||
|
||||
public abstract long GetAvailableFreeSpace(string aDriveId);
|
||||
|
||||
public abstract long GetTotalFreeSpace(string aDriveId);
|
||||
|
||||
public abstract string GetFileSystemType(string aDriveId);
|
||||
|
||||
public abstract string GetFileSystemLabel(string aDriveId);
|
||||
|
||||
public abstract void SetFileSystemLabel(string aDriveId, string aLabel);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,19 +201,20 @@ namespace Cosmos.System.FileSystem.VFS
|
|||
return mVFS.GetVolumes();
|
||||
}
|
||||
|
||||
public static void RegisterFileSystem(FileSystemFactory aFileSystemFactory)
|
||||
{
|
||||
mVFS.RegisterFileSystem(aFileSystemFactory);
|
||||
}
|
||||
|
||||
public static List<string> GetLogicalDrives()
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetLogicalDrives ---");
|
||||
|
||||
//TODO: Directory.GetLogicalDrives() will call this.
|
||||
return null;
|
||||
|
||||
/*
|
||||
List<string> xDrives = new List<string>();
|
||||
foreach (FilesystemEntry entry in GetVolumes())
|
||||
xDrives.Add(entry.Name + Path.VolumeSeparatorChar + Path.DirectorySeparatorChar);
|
||||
return xDrives.ToArray();
|
||||
*/
|
||||
foreach (DirectoryEntry entry in GetVolumes())
|
||||
xDrives.Add(entry.mName + Path.VolumeSeparatorChar + Path.DirectorySeparatorChar);
|
||||
|
||||
return xDrives;
|
||||
}
|
||||
|
||||
public static List<string> InternalGetFileDirectoryNames(
|
||||
|
|
@ -430,6 +431,43 @@ namespace Cosmos.System.FileSystem.VFS
|
|||
Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFileAttributes ---");
|
||||
mVFS.SetFileAttributes(aPath, fileAttributes);
|
||||
}
|
||||
|
||||
public static bool IsValidDriveId(string aPath)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFileAttributes ---");
|
||||
return mVFS.IsValidDriveId(aPath);
|
||||
}
|
||||
|
||||
public static long GetTotalSize(string aDriveId)
|
||||
{
|
||||
return mVFS.GetTotalSize(aDriveId);
|
||||
}
|
||||
|
||||
public static long GetAvailableFreeSpace(string aDriveId)
|
||||
{
|
||||
return mVFS.GetAvailableFreeSpace(aDriveId);
|
||||
}
|
||||
|
||||
public static long GetTotalFreeSpace(string aDriveId)
|
||||
{
|
||||
return mVFS.GetTotalFreeSpace(aDriveId);
|
||||
}
|
||||
|
||||
public static string GetFileSystemType(string aDriveId)
|
||||
{
|
||||
return mVFS.GetFileSystemType(aDriveId);
|
||||
}
|
||||
|
||||
public static string GetFileSystemLabel(string aDriveId)
|
||||
{
|
||||
return mVFS.GetFileSystemLabel(aDriveId);
|
||||
}
|
||||
|
||||
public static void SetFileSystemLabel(string aDriveId, string aLabel)
|
||||
{
|
||||
mVFS.SetFileSystemLabel(aDriveId, aLabel);
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
public static char GetAltDirectorySeparatorChar()
|
||||
|
|
|
|||
115
source/Cosmos.System2_Plugs/System/IO/CosmosDriveInfo.cs
Normal file
115
source/Cosmos.System2_Plugs/System/IO/CosmosDriveInfo.cs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
//#define COSMOSDEBUG
|
||||
using Cosmos.System;
|
||||
using Cosmos.System.FileSystem;
|
||||
using Cosmos.System.FileSystem.VFS;
|
||||
using IL2CPU.API.Attribs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Cosmos.System_Plugs.System.IO
|
||||
{
|
||||
[Plug(Target = typeof(DriveInfo))]
|
||||
public static class DriveInfoImpl
|
||||
{
|
||||
public static string NormalizeDriveName(string driveName)
|
||||
{
|
||||
string name;
|
||||
|
||||
if (driveName.Length == 1)
|
||||
name = driveName + ":\\";
|
||||
else
|
||||
{
|
||||
name = Path.GetPathRoot(driveName);
|
||||
// Disallow null or empty drive letters and UNC paths
|
||||
if (name == null || name.Length == 0 || name.StartsWith("\\\\", StringComparison.Ordinal))
|
||||
throw new ArgumentException("Argument must be drive identifier or root dir");
|
||||
}
|
||||
// We want to normalize to have a trailing backslash so we don't have two equivalent forms and
|
||||
// because some Win32 API don't work without it.
|
||||
if (name.Length == 2 && name[1] == ':')
|
||||
{
|
||||
name = name + "\\";
|
||||
}
|
||||
|
||||
if (!VFSManager.IsValidDriveId(name))
|
||||
{
|
||||
throw new ArgumentException("Argument must be drive identifier or root dir");
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static long get_AvailableFreeSpace(DriveInfo aThis)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Getting Available Free Space of {aThis.Name}");
|
||||
|
||||
return VFSManager.GetAvailableFreeSpace(aThis.Name);
|
||||
}
|
||||
|
||||
public static long get_TotalFreeSpace(DriveInfo aThis)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Getting Total Free Space of {aThis.Name}");
|
||||
|
||||
return VFSManager.GetTotalFreeSpace(aThis.Name);
|
||||
}
|
||||
|
||||
public static long get_TotalSize(DriveInfo aThis)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Getting size of {aThis.Name}");
|
||||
|
||||
return VFSManager.GetTotalSize(aThis.Name);
|
||||
}
|
||||
|
||||
public static string get_DriveFormat(DriveInfo aThis)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Getting format of {aThis.Name}");
|
||||
|
||||
return VFSManager.GetFileSystemType(aThis.Name);
|
||||
}
|
||||
|
||||
public static string get_VolumeLabel(DriveInfo aThis)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Getting label of {aThis.Name}");
|
||||
|
||||
return VFSManager.GetFileSystemLabel(aThis.Name);
|
||||
}
|
||||
|
||||
public static void set_VolumeLabel(DriveInfo aThis, string aLabel)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Setting label of {aThis.Name} with {aLabel}");
|
||||
|
||||
VFSManager.SetFileSystemLabel(aThis.Name, aLabel);
|
||||
}
|
||||
|
||||
/* For now I'm forcing IsReady to be always true as only fixed drives are supported in Cosmos for now */
|
||||
public static bool get_IsReady(DriveInfo aThis)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Getting isReady status of {aThis.Name}");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* For now I'm forcing DriveType to always be 'Fixed' as only fixed drives are supported in Cosmos for now */
|
||||
public static DriveType get_DriveType(DriveInfo aThis)
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal($"Getting DriveType of {aThis.Name}");
|
||||
return DriveType.Fixed;
|
||||
}
|
||||
|
||||
public static DriveInfo[] GetDrives()
|
||||
{
|
||||
Global.mFileSystemDebugger.SendInternal("GetDrives called");
|
||||
|
||||
List<string> drives = VFSManager.GetLogicalDrives();
|
||||
|
||||
DriveInfo[] result = new DriveInfo[drives.Count];
|
||||
for (int i = 0; i < drives.Count; i++)
|
||||
{
|
||||
result[i] = new DriveInfo(drives[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,5 +46,20 @@ namespace Cosmos.System_Plugs.System
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* .Net Core TryParse is calling Number.TryParse() that does NRE in Cosmos, plugged it for now */
|
||||
public static bool TryParse(string s, out int result)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = Int32.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
result = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue