Skip to content

Commit

Permalink
FAT works (start): Directory.Exists works for root folders.
Browse files Browse the repository at this point in the history
  • Loading branch information
mterwoord committed Jul 4, 2015
1 parent 732a3e2 commit ebba2f1
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 108 deletions.
Binary file modified Build/VMWare/Workstation/Filesystem.vmdk
Binary file not shown.
2 changes: 1 addition & 1 deletion Users/Sentinel/SentinelKernel/Kernel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ protected override void Run()
try
{
var xRoot = Path.GetPathRoot(@"0:\test");
bool xTest = Directory.Exists("0:\\test");
bool xTest = Directory.Exists("0:\\TEST");
Console.WriteLine("After test");
if (xTest)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Linq;
using System.Threading.Tasks;

namespace SentinelKernel.System.FileSystem.FAT
{
public static class DirectoryEntryAttributeConsts
{
public const int Test = 0x01;
public const int Hidden = 0x02;
public const int System = 0x04;
public const int VolumeID = 0x08;
public const int Directory = 0x10;
public const int Archive = 0x20;
// LongName was created after and is a combination of other attribs. Its "special".
public const int LongName = 0x0F;
}
}
178 changes: 97 additions & 81 deletions Users/Sentinel/SentinelSystem/FileSystem/FAT/FatFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System.Text;
using Cosmos.Common.Extensions;
using Cosmos.HAL.BlockDevice;
using SentinelKernel.System.FileSystem.FAT.Listing;
using SentinelKernel.System.FileSystem.Listing;

namespace SentinelKernel.System.FileSystem.FAT
{
Expand All @@ -28,18 +30,6 @@ public class FatFileSystem : FileSystem
readonly public UInt32 DataSector; // First Data Sector
readonly public UInt32 DataSectorCount;

public static class Attribs
{
public const int Test = 0x01;
public const int Hidden = 0x02;
public const int System = 0x04;
public const int VolumeID = 0x08;
public const int Directory = 0x10;
public const int Archive = 0x20;
// LongName was created after and is a combination of other attribs. Its "special".
public const int LongName = 0x0F;
}

public enum FatTypeEnum { Unknown, Fat12, Fat16, Fat32 }
readonly public FatTypeEnum FatType = FatTypeEnum.Unknown;

Expand Down Expand Up @@ -85,7 +75,7 @@ public UInt64 GetFatEntry(byte[] aSector, UInt64 aClusterNum, UInt64 aOffset)
}
// We now access the FAT entry as a WORD just as we do for FAT16, but if the cluster number is
// EVEN, we only want the low 12-bits of the 16-bits we fetch. If the cluster number is ODD
// we want the high 12-bits of the 16-bits we fetch.
// we want the high 12-bits of the 16-bits we fetch.
UInt32 xResult = aSector.ToUInt16(aOffset);
if ((aClusterNum & 0x01) == 0)
{ // Even
Expand Down Expand Up @@ -143,12 +133,12 @@ public FatFileSystem(Cosmos.HAL.BlockDevice.BlockDevice aDevice)

DataSectorCount = TotalSectorCount - (ReservedSectorCount + (NumberOfFATs * FatSectorCount) + ReservedSectorCount);

// Computation rounds down.
// Computation rounds down.
ClusterCount = DataSectorCount / SectorsPerCluster;
// Determine the FAT type. Do not use another method - this IS the official and
// proper way to determine FAT type.
// Comparisons are purposefully < and not <=
// FAT16 starts at 4085, FAT32 starts at 65525
// FAT16 starts at 4085, FAT32 starts at 65525
if (ClusterCount < 4085)
{
FatType = FatTypeEnum.Fat12;
Expand Down Expand Up @@ -222,16 +212,25 @@ public void GetFatTableSector(UInt64 aClusterNum, out UInt32 oSector, out UInt32
mDevice.ReadBlock(RootSector, RootSectorCount, xData);
}
//TODO: Change xLongName to StringBuilder
string xLongName = "";
for (UInt32 i = 0; i < xData.Length; i = i + 32)
{
FatHelpers.Debug("-------------------------------------------------");
string xLongName = "";
byte xAttrib = xData[i + 11];
if (xAttrib == Attribs.LongName)
FatHelpers.Debug("Attrib = " + xAttrib.ToString());
if (xAttrib == DirectoryEntryAttributeConsts.LongName)
{
byte xType = xData[i + 12];
byte xOrd = xData[i];
FatHelpers.Debug("Reading LFN with Seqnr " + xOrd.ToString());
if (xOrd == 0xE5)
{
FatHelpers.Debug("Skipping deleted entry");
continue;
}
if (xType == 0)
{
byte xOrd = xData[i];

if ((xOrd & 0x40) > 0)
{
xLongName = "";
Expand All @@ -253,87 +252,94 @@ public void GetFatTableSector(UInt64 aClusterNum, out UInt32 oSector, out UInt32
}
}
xLongName = xLongPart + xLongName;
//TODO: LDIR_Chksum
//TODO: LDIR_Chksum
}
}
else
string xName = xLongName;
byte xStatus = xData[i];
if (xStatus == 0x00)
{
byte xStatus = xData[i];
if (xStatus == 0x00)
{
// Empty slot, and no more entries after this
break;
}
else if (xStatus == 0x05)
{
// Japanese characters - We dont handle these
}
else if (xStatus == 0xE5)
{
// Empty slot, skip it
}
else if (xStatus >= 0x20)
// Empty slot, and no more entries after this
break;
}
else if (xStatus == 0x05)
{
// Japanese characters - We dont handle these
}
else if (xStatus == 0xE5)
{
// Empty slot, skip it
}
else if (xStatus >= 0x20)
{

if (xLongName.Length > 0)
{
string xName;
if (xLongName.Length > 0)
// Leading and trailing spaces are to be ignored according to spec.
// Many programs (including Windows) pad trailing spaces although it
// it is not required for long names.
// As per spec, ignore trailing periods
xName = xLongName.Trim();

//If there are trailing periods
int nameIndex = xName.Length - 1;
if (xName[nameIndex] == '.')
{
// Leading and trailing spaces are to be ignored according to spec.
// Many programs (including Windows) pad trailing spaces although it
// it is not required for long names.
// As per spec, ignore trailing periods
xName = xLongName.Trim();

//If there are trailing periods
int nameIndex = xName.Length - 1;
if (xName[nameIndex] == '.')
//Search backwards till we find the first non-period character
for (; nameIndex > 0; nameIndex--)
{
//Search backwards till we find the first non-period character
for (; nameIndex > 0; nameIndex--)
if (xName[nameIndex] != '.')
{
if (xName[nameIndex] != '.')
{
break;
}
break;
}
//Substring to remove the periods
xName = xName.Substring(0, nameIndex + 1);
}
}
else
{
string xEntry = xData.GetAsciiString(i, 11);
xName = xEntry.Substring(0, 8).TrimEnd();
string xExt = xEntry.Substring(8, 3).TrimEnd();
if (xExt.Length > 0)
{
xName = xName + "." + xExt;
}
//Substring to remove the periods
xName = xName.Substring(0, nameIndex + 1);
}

UInt32 xFirstCluster = (UInt32)(xData.ToUInt16(i + 20) << 16 | xData.ToUInt16(i + 26));

var xTest = xAttrib & (Attribs.Directory | Attribs.VolumeID);
if (xTest == 0)
{
UInt32 xSize = xData.ToUInt32(i + 28);
xResult.Add(new Listing.FatFile(this, xName, xSize, xFirstCluster));
}
else if (xTest == Attribs.VolumeID)
{
//
}
else if (xTest == Attribs.Directory)
}
else
{
string xEntry = xData.GetAsciiString(i, 11);
xName = xEntry.Substring(0, 8).TrimEnd();
string xExt = xEntry.Substring(8, 3).TrimEnd();
if (xExt.Length > 0)
{
xResult.Add(new Listing.FatDirectory(this, xName));
xName = xName + "." + xExt;
}
xLongName = "";
}
}
UInt32 xFirstCluster = (UInt32)(xData.ToUInt16(i + 20) << 16 | xData.ToUInt16(i + 26));

var xTest = xAttrib & (DirectoryEntryAttributeConsts.Directory | DirectoryEntryAttributeConsts.VolumeID);
if (xTest == 0)
{
UInt32 xSize = xData.ToUInt32(i + 28);
xResult.Add(new Listing.FatFile(this, xName, xSize, xFirstCluster));
FatHelpers.Debug("Returning file '" + xName + "'");
}
else if (xTest == DirectoryEntryAttributeConsts.VolumeID)
{
FatHelpers.Debug("Directory entry is VolumeID");
//
}
else if (xTest == DirectoryEntryAttributeConsts.Directory || xAttrib == DirectoryEntryAttributeConsts.LongName)
{
var xFatDirectory = new Listing.FatDirectory(this, xName);
FatHelpers.Debug("Returning directory '" + xName + "'");
xResult.Add(xFatDirectory);
}
else
{
FatHelpers.Debug("Not sure what to do!");
}
xLongName = "";
}

return xResult;
}



public static bool IsDeviceFAT(Partition aDevice)
{
byte[] xBPB = aDevice.NewBlockArray(1);
Expand All @@ -345,5 +351,15 @@ public static bool IsDeviceFAT(Partition aDevice)
}
return true;
}

public override List<Base> GetDirectoryListing(Directory baseDirectory)
{
if (baseDirectory == null)
{
// get root folder
return GetRoot();
}
throw new NotImplementedException();
}
}
}
}
14 changes: 14 additions & 0 deletions Users/Sentinel/SentinelSystem/FileSystem/FatHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using Cosmos.Debug.Kernel;

