diff --git a/source/SDFS Demo/Kernel.cs b/source/SDFS Demo/Kernel.cs
deleted file mode 100644
index f48e0b1..0000000
--- a/source/SDFS Demo/Kernel.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Sys = Cosmos.System;
-
-namespace SDFS_Demo
-{
- public class Kernel : Sys.Kernel
- {
- protected override void BeforeRun()
- {
- Console.WriteLine("Cosmos booted successfully. Type a line of text to get it echoed back.");
- }
-
- protected override void Run()
- {
- Console.Write("Input: ");
- var input = Console.ReadLine();
- Console.Write("Text typed: ");
- Console.WriteLine(input);
- }
- }
-}
diff --git a/source/SDFS.sln b/source/SDFS.sln
index ef3141a..709b437 100644
--- a/source/SDFS.sln
+++ b/source/SDFS.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28306.52
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDFS Demo", "SDFS Demo\SDFS Demo.csproj", "{12BDB11A-DDC1-4EBE-A4D4-CDE925AB599B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDFS_Demo", "SDFS_Demo\SDFS_Demo.csproj", "{12BDB11A-DDC1-4EBE-A4D4-CDE925AB599B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDFS", "SDFS\SDFS.csproj", "{7992A7ED-E612-4D4D-A6A7-4064ADEB90B4}"
EndProject
diff --git a/source/SDFS/IO.cs b/source/SDFS/IO.cs
new file mode 100644
index 0000000..c2e41bc
--- /dev/null
+++ b/source/SDFS/IO.cs
@@ -0,0 +1,213 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SDFS_Directory = SDFS.Logical.Entries.Directory;
+using SDFS_File = SDFS.Logical.Entries.File;
+using SDFS.Logical.Entries;
+using SDFS.Logical;
+
+
+namespace SDFS.IO
+{
+ public class Directory
+ {
+ private static Logical.Entries.Directory sf;
+
+ ///
+ /// Creates the specified directory
+ ///
+ ///
+ public static void Create(string directory)
+ {
+ Filesystem.cFS.Root.AddDirectory(directory);
+ sf = Filesystem.cFS.Root.GetDirectoryByName(directory);
+ if (sf == null)
+ {
+ // Cannot create required files, aborting creation of directory
+ throw new Exception("Failed creation of directory.");
+ }
+ }
+
+ ///
+ /// Creates the specified directory
+ ///
+ ///
+ public static void Remove(string directory)
+ {
+ SDFS_Directory dir = Filesystem.cFS.Root.GetDirectoryByName(directory);
+ if (dir != null)
+ {
+ Filesystem.cFS.Root.RemoveDirectory(directory);
+ }
+ else
+ {
+ // Cannot create required files, aborting creation of directory
+ throw new Exception("Failed deletion of directory.");
+ }
+ }
+ }
+
+ public class File
+ {
+ ///
+ /// Creates the specified file
+ ///
+ ///
+ ///
+ public static void Create(string file, string directory)
+ {
+ SDFS_Directory dir = Filesystem.cFS.Root.GetDirectoryByName(directory);
+ if (dir != null)
+ {
+ dir.AddFile(file);
+ SDFS_File nf = dir.RetrieveFileByName(file);
+ if (nf == null)
+ {
+ throw new Exception("Could not create!");
+ }
+
+ }
+ else
+ {
+ throw new ArgumentException("Bad directory");
+ }
+ }
+
+ public static void Delete(string file, string directory)
+ {
+ SDFS_Directory dir = Filesystem.cFS.Root.GetDirectoryByName(directory);
+ if (dir != null)
+ {
+ SDFS_File mFile = dir.RetrieveFileByName(file);
+ if (mFile != null)
+ {
+ dir.RemoveFile(file);
+ }
+ else
+ {
+ throw new Exception("Could not delete file!");
+ }
+ }
+ }
+
+ ///
+ /// Writes the specified byte array into the specified path and filename
+ /// if the file doesn't exist - create it
+ ///
+ ///
+ ///
+ ///
+ public static void WriteAllBytes(string file, string directory, byte[] data)
+ {
+ SDFS_Directory dir = Filesystem.cFS.Root.GetDirectoryByName(directory);
+ if (dir != null)
+ {
+ dir.AddFile(file);
+ SDFS_File nf = dir.RetrieveFileByName(file);
+ if (nf == null)
+ {
+ throw new Exception("Could not create!");
+ }
+ else
+ {
+ nf.WriteAllBytes(data);
+ }
+
+ }
+ else
+ {
+ throw new ArgumentException("Bad directory");
+ }
+ }
+ ///
+ /// Writes the specified string into the specified path and filename
+ /// if the file doesn't exist - create it
+ ///
+ ///
+ ///
+ ///
+ public static void WriteAllText(string file, string directory, string data)
+ {
+ SDFS_Directory dir = Filesystem.cFS.Root.GetDirectoryByName(directory);
+ if (dir != null)
+ {
+ dir.AddFile(file);
+ SDFS_File nf = dir.RetrieveFileByName(file);
+ if (nf == null)
+ {
+ throw new Exception("Could not create!");
+ }
+ else
+ {
+ nf.WriteAllText(data);
+ }
+
+ }
+ else
+ {
+ throw new ArgumentException("Bad directory");
+ }
+ }
+
+
+
+ ///
+ /// Writes the specified byte array into the specified path and filename
+ /// if the file doesn't exist - create it
+ ///
+ ///
+ ///
+ ///
+ public static byte[] ReadAllBytes(string file, string directory)
+ {
+ SDFS_Directory dir = Filesystem.cFS.Root.GetDirectoryByName(directory);
+ if (dir != null)
+ {
+ dir.AddFile(file);
+ SDFS_File nf = dir.RetrieveFileByName(file);
+ if (nf == null)
+ {
+ throw new Exception("Could not read!");
+ }
+ else
+ {
+ return nf.ReadAllBytes();
+ }
+
+ }
+ else
+ {
+ throw new ArgumentException("Bad directory");
+ }
+ }
+ ///
+ /// Writes the specified string into the specified path and filename
+ /// if the file doesn't exist - create it
+ ///
+ ///
+ ///
+ ///
+ public static string ReadAllText(string file, string directory)
+ {
+ SDFS_Directory dir = Filesystem.cFS.Root.GetDirectoryByName(directory);
+ if (dir != null)
+ {
+ dir.AddFile(file);
+ SDFS_File nf = dir.RetrieveFileByName(file);
+ if (nf == null)
+ {
+ throw new Exception("Could not create!");
+ }
+ else
+ {
+ return nf.ReadAllText();
+ }
+
+ }
+ else
+ {
+ throw new ArgumentException("Bad directory");
+ }
+ }
+ }
+}
diff --git a/source/SDFS/Logical/Block.cs b/source/SDFS/Logical/Block.cs
index cebdf92..56e98da 100644
--- a/source/SDFS/Logical/Block.cs
+++ b/source/SDFS/Logical/Block.cs
@@ -1,10 +1,234 @@
using System;
using System.Collections.Generic;
using System.Text;
+using SDFS.Physical;
+using Cosmos.HAL.BlockDevice;
namespace SDFS.Logical
{
public class Block
{
+ ///
+ /// Maxmimum size of content which a Block can contain
+ ///
+ public static uint MaxBlockContentSize = 491;
+
+ ///
+ /// This block's filesystem partition (private)
+ ///
+ private Partition _Partition;
+
+ ///
+ /// Block number (private)
+ ///
+ private ulong _blockNo = 0;
+
+ ///
+ /// Boolean value - is this block in use?
+ ///
+ private bool _Used = false;
+
+ ///
+ /// Content size of the block
+ ///
+ private uint _cSize = 0;
+
+ ///
+ /// Total size of the block (private)
+ ///
+ private ulong _tSize = 0;
+
+ ///
+ /// Next available block allocation
+ ///
+ private ulong _nBlock = 0;
+
+ ///
+ /// The partition holding the block
+ ///
+ public Partition mPartition
+ {
+ get
+ {
+ return _Partition;
+ }
+ }
+
+ ///
+ /// The number of the current block
+ ///
+ public ulong BlockNumber
+ {
+ get
+ {
+ return _blockNo;
+ }
+ }
+
+ ///
+ /// Bool whether block used or not used
+ ///
+ public bool Used
+ {
+ get
+ {
+ return _Used;
+ }
+ set
+ {
+ _Used = value;
+ }
+ }
+
+ ///
+ /// The current content size
+ ///
+ public uint ContentSize
+ {
+ get
+ {
+ return _cSize;
+ }
+ set
+ {
+ _cSize = value;
+ }
+ }
+
+ ///
+ /// Total size of the Entry
+ ///
+ public ulong TotalSize
+ {
+ get
+ {
+ return _tSize;
+ }
+ set
+ {
+ _tSize = value;
+ }
+ }
+
+ ///
+ /// The next block number to read al the content
+ ///
+ public ulong NextBlock
+ {
+ get
+ {
+ return _nBlock;
+ }
+ set
+ {
+ _nBlock = value;
+ }
+ }
+
+ ///
+ /// The Content Byte Array. TO-DO: code this better
+ ///
+ public Byte[] Content;
+
+ ///
+ /// Creates a new virtual Block.
+ ///
+ /// The Byte data
+ /// The partition to use
+ /// The block number
+ public Block(Byte[] Data, Partition p, ulong bn)
+ {
+ _blockNo = bn;
+ _Partition = p;
+ Content = new Byte[Data.Length - 21];
+ if (Data[0] == 0x00)
+ {
+ _Used = false;
+ for (int i = 0; i < Content.Length; i++)
+ {
+ Content[i] = 0;
+ }
+ }
+ else
+ {
+ _Used = true;
+ _cSize = BitConverter.ToUInt32(Data, 1);
+ _tSize = BitConverter.ToUInt64(Data, 5);
+ _nBlock = BitConverter.ToUInt64(Data, 13);
+ for (int i = 21; i < Data.Length; i++)
+ {
+ Content[i - 21] = Data[i];
+ }
+ }
+ }
+
+ ///
+ /// The
+ ///
+ /// The partition to read
+ /// The blocknumber to read
+ public static Block Read(Partition p, ulong bn)
+ {
+ Byte[] data = p.NewBlockArray(1);
+ p.ReadBlock(bn, 1, data);
+ return new Block(data, p, bn);
+ }
+
+ ///
+ /// Writes a block into a specific partition
+ ///
+ /// The partition to write to
+ /// The block to write
+ public static void Write(Partition p, Block b)
+ {
+ Byte[] data = new Byte[p.BlockSize];
+ int index = 0;
+ if (b.Used)
+ {
+ data[index++] = 0x01;
+ }
+ else
+ {
+ data[index++] = 0x00;
+ }
+ Byte[] x = BitConverter.GetBytes(b.ContentSize);
+ for (int i = 0; i < x.Length; i++)
+ {
+ data[index++] = x[i];
+ }
+ x = BitConverter.GetBytes(b.TotalSize);
+ for (int i = 0; i < x.Length; i++)
+ {
+ data[index++] = x[i];
+ }
+ x = BitConverter.GetBytes(b.NextBlock);
+ for (int i = 0; i < x.Length; i++)
+ {
+ data[index++] = x[i];
+ }
+ x = b.Content;
+ for (int i = 0; i < x.Length; i++)
+ {
+ data[index++] = x[i];
+ }
+ p.WriteBlock(b.BlockNumber, 1, data);
+ }
+
+ ///
+ /// Get the next free block from the selected partition (TO-DO: Implement something that runs faster)
+ ///
+ /// The partition to get the block from
+ public static Block GetFreeBlock(Partition p)
+ {
+ for (ulong i = 1; i < p.BlockCount; i++)
+ {
+ Block b = Read(p, i);
+ if (!b.Used)
+ {
+ return b;
+ }
+ }
+ return null;
+ }
}
}
diff --git a/source/SDFS/Logical/Entries/Directory.cs b/source/SDFS/Logical/Entries/Directory.cs
index 86f082b..80932e4 100644
--- a/source/SDFS/Logical/Entries/Directory.cs
+++ b/source/SDFS/Logical/Entries/Directory.cs
@@ -1,10 +1,450 @@
using System;
using System.Collections.Generic;
using System.Text;
+using Cosmos.HAL.BlockDevice;
+using SDFS.Physical;
namespace SDFS.Logical.Entries
{
public class Directory : Entry
{
+ ///
+ /// The full path (path+Name) of the current Directory
+ ///
+ public String DirectoryName
+ {
+ get
+ {
+ return Filesystem.ConcatDirectory(_path, Name);
+ }
+ }
+
+ ///
+ /// Creates a new Directory Object
+ ///
+ /// The partition to use
+ /// The block number we want to use
+ /// The path of the new directory
+ public Directory(Partition partition, ulong blockNumber, String path)
+ {
+ _path = path;
+ _partition = partition;
+ sBlock = Block.Read(partition, blockNumber);
+ if (blockNumber == 1 && path == "/" && sBlock.Content[0] != '/')
+ {
+ Char[] nm = "/".ToCharArray();
+ for (int i = 0; i < nm.Length; i++)
+ {
+ sBlock.Content[i] = (byte)nm[i];
+ }
+ sBlock.Used = true;
+ sBlock.NextBlock = 0;
+ Block.Write(partition, sBlock);
+ }
+ if (!sBlock.Used)
+ {
+ sBlock.Used = true;
+ String n = "New Directory";
+ if (path == Filesystem.Separator)
+ {
+ _path = "";
+ n = path;
+ }
+ CreateEntry(partition, sBlock, n);
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public Directory[] RetrieveDirectories()
+ {
+ Block curb = sBlock;
+ List d = new List();
+ while (curb.NextBlock != 0)
+ {
+ int index = 0;
+ curb = Block.Read(sBlock.mPartition, sBlock.NextBlock);
+ while (index < curb.ContentSize)
+ {
+ ulong a = BitConverter.ToUInt64(curb.Content, index);
+ index += 8;
+ uint sep = BitConverter.ToUInt32(curb.Content, index);
+ index += 4;
+ if (sep == 1)
+ {
+ d.Add(new Directory(_partition, a, Filesystem.ConcatDirectory(_path, Name)));
+ }
+ }
+ }
+ return d.ToArray();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public File[] RetrieveFiles()
+ {
+ Block curb = sBlock;
+ List d = new List();
+ while (curb.NextBlock != 0)
+ {
+ int index = 0;
+ curb = Block.Read(sBlock.mPartition, sBlock.NextBlock);
+ while (index < curb.ContentSize)
+ {
+ ulong a = BitConverter.ToUInt64(curb.Content, index);
+ index += 8;
+ uint sep = BitConverter.ToUInt32(curb.Content, index);
+ index += 4;
+ if (sep == 1)
+ {
+ d.Add(new File(_partition, a, Filesystem.ConcatDirectory(_path, Name)));
+ }
+ }
+ }
+ return d.ToArray();
+ }
+
+ ///
+ /// Retrieves the entries stored in the directory
+ ///
+ ///
+ public Entry[] RetrieveEntries()
+ {
+ Block edge = sBlock;
+ List entries = new List();
+ while (edge.NextBlock != 0)
+ {
+ int index = 0;
+ edge = Block.Read(sBlock.mPartition, sBlock.NextBlock);
+ while (index < edge.ContentSize)
+ {
+ ulong a = BitConverter.ToUInt64(edge.Content, index);
+ index += 8;
+ uint sep = BitConverter.ToUInt32(edge.Content, index);
+ index += 4;
+ if (sep == 1)
+ {
+ entries.Add(new Directory(_partition, a, Filesystem.ConcatDirectory(_path, Name)));
+ }
+ else if (sep == 2)
+ {
+ entries.Add(new File(_partition, a, Filesystem.ConcatDirectory(_path, Name)));
+ }
+ }
+ }
+ return entries.ToArray();
+ }
+
+
+ ///
+ /// Creates a new File to the current directory
+ ///
+ /// The new File's name
+ public void AddFile(String Name)
+ {
+ Entry[] dirs = RetrieveEntries();
+ for (int i = 0; i < dirs.Length; i++)
+ {
+ if (dirs[i].Name == Name)
+ {
+ // Entry with same Name already exists!
+ return;
+ }
+ }
+ Block curb = EditBlock();
+ Block newfileb = CreateEntry(_partition, Name);
+ //if (newfileb != null)
+ //{
+ BitConverter.GetBytes(newfileb.BlockNumber).CopyTo(curb.Content, curb.ContentSize);
+ BitConverter.GetBytes((uint)2).CopyTo(curb.Content, curb.ContentSize + 8);
+ curb.ContentSize += 12;
+ Block.Write(_partition, curb);
+ EditAttributes(EntryAttribute.DtM, UtilityMethods.UNIXTimeStamp);
+ EditAttributes(EntryAttribute.DtA, UtilityMethods.UNIXTimeStamp);
+ //}
+ }
+
+ ///
+ /// Permits to remove a Directory by passing it's name
+ ///
+ /// The Directory's name to remove
+ public void RemoveDirectory(String Name)
+ {
+ Directory[] dirs = RetrieveDirectories();
+ bool found = false;
+ int index = 0;
+ for (int i = 0; i < dirs.Length; i++)
+ {
+ if (dirs[i].Name == Name)
+ {
+ index = i;
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ {
+ RemoveDirectory(dirs[index]);
+ }
+ }
+
+ ///
+ /// Permits to remove a Directory by passing it
+ ///
+ /// The Directory to remove
+ private void RemoveDirectory(Directory Directory)
+ {
+ Directory[] subdirs = Directory.RetrieveDirectories();
+ for (int i = 0; i < subdirs.Length; i++)
+ {
+ Directory.RemoveDirectory(subdirs[i]);
+ }
+ File[] subfiles = Directory.RetrieveFiles();
+ for (int i = 0; i < subdirs.Length; i++)
+ {
+ Directory.RemoveFile(subfiles[i].Name);
+ }
+ Filesystem.Clean(Directory.sBlock);
+ DeleteBlock(Directory.sBlock);
+ }
+
+ ///
+ /// Permits to remove a File by passing it's name
+ ///
+ /// The File's name to remove
+ public void RemoveFile(String Name)
+ {
+ File[] files = RetrieveFiles();
+ bool found = false;
+ int index = 0;
+ for (int i = 0; i < files.Length; i++)
+ {
+ if (files[i].Name == Name)
+ {
+ index = i;
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ {
+ Filesystem.Clean(files[index].StartBlock);
+ DeleteBlock(files[index].StartBlock);
+ }
+ }
+
+ ///
+ /// Permits to remove a Block by passing it
+ ///
+ /// The Block to remove
+ private void DeleteBlock(Block FSBlock)
+ {
+ Block curb = sBlock;
+ while (curb.NextBlock != 0)
+ {
+ int index = 0;
+ bool found = false;
+ List cont = new List();
+ curb = Block.Read(sBlock.mPartition, sBlock.NextBlock);
+ while (index < curb.ContentSize)
+ {
+ ulong a = BitConverter.ToUInt64(curb.Content, index);
+ Byte[] app = BitConverter.GetBytes(a);
+ for (int i = 0; i < app.Length; i++)
+ {
+ cont.Add(app[i]);
+ }
+ index += 8;
+ uint sep = BitConverter.ToUInt32(curb.Content, index);
+ index += 4;
+ if (a == FSBlock.BlockNumber)
+ {
+ app = BitConverter.GetBytes((uint)0);
+ for (int i = 0; i < app.Length; i++)
+ {
+ cont.Add(app[i]);
+ }
+ found = true;
+ }
+ else
+ {
+ app = BitConverter.GetBytes(sep);
+ for (int i = 0; i < app.Length; i++)
+ {
+ cont.Add(app[i]);
+ }
+ }
+ }
+ if (found)
+ {
+ curb.Content = cont.ToArray();
+ curb.ContentSize = (uint)cont.Count;
+ Block.Write(_partition, curb);
+ }
+ }
+ }
+
+ public void AddDirectory(String Name)
+ {
+ Entry[] directories = RetrieveEntries();
+ for (int i = 0; i < directories.Length; i++)
+ {
+ if (directories[i].Name == Name)
+ {
+ // The directory already exists!
+ return;
+ }
+ }
+ Block edge = EditBlock();
+ Block nDirB = CreateEntry(_partition, Name);
+ BitConverter.GetBytes(nDirB.BlockNumber).CopyTo(edge.Content, edge.ContentSize);
+ BitConverter.GetBytes((uint)1).CopyTo(edge.Content, edge.ContentSize + 8);
+ edge.ContentSize += 12;
+ Block.Write(_partition, edge);
+ EditAttributes(EntryAttribute.DtM, UtilityMethods.UNIXTimeStamp);
+ EditAttributes(EntryAttribute.DtA, UtilityMethods.UNIXTimeStamp);
+ }
+
+
+ ///
+ /// Gets the last Block of the directory
+ ///
+ private Block EditBlock()
+ {
+ Block ret = sBlock;
+ while (ret.NextBlock != 0)
+ {
+ ret = Block.Read(sBlock.mPartition, sBlock.NextBlock);
+ }
+ if (ret.BlockNumber == sBlock.BlockNumber)
+ {
+ ret = Block.GetFreeBlock(_partition);
+ ret.Used = true;
+ ret.ContentSize = 0;
+ ret.NextBlock = 0;
+ sBlock.NextBlock = ret.BlockNumber;
+ Block.Write(_partition, sBlock);
+ Block.Write(_partition, ret);
+ }
+ if (_partition.NewBlockArray(1).Length - ret.ContentSize < 12)
+ {
+ Block block = Block.GetFreeBlock(_partition);
+ if (block == null)
+ {
+ return null;
+ }
+ ret.NextBlock = block.BlockNumber;
+ Block.Write(_partition, ret);
+ block.Used = true;
+ ret = block;
+ }
+ return ret;
+ }
+
+ ///
+ /// Get the directory specified by the Fullname passed
+ ///
+ /// The fullname of the directory
+ public static Directory GetDirectoryByFullName(String fn)
+ {
+ Directory dir = Filesystem.cFS.Root;
+ if (fn == dir.Name)
+ {
+ return dir;
+ }
+ if (fn == null || fn == "")
+ {
+ return null;
+ }
+ String[] names = fn.Split('/');
+ if (names[0] != "")
+ {
+ return null;
+ }
+ for (int i = 0; i < names.Length; i++)
+ {
+ if (names[i] != null && names[i] != "")
+ {
+ dir = dir.GetDirectoryByName(names[i]);
+ if (dir == null)
+ {
+ break;
+ }
+ }
+ }
+ return dir;
+ }
+
+ ///
+ /// Get the directory specified by the Name passed
+ ///
+ /// The name of the child directory
+ public Directory GetDirectoryByName(String n)
+ {
+ Directory[] dirs = RetrieveDirectories();
+ for (int i = 0; i < dirs.Length; i++)
+ {
+ if (dirs[i].Name == n)
+ {
+ return dirs[i];
+ }
+ }
+ return null;
+ }
+
+ ///
+ /// Overrides the ToString Method.
+ ///
+ public override String ToString()
+ {
+ return this.Name;
+ }
+
+ ///
+ /// Get the directory specified by the Fullname passed
+ ///
+ /// The fullname of the directory
+ public static File GetFileByFullName(String fn)
+ {
+ Directory dir = new Directory(Filesystem.cFS.mPartition, 1, Filesystem.Separator);
+ if (fn == null || fn == "")
+ {
+ return null;
+ }
+ String[] names = fn.Split('/');
+ for (int i = 0; i < names.Length - 1; i++)
+ {
+ if (names[i] != "")
+ {
+ dir = dir.GetDirectoryByName(names[i]);
+ if (dir == null)
+ {
+ break;
+ }
+ }
+ }
+ return dir.RetrieveFileByName(names[names.Length - 1]);
+ }
+
+ ///
+ /// Get the file specified by the Name passed
+ ///
+ /// The name of the child file
+ public File RetrieveFileByName(String n)
+ {
+ File[] files = RetrieveFiles();
+ for (int i = 0; i < files.Length; i++)
+ {
+ if (files[i].Name == n)
+ {
+ return files[i];
+ }
+ }
+ return null;
+ }
}
}
diff --git a/source/SDFS/Logical/Entries/Entry.cs b/source/SDFS/Logical/Entries/Entry.cs
index c565379..8597051 100644
--- a/source/SDFS/Logical/Entries/Entry.cs
+++ b/source/SDFS/Logical/Entries/Entry.cs
@@ -1,10 +1,194 @@
using System;
using System.Collections.Generic;
using System.Text;
+using Cosmos.HAL.BlockDevice;
+using SDFS.Physical;
namespace SDFS.Logical.Entries
{
+ ///
+ /// Modifiable attributes of filesystem entries
+ ///
+ public enum EntryAttribute
+ {
+ ///
+ /// Date/Time Created
+ ///
+ DtC = 0x00,
+
+ ///
+ /// Date/Time Modified
+ ///
+ DtM = 0x08,
+
+ ///
+ /// Date/Time Last Accessed
+ ///
+ DtA = 0x10,
+
+ ///
+ /// Owner
+ ///
+ OwR = 0x18,
+
+ ///
+ /// Group
+ ///
+ GoP = 0x20,
+
+ ///
+ /// Visisibility
+ ///
+ HdN = 0x28,
+
+ ///
+ /// Read/Write Permissions
+ ///
+ ReW = 0x29,
+
+ ///
+ /// Owner Permissions
+ ///
+ OwP = 0x30,
+
+ ///
+ /// Group Permissions
+ ///
+ GrP = 0x3a,
+
+ ///
+ /// Global Permissions
+ ///
+ GlP = 0x3b
+ }
+
public class Entry
{
+ ///
+ /// Char[] array of characters that are invalid for use in files/directories
+ ///
+ protected static Char[] UnacceptableChars = new char[] { '/', '?', '*' };
+
+ ///
+ /// The starting block of this FileSystem entry
+ ///
+ protected Block sBlock;
+
+ ///
+ /// The filesystem path of the entry
+ ///
+ protected String _path;
+
+ ///
+ /// The partition upon which the entry resides
+ ///
+ protected Partition _partition;
+
+ ///
+ /// The maximum length a filename can be
+ ///
+ private static int MaxFNL = 255;
+
+ ///
+ /// Retrieves the start block
+ ///
+ public Block StartBlock
+ {
+ get
+ {
+ return sBlock;
+ }
+ }
+
+ ///
+ /// Path of the FS entry
+ ///
+ public String Path
+ {
+ get
+ {
+ return _path;
+ }
+ }
+
+ ///
+ /// Returns the FileSystem entryname
+ ///
+ public String Name
+ {
+ get
+ {
+ Byte[] arr = sBlock.Content;
+ String ret = "";
+ for (int i = 0; i < MaxFNL; i++)
+ {
+ if (arr[i] == 0)
+ {
+ break;
+ }
+ ret += ((Char)arr[i]).ToString();
+ }
+ return ret;
+ }
+ }
+
+ ///
+ /// Sets the entry's attributes to the specified
+ ///
+ ///
+ ///
+ public void EditAttributes(EntryAttribute Attrib, long value)
+ {
+ if (Attrib < EntryAttribute.HdN)
+ {
+ UtilityMethods.CopyByteToByte(BitConverter.GetBytes(value), 0, sBlock.Content, MaxFNL + (int)Attrib, 8, false);
+ }
+ else
+ {
+ UtilityMethods.CopyByteToByte(BitConverter.GetBytes(value), 0, sBlock.Content, MaxFNL + (int)Attrib, 1, false);
+ }
+ }
+
+ ///
+ /// Creates a new FS entry at the specified partititon block
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected static Block CreateEntry(Partition _part, Block block, String name)
+ {
+ if (block != null && ((!UtilityMethods.StringContains(name, UnacceptableChars)) || block.BlockNumber == 0))
+ {
+ block.Used = true;
+ block.NextBlock = 0;
+ block.TotalSize = 0;
+ char[] nm = name.ToCharArray();
+ for (int i = 0; i < nm.Length; i++)
+ {
+ block.Content[i] = (byte)nm[i];
+ }
+ if (block.BlockNumber != 0)
+ {
+ UtilityMethods.CopyByteToByte(BitConverter.GetBytes(UtilityMethods.UNIXTimeStamp), 0, block.Content, MaxFNL + (int)EntryAttribute.DtC, 8, false);
+ }
+ block.Content[nm.Length] = 0;
+ block.ContentSize = (uint)nm.Length;
+ Block.Write(_part, block);
+ return block;
+ }
+ return null;
+ }
+
+ ///
+ /// Creates a new FS entry at the next available partition block
+ ///
+ ///
+ ///
+ ///
+ protected static Block CreateEntry(Partition _part, String name)
+ {
+ return CreateEntry(_part, Block.GetFreeBlock(_part), name);
+ }
}
}
diff --git a/source/SDFS/Logical/Entries/File.cs b/source/SDFS/Logical/Entries/File.cs
index bb221a6..014c982 100644
--- a/source/SDFS/Logical/Entries/File.cs
+++ b/source/SDFS/Logical/Entries/File.cs
@@ -1,10 +1,127 @@
using System;
using System.Collections.Generic;
-using System.Text;
+using Cosmos.HAL.BlockDevice;
namespace SDFS.Logical.Entries
{
public class File : Entry
{
+ ///
+ /// The full path (path + filename) of the current file
+ ///
+ public String Filename
+ {
+ get
+ {
+ return Filesystem.ConcatDirectory(_path, Name);
+ }
+ }
+
+ ///
+ /// Writes the specified byte array into the file
+ ///
+ ///
+ public void WriteAllBytes(Byte[] Data)
+ {
+ if (sBlock.NextBlock != 0)
+ {
+ Filesystem.Clean(sBlock);
+ sBlock.NextBlock = 0;
+ Block.Write(Filesystem.cFS.mPartition, sBlock);
+ }
+ int index = 0;
+ Block edge = Block.GetFreeBlock(Filesystem.cFS.mPartition);
+ sBlock.NextBlock = edge.BlockNumber;
+ Block.Write(_partition, sBlock);
+ do
+ {
+ Byte[] arr = new byte[Block.MaxBlockContentSize];
+ index = UtilityMethods.CopyByteToByte(Data, index, arr, 0, arr.Length);
+ edge.Used = true;
+ edge.Content = arr;
+ if (index != Data.Length)
+ {
+ Block fB = Block.GetFreeBlock(Filesystem.cFS.mPartition);
+ edge.NextBlock = fB.BlockNumber;
+ edge.ContentSize = (uint)arr.Length;
+ Block.Write(Filesystem.cFS.mPartition, edge);
+ edge = fB;
+ }
+ else
+ {
+ edge.ContentSize = (uint)(Data.Length % arr.Length);
+ Block.Write(Filesystem.cFS.mPartition, edge);
+ }
+ }
+ while (index != Data.Length);
+ EditAttributes(EntryAttribute.DtM, UtilityMethods.UNIXTimeStamp);
+ EditAttributes(EntryAttribute.DtA, UtilityMethods.UNIXTimeStamp);
+ }
+
+ ///
+ /// Converts the specified text into a byte[] array, and writes the bytes to the file entry (WriteAllBytes())
+ ///
+ ///
+ public void WriteAllText(String txt)
+ {
+ Byte[] tB = new byte[txt.Length];
+ UtilityMethods.CopyCharToByte(txt.ToCharArray(), 0, tB, 0, txt.Length);
+ WriteAllBytes(tB);
+ }
+
+ ///
+ /// Returns the bytes stored in the file entry
+ ///
+ ///
+ public Byte[] ReadAllBytes()
+ {
+ if (sBlock.NextBlock == 0)
+ {
+ return new byte[0];
+ }
+ Block b = sBlock;
+ List bL = new List();
+ while (b.NextBlock != 0)
+ {
+ b = Block.Read(b.mPartition, b.NextBlock);
+ for (int i = 0; i < b.ContentSize; i++)
+ {
+ bL.Add(b.Content[i]);
+ }
+ }
+ EditAttributes(EntryAttribute.DtA, UtilityMethods.UNIXTimeStamp);
+ return bL.ToArray();
+ }
+
+ ///
+ /// Converts the file entry's bytes into a string, and returns it
+ ///
+ ///
+ public string ReadAllText()
+ {
+ Byte[] b = ReadAllBytes();
+ Char[] txt = new char[b.Length];
+ UtilityMethods.CopyByteToChar(b, 0, txt, 0, b.Length);
+ return UtilityMethods.CharToString(txt);
+ }
+
+ ///
+ /// FS File object constructor
+ ///
+ ///
+ ///
+ ///
+ public File(Partition part, ulong blockNumber, String path)
+ {
+ _path = path;
+ _partition = part;
+ sBlock = Block.Read(part, blockNumber);
+ if (!sBlock.Used)
+ {
+ sBlock.Used = true;
+ String name = "New File";
+ CreateEntry(_partition, sBlock, name);
+ }
+ }
}
}
diff --git a/source/SDFS/Logical/Filesystem.cs b/source/SDFS/Logical/Filesystem.cs
index 5836486..5b98427 100644
--- a/source/SDFS/Logical/Filesystem.cs
+++ b/source/SDFS/Logical/Filesystem.cs
@@ -1,9 +1,324 @@
using System;
+using SDFS.Physical;
+using Cosmos.HAL.BlockDevice;
+using SDFS.Logical.Entries;
namespace SDFS.Logical
{
public class Filesystem
{
-
+ public Directory Root
+ {
+ get
+ {
+ return new Directory(_Partition, 1, Separator);
+ }
+ }
+
+ ///
+ /// Concatenates a file and it's path location, resulting in full path
+ ///
+ ///
+ ///
+ /// Full path location of file
+ public static string ConcatFile(string path, string fname)
+ {
+ String file = "";
+ file = path.TrimEnd(Separator.ToCharArray());
+ if (file == null)
+ {
+ file = "";
+ }
+ if (fname != Separator)
+ {
+ file += file += Separator + fname;
+ }
+ else
+ {
+ file = Separator;
+ }
+ return file;
+ }
+
+ ///
+ /// Concatenates a directory and it's path location, resulting in full path
+ ///
+ ///
+ ///
+ /// Full path location of directory
+ public static string ConcatDirectory(string path, string dir)
+ {
+ String directory = "";
+ directory = path.TrimEnd(Separator.ToCharArray());
+ if (directory == null)
+ {
+ directory = "";
+ }
+ if (dir != Separator)
+ {
+ directory += Separator + dir + Separator;
+ }
+ else
+ {
+ directory = Separator;
+ }
+ return directory;
+ }
+
+ ///
+ /// The filesystem that is currently in use
+ ///
+ public static Filesystem cFS = null;
+
+ ///
+ /// Constructor for a filesystem object
+ /// Runs test for valid FS on specified partition
+ ///
+ public Filesystem(Partition aPartition)
+ {
+ _Partition = aPartition;
+ Console.WriteLine("Checking for valid filesystem...");
+ if (!IsValidFS())
+ {
+ Console.WriteLine("Generating filesystem...");
+ // If unable to detect a valid partition
+ if (!GenerateFS())
+ {
+ // Error - unable to create a new filesystem on specified partition
+ throw new Exception("Unable to create a new filesystem on the specified partition");
+ }
+ }
+ }
+
+ ///
+ /// Separator character that splits files/directories from their parent directory.
+ ///
+ public static string Separator = "/";
+
+ ///
+ /// Property of the partition upon which this filesystem resides
+ ///
+ private Partition _Partition;
+
+ private static byte[] fsSignature = new byte[]
+ {
+ 0x4D,
+ 0x65,
+ 0x64,
+ 0x6C,
+ 0x69,
+ 0x44,
+ 0x46,
+ 0x53
+ };
+
+ ///
+ /// Public property of the partition upon which this filesystem resides
+ ///
+ public Partition mPartition
+ {
+ get
+ {
+ return _Partition;
+ }
+ }
+
+ ///
+ /// Returns block size of this FileSystem's partition
+ ///
+ public ulong BlockSize
+ {
+ get
+ {
+ return _Partition.BlockSize;
+ }
+ }
+
+ ///
+ /// Returns block count of this FileSystem's partition
+ ///
+ public ulong BlockCount
+ {
+ get
+ {
+ return _Partition.BlockCount;
+ }
+ }
+
+ ///
+ /// Map a specified filesystem to the methods and properties of SDFS
+ ///
+ ///
+ public static void MapFilesystem (Filesystem fs)
+ {
+ cFS = fs;
+ }
+
+
+ ///
+ /// Generates a new FS block structure on specified filesystem
+ ///
+ ///
+ ///
+ private static bool GenerateFS(Partition part)
+ {
+ Console.WriteLine("Cleaning filesystem blocks...");
+ Refresh(part, 10000);
+ Byte[] data = part.NewBlockArray(1);
+ fsSignature.CopyTo(data, 0);
+ Console.WriteLine("Writing filesystem signature\n");
+ for (int i = 0; i < fsSignature.Length; i++)
+ {
+ data[i] = fsSignature[i];
+ }
+ string MedliDFS = System.Text.Encoding.ASCII.GetString(fsSignature);
+ for (int i = 0; i < MedliDFS.Length; i++)
+ {
+ if (i != MedliDFS.Length)
+ {
+ Console.Write(MedliDFS.ToCharArray()[i] + ":");
+ }
+ else
+ {
+ Console.Write(MedliDFS.ToCharArray()[i]);
+ }
+
+ }
+ part.WriteBlock(0, 1, data);
+ return true;
+ }
+
+ ///
+ /// Generates a new FS block structure on pre-set filesystem
+ ///
+ ///
+ ///
+ private bool GenerateFS()
+ {
+ Console.WriteLine("Cleaning filesystem blocks...");
+ //Refresh(_Partition, 10000);
+ Byte[] data = _Partition.NewBlockArray(1);
+ //fsSignature.CopyTo(data, 0);
+ Console.WriteLine("Writing filesystem signature\n");
+ for (int i = 0; i < fsSignature.Length; i++)
+ {
+ data[i] = fsSignature[i];
+ }
+ string MedliDFS = System.Text.Encoding.ASCII.GetString(fsSignature);
+ for (int i = 0; i < MedliDFS.Length; i++)
+ {
+ if (i != MedliDFS.Length)
+ {
+ Console.Write(MedliDFS.ToCharArray()[i] + ":");
+ }
+ else
+ {
+ Console.Write(MedliDFS.ToCharArray()[i]);
+ }
+
+ }
+ _Partition.WriteBlock(0, 1, data);
+ return true;
+ }
+
+ ///
+ /// Tests to see if partition object (_partition) contains a valid MDFS filesystem block structure (does the partition signature match the ASCII string 'MedliDFS')
+ ///
+ ///
+ public bool IsValidFS()
+ {
+ Byte[] data = _Partition.NewBlockArray(1);
+ for (int i = 0; i < fsSignature.Length; i++)
+ {
+ if (fsSignature[i] != data[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ ///
+ /// Cleans a filesystem by a specified amount of blocks
+ /// (default is BlockCount)
+ ///
+ ///
+ public void Refresh(ulong sBlock = 0)
+ {
+ Byte[] data = _Partition.NewBlockArray(1);
+ for (int i = 0; i < data.Length; i++)
+ {
+ data[i] = 0;
+ }
+ // Proceeding to refresh the filesystem...
+ ulong lBlock = _Partition.BlockCount;
+ if (sBlock != 0)
+ {
+ lBlock = sBlock;
+ }
+ ulong rate = lBlock / 100;
+ uint perc = 0;
+ // perc + "% refreshed. " + (uint)lBlock + " blocks remaining.
+ for (ulong i = 0; i < lBlock; i++)
+ {
+ mPartition.WriteBlock(i, 1, data);
+ if (i % rate == 0)
+ {
+ perc++;
+ }
+ if (i % 32 == 0)
+ {
+ // perc + "% refreshed. " + ((uint)(lBlock - i)) + " blocks remaining.
+ }
+ }
+ // Successfully refreshed filesystem.
+ }
+
+ ///
+ /// Cleans a filesystem by a specified amount of blocks
+ /// (default is BlockCount)
+ ///
+ ///
+ public static void Refresh(Partition aPartition, ulong sBlock = 0)
+ {
+ Byte[] data = aPartition.NewBlockArray(1);
+ for (int i = 0; i < data.Length; i++)
+ {
+ data[i] = 0;
+ }
+ // Proceeding to refresh the filesystem...
+ ulong lBlock = aPartition.BlockCount;
+ if (sBlock != 0)
+ {
+ lBlock = sBlock;
+ }
+ ulong rate = lBlock / 100;
+ uint perc = 0;
+ // perc + "% refreshed. " + (uint)lBlock + " blocks remaining.
+ for (ulong i = 0; i < lBlock; i++)
+ {
+ aPartition.WriteBlock(i, 1, data);
+ if (i % rate == 0)
+ {
+ perc++;
+ }
+ if (i % 32 == 0)
+ {
+ // perc + "% refreshed. " + ((uint)(lBlock - i)) + " blocks remaining.
+ }
+ }
+ // Successfully refreshed filesystem.
+ }
+
+ public static void Clean(Block sBlock)
+ {
+ Block block = sBlock;
+ while (block.NextBlock != 0)
+ {
+ block = Block.Read(block.mPartition, block.NextBlock);
+ block.Used = false;
+ Block.Write(cFS.mPartition, block);
+ }
+ }
}
}
diff --git a/source/SDFS/Physical/IDE.cs b/source/SDFS/Physical/IDE.cs
index 0352f3c..aa44835 100644
--- a/source/SDFS/Physical/IDE.cs
+++ b/source/SDFS/Physical/IDE.cs
@@ -1,10 +1,140 @@
using System;
using System.Collections.Generic;
using System.Text;
+using Cosmos.HAL.BlockDevice;
namespace SDFS.Physical
{
public class IDE
{
+ ///
+ /// List of ATA IDE Devices
+ ///
+ public static List Devices
+ {
+ get
+ {
+ List devs = new List();
+ for (int i = 0; i < BlockDevice.Devices.Count; i++)
+ {
+ if (BlockDevice.Devices[i] is AtaPio)
+ {
+ IDE device = new IDE((AtaPio)BlockDevice.Devices[i]);
+ devs.Add(device);
+ }
+ }
+ return devs;
+ }
+ }
+
+ ///
+ /// Retrieves this IDE device's size in megabytes
+ ///
+ public UInt32 Size
+ {
+ get
+ {
+ return (uint)(((this.BlockCount * this.BlockSize) / 1024) / 1024) + 1;
+ }
+ }
+
+ ///
+ /// This object's IDE BlockDevice (ATA hard disk drive)
+ ///
+ private BlockDevice blockDevice;
+
+ ///
+ /// Constructor for IDE
+ ///
+ ///
+ public IDE(AtaPio Device)
+ {
+ this.blockDevice = Device;
+ }
+
+ ///
+ /// Returns this IDE device's block count
+ ///
+ public UInt64 BlockCount
+ {
+ get
+ {
+ return this.blockDevice.BlockCount;
+ }
+ }
+
+ ///
+ /// Returns this IDE device's block size
+ ///
+ public UInt64 BlockSize
+ {
+ get
+ {
+ return this.blockDevice.BlockSize;
+ }
+ }
+
+ ///
+ /// Retrieves a new byte array with a length of (num * BlockSize)
+ ///
+ ///
+ /// New byte[] Array
+ public Byte[] NewBlockArray(uint num)
+ {
+ return blockDevice.NewBlockArray(num);
+ }
+
+ ///
+ /// Reads the specified amount of blocks from the BlockDevice
+ ///
+ /// Start block number
+ /// Number of blocks
+ /// Buffer to write to
+ public void ReadBlock(ulong aBlockNo, uint aBlockCount, byte[] aData)
+ {
+ blockDevice.ReadBlock(aBlockNo, aBlockCount, aData);
+ }
+
+ ///
+ /// Writes the specified byte[] array to the specified block and number of blocks
+ ///
+ /// Start block number
+ /// Number of blocks
+ /// Buffer to write to
+ public void WriteBlock(ulong aBlockNo, uint aBlockCount, byte[] aData)
+ {
+ blockDevice.WriteBlock(aBlockNo, aBlockCount, aData);
+ }
+
+
+ public PrimaryPartition[] PrimaryPartitions
+ {
+ get
+ {
+ List l = new List();
+ for (int i = 0; i < MBR.Partitions.Length; i++)
+ {
+ if (MBR.Partitions[i].SystemID != 0)
+ {
+ l.Add(new PrimaryPartition(blockDevice, MBR.Partitions[i].StartSector, MBR.Partitions[i].SectorCount, MBR.Partitions[i]));
+ }
+ }
+ return l.ToArray();
+ }
+ }
+
+ ///
+ /// Retrieves the master boot record of this class instance's BlockDevice
+ ///
+ public MBR MBR
+ {
+ get
+ {
+ Byte[] data = blockDevice.NewBlockArray(1);
+ this.blockDevice.ReadBlock(0, 1, data);
+ MBR m = new MBR(data, blockDevice);
+ return m;
+ }
+ }
}
}
diff --git a/source/SDFS/Physical/MBR.cs b/source/SDFS/Physical/MBR.cs
index 3f936f4..49333b7 100644
--- a/source/SDFS/Physical/MBR.cs
+++ b/source/SDFS/Physical/MBR.cs
@@ -1,10 +1,78 @@
using System;
using System.Collections.Generic;
using System.Text;
+using Cosmos.HAL.BlockDevice;
namespace SDFS.Physical
{
public class MBR
{
+ ///
+ /// An array containing all patitions
+ ///
+ public PartitionObj[] Partitions
+ {
+ get
+ {
+ return mPartitions.ToArray();
+ }
+ }
+
+ ///
+ /// List of partitions found on the Master Boot Record
+ ///
+ private List mPartitions = new List();
+
+ ///
+ /// The block device on which this MBR resides
+ ///
+ private BlockDevice mBlockDevice;
+
+ ///
+ /// Constructor for a Master Boot Record
+ ///
+ ///
+ ///
+ public MBR (Byte[] aMBR, BlockDevice aBlockDevice)
+ {
+ mBlockDevice = aBlockDevice;
+ UtilityMethods.CopyByteToByte(aMBR, 0, BootArray, 0, 440);
+ Signature = BitConverter.ToUInt32(aMBR, 440);
+ // Partition entries are located at MBR offsets 446, 462, 478 and 494
+ // MBR only consists of 512 bytes
+ ReadPartitions(aMBR, 446);
+ ReadPartitions(aMBR, 462);
+ ReadPartitions(aMBR, 478);
+ ReadPartitions(aMBR, 494);
+ }
+
+ ///
+ /// The Byte Array containing the bootable code and partition information of the MBR
+ ///
+ public readonly Byte[] BootArray = new Byte[440];
+
+ ///
+ /// The Disk signature
+ ///
+ public readonly UInt32 Signature = 0;
+
+ ///
+ /// Reads the Master Boot Record for partition entries, and parses information such as sector count, block size and partition ID
+ ///
+ ///
+ ///
+ private void ReadPartitions(byte[] MBR, UInt32 aLocation)
+ {
+ byte xPartitionID = MBR[aLocation + 4];
+ // A partition ID of 0 identifies an empty (null) partition
+ if (xPartitionID != 0)
+ {
+ UInt32 xStartSector = BitConverter.ToUInt32(MBR, (int)aLocation + 8);
+ UInt32 xSectorCount = BitConverter.ToUInt32(MBR, (int)aLocation + 12);
+
+ var xPartitionObject = new PartitionObj(xPartitionID, xStartSector, xSectorCount, mBlockDevice.BlockSize);
+ mPartitions.Add(xPartitionObject);
+ }
+ }
}
}
diff --git a/source/SDFS/Physical/Partitions.cs b/source/SDFS/Physical/Partitions.cs
index b44ed0e..31d0171 100644
--- a/source/SDFS/Physical/Partitions.cs
+++ b/source/SDFS/Physical/Partitions.cs
@@ -4,7 +4,49 @@
namespace SDFS.Physical
{
- public class Partitions
+ public class PartitionObj
{
+ ///
+ /// Constructor for a new partition
+ ///
+ ///
+ ///
+ ///
+ public PartitionObj(byte SysID, UInt32 startSector, UInt32 sectCount, UInt64 blockSize)
+ {
+ SystemID = SysID;
+ StartSector = startSector;
+ SectorCount = sectCount;
+ BlockSize = blockSize;
+ }
+
+ ///
+ /// Returns the total size of this partition in megabytes
+ ///
+ public UInt32 TotalSize
+ {
+ get
+ {
+ return (uint)(((BlockSize * SectorCount) / 1024) / 1024);
+ }
+ }
+
+ ///
+ /// Block size of this partition
+ ///
+ public readonly UInt64 BlockSize;
+
+ ///
+ /// The partition's FS ID
+ ///
+ public readonly byte SystemID;
+ ///
+ /// The partition's starting sector
+ ///
+ public readonly UInt32 StartSector;
+ ///
+ /// The number of sectors in the partition
+ ///
+ public readonly UInt32 SectorCount;
}
}
diff --git a/source/SDFS/Physical/PrimaryPartition.cs b/source/SDFS/Physical/PrimaryPartition.cs
new file mode 100644
index 0000000..7d10fea
--- /dev/null
+++ b/source/SDFS/Physical/PrimaryPartition.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Cosmos.HAL.BlockDevice;
+
+namespace SDFS.Physical
+{
+ public class PrimaryPartition : Partition
+ {
+ ///
+ /// The primary partition's block device
+ ///
+ BlockDevice HostDevice;
+
+ ///
+ /// The primary partition's starting sector
+ ///
+ ulong StartingSector;
+
+ ///
+ /// Partition Information instance for this partition
+ ///
+ private PartitionObj _Partition;
+
+ ///
+ /// Readonly public property for partition info instance
+ ///
+ public PartitionObj Info
+ {
+ get
+ {
+ return _Partition;
+ }
+ }
+
+ ///
+ /// Constructor for a primary partition
+ ///
+ ///
+ ///
+ ///
+ ///
+ public PrimaryPartition(BlockDevice aHost, ulong aStartingSector, ulong aSectorCount, PartitionObj info)
+ : base(aHost, aStartingSector, aSectorCount)
+ {
+ HostDevice = aHost;
+ StartingSector = aStartingSector;
+ mBlockCount = aSectorCount;
+ mBlockSize = aHost.BlockSize;
+ _Partition = info;
+ }
+
+
+ ///
+ /// Reads the specified number of blocks from this partition
+ ///
+ /// Starting block number
+ /// Number of blocks to read
+ /// byte[] array to read to
+ public override void ReadBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData)
+ {
+ UInt64 HostBlockNumber = StartingSector + aBlockNo;
+ CheckBlockNo(HostBlockNumber, aBlockCount);
+ HostDevice.ReadBlock(HostBlockNumber, aBlockCount, aData);
+ }
+
+ ///
+ /// Writes the specified byte[] array to the specified block and number of blocks
+ ///
+ /// Starting block number
+ /// Number of blocks to write to
+ /// Byte[] array containing data to be written
+ public override void WriteBlock(ulong aBlockNo, ulong aBlockCount, byte[] aData)
+ {
+ UInt64 HostBlockNumber = StartingSector + aBlockNo;
+ CheckBlockNo(HostBlockNumber, aBlockCount);
+ HostDevice.WriteBlock(HostBlockNumber, aBlockCount, aData);
+ }
+ }
+}
diff --git a/source/SDFS/Physical/PrimaryPartitions.cs b/source/SDFS/Physical/PrimaryPartitions.cs
deleted file mode 100644
index d4f2dc4..0000000
--- a/source/SDFS/Physical/PrimaryPartitions.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace SDFS.Physical
-{
- public class PrimaryPartitions
- {
- }
-}
diff --git a/source/SDFS/SDFS.csproj b/source/SDFS/SDFS.csproj
index 368944a..352df0e 100644
--- a/source/SDFS/SDFS.csproj
+++ b/source/SDFS/SDFS.csproj
@@ -2,11 +2,11 @@
Library
- MDFS
+ SDFS
netcoreapp2.0
- MDFS
+ SDFS
diff --git a/source/SDFS/UtilityMethods.cs b/source/SDFS/UtilityMethods.cs
index 0305574..d4aa448 100644
--- a/source/SDFS/UtilityMethods.cs
+++ b/source/SDFS/UtilityMethods.cs
@@ -6,5 +6,240 @@ namespace SDFS
{
public class UtilityMethods
{
+ ///
+ /// Converts a byte array into a hexadecimal string
+ ///
+ ///
+ ///
+ public static String byteArrayToByteString(Byte[] inp)
+ {
+ Byte ch = 0x00;
+ String ret = "";
+
+ String[] pseudo = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+ "A", "B", "C", "D", "E", "F" };
+
+ for (int i = 0; i < inp.Length; i++)
+ {
+ ret += "0x";
+ ch = (byte)(inp[i] & 0xF0);
+ ch = (byte)(ch >> 4);
+ ch = (byte)(ch & 0x0F);
+
+ ret += pseudo[(int)ch].ToString();
+
+ ch = (byte)(inp[i] & 0x0F);
+ ret += pseudo[(int)ch].ToString();
+
+ ret += " ";
+ }
+ return ret;
+ }
+
+ ///
+ /// Checks the specified string if it contains the specified char array
+ ///
+ ///
+ ///
+ ///
+ public static bool StringContains(String instr, char[] chars)
+ {
+ for (int i = 0; i < chars.Length; i++)
+ {
+ if (Contains(instr, chars[i]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Checks the specified string if it contains the specified char
+ ///
+ ///
+ ///
+ ///
+ private static bool Contains(string instr, char p)
+ {
+ for (int i = 0; i < instr.Length; i++)
+ {
+ if (instr[i] == p)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Copies the contents of one byte array into another starting at the specified index
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int CopyByteToByte(byte[] Data, int DataIndex, byte[] Array, int ArrayIndex, int Length)
+ {
+ int i = 0;
+ int j = ArrayIndex;
+ for (i = DataIndex; i < Length + DataIndex && i < Data.Length; i++)
+ {
+ Array[j++] = Data[i];
+ }
+ while (j < Length + ArrayIndex)
+ {
+ Array[j++] = 0;
+ }
+ return i;
+ }
+
+ ///
+ /// Copies the contents of one byte array into another starting at the specified index
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int CopyByteToByte(byte[] Data, int DataIndex, byte[] Array, int ArrayIndex, int Length, bool writeallzero)
+ {
+ int i = 0;
+ int j = ArrayIndex;
+ for (i = DataIndex; i < Length + DataIndex && i < Data.Length; i++)
+ {
+ Array[j++] = Data[i];
+ }
+ while (writeallzero && j < Length + ArrayIndex)
+ {
+ Array[j++] = 0;
+ }
+ return i;
+ }
+
+ ///
+ /// Copies the contents of a char array into a byte array
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int CopyCharToByte(Char[] Data, int dind, byte[] arr, int arrind, int many)
+ {
+ int i = 0;
+ int j = arrind;
+ for (i = dind; i < many && i < Data.Length; i++)
+ {
+ arr[j++] = (byte)Data[i];
+ }
+ while (j < many)
+ {
+ arr[j++] = 0;
+ }
+ return i;
+ }
+
+ ///
+ /// Copies the contents of a byte array into a char array
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static int CopyByteToChar(byte[] Data, int dind, Char[] arr, int arrind, int many)
+ {
+ int i = 0;
+ int j = arrind;
+ for (i = dind; i < many && i < Data.Length; i++)
+ {
+ arr[j++] = (Char)Data[i];
+ }
+ while (j < many)
+ {
+ arr[j++] = '\0';
+ }
+ return i;
+ }
+
+ ///
+ /// Converts a char[] array into a string and returns it
+ ///
+ ///
+ ///
+ public static string CharToString(char[] text)
+ {
+ String ret = "";
+ for (int i = 0; i < text.Length; i++)
+ {
+ ret += text[i];
+ }
+ return ret;
+ }
+
+ ///
+ /// Currently date and time represented in a UNIX timestamp
+ ///
+ public static long UNIXTimeStamp
+ {
+ get
+ {
+ long ret = 0;
+ long secondsinyear = 31536000;
+ long secondsinday = 86400;
+ for (int i = 1970; i < DateTime.Now.Year - 1; i++)
+ {
+ ret += secondsinyear;
+ if ((i % 400 == 0 || (i % 4 == 0 && i % 100 != 0)))
+ {
+ ret += secondsinday;
+ }
+ }
+ for (int i = 1; i < DateTime.Now.Month - 1; i++)
+ {
+ ret += MonthToDays[i] * secondsinday;
+ if (i == 2 && (DateTime.Now.Year % 400 == 0 || (DateTime.Now.Year % 4 == 0 && DateTime.Now.Year % 100 != 0)))
+ {
+ ret += secondsinday;
+ }
+ }
+ ret += DateTime.Now.Day * secondsinday;
+ ret += DateTime.Now.Hour * 3600;
+ ret += DateTime.Now.Minute * 60;
+ ret += DateTime.Now.Second;
+ return ret;
+ }
+ }
+
+ ///
+ /// Retrieves the number of days in each month
+ ///
+ private static int[] MonthToDays
+ {
+ get
+ {
+ List l = new List();
+ l.Add(31);
+ l.Add(28);
+ l.Add(31);
+ l.Add(30);
+ l.Add(31);
+ l.Add(30);
+ l.Add(31);
+ l.Add(31);
+ l.Add(30);
+ l.Add(31);
+ l.Add(30);
+ l.Add(31);
+ return l.ToArray();
+ }
+ }
}
}
diff --git a/source/SDFS_Demo/DiskHandler.cs b/source/SDFS_Demo/DiskHandler.cs
new file mode 100644
index 0000000..8c12c33
--- /dev/null
+++ b/source/SDFS_Demo/DiskHandler.cs
@@ -0,0 +1,433 @@
+/*
+ *
+ *
+ * This following source is licenced via the following:
+ *
+ *
+ * The Clear BSD License
+
+ * Copyright (c) 2018, Siaranite Solutions, Medli
+ * All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Siaranite Solutions nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+THIS SOFTWARE IS PROVIDED BY SIARANITE SOLUTIONS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SIARANITE SOLUTIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using SDFS.Physical;
+using SDFS;
+
+namespace SDFS_Demo
+{
+ ///
+ /// Defines a disk listing
+ ///
+ public class DiskListing
+ {
+ ///
+ /// Static List of DiskListings
+ ///
+ public static List DiskListings = new List();
+
+ ///
+ /// Static List of PartitionListings
+ ///
+ public List PartitionListings = new List();
+
+ ///
+ /// The DiskListing's BlockDevice
+ ///
+ public IDE Disk;
+
+ ///
+ /// The DiskListing's Disk Number
+ ///
+ public int DiskNumber;
+
+ ///
+ /// Constructor for a Disk Listing
+ ///
+ ///
+ ///
+ public DiskListing(int num, IDE disk)
+ {
+ DiskNumber = num + 1;
+ Disk = disk;
+ DiskListings.Add(this);
+ int pnum = 0;
+ foreach (PrimaryPartition Partition in disk.PrimaryPartitions)
+ {
+ pnum += 1;
+ PartitionListings.Add(new PartitionListing(pnum, this, Partition.Info));
+ }
+ }
+
+ ///
+ /// String containing information about the Disk Listing
+ ///
+ public string Info
+ {
+ get
+ {
+ return ("Disk: " + DiskNumber + " Size: " + Disk.Size + " MBs");
+ }
+ }
+
+ public void PartInfo()
+ {
+ foreach (PartitionListing partition in PartitionListings)
+ {
+ Console.WriteLine(partition.Info);
+ }
+ }
+
+ ///
+ /// Prints information about the DiskListing
+ ///
+ public void PrintInfo()
+ {
+ Console.WriteLine(Info);
+ }
+ }
+
+ ///
+ /// Defines a partition listing
+ ///
+ public class PartitionListing
+ {
+ public DiskListing Disk;
+ public int PartNum;
+ public PartitionObj Partition;
+ public uint Size;
+ public byte ID;
+
+ public PartitionListing(int num, DiskListing disk, PartitionObj part)
+ {
+ this.Disk = disk;
+ this.PartNum = num;
+ this.Partition = part;
+ this.Size = part.TotalSize;
+ this.ID = part.SystemID;
+ }
+
+ public string Info
+ {
+ get
+ {
+ return ("Disk: " + this.Disk.DiskNumber + ", Partition: " + this.PartNum + ", Type: " + this.ID + ", Size: " + this.Size + "MBs");
+ }
+ }
+ }
+
+ ///
+ /// The Disk Utility class, containing methods and properties
+ ///
+ public class SDFSUtility
+ {
+ ///
+ /// Prints information about the currently selected disk, if any is selected
+ ///
+ public static void PrintSelectedDisk()
+ {
+ if (SelectedDisk != null)
+ {
+
+ SelectedDisk.PrintInfo();
+ }
+ else
+ {
+ Console.WriteLine("No disk is currently selected!");
+ }
+ }
+ ///
+ /// Defines the selected DiskListing
+ ///
+ public static DiskListing SelectedDisk = null;
+
+ ///
+ /// Main Disk Utility method, with the list of IDE devices passed as the parameter
+ /// TODO - Remove the requirement for the IDE array to be passed as array - or move detection to INIT1
+ ///
+ ///
+ public static void Main(IDE[] List)
+ {
+
+ bool running = true;
+ Console.BackgroundColor = ConsoleColor.Blue;
+ Console.Clear();
+ Console.WriteLine("Welcome to the Medli File System Utility [MFSU]");
+ Console.WriteLine("");
+ while (running == true)
+ {
+ Console.WriteLine("");
+ Console.WriteLine("1) List Disks 2) Select Disks 3) List Partitions\n4) Create Partitions 5) Exit disk utility");
+ Console.WriteLine("");
+ Console.Write(">");
+ string option = Console.ReadLine().ToLower();
+ if (option == "1")
+ {
+ ListDisks();
+ }
+ else if (option == "2")
+ {
+ SelectDisk();
+ }
+ else if (option == "3")
+ {
+ DiskPartInfo();
+ }
+ else if (option == "4")
+ {
+ CreatePartitions();
+ }
+ else if (option == "quit" || option == "exit" || option == "5")
+ {
+ running = false;
+ }
+ else
+ {
+ Console.WriteLine(option + ": Invalid option!");
+ }
+ }
+ Console.Clear();
+ }
+ ///
+ /// Selects a DiskListing from the list
+ ///
+ public static void SelectDisk()
+ {
+ SelectedDisk = null;
+ do
+ {
+ Console.WriteLine("Which disk do you wish to use?\n");
+ ListDisks();
+ string nums = Console.ReadLine();
+ int num = int.Parse(nums) - 1;
+ if (num >= 0 && num < DiskListing.DiskListings.Count)
+ {
+ SelectedDisk = DiskListing.DiskListings[num];
+ }
+ }
+ while (SelectedDisk == null);
+ }
+
+ ///
+ /// Lists each of the disks from the list
+ ///
+ public static void ListDisks()
+ {
+ foreach (DiskListing disklist in DiskListing.DiskListings)
+ {
+ if (disklist == SelectedDisk)
+ {
+ Console.WriteLine("* " + disklist.Info);
+ }
+ else
+ {
+ disklist.PrintInfo();
+ }
+ }
+ }
+
+ ///
+ /// Lists the partitions in the specified disk
+ ///
+ ///
+ public static void DiskPartInfo()
+ {
+ if (SelectedDisk != null)
+ {
+ SelectedDisk.PartInfo();
+ }
+ else
+ {
+ Console.WriteLine("No disk selected!\n");
+ }
+ }
+
+ //public static void ListPartitions(IDE Device)
+ //{
+ // if (Device == null)
+ // {
+ // Console.WriteLine("No disk selected!\n");
+ // }
+ // else
+ // {
+ // MBR mbr = Device.MBR;
+ // PartitionInfo[] partitions = mbr.Partitions;
+ // if ((partitions.Length > 0) && (partitions.Length <= 4))
+ // {
+ // foreach (PartitionInfo part in partitions)
+ // {
+ // Console.WriteLine("Partition ID: " + part.SystemID + " Size: " + part.TotalSize + " MBs");
+ // }
+ // }
+ // else
+ // {
+ // Console.WriteLine("No partitions detected!\n");
+ // }
+ // }
+ //}
+
+
+ ///
+ /// Creates partitions on the selected disk
+ ///
+ public static void CreatePartitions()
+ {
+ if (SelectedDisk == null)
+ {
+ Console.WriteLine("No disk is currently selected!");
+ }
+ else
+ {
+ int PartitionNumber = 0;
+ ulong DisplayCount = SelectedDisk.Disk.BlockCount - 1;
+ Console.WriteLine("How many primary partitions do you want to have? (Max. 4)");
+ do
+ {
+ Console.WriteLine("Insert number");
+ String nums = Console.ReadLine();
+ PartitionNumber = int.Parse(nums);
+ }
+ while (PartitionNumber == 0 || PartitionNumber > 4);
+
+ uint mbrpos = 446;
+ Byte[] type = new Byte[] { 0x00, 0x00, 0x00, 0x00 };
+ uint[] StartBlock = new uint[] { 1, 0, 0, 0 };
+ uint[] BlockNum = new uint[] { 0, 0, 0, 0 };
+ for (int i = 0; i < PartitionNumber; i++)
+ {
+ type[i] = 0xFA;
+ Console.WriteLine("How many blocks for Partition N. " + (i + 1) + "? (Max: " + ((uint)(DisplayCount - (uint)(PartitionNumber - (i + 1)))).ToString() + "): ");
+ String nums = Console.ReadLine();
+ uint num = (uint)int.Parse(nums);
+ if (num >= 0 && num <= DisplayCount - (uint)(PartitionNumber - (i + 1)))
+ {
+ BlockNum[i] = num;
+ if (i < PartitionNumber - 1)
+ {
+ StartBlock[i + 1] = (num) + StartBlock[i];
+ }
+ DisplayCount = DisplayCount - (num);
+ }
+ else
+ {
+ i--;
+ }
+ }
+ Byte[] data = SelectedDisk.Disk.NewBlockArray(1);
+ SelectedDisk.Disk.ReadBlock(0, 1, data);
+ for (int i = 0; i < 4; i++)
+ {
+ mbrpos += 4;
+ data[mbrpos] = type[i];
+ mbrpos += 4;
+ Byte[] b = BitConverter.GetBytes(StartBlock[i]);
+ UtilityMethods.CopyByteToByte(b, 0, data, (int)mbrpos, b.Length);
+ mbrpos += 4;
+ b = BitConverter.GetBytes(BlockNum[i]);
+ UtilityMethods.CopyByteToByte(b, 0, data, (int)mbrpos, b.Length);
+ mbrpos += 4;
+ SelectedDisk.Disk.WriteBlock(StartBlock[i], 1, SelectedDisk.Disk.NewBlockArray(1));
+ }
+ SelectedDisk.Disk.WriteBlock(0, 1, data);
+ DiskPartInfo();
+ }
+ }
+
+ public static void CreatePartitions(IDE[] IDEs)
+ {
+ int PartitionNumber = 0;
+ ulong DisplayCount = SelectedDisk.Disk.BlockCount - 1;
+ Console.WriteLine("How many primary partitions do you want to have? (Max. 4)");
+ Console.Write("Insert number:");
+ do
+ {
+ String nums = Console.ReadLine();
+ PartitionNumber = int.Parse(nums);
+ }
+ while (PartitionNumber == 0 || PartitionNumber > 4);
+
+ uint mbrpos = 446;
+ Byte[] type = new Byte[] { 0x00, 0x00, 0x00, 0x00 };
+ uint[] StartBlock = new uint[] { 1, 0, 0, 0 };
+ uint[] BlockNum = new uint[] { 0, 0, 0, 0 };
+ for (int i = 0; i < PartitionNumber; i++)
+ {
+ type[i] = 0xFA;
+ Console.Write("How many blocks for Partition N. " + (i + 1) + "? (Max: " + ((uint)(DisplayCount - (uint)(PartitionNumber - (i + 1)))).ToString() + "): ");
+ String nums = Console.ReadLine();
+ uint num = (uint)int.Parse(nums);
+ if (num >= 0 && num <= DisplayCount - (uint)(PartitionNumber - (i + 1)))
+ {
+ BlockNum[i] = num;
+ if (i < PartitionNumber - 1)
+ {
+ StartBlock[i + 1] = (num) + StartBlock[i];
+ }
+ DisplayCount = DisplayCount - (num);
+ }
+ else
+ {
+ i--;
+ }
+ }
+ Byte[] data = SelectedDisk.Disk.NewBlockArray(1);
+ SelectedDisk.Disk.ReadBlock(0, 1, data);
+ for (int i = 0; i < 4; i++)
+ {
+ mbrpos += 4;
+ data[mbrpos] = type[i];
+ mbrpos += 4;
+ Byte[] b = BitConverter.GetBytes(StartBlock[i]);
+ UtilityMethods.CopyByteToByte(b, 0, data, (int)mbrpos, b.Length);
+ mbrpos += 4;
+ b = BitConverter.GetBytes(BlockNum[i]);
+ UtilityMethods.CopyByteToByte(b, 0, data, (int)mbrpos, b.Length);
+ mbrpos += 4;
+ SelectedDisk.Disk.WriteBlock(StartBlock[i], 1, SelectedDisk.Disk.NewBlockArray(1));
+ }
+ SelectedDisk.Disk.WriteBlock(0, 1, data);
+ DiskPartInfo();
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/SDFS_Demo/Kernel.cs b/source/SDFS_Demo/Kernel.cs
new file mode 100644
index 0000000..e309ddc
--- /dev/null
+++ b/source/SDFS_Demo/Kernel.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Sys = Cosmos.System;
+using SDFS;
+using SDFS.Logical;
+using SDFS.Physical;
+
+namespace SDFS_Demo
+{
+ public class Kernel : Sys.Kernel
+ {
+ public static Filesystem fs;
+ ///
+ /// Partition containing a valid SDFS partition
+ ///
+ private static PrimaryPartition workPartition = null;
+
+ protected override void BeforeRun()
+ {
+ IDE[] IDEs = IDE.Devices.ToArray();
+ for (int i = 0; i < IDEs.Length; i++)
+ {
+ new DiskListing(i, IDEs[i]);
+ }
+
+ Console.WriteLine("Number of IDE disks: " + IDEs.Length);
+ Console.WriteLine("Looking for valid partitions...");
+ for (int i = 0; i < IDEs.Length; i++)
+ {
+ PrimaryPartition[] parts = IDEs[i].PrimaryPartitions;
+ for (int j = 0; j < parts.Length; j++)
+ {
+ if (parts[j].Info.SystemID == 0xFA)
+ {
+ workPartition = parts[j];
+ }
+ }
+ }
+ //#warning Revert to == null!!!
+ if (workPartition == null)
+ {
+ SDFSUtility.Main(IDEs);
+ Console.WriteLine("The machine needs to be restarted.");
+ Console.ReadKey(true);
+ Sys.Power.Reboot();
+ }
+
+ Console.Write("Checking FileSystem... ");
+
+ try
+ {
+ fs = new Filesystem(workPartition);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Error!" + ex.Message);
+ }
+
+ Console.WriteLine("\n Size:" + workPartition.Info.TotalSize + "MBs");
+ Console.WriteLine("Type: " + workPartition.Info.SystemID.ToString());
+
+ Console.ReadKey(true);
+ try
+ {
+ fs.Root.AddDirectory("Test");
+ SDFS.IO.File.WriteAllText("test.txt", "Test", "Welcome to SDFS Filesystem");
+ string ExampleString = SDFS.IO.File.ReadAllText("test.txt", "Test");
+
+ Console.WriteLine(ExampleString);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ Console.ReadKey(true);
+ }
+
+ }
+
+ protected override void Run()
+ {
+ Console.ReadKey(true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/SDFS Demo/SDFS Demo.csproj b/source/SDFS_Demo/SDFS_Demo.csproj
similarity index 93%
rename from source/SDFS Demo/SDFS Demo.csproj
rename to source/SDFS_Demo/SDFS_Demo.csproj
index 3dfd74f..5b57caa 100644
--- a/source/SDFS Demo/SDFS Demo.csproj
+++ b/source/SDFS_Demo/SDFS_Demo.csproj
@@ -22,6 +22,8 @@
VMware
Use VMware Player or Workstation to deploy and debug.
192.168.0.8
+ SDFS_Demo
+ SDFS_Demo