Merge pull request #1 from jp2masa/fat-stuff

FAT Updates
This commit is contained in:
Michael VanOverbeek 2016-08-18 09:55:39 -05:00 committed by GitHub
commit 130363a8b0
11 changed files with 188 additions and 78 deletions

View file

@ -77,27 +77,22 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Cosmos.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5ae71220097cb983, processorArchitecture=x86">
<HintPath>..\..\source\Cosmos.Common\bin\Debug\Cosmos.Common.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="Cosmos.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5ae71220097cb983, processorArchitecture=MSIL">
<HintPath>..\..\source\Cosmos.Core\bin\Debug\Cosmos.Core.dll</HintPath>
</Reference>
<Reference Include="Cosmos.HAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5ae71220097cb983, processorArchitecture=MSIL">
<HintPath>..\..\source\Cosmos.HAL\obj\Debug\Cosmos.HAL.dll</HintPath>
</Reference>
<Reference Include="Cosmos.System, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5ae71220097cb983, processorArchitecture=MSIL">
<HintPath>..\..\source\Cosmos.System\bin\Debug\Cosmos.System.dll</HintPath>
</Reference>
<Reference Include="Cosmos.Debug.Kernel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5ae71220097cb983, processorArchitecture=MSIL">
<HintPath>..\..\source\Cosmos.Debug.Kernel\bin\Debug\Cosmos.Debug.Kernel.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="GuessOS.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\source\Cosmos.Debug.Kernel\Cosmos.Debug.Kernel.csproj">
<Project>{61607f1e-58f9-41cf-972f-128384f3e115}</Project>
<Name>Cosmos.Debug.Kernel</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.System\Cosmos.System.csproj">
<Project>{3def0461-08ab-471a-8f03-a9c556652a0f}</Project>
<Name>Cosmos.System</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -8,6 +8,7 @@ namespace Cosmos.TestRunner.Core
public static IEnumerable<Type> GetStableKernelTypes()
{
yield return typeof(VGACompilerCrash.Kernel);
//yield return typeof(Cosmos.Compiler.Tests.Encryption.Kernel);
yield return typeof(Cosmos.Compiler.Tests.Bcl.Kernel);
yield return typeof(Cosmos.Compiler.Tests.SingleEchoTest.Kernel);
@ -16,7 +17,9 @@ namespace Cosmos.TestRunner.Core
yield return typeof(Cosmos.Compiler.Tests.Exceptions.Kernel);
yield return typeof(Cosmos.Compiler.Tests.LinqTests.Kernel);
yield return typeof(Cosmos.Compiler.Tests.MethodTests.Kernel);
yield return typeof(Cosmos.Kernel.Tests.Fat.Kernel);
//yield return typeof(FrotzKernel.Kernel);
}
}
}

View file

@ -62,6 +62,18 @@ namespace Cosmos.System.Plugs.System.IO
return new DirectoryInfo(aPath);
}
public static void Delete(string aPath)
{
Delete(aPath, false);
}
public static void Delete(string aPath, bool recursive)
{
String xFullPath = Path.GetFullPath(aPath);
VFSManager.DeleteDirectory(xFullPath, recursive);
}
public static DirectoryInfo GetParent(string aPath)
{
Global.mFileSystemDebugger.SendInternal("Directory.GetParent:");
@ -133,6 +145,5 @@ namespace Cosmos.System.Plugs.System.IO
return xFiles.ToArray();
}
}
}

View file

