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();
}