namespace SentinelKernel.System.FileSystem
{
public static class FatHelpers
{
private static Debugger mDebugger = new Debugger("FAT", "Debug");
public static void Debug(string message)
{
//mDebugger.Send("FAT Debug: " + message);
}
}
}
23 changes: 13 additions & 10 deletions Users/Sentinel/SentinelSystem/FileSystem/FileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SentinelKernel.System.FileSystem.Listing;

namespace SentinelKernel.System.FileSystem
{
Expand All @@ -12,22 +13,22 @@ public enum FileSystemType
Unknown
}

public class FileSystem
public abstract class FileSystem
{
// Currently we map to the Windows scheme of single lettter: for drives. Cosmos will
// Currently we map to the Windows scheme of single lettter: for drives. Cosmos will
// NOT do this in the future, but it will be able to map paths to things that look like
// drive letters for compatibility with Windows code.
// For now we use Dictionary for simplicity, but in future this will change.
//static protected Dictionary<string, FileSystem> mMappings = new Dictionary<string, FileSystem>();

static protected FileSystem mFS;
//static protected FileSystem mFS;

static public void AddMapping(string aPath, FileSystem aFileSystem)
{
//mMappings.Add(aPath.ToUpper(), aFileSystem);
// Dictionary<> doesnt work yet, so for now we just hack this and support only one FS
mFS = aFileSystem;
}
//static public void AddMapping(string aPath, FileSystem aFileSystem)
//{
// //mMappings.Add(aPath.ToUpper(), aFileSystem);
// // Dictionary<> doesnt work yet, so for now we just hack this and support only one FS
// mFS = aFileSystem;
//}

public static FileSystemType GetFileSystemType(Partition aDevice)
{
Expand All @@ -38,5 +39,7 @@ public static FileSystemType GetFileSystemType(Partition aDevice)

return FileSystemType.Unknown;
}

public abstract List<Listing.Base> GetDirectoryListing(Directory baseDirectory);
}
}
}
Loading

0 comments on commit ebba2f1

Please sign in to comment.