@ -15,12 +15,6 @@ namespace Cosmos.System.Plugs.System.IO
[Plug(Target = typeof(File))]
public static class FileImpl
{
public static void InternalDelete(string aPath, bool checkHost)
{
String xFullPath = Path.GetFullPath(aPath);
VFSManager.DeleteFile(xFullPath);
}
public static bool Exists(string aFile)
{
Global.mFileSystemDebugger.SendInternal("File.Exists:");
@ -172,10 +166,16 @@ namespace Cosmos.System.Plugs.System.IO
var xBuff = new byte[(int)xFS.Length];
var yFS = new FileStream(destFile, FileMode.Create);
yFS.Write(xBuff, 0, xBuff.Length);
}
}
public static void InternalDelete(string aPath, bool checkHost)
{
String xFullPath = Path.GetFullPath(aPath);
VFSManager.DeleteFile(xFullPath);
}
public static FileStream Create(string aFile)
{
Global.mFileSystemDebugger.SendInternal("File.Create:");
@ -185,7 +185,6 @@ namespace Cosmos.System.Plugs.System.IO
throw new ArgumentException("Argument is null or empty", nameof(aFile));
}
var xEntry = VFSManager.CreateFile(aFile);
if (xEntry == null)
{

View file

@ -148,6 +148,47 @@ namespace Cosmos.System.FileSystem
return xFS.CreateDirectory(xParentEntry, xDirectoryToCreate);
}
/// <summary>
/// Deletes a file.
/// </summary>
/// <param name="aPath">The full path.</param>
/// <returns></returns>
public override bool DeleteFile(DirectoryEntry aPath)
{
try
{
var xFS = GetFileSystemFromPath(aPath.mFullPath);
xFS.DeleteFile(aPath);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Deletes an empty directory.
/// </summary>
/// <param name="aPath">The full path.</param>
/// <returns></returns>
public override bool DeleteDirectory(DirectoryEntry aPath)
{
try
{
if (GetDirectoryListing(aPath).Count > 0)
throw new Exception("Directory is not empty");
var xFS = GetFileSystemFromPath(aPath.mFullPath);
xFS.DeleteDirectory(aPath);
return true;
}
catch
{
return false;
}
}
/// <summary>
/// Gets the directory listing for a path.
/// </summary>
@ -167,15 +208,12 @@ namespace Cosmos.System.FileSystem
/// <returns></returns>
public override List<DirectoryEntry> GetDirectoryListing(DirectoryEntry aDirectory)
{
DirectoryEntry xTempEntry = aDirectory;
string xFullPath = "";
while (xTempEntry.mParent != null)
if (aDirectory == null || String.IsNullOrEmpty(aDirectory.mFullPath))
{
xFullPath = Path.Combine(xTempEntry.mName, xFullPath);
xTempEntry = xTempEntry.mParent;
throw new ArgumentException("Argument is null or empty", nameof(aDirectory));
}
return GetDirectoryListing(xFullPath);
return GetDirectoryListing(aDirectory.mFullPath);
}
/// <summary>
@ -321,7 +359,7 @@ namespace Cosmos.System.FileSystem
if ((mFileSystems.Count > 0) && (mFileSystems[mFileSystems.Count - 1].mRootPath == xRootPath))
{
string xMessage = string.Concat("Initialized ", mFileSystems.Count, "filesystem(s)...");
string xMessage = string.Concat("Initialized ", mFileSystems.Count, " filesystem(s)...");
global::System.Console.WriteLine(xMessage);
mFileSystems[i].DisplayFileSystemInfo();
Directory.SetCurrentDirectory(xRootPath);
@ -455,20 +493,5 @@ namespace Cosmos.System.FileSystem
return aFS.GetRootDirectory();
}
public override bool DeleteFile(DirectoryEntry aPath)
{
try
{
var xFS = GetFileSystemFromPath(aPath.mFullPath);
xFS.Delete(aPath);
return true;
}
catch
{
return false;
}
}
}
}

View file

