mirror of
https://github.com/aaru-dps/Aaru.git
synced 2026-07-08 17:56:18 +00:00
[GDFX] Implement GetInformation and Identify.
This commit is contained in:
@@ -29,7 +29,10 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Aaru.CommonTypes.AaruMetadata;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Logging;
|
||||
using Marshal = Aaru.Helpers.Marshal;
|
||||
using Partition = Aaru.CommonTypes.Partition;
|
||||
|
||||
namespace Aaru.Filesystems;
|
||||
@@ -39,11 +42,133 @@ public sealed partial class GDFX
|
||||
#region IFilesystem Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Identify(IMediaImage imagePlugin, Partition partition) => throw new NotImplementedException();
|
||||
public bool Identify(IMediaImage imagePlugin, Partition partition)
|
||||
{
|
||||
(ulong baseOffset, uint vdSector)[] probes =
|
||||
[
|
||||
(STANDARD_OFFSET, VD_SECTOR), (GLOBAL_PARTITION_OFFSET, VD_SECTOR), (XGD3_PARTITION_OFFSET, VD_SECTOR),
|
||||
(XGD1_PARTITION_OFFSET, VD_SECTOR), (STANDARD_OFFSET, REBUILT_VD_SECTOR)
|
||||
];
|
||||
|
||||
byte[] magicBytes = Encoding.ASCII.GetBytes(MAGIC);
|
||||
|
||||
foreach((ulong baseOffset, uint vdSector) in probes)
|
||||
{
|
||||
ulong absoluteSector = baseOffset / SECTOR_SIZE + vdSector + partition.Start;
|
||||
|
||||
if(absoluteSector >= partition.End) continue;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(absoluteSector, false, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) continue;
|
||||
|
||||
if(sector.Length < MAGIC1_OFFSET + MAGIC.Length) continue;
|
||||
|
||||
var magic0Match = true;
|
||||
var magic1Match = true;
|
||||
|
||||
for(var i = 0; i < magicBytes.Length; i++)
|
||||
{
|
||||
if(sector[i] != magicBytes[i]) magic0Match = false;
|
||||
|
||||
if(sector[MAGIC1_OFFSET + i] != magicBytes[i]) magic1Match = false;
|
||||
}
|
||||
|
||||
if(!magic0Match || !magic1Match) continue;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"Found XDVDFS volume descriptor at base offset 0x{0:X8}, VD sector {1}",
|
||||
baseOffset,
|
||||
vdSector);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void GetInformation(IMediaImage imagePlugin, Partition partition, Encoding encoding, out string information,
|
||||
out FileSystem metadata) => throw new NotImplementedException();
|
||||
out FileSystem metadata)
|
||||
{
|
||||
information = "";
|
||||
metadata = new FileSystem();
|
||||
|
||||
(ulong baseOffset, uint vdSector)[] probes =
|
||||
[
|
||||
(STANDARD_OFFSET, VD_SECTOR), (GLOBAL_PARTITION_OFFSET, VD_SECTOR), (XGD3_PARTITION_OFFSET, VD_SECTOR),
|
||||
(XGD1_PARTITION_OFFSET, VD_SECTOR), (STANDARD_OFFSET, REBUILT_VD_SECTOR)
|
||||
];
|
||||
|
||||
byte[] magicBytes = Encoding.ASCII.GetBytes(MAGIC);
|
||||
byte[] sector = null;
|
||||
ulong matchBaseOffset = 0;
|
||||
uint matchVdSector = VD_SECTOR;
|
||||
|
||||
foreach((ulong baseOffset, uint vdSector) in probes)
|
||||
{
|
||||
ulong absoluteSector = baseOffset / SECTOR_SIZE + vdSector + partition.Start;
|
||||
|
||||
if(absoluteSector >= partition.End) continue;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(absoluteSector, false, out byte[] s, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) continue;
|
||||
|
||||
if(s.Length < MAGIC1_OFFSET + MAGIC.Length) continue;
|
||||
|
||||
var magic0Match = true;
|
||||
var magic1Match = true;
|
||||
|
||||
for(var i = 0; i < magicBytes.Length; i++)
|
||||
{
|
||||
if(s[i] != magicBytes[i]) magic0Match = false;
|
||||
|
||||
if(s[MAGIC1_OFFSET + i] != magicBytes[i]) magic1Match = false;
|
||||
}
|
||||
|
||||
if(!magic0Match || !magic1Match) continue;
|
||||
|
||||
sector = s;
|
||||
matchBaseOffset = baseOffset;
|
||||
matchVdSector = vdSector;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(sector is null) return;
|
||||
|
||||
VolumeDescriptor vd = Marshal.ByteArrayToStructureLittleEndian<VolumeDescriptor>(sector);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(Localization.Xbox_DVD_File_System);
|
||||
|
||||
string discType = (matchBaseOffset, matchVdSector) switch
|
||||
{
|
||||
(var b, REBUILT_VD_SECTOR) when b == STANDARD_OFFSET => Localization.Rebuilt_XISO,
|
||||
var (b, _) when b == XGD1_PARTITION_OFFSET => Localization.XGD1,
|
||||
var (b, _) when b == GLOBAL_PARTITION_OFFSET => Localization.XGD2,
|
||||
var (b, _) when b == XGD3_PARTITION_OFFSET => Localization.XGD3,
|
||||
_ => Localization.Standard_Xbox_image
|
||||
};
|
||||
|
||||
sb.AppendFormat(Localization.Disc_type_0, discType).AppendLine();
|
||||
sb.AppendFormat(Localization.Root_directory_sector_0, vd.rootDirSector).AppendLine();
|
||||
sb.AppendFormat(Localization.Root_directory_size_0_bytes, vd.rootDirSize).AppendLine();
|
||||
|
||||
if(vd.fileTime > 0)
|
||||
{
|
||||
var creationDate = DateTime.FromFileTimeUtc((long)vd.fileTime);
|
||||
sb.AppendFormat(Localization.Volume_created_on_0, creationDate).AppendLine();
|
||||
metadata.CreationDate = creationDate;
|
||||
}
|
||||
|
||||
information = sb.ToString();
|
||||
|
||||
metadata.Type = FS_TYPE;
|
||||
metadata.ClusterSize = SECTOR_SIZE;
|
||||
metadata.Clusters = partition.Size / SECTOR_SIZE;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -5349,6 +5349,54 @@ namespace Aaru.Filesystems {
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Xbox_DVD_File_System {
|
||||
get {
|
||||
return ResourceManager.GetString("Xbox_DVD_File_System", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Disc_type_0 {
|
||||
get {
|
||||
return ResourceManager.GetString("Disc_type_0", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Root_directory_sector_0 {
|
||||
get {
|
||||
return ResourceManager.GetString("Root_directory_sector_0", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Rebuilt_XISO {
|
||||
get {
|
||||
return ResourceManager.GetString("Rebuilt_XISO", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string XGD1 {
|
||||
get {
|
||||
return ResourceManager.GetString("XGD1", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string XGD2 {
|
||||
get {
|
||||
return ResourceManager.GetString("XGD2", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string XGD3 {
|
||||
get {
|
||||
return ResourceManager.GetString("XGD3", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Standard_Xbox_image {
|
||||
get {
|
||||
return ResourceManager.GetString("Standard_Xbox_image", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string LIF_Name {
|
||||
get {
|
||||
return ResourceManager.GetString("LIF_Name", resourceCulture);
|
||||
|
||||
@@ -2678,6 +2678,30 @@
|
||||
</data>
|
||||
<data name="GDFX_Name" xml:space="preserve">
|
||||
<value>Xbox DVD File System</value>
|
||||
</data>
|
||||
<data name="Xbox_DVD_File_System" xml:space="preserve">
|
||||
<value>Xbox DVD File System</value>
|
||||
</data>
|
||||
<data name="Disc_type_0" xml:space="preserve">
|
||||
<value>Disc type: {0}</value>
|
||||
</data>
|
||||
<data name="Root_directory_sector_0" xml:space="preserve">
|
||||
<value>Root directory sector: {0}</value>
|
||||
</data>
|
||||
<data name="Rebuilt_XISO" xml:space="preserve">
|
||||
<value>Rebuilt XISO</value>
|
||||
</data>
|
||||
<data name="XGD1" xml:space="preserve">
|
||||
<value>XGD1</value>
|
||||
</data>
|
||||
<data name="XGD2" xml:space="preserve">
|
||||
<value>XGD2</value>
|
||||
</data>
|
||||
<data name="XGD3" xml:space="preserve">
|
||||
<value>XGD3</value>
|
||||
</data>
|
||||
<data name="Standard_Xbox_image" xml:space="preserve">
|
||||
<value>Standard Xbox image</value>
|
||||
</data>
|
||||
<data name="LIF_Name" xml:space="preserve">
|
||||
<value>HP Logical Interchange Format Plugin</value>
|
||||
|
||||
Reference in New Issue
Block a user