From 8427ece15708bee20644d5389bf17d6f464c3822 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Sat, 21 Sep 2024 22:03:40 +0200 Subject: [PATCH] File System Labels [WIP] --- source/Cosmos.System2/FileSystem/Disk.cs | 31 ++++++++++- .../FileSystem/FAT/FatFileSystem.cs | 51 +++++++++++++++---- .../Cosmos.System2/FileSystem/FileSystem.cs | 2 +- .../FileSystem/ISO9660/ISO9660FileSystem.cs | 2 +- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/source/Cosmos.System2/FileSystem/Disk.cs b/source/Cosmos.System2/FileSystem/Disk.cs index 87f35303ce..e64d6e1867 100644 --- a/source/Cosmos.System2/FileSystem/Disk.cs +++ b/source/Cosmos.System2/FileSystem/Disk.cs @@ -5,6 +5,7 @@ using System.ComponentModel.Design.Serialization; using System.Net.Mime; using System.Text; +using Cosmos.HAL; using Cosmos.HAL.BlockDevice; using Cosmos.System.FileSystem.FAT; using Cosmos.System.FileSystem.ISO9660; @@ -282,7 +283,7 @@ public virtual void FormatPartition(int index, string format, bool quick = true, } if (format.StartsWith("FAT")) { - FatFileSystem.CreateFatFileSystem(part.Host, FilesystemLetter + ":\\", xSize, format); + FatFileSystem.CreateFatFileSystem(part.Host, FilesystemLetter, xSize, format); Mount(); } else @@ -306,7 +307,33 @@ public void MountPartition(int index) //We already mounted this partiton return; } - string xRootPath = string.Concat(VFSManager.GetNextFilesystemLetter(), VFSBase.VolumeSeparatorChar, VFSBase.DirectorySeparatorChar); + string Label = ""; + + var xBPB = part.Host.NewBlockArray(1); + part.Host.ReadBlock(0UL, 1U, ref xBPB); + ushort xSig = BitConverter.ToUInt16(xBPB, 510); + if (xSig == 0xAA55) //FAT signature + { + global::System.Console.WriteLine("Correct FAT signature"); + byte[] volumeLabelBytes = new byte[11]; + Array.Copy(xBPB, 0x047, volumeLabelBytes, 0, 11); + int actualLength = Array.IndexOf(volumeLabelBytes, (byte)0); + if (actualLength == -1) + { + actualLength = volumeLabelBytes.Length; + } + byte[] trimmedVolumeLabelBytes = new byte[actualLength]; + Array.Copy(volumeLabelBytes, trimmedVolumeLabelBytes, actualLength); + Label = Encoding.UTF8.GetString(trimmedVolumeLabelBytes); + global::System.Console.WriteLine("Label (saved): " + Label); + } + else + { + Label = VFSManager.GetNextFilesystemLetter(); + global::System.Console.WriteLine("Generated new Label " + Label); + } + + string xRootPath = string.Concat(Label, VFSBase.VolumeSeparatorChar, VFSBase.DirectorySeparatorChar); var xSize = (long)(Host.BlockCount * Host.BlockSize / 1024 / 1024); foreach (var item in FileSystemManager.RegisteredFileSystems) diff --git a/source/Cosmos.System2/FileSystem/FAT/FatFileSystem.cs b/source/Cosmos.System2/FileSystem/FAT/FatFileSystem.cs index 40ba64c891..ea0e85f896 100644 --- a/source/Cosmos.System2/FileSystem/FAT/FatFileSystem.cs +++ b/source/Cosmos.System2/FileSystem/FAT/FatFileSystem.cs @@ -2,6 +2,7 @@ // #define COSMOSDEBUG using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text; @@ -319,7 +320,8 @@ public void ClearAllFat() /// Output data byte. /// Thrown when data lenght is greater then Int32.MaxValue. /// Thrown when data size invalid. - private void ReadFatSector(ulong aSector, ref byte[] aData) { + private void ReadFatSector(ulong aSector, ref byte[] aData) + { Global.Debugger.SendInternal("-- FatFileSystem.ReadFatSector --"); ulong xSector = mFatSector + aSector; Global.Debugger.SendInternal("xSector =" + xSector); @@ -646,6 +648,11 @@ internal ulong FatEntryEofValue() /// public uint TotalSectorCount { get; private set; } + /// + /// File System Label used in root path. + /// + public string FileSystemLabel { get; private set; } + /// /// FATs array. /// @@ -781,7 +788,7 @@ public static FatFileSystem CreateFatFileSystem(Partition aDevice, string aRootP Global.Debugger.SendInternal("Creating a new " + aDriveFormat + " FileSystem."); var fs = new FatFileSystem(aDevice, aRootPath, aSize, false); - fs.Format(aDriveFormat, true); + fs.Format(aDriveFormat, true, aRootPath); return fs; } @@ -866,6 +873,19 @@ internal void ReadBootSector() { mFats[i] = new Fat(this, ReservedSectorCount + i * FatSectorCount); } + + // Read volume label (11 bytes) + byte[] volumeLabelBytes = new byte[11]; + Array.Copy(xBPB, 0x047, volumeLabelBytes, 0, 11); + int actualLength = Array.IndexOf(volumeLabelBytes, (byte)0); + if (actualLength == -1) + { + actualLength = volumeLabelBytes.Length; + } + byte[] trimmedVolumeLabelBytes = new byte[actualLength]; + Array.Copy(volumeLabelBytes, trimmedVolumeLabelBytes, actualLength); + + FileSystemLabel = Encoding.UTF8.GetString(trimmedVolumeLabelBytes); } /// @@ -962,7 +982,7 @@ internal void Write(long aCluster, byte[] aData, long aSize = 0, long aOffset = { aSize = BytesPerCluster; } - + if (mFatType == FatTypeEnum.Fat32) { @@ -997,6 +1017,7 @@ public override void DisplayFileSystemInfo() global::System.Console.WriteLine("Root Sector Count = " + RootSectorCount); global::System.Console.WriteLine("Sectors per Cluster = " + SectorsPerCluster); global::System.Console.WriteLine("Total Sector Count = " + TotalSectorCount); + global::System.Console.WriteLine("File System Label = " + FileSystemLabel); Global.Debugger.SendInternal("Bytes per Cluster ="); Global.Debugger.SendInternal(BytesPerCluster); @@ -1465,7 +1486,7 @@ internal enum FatTypeEnum /// Thrown on fatal error. /// Thrown when the data in aData is corrupted. /// Thrown when FAT type is unknown. - public override void Format(string aDriveFormat, bool aQuick) + public override void Format(string aDriveFormat, bool aQuick, string Label) { /* Parmaters check */ if (Device == null) @@ -1587,12 +1608,24 @@ public override void Format(string aDriveFormat, bool aQuick) xBPB.Write8(0x42, 0x29); //signature var SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 }; - var VolumeLabel = "COSMOSDISK"; xBPB.Copy(0x43, SerialID, 0, SerialID.Length); - xBPB.WriteString(0x47, " "); - xBPB.WriteString(0x47, VolumeLabel); - xBPB.WriteString(0x52, "FAT32 "); + + byte[] labelBytes = Encoding.UTF8.GetBytes(Label); + if (labelBytes.Length < 11) + { + byte[] paddedLabelBytes = new byte[11]; + Array.Copy(labelBytes, paddedLabelBytes, labelBytes.Length); + labelBytes = paddedLabelBytes; + } + else if (labelBytes.Length > 11) + { + throw new Exception("FAT32 label cannot be larger than 11 bytes."); + } + + xBPB.Copy(0x047, labelBytes, 0, labelBytes.Length); + FileSystemLabel = Label; + //TODO: OS Boot Code } @@ -1691,4 +1724,4 @@ private ulong GetFatSizeSectors() return Numerator / Denominator + 1; } } -} +} \ No newline at end of file diff --git a/source/Cosmos.System2/FileSystem/FileSystem.cs b/source/Cosmos.System2/FileSystem/FileSystem.cs index 98d6179772..5301001627 100644 --- a/source/Cosmos.System2/FileSystem/FileSystem.cs +++ b/source/Cosmos.System2/FileSystem/FileSystem.cs @@ -252,6 +252,6 @@ protected FileSystem(Partition aDevice, string aRootPath, long aSize) /// Thrown on fatal error. /// Thrown when the data in aData is corrupted. /// Thrown when FAT type is unknown. - public abstract void Format(string aDriveFormat, bool aQuick); + public abstract void Format(string aDriveFormat, bool aQuick, string Label); } } diff --git a/source/Cosmos.System2/FileSystem/ISO9660/ISO9660FileSystem.cs b/source/Cosmos.System2/FileSystem/ISO9660/ISO9660FileSystem.cs index 96ed44c18b..67b36b9fe7 100644 --- a/source/Cosmos.System2/FileSystem/ISO9660/ISO9660FileSystem.cs +++ b/source/Cosmos.System2/FileSystem/ISO9660/ISO9660FileSystem.cs @@ -243,7 +243,7 @@ public override void DeleteFile(DirectoryEntry aPath) { throw new NotImplementedException("Read only file system"); } - public override void Format(string aDriveFormat, bool aQuick) + public override void Format(string aDriveFormat, bool aQuick, string Label) { throw new NotImplementedException(); }