@ -142,6 +142,15 @@ namespace Cosmos.System.FileSystem.FAT
throw new Exception("Failed to find an unallocated FAT entry.");
}
/// <summary>
/// Clears a fat entry.
/// </summary>
/// <param name="aEntryNumber">The entry number.</param>
public void ClearFatEntry(ulong aEntryNumber)
{
SetFatEntry(aEntryNumber, 0);
}
private void ReadFatSector(ulong aSector, out byte[] aData)
{
@ -222,7 +231,7 @@ namespace Cosmos.System.FileSystem.FAT
/// <summary>
/// Sets a fat entry.
/// </summary>
/// <param name="aEntryNumber"></param>
/// <param name="aEntryNumber">The entry number.</param>
/// <param name="aValue">The value.</param>
private void SetFatEntry(ulong aEntryNumber, ulong aValue)
{
@ -624,9 +633,35 @@ namespace Cosmos.System.FileSystem.FAT
return xDirectoryEntryToAdd;
}
public override void Delete(DirectoryEntry aPath)
public override void DeleteDirectory(DirectoryEntry aDirectoryEntry)
{
aPath.Delete();
if(aDirectoryEntry == null)
{
throw new ArgumentNullException(nameof(aDirectoryEntry));
}
var xDirectoryEntry = (FatDirectoryEntry)aDirectoryEntry;
xDirectoryEntry.DeleteDirectoryEntry();
}
public override void DeleteFile(DirectoryEntry aDirectoryEntry)
{
if (aDirectoryEntry == null)
{
throw new ArgumentNullException(nameof(aDirectoryEntry));
}
var xDirectoryEntry = (FatDirectoryEntry)aDirectoryEntry;
var entries = xDirectoryEntry.GetFatTable();
foreach (var entry in entries)
{
GetFat(0).ClearFatEntry(entry);
}
xDirectoryEntry.DeleteDirectoryEntry();
}
private enum FatTypeEnum

View file

@ -178,6 +178,14 @@ namespace Cosmos.System.FileSystem.FAT.Listing
throw new ArgumentOutOfRangeException(nameof(aType), "Unknown directory entry type.");
}
public void DeleteDirectoryEntry()
{
if (mEntryType == DirectoryEntryTypeEnum.Unknown)
throw new NotImplementedException();
SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata.FirstByte, FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry);
}
public List<FatDirectoryEntry> ReadDirectoryContents()
{
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.ReadDirectoryContents --");
@ -197,15 +205,14 @@ namespace Cosmos.System.FileSystem.FAT.Listing
if (xAttrib == FatDirectoryEntryAttributeConsts.LongName)
{
byte xType = xData[i + 12];
byte xOrd = xData[i];
if (xOrd == 0xE5)
if (xStatus == FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry)
{
Global.mFileSystemDebugger.SendInternal("<DELETED> : Attrib = " + xAttrib + ", Status = " + xStatus);
continue;
}
if (xType == 0)
{
if ((xOrd & 0x40) > 0)
if ((xStatus & 0x40) > 0)
{
xLongName = "";
}
@ -243,7 +250,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
case 0x05:
// Japanese characters - We dont handle these
break;
case 0xE5:
case FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry:
// Empty slot, skip it
break;
default:
@ -291,7 +298,11 @@ namespace Cosmos.System.FileSystem.FAT.Listing
uint xFirstCluster = (uint)(xData.ToUInt16(i + 20) << 16 | xData.ToUInt16(i + 26));
int xTest = xAttrib & (FatDirectoryEntryAttributeConsts.Directory | FatDirectoryEntryAttributeConsts.VolumeID);
if (xAttrib == FatDirectoryEntryAttributeConsts.LongName)
if (xStatus == FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry)
{
// deleted file
}
else if (xAttrib == FatDirectoryEntryAttributeConsts.LongName)
{
// skip adding, as it's a LongFileName entry, meaning the next normal entry is the item with the name.
//Global.mFileSystemDebugger.SendInternal($"Entry was a Long FileName entry. Current LongName = '{xLongName}'");
@ -458,13 +469,5 @@ namespace Cosmos.System.FileSystem.FAT.Listing
((FatDirectoryEntry)mParent).SetDirectoryEntryData(xData);
}
}
public override void Delete()
{
if (mEntryType == DirectoryEntryTypeEnum.Directory || mEntryType == DirectoryEntryTypeEnum.Unknown)
throw new NotImplementedException();
SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata.FirstByte, FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry);
}
}
}

