Cosmos/source/Cosmos.System/SentinelVFS.cs
2015-10-02 19:39:56 +02:00

259 lines
9.4 KiB
C#

//using Cosmos.HAL.BlockDevice;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Cosmos.HAL.BlockDevice;
using Cosmos.System.FileSystem;
using Cosmos.System.FileSystem.FAT;
using Cosmos.System.FileSystem.Listing;
using Cosmos.System.FileSystem.VFS;
using Directory = Cosmos.System.FileSystem.Listing.Directory;
namespace Cosmos.System
{
[Serializable]
public struct KVP<TKey, TValue>
{
private readonly TKey key;
private readonly TValue value;
public KVP(TKey key, TValue value)
{
this.key = key;
this.value = value;
}
public TKey Key
{
get { return key; }
}
public TValue Value
{
get { return value; }
}
}
public class SentinelVFS : VFSBase
{
private List<Partition> mPartitions;
private List<KVP<string, Cosmos.System.FileSystem.FileSystem>> mFileSystems;
protected virtual void InitializePartitions()
{
for (int i = 0; i < BlockDevice.Devices.Count; i++)
{
var xBlockDevice = BlockDevice.Devices[i];
FatHelpers.Debug("BlockDevice found: ");
FatHelpers.Debug(xBlockDevice.ToString());
var xItem = xBlockDevice as Partition;
if (xItem == null && xBlockDevice.ToString() == "Partition")
{
FatHelpers.Debug("BlockDevice returns partition, but type check doesn't work!");
}
xItem = xBlockDevice as Partition;
if (xItem != null)
{
mPartitions.Add(xItem);
break;
}
}
if (mPartitions.Count > 0)
{
for (int i = 0; i < mPartitions.Count; i++)
{
FatHelpers.Debug("Partition #: " + (i + 1));
FatHelpers.Debug("Block Size: " + mPartitions[i].BlockSize + " bytes");
FatHelpers.Debug("Size: " + mPartitions[i].BlockCount * mPartitions[i].BlockSize / 1024 / 1024 + " MB");
}
}
else
{
FatHelpers.Debug("No partitions found!");
}
}
protected virtual void InitializeFileSystems()
{
for (int i = 0; i < mPartitions.Count; i++)
{
string xRootPath = string.Concat(i, VolumeSeparatorChar, DirectorySeparatorChar);
Cosmos.System.FileSystem.FileSystem xFileSystem = null;
switch (Cosmos.System.FileSystem.FileSystem.GetFileSystemType(mPartitions[i]))
{
case FileSystemType.FAT:
xFileSystem = new FatFileSystem(mPartitions[i]);
mFileSystems.Add(new KVP<string, Cosmos.System.FileSystem.FileSystem>(xRootPath, xFileSystem));
break;
default:
FatHelpers.Debug("Unknown filesystem type!");
return;
}
//global::System.Console.Write("i = ");
//global::System.Console.WriteLine(i.ToString());
//global::System.Console.Write("mFileSystems.Count = ");
//global::System.Console.WriteLine(mFileSystems.Count);
var xEntry = mFileSystems[i];
if (xEntry.Key == xRootPath)
{
var xFatFS = (FatFileSystem)xFileSystem;
FatHelpers.Debug("-------File System--------");
FatHelpers.Debug("Bytes per Cluster: " + xFatFS.BytesPerCluster);
FatHelpers.Debug("Bytes per Sector: " + xFatFS.BytesPerSector);
FatHelpers.Debug("Cluster Count: " + xFatFS.ClusterCount);
FatHelpers.Debug("Data Sector: " + xFatFS.DataSector);
FatHelpers.Debug("Data Sector Count: " + xFatFS.DataSectorCount);
FatHelpers.Debug("FAT Sector Count: " + xFatFS.FatSectorCount);
FatHelpers.Debug("FAT Type: " + xFatFS.FatType);
FatHelpers.Debug("Number of FATS: " + xFatFS.NumberOfFATs);
FatHelpers.Debug("Reserved Sector Count: " + xFatFS.ReservedSectorCount);
FatHelpers.Debug("Root Cluster: " + xFatFS.RootCluster);
FatHelpers.Debug("Root Entry Count: " + xFatFS.RootEntryCount);
FatHelpers.Debug("Root Sector: " + xFatFS.RootSector);
FatHelpers.Debug("Root Sector Count: " + xFatFS.RootSectorCount);
FatHelpers.Debug("Sectors per Cluster: " + xFatFS.SectorsPerCluster);
FatHelpers.Debug("Total Sector Count: " + xFatFS.TotalSectorCount);
//Console.WriteLine();
//Console.WriteLine("Mapping Drive C...");
//FatFileSystem.AddMapping("C", mFileSystem);
//SentinelKernel.System.Filesystem.FAT.Listing.FatDirectory dir = new Sys.Filesystem.FAT.Listing.FatDirectory(mFileSystem, "Sentinel");
}
else
{
FatHelpers.Debug("No filesystem found.");
}
}
}
protected Cosmos.System.FileSystem.FileSystem GetFileSystemFromPath(string aPath)
{
FatHelpers.Debug("In SentinelVFS.GetFileSystemFromPath");
string xPath = Path.GetPathRoot(aPath);
FatHelpers.Debug("PathRoot retrieved");
for (int i = 0; i < mFileSystems.Count; i++)
{
string xTest = mFileSystems[i].Key;
if (String.Equals(xTest, xPath))
{
return mFileSystems[i].Value;
}
}
throw new Exception("Unable to determine filesystem for path: " + aPath);
}
public override void Initialize()
{
mPartitions = new List<Partition>();
mFileSystems = new List<KVP<string, Cosmos.System.FileSystem.FileSystem>>();
InitializePartitions();
if (mPartitions.Count > 0)
{
InitializeFileSystems();
}
}
public override Directory GetDirectory(string aPath)
{
FatHelpers.Debug("In SentinelVFS.GetDirectory");
var xFS = GetFileSystemFromPath(aPath);
if (xFS == null)
{
FatHelpers.Debug("No FS found for path!");
}
else
{
FatHelpers.Debug("Filesystem found.");
}
return DoGetDirectory(aPath, xFS);
}
private Directory DoGetDirectory(string aPath, Cosmos.System.FileSystem.FileSystem aFS)
{
if (aFS == null)
{
throw new ArgumentNullException("aFS");
}
FatHelpers.Debug("In SentinelVFS.DoGetDirectory");
FatHelpers.Debug("Path = " + aPath);
string[] xPathParts = VFSManager.SplitPath(aPath);
if (xPathParts.Length == 1)
{
return GetVolume(aFS, aPath);
}
Directory xBaseDirectory = null;
// start at index 1, because 0 is the volume
for (int i = 1; i < xPathParts.Length; i++)
{
var xPathPart = xPathParts[i];
var xPartFound = false;
var xListing = aFS.GetDirectoryListing(xBaseDirectory);
for (int j = 0; j < xListing.Count; j++)
{
var xListingItem = xListing[j];
if (String.Equals(xListingItem.Name, xPathPart, StringComparison.OrdinalIgnoreCase))
{
if (xListingItem is Directory)
{
xBaseDirectory = (Directory)xListingItem;
xPartFound = true;
}
else
{
throw new Exception("Path part '" + xPathPart + "' found, but not a directory!");
}
}
}
if (!xPartFound)
{
throw new Exception("Path part '" + xPathPart + "' not found!");
}
}
return xBaseDirectory;
}
public override List<Base> GetDirectoryListing(string aPath)
{
FatHelpers.Debug("In SentinelVFS.GetDirectoryListing");
var xFS = GetFileSystemFromPath(aPath);
FatHelpers.Debug("Filesystem retrieved");
var xDirectory = DoGetDirectory(aPath, xFS);
FatHelpers.Debug("Base directory retrieved.");
return xFS.GetDirectoryListing(xDirectory);
}
public override List<Base> GetDirectoryListing(Directory aParentDirectory)
{
throw new NotImplementedException();
}
public override Directory GetVolume(string aVolume)
{
throw new NotImplementedException();
}
public override List<Directory> GetVolumes()
{
throw new NotImplementedException();
}
public Directory GetVolume(Cosmos.System.FileSystem.FileSystem filesystem, string name)
{
return filesystem.GetRootDirectory(name);
}
}
}