View file

@ -35,11 +35,12 @@ namespace Cosmos.System.FileSystem
public abstract DirectoryEntry CreateFile(DirectoryEntry aParentDirectory, string aNewFile);
public abstract void DeleteDirectory(DirectoryEntry aPath);
public abstract void DeleteFile(DirectoryEntry aPath);
protected Partition mDevice { get; }
public string mRootPath { get; }
public abstract void Delete(DirectoryEntry aPath);
}
}

View file

@ -80,7 +80,5 @@ namespace Cosmos.System.FileSystem.Listing
public abstract void SetSize(long aSize);
public abstract Stream GetFileStream();
public abstract void Delete();
}
}

View file

@ -11,6 +11,10 @@ namespace Cosmos.System.FileSystem.VFS
public abstract DirectoryEntry CreateDirectory(string aPath);
public abstract bool DeleteFile(DirectoryEntry aPath);
public abstract bool DeleteDirectory(DirectoryEntry aPath);
public abstract DirectoryEntry GetDirectory(string aPath);
public abstract DirectoryEntry GetFile(string aPath);
@ -21,8 +25,6 @@ namespace Cosmos.System.FileSystem.VFS
public abstract DirectoryEntry GetVolume(string aVolume);
public abstract bool DeleteFile(DirectoryEntry aPath);
public abstract List<DirectoryEntry> GetVolumes();
public static char DirectorySeparatorChar { get { return '\\'; } }

View file

@ -12,15 +12,6 @@ namespace Cosmos.System.FileSystem.VFS
{
private static VFSBase mVFS;
public static void DeleteFile(string aPath)
{
if (mVFS == null)
throw new Exception("VFSManager isn't ready.");
var xFile = mVFS.GetFile(aPath);
mVFS.DeleteFile(xFile);
}
public static void RegisterVFS(VFSBase aVFS)
{
Global.mFileSystemDebugger.SendInternal("--- VFSManager.RegisterVFS ---");
@ -48,6 +39,19 @@ namespace Cosmos.System.FileSystem.VFS
return mVFS.CreateFile(aPath);
}
public static void DeleteFile(string aPath)
{
if (mVFS == null)
throw new Exception("VFSManager isn't ready.");
var xFile = mVFS.GetFile(aPath);
if (xFile.mEntryType != DirectoryEntryTypeEnum.File)
throw new UnauthorizedAccessException("The specified path isn't a file");
mVFS.DeleteFile(xFile);
}
public static DirectoryEntry GetFile(string aPath)
{
Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetFile ---");
@ -103,6 +107,42 @@ namespace Cosmos.System.FileSystem.VFS
return mVFS.CreateDirectory(aPath);
}
public static void DeleteDirectory(string aPath, bool recursive)
{
if (mVFS == null)
throw new Exception("VFSManager isn't ready.");
var xDirectory = mVFS.GetDirectory(aPath);
var xDirectoryListing = mVFS.GetDirectoryListing(xDirectory);
if (xDirectory.mEntryType != DirectoryEntryTypeEnum.Directory)
throw new IOException("The specified path isn't a directory");
if (xDirectoryListing.Count > 0 && !recursive)
throw new IOException("Directory is not empty");
if(recursive)
{
foreach (var entry in xDirectoryListing)
{
if (entry.mEntryType == DirectoryEntryTypeEnum.Directory)
{
DeleteDirectory(entry.mFullPath, true);
}
else if (entry.mEntryType == DirectoryEntryTypeEnum.File)
{
DeleteFile(entry.mFullPath);
}
else
{
throw new IOException("The directory contains a corrupted file");
}
}
}
mVFS.DeleteDirectory(xDirectory);
}
public static DirectoryEntry GetDirectory(string aPath)
{
Global.mFileSystemDebugger.SendInternal("--- VFSManager.GetDirectory ---");