mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Update ReadSector and ReadSectors methods to include sector status output
This commit is contained in:
@@ -57,32 +57,6 @@ public sealed class Acorn : IPartition
|
||||
const uint TYPE_MASK = 15;
|
||||
readonly byte[] _linuxIcsMagic = "LinuxPart"u8.ToArray();
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Acorn_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("A7C8FEBE-8D00-4933-B9F3-42184C8BA808");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NATALIA_PORTILLO;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset)
|
||||
{
|
||||
partitions = [];
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
GetFileCorePartitions(imagePlugin, partitions, sectorOffset, ref counter);
|
||||
GetIcsPartitions(imagePlugin, partitions, sectorOffset, ref counter);
|
||||
|
||||
return partitions.Count != 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static void GetFileCorePartitions(IMediaImage imagePlugin, List<Partition> partitions, ulong sectorOffset,
|
||||
ref ulong counter)
|
||||
{
|
||||
@@ -96,7 +70,7 @@ public sealed class Acorn : IPartition
|
||||
else
|
||||
sbSector = ADFS_SB_POS / imagePlugin.Info.SectorSize;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sbSector, out byte[] sector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sbSector, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return;
|
||||
|
||||
@@ -112,7 +86,7 @@ public sealed class Acorn : IPartition
|
||||
|
||||
if((ulong)mapSector >= imagePlugin.Info.Sectors) return;
|
||||
|
||||
errno = imagePlugin.ReadSector((ulong)mapSector, out byte[] map);
|
||||
errno = imagePlugin.ReadSector((ulong)mapSector, out byte[] map, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return;
|
||||
|
||||
@@ -206,7 +180,7 @@ public sealed class Acorn : IPartition
|
||||
// RISC OS always checks for the partition on 0. Afaik no emulator chains it.
|
||||
if(sectorOffset != 0) return;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return;
|
||||
|
||||
@@ -246,7 +220,7 @@ public sealed class Acorn : IPartition
|
||||
}
|
||||
|
||||
// Negative size means Linux partition, first sector needs to be read
|
||||
errno = imagePlugin.ReadSector(entry.start, out sector);
|
||||
errno = imagePlugin.ReadSector(entry.start, out sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) continue;
|
||||
|
||||
@@ -393,5 +367,31 @@ public sealed class Acorn : IPartition
|
||||
public readonly RiscIxEntry[] partitions;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Acorn_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("A7C8FEBE-8D00-4933-B9F3-42184C8BA808");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NATALIA_PORTILLO;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset)
|
||||
{
|
||||
partitions = [];
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
GetFileCorePartitions(imagePlugin, partitions, sectorOffset, ref counter);
|
||||
GetIcsPartitions(imagePlugin, partitions, sectorOffset, ref counter);
|
||||
|
||||
return partitions.Count != 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public sealed partial class AppleMap : IPartition
|
||||
|
||||
if(sectorOffset + 2 >= imagePlugin.Info.Sectors) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] ddmSector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] ddmSector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
@@ -103,8 +103,7 @@ public sealed partial class AppleMap : IPartition
|
||||
return false;
|
||||
}
|
||||
|
||||
AppleDriverDescriptorMap ddm =
|
||||
Marshal.ByteArrayToStructureBigEndian<AppleDriverDescriptorMap>(ddmSector);
|
||||
AppleDriverDescriptorMap ddm = Marshal.ByteArrayToStructureBigEndian<AppleDriverDescriptorMap>(ddmSector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "ddm.sbSig = 0x{0:X4}", ddm.sbSig);
|
||||
AaruLogging.Debug(MODULE_NAME, "ddm.sbBlockSize = {0}", ddm.sbBlockSize);
|
||||
@@ -155,7 +154,7 @@ public sealed partial class AppleMap : IPartition
|
||||
}
|
||||
}
|
||||
|
||||
errno = imagePlugin.ReadSector(1 + sectorOffset, out byte[] partSector);
|
||||
errno = imagePlugin.ReadSector(1 + sectorOffset, out byte[] partSector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
@@ -259,7 +258,7 @@ public sealed partial class AppleMap : IPartition
|
||||
return partitions.Count > 0;
|
||||
}
|
||||
|
||||
errno = imagePlugin.ReadSectors(sectorOffset, sectorsToRead, out byte[] entries);
|
||||
errno = imagePlugin.ReadSectors(sectorOffset, sectorsToRead, out byte[] entries, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
|
||||
@@ -71,308 +71,6 @@ public sealed class Apricot : IPartition
|
||||
readonly string[] _printDevices = [Localization.Parallel_print_device, Localization.Serial_print_device];
|
||||
readonly double[] _stopBits = [1, 1.5, 2];
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Apricot_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("8CBF5864-7B5A-47A0-8CEB-199C74FA22DE");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NATALIA_PORTILLO;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset)
|
||||
{
|
||||
partitions = [];
|
||||
|
||||
// I think Apricot can't chain partitions so.
|
||||
if(sectorOffset != 0) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return false;
|
||||
|
||||
Label label = Marshal.ByteArrayToStructureLittleEndian<Label>(sector);
|
||||
|
||||
// Not much to check but...
|
||||
ulong deviceSectors = imagePlugin.Info.Sectors;
|
||||
ulong deviceSizeAccordingToLabel = label.cylinders * label.heads * label.spt;
|
||||
|
||||
if(label.operatingSystem > 4 ||
|
||||
label.bootType > 5 ||
|
||||
label.partitionCount > 8 ||
|
||||
deviceSizeAccordingToLabel > deviceSectors ||
|
||||
label.firstDataBlock > deviceSectors)
|
||||
return false;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.version = \"{0}\"", StringHandlers.CToString(label.version));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.operatingSystem = {0} ({1})",
|
||||
label.operatingSystem,
|
||||
label.operatingSystem < _operatingSystemCodes.Length
|
||||
? _operatingSystemCodes[label.operatingSystem]
|
||||
: Localization.Unknown_operating_system);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.writeProtected = {0}", label.writeProtected);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.copyProtected = {0}", label.copyProtected);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.bootType = {0} ({1})",
|
||||
label.bootType,
|
||||
label.bootType < _bootTypeCodes.Length
|
||||
? _bootTypeCodes[label.bootType]
|
||||
: Localization.Unknown_boot_type);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitionCount = {0}", label.partitionCount);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.winchester = {0}", label.winchester);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.sectorSize = {0}", label.sectorSize);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.spt = {0}", label.spt);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.cylinders = {0}", label.cylinders);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.heads = {0}", label.heads);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.interleave = {0}", label.interleave);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.skew = {0}", label.skew);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.bootLocation = {0}", label.bootLocation);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.bootSize = {0}", label.bootSize);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.bootAddress = 0x{0:X8}", label.bootAddress);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.bootOffset:label.bootSegment = {0:X4}:{1:X4}",
|
||||
label.bootOffset,
|
||||
label.bootSegment);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.firstDataBlock = {0}", label.firstDataBlock);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.generation = {0}", label.generation);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.copyCount = {0}", label.copyCount);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.maxCopies = {0}", label.maxCopies);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.serialNumber = \"{0}\"",
|
||||
StringHandlers.CToString(label.serialNumber));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partNumber = \"{0}\"",
|
||||
StringHandlers.CToString(label.partNumber));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.copyright = \"{0}\"", StringHandlers.CToString(label.copyright));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.bps = {0}", label.mainBPB.bps);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.spc = {0}", label.mainBPB.spc);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.rsectors = {0}", label.mainBPB.rsectors);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.fats_no = {0}", label.mainBPB.fats_no);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.root_ent = {0}", label.mainBPB.root_ent);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.sectors = {0}", label.mainBPB.sectors);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.media = {0}", label.mainBPB.media);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.spfat = {0}", label.mainBPB.spfat);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.mainBPB.diskType = {0} ({1})",
|
||||
label.mainBPB.diskType,
|
||||
label.mainBPB.diskType < _diskTypeCodes.Length
|
||||
? _diskTypeCodes[label.mainBPB.diskType]
|
||||
: Localization.Unknown_disk_type);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.startSector = {0}", label.mainBPB.startSector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.fontName = \"{0}\"", StringHandlers.CToString(label.fontName));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.keyboardName = \"{0}\"",
|
||||
StringHandlers.CToString(label.keyboardName));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.biosMajorVersion = {0}", label.biosMajorVersion);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.biosMinorVersion = {0}", label.biosMinorVersion);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.diagnosticsFlag = {0}", label.diagnosticsFlag);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.prnDevice = {0} ({1})",
|
||||
label.prnDevice,
|
||||
label.prnDevice < _printDevices.Length
|
||||
? _printDevices[label.prnDevice]
|
||||
: Localization.Unknown_print_device);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.bellVolume = {0}", label.bellVolume);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.enableCache = {0}", label.enableCache);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.enableGraphics = {0}", label.enableGraphics);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.dosLength = {0}", label.dosLength);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.fontLength = {0}", label.fontLength);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.keyboardLength = {0}", label.keyboardLength);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.dosStart = {0}", label.dosStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.fontStart = {0}", label.fontStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.keyboardStart = {0}", label.keyboardStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.keyboardVolume = {0}", label.keyboardVolume);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.autorepeat = {0}", label.autorepeat);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.autorepeatLeadIn = {0}", label.autorepeatLeadIn);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.autorepeatInterval = {0}", label.autorepeatInterval);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.microscreenMode = {0}", label.microscreenMode);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareKeyboard is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareKeyboard));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.lineMode = {0} ({1} lines)",
|
||||
label.lineMode,
|
||||
label.lineMode < _lineModes.Length ? _lineModes[label.lineMode] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.lineWidth = {0} ({1} columns)",
|
||||
label.lineWidth,
|
||||
label.lineWidth < _lineWidths.Length ? _lineWidths[label.lineWidth] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.imageOff = {0}", label.imageOff);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareScreen is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareScreen));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.txBaudRate = {0} ({1} bps)",
|
||||
label.txBaudRate,
|
||||
label.txBaudRate < _baudRates.Length ? _baudRates[label.txBaudRate] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.rxBaudRate = {0} ({1} bps)",
|
||||
label.rxBaudRate,
|
||||
label.rxBaudRate < _baudRates.Length ? _baudRates[label.rxBaudRate] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.txBits = {0}", label.txBits);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.rxBits = {0}", label.rxBits);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.stopBits = {0} ({1} bits)",
|
||||
label.stopBits,
|
||||
label.stopBits < _stopBits.Length ? _stopBits[label.stopBits] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.parityCheck = {0}", label.parityCheck);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.parityType = {0} ({1})",
|
||||
label.parityType,
|
||||
label.parityType < _parityTypes.Length
|
||||
? _parityTypes[label.parityType]
|
||||
: Localization.Unknown_parity_type);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.txXonXoff = {0}", label.txXonXoff);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.rxXonXoff = {0}", label.rxXonXoff);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.xonCharacter = {0}", label.xonCharacter);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.xoffCharacter = {0}", label.xoffCharacter);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.rxXonXoffBuffer = {0}", label.rxXonXoffBuffer);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.dtrDsr = {0}", label.dtrDsr);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.ctsRts = {0}", label.ctsRts);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.nullsAfterCr = {0}", label.nullsAfterCr);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.nullsAfterFF = {0}", label.nullsAfterFF);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.lfAfterCRSerial = {0}", label.lfAfterCRSerial);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.biosErrorReportSerial = {0}", label.biosErrorReportSerial);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareSerial is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareSerial));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.lfAfterCrParallel = {0}", label.lfAfterCrParallel);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.selectLine = {0}", label.selectLine);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.paperEmpty = {0}", label.paperEmpty);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.faultLine = {0}", label.faultLine);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.biosErrorReportParallel = {0}", label.biosErrorReportParallel);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareParallel is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareParallel));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareWinchester is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareWinchester));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.parkingEnabled = {0}", label.parkingEnabled);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.formatProtection = {0}", label.formatProtection);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareRamDisk is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareRamDisk));
|
||||
|
||||
for(int i = 0; i < 32; i++)
|
||||
AaruLogging.Debug(MODULE_NAME, "label.badBlocks[{1}] = {0}", label.badBlocks[i], i);
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].bps = {0}", label.partitions[i].bps, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].spc = {0}", label.partitions[i].spc, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partitions[{1}].rsectors = {0}",
|
||||
label.partitions[i].rsectors,
|
||||
i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partitions[{1}].fats_no = {0}",
|
||||
label.partitions[i].fats_no,
|
||||
i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partitions[{1}].root_ent = {0}",
|
||||
label.partitions[i].root_ent,
|
||||
i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partitions[{1}].sectors = {0}",
|
||||
label.partitions[i].sectors,
|
||||
i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].media = {0}", label.partitions[i].media, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].spfat = {0}", label.partitions[i].spfat, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partitions[{1}].diskType = {0} ({2})",
|
||||
label.partitions[i].diskType,
|
||||
i,
|
||||
label.partitions[i].diskType < _diskTypeCodes.Length
|
||||
? _diskTypeCodes[label.partitions[i].diskType]
|
||||
: Localization.Unknown_disk_type);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partitions[{1}].startSector = {0}",
|
||||
label.partitions[i].startSector,
|
||||
i);
|
||||
}
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spare is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spare));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.cpmDoubleSided = {0}", label.cpmDoubleSided);
|
||||
|
||||
// Only hard disks can contain partitions
|
||||
if(!label.winchester) return false;
|
||||
|
||||
for(byte i = 0; i < label.partitionCount; i++)
|
||||
{
|
||||
var part = new Partition
|
||||
{
|
||||
Start = label.partitions[i].startSector,
|
||||
Size = (ulong)(label.partitions[i].sectors * label.sectorSize),
|
||||
Length = label.partitions[i].sectors,
|
||||
Type = "ACT Apricot partition",
|
||||
Sequence = i,
|
||||
Scheme = Name,
|
||||
Offset = (ulong)(label.partitions[i].startSector * label.sectorSize)
|
||||
};
|
||||
|
||||
if(part.Start < deviceSectors && part.End < deviceSectors) partitions.Add(part);
|
||||
}
|
||||
|
||||
return partitions.Count > 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Label
|
||||
|
||||
/// <summary>Apricot Label.</summary>
|
||||
@@ -615,5 +313,286 @@ public sealed class Apricot : IPartition
|
||||
public readonly ushort startSector;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.Apricot_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("8CBF5864-7B5A-47A0-8CEB-199C74FA22DE");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NATALIA_PORTILLO;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset)
|
||||
{
|
||||
partitions = [];
|
||||
|
||||
// I think Apricot can't chain partitions so.
|
||||
if(sectorOffset != 0) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return false;
|
||||
|
||||
Label label = Marshal.ByteArrayToStructureLittleEndian<Label>(sector);
|
||||
|
||||
// Not much to check but...
|
||||
ulong deviceSectors = imagePlugin.Info.Sectors;
|
||||
ulong deviceSizeAccordingToLabel = label.cylinders * label.heads * label.spt;
|
||||
|
||||
if(label.operatingSystem > 4 ||
|
||||
label.bootType > 5 ||
|
||||
label.partitionCount > 8 ||
|
||||
deviceSizeAccordingToLabel > deviceSectors ||
|
||||
label.firstDataBlock > deviceSectors)
|
||||
return false;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.version = \"{0}\"", StringHandlers.CToString(label.version));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.operatingSystem = {0} ({1})",
|
||||
label.operatingSystem,
|
||||
label.operatingSystem < _operatingSystemCodes.Length
|
||||
? _operatingSystemCodes[label.operatingSystem]
|
||||
: Localization.Unknown_operating_system);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.writeProtected = {0}", label.writeProtected);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.copyProtected = {0}", label.copyProtected);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.bootType = {0} ({1})",
|
||||
label.bootType,
|
||||
label.bootType < _bootTypeCodes.Length
|
||||
? _bootTypeCodes[label.bootType]
|
||||
: Localization.Unknown_boot_type);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitionCount = {0}", label.partitionCount);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.winchester = {0}", label.winchester);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.sectorSize = {0}", label.sectorSize);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.spt = {0}", label.spt);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.cylinders = {0}", label.cylinders);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.heads = {0}", label.heads);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.interleave = {0}", label.interleave);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.skew = {0}", label.skew);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.bootLocation = {0}", label.bootLocation);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.bootSize = {0}", label.bootSize);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.bootAddress = 0x{0:X8}", label.bootAddress);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.bootOffset:label.bootSegment = {0:X4}:{1:X4}",
|
||||
label.bootOffset,
|
||||
label.bootSegment);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.firstDataBlock = {0}", label.firstDataBlock);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.generation = {0}", label.generation);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.copyCount = {0}", label.copyCount);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.maxCopies = {0}", label.maxCopies);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.serialNumber = \"{0}\"", StringHandlers.CToString(label.serialNumber));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partNumber = \"{0}\"", StringHandlers.CToString(label.partNumber));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.copyright = \"{0}\"", StringHandlers.CToString(label.copyright));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.bps = {0}", label.mainBPB.bps);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.spc = {0}", label.mainBPB.spc);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.rsectors = {0}", label.mainBPB.rsectors);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.fats_no = {0}", label.mainBPB.fats_no);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.root_ent = {0}", label.mainBPB.root_ent);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.sectors = {0}", label.mainBPB.sectors);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.media = {0}", label.mainBPB.media);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.spfat = {0}", label.mainBPB.spfat);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.mainBPB.diskType = {0} ({1})",
|
||||
label.mainBPB.diskType,
|
||||
label.mainBPB.diskType < _diskTypeCodes.Length
|
||||
? _diskTypeCodes[label.mainBPB.diskType]
|
||||
: Localization.Unknown_disk_type);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.mainBPB.startSector = {0}", label.mainBPB.startSector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.fontName = \"{0}\"", StringHandlers.CToString(label.fontName));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.keyboardName = \"{0}\"", StringHandlers.CToString(label.keyboardName));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.biosMajorVersion = {0}", label.biosMajorVersion);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.biosMinorVersion = {0}", label.biosMinorVersion);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.diagnosticsFlag = {0}", label.diagnosticsFlag);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.prnDevice = {0} ({1})",
|
||||
label.prnDevice,
|
||||
label.prnDevice < _printDevices.Length
|
||||
? _printDevices[label.prnDevice]
|
||||
: Localization.Unknown_print_device);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.bellVolume = {0}", label.bellVolume);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.enableCache = {0}", label.enableCache);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.enableGraphics = {0}", label.enableGraphics);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.dosLength = {0}", label.dosLength);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.fontLength = {0}", label.fontLength);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.keyboardLength = {0}", label.keyboardLength);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.dosStart = {0}", label.dosStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.fontStart = {0}", label.fontStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.keyboardStart = {0}", label.keyboardStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.keyboardVolume = {0}", label.keyboardVolume);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.autorepeat = {0}", label.autorepeat);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.autorepeatLeadIn = {0}", label.autorepeatLeadIn);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.autorepeatInterval = {0}", label.autorepeatInterval);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.microscreenMode = {0}", label.microscreenMode);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareKeyboard is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareKeyboard));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.lineMode = {0} ({1} lines)",
|
||||
label.lineMode,
|
||||
label.lineMode < _lineModes.Length ? _lineModes[label.lineMode] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.lineWidth = {0} ({1} columns)",
|
||||
label.lineWidth,
|
||||
label.lineWidth < _lineWidths.Length ? _lineWidths[label.lineWidth] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.imageOff = {0}", label.imageOff);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareScreen is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareScreen));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.txBaudRate = {0} ({1} bps)",
|
||||
label.txBaudRate,
|
||||
label.txBaudRate < _baudRates.Length ? _baudRates[label.txBaudRate] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.rxBaudRate = {0} ({1} bps)",
|
||||
label.rxBaudRate,
|
||||
label.rxBaudRate < _baudRates.Length ? _baudRates[label.rxBaudRate] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.txBits = {0}", label.txBits);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.rxBits = {0}", label.rxBits);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.stopBits = {0} ({1} bits)",
|
||||
label.stopBits,
|
||||
label.stopBits < _stopBits.Length ? _stopBits[label.stopBits] : 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.parityCheck = {0}", label.parityCheck);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.parityType = {0} ({1})",
|
||||
label.parityType,
|
||||
label.parityType < _parityTypes.Length
|
||||
? _parityTypes[label.parityType]
|
||||
: Localization.Unknown_parity_type);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.txXonXoff = {0}", label.txXonXoff);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.rxXonXoff = {0}", label.rxXonXoff);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.xonCharacter = {0}", label.xonCharacter);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.xoffCharacter = {0}", label.xoffCharacter);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.rxXonXoffBuffer = {0}", label.rxXonXoffBuffer);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.dtrDsr = {0}", label.dtrDsr);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.ctsRts = {0}", label.ctsRts);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.nullsAfterCr = {0}", label.nullsAfterCr);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.nullsAfterFF = {0}", label.nullsAfterFF);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.lfAfterCRSerial = {0}", label.lfAfterCRSerial);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.biosErrorReportSerial = {0}", label.biosErrorReportSerial);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareSerial is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareSerial));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.lfAfterCrParallel = {0}", label.lfAfterCrParallel);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.selectLine = {0}", label.selectLine);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.paperEmpty = {0}", label.paperEmpty);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.faultLine = {0}", label.faultLine);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.biosErrorReportParallel = {0}", label.biosErrorReportParallel);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareParallel is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareParallel));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareWinchester is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareWinchester));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.parkingEnabled = {0}", label.parkingEnabled);
|
||||
AaruLogging.Debug(MODULE_NAME, "label.formatProtection = {0}", label.formatProtection);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.spareRamDisk is null? = {0}",
|
||||
ArrayHelpers.ArrayIsNullOrEmpty(label.spareRamDisk));
|
||||
|
||||
for(var i = 0; i < 32; i++) AaruLogging.Debug(MODULE_NAME, "label.badBlocks[{1}] = {0}", label.badBlocks[i], i);
|
||||
|
||||
for(var i = 0; i < 8; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].bps = {0}", label.partitions[i].bps, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].spc = {0}", label.partitions[i].spc, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].rsectors = {0}", label.partitions[i].rsectors, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].fats_no = {0}", label.partitions[i].fats_no, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].root_ent = {0}", label.partitions[i].root_ent, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].sectors = {0}", label.partitions[i].sectors, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].media = {0}", label.partitions[i].media, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.partitions[{1}].spfat = {0}", label.partitions[i].spfat, i);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partitions[{1}].diskType = {0} ({2})",
|
||||
label.partitions[i].diskType,
|
||||
i,
|
||||
label.partitions[i].diskType < _diskTypeCodes.Length
|
||||
? _diskTypeCodes[label.partitions[i].diskType]
|
||||
: Localization.Unknown_disk_type);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"label.partitions[{1}].startSector = {0}",
|
||||
label.partitions[i].startSector,
|
||||
i);
|
||||
}
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.spare is null? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(label.spare));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "label.cpmDoubleSided = {0}", label.cpmDoubleSided);
|
||||
|
||||
// Only hard disks can contain partitions
|
||||
if(!label.winchester) return false;
|
||||
|
||||
for(byte i = 0; i < label.partitionCount; i++)
|
||||
{
|
||||
var part = new Partition
|
||||
{
|
||||
Start = label.partitions[i].startSector,
|
||||
Size = (ulong)(label.partitions[i].sectors * label.sectorSize),
|
||||
Length = label.partitions[i].sectors,
|
||||
Type = "ACT Apricot partition",
|
||||
Sequence = i,
|
||||
Scheme = Name,
|
||||
Offset = (ulong)(label.partitions[i].startSector * label.sectorSize)
|
||||
};
|
||||
|
||||
if(part.Start < deviceSectors && part.End < deviceSectors) partitions.Add(part);
|
||||
}
|
||||
|
||||
return partitions.Count > 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -61,6 +61,45 @@ public sealed class AtariPartitions : IPartition
|
||||
const uint TYPE_MINIX2 = 0x004D4E58;
|
||||
const string MODULE_NAME = "Atari partitions plugin";
|
||||
|
||||
#region Nested type: AtariEntry
|
||||
|
||||
/// <summary>Atari partition entry</summary>
|
||||
struct AtariEntry
|
||||
{
|
||||
/// <summary>First byte flag, three bytes type in ASCII. Flag bit 0 = active Flag bit 7 = bootable</summary>
|
||||
public uint Type;
|
||||
/// <summary>Starting sector</summary>
|
||||
public uint Start;
|
||||
/// <summary>Length in sectors</summary>
|
||||
public uint Length;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: AtariTable
|
||||
|
||||
struct AtariTable
|
||||
{
|
||||
/// <summary>Boot code for 342 bytes</summary>
|
||||
public byte[] Boot;
|
||||
/// <summary>8 extra entries for ICDPro driver</summary>
|
||||
public AtariEntry[] IcdEntries;
|
||||
/// <summary>Unused, 12 bytes</summary>
|
||||
public byte[] Unused;
|
||||
/// <summary>Disk size in sectors</summary>
|
||||
public uint Size;
|
||||
/// <summary>4 partition entries</summary>
|
||||
public AtariEntry[] Entries;
|
||||
/// <summary>Starting sector of bad block list</summary>
|
||||
public uint BadStart;
|
||||
/// <summary>Length in sectors of bad block list</summary>
|
||||
public uint BadLength;
|
||||
/// <summary>Checksum for bootable disks</summary>
|
||||
public ushort Checksum;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -77,7 +116,7 @@ public sealed class AtariPartitions : IPartition
|
||||
{
|
||||
partitions = [];
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return false;
|
||||
|
||||
@@ -91,7 +130,7 @@ public sealed class AtariPartitions : IPartition
|
||||
|
||||
Array.Copy(sector, 0, table.Boot, 0, 342);
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
for(var i = 0; i < 8; i++)
|
||||
{
|
||||
table.IcdEntries[i].Type = BigEndianBitConverter.ToUInt32(sector, 342 + i * 12 + 0);
|
||||
table.IcdEntries[i].Start = BigEndianBitConverter.ToUInt32(sector, 342 + i * 12 + 4);
|
||||
@@ -102,7 +141,7 @@ public sealed class AtariPartitions : IPartition
|
||||
|
||||
table.Size = BigEndianBitConverter.ToUInt32(sector, 450);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
for(var i = 0; i < 4; i++)
|
||||
{
|
||||
table.Entries[i].Type = BigEndianBitConverter.ToUInt32(sector, 454 + i * 12 + 0);
|
||||
table.Entries[i].Start = BigEndianBitConverter.ToUInt32(sector, 454 + i * 12 + 4);
|
||||
@@ -117,62 +156,59 @@ public sealed class AtariPartitions : IPartition
|
||||
sha1Ctx.Update(table.Boot);
|
||||
AaruLogging.Debug(MODULE_NAME, Localization.Boot_code_SHA1_0, sha1Ctx.End());
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
for(var i = 0; i < 8; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Markup.Escape("table.icdEntries[{0}].flag = 0x{1:X2}"),
|
||||
i,
|
||||
(table.IcdEntries[i].Type & 0xFF000000) >> 24);
|
||||
Markup.Escape("table.icdEntries[{0}].flag = 0x{1:X2}"),
|
||||
i,
|
||||
(table.IcdEntries[i].Type & 0xFF000000) >> 24);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Markup.Escape("table.icdEntries[{0}].type = 0x{1:X6}"),
|
||||
i,
|
||||
table.IcdEntries[i].Type & 0x00FFFFFF);
|
||||
Markup.Escape("table.icdEntries[{0}].type = 0x{1:X6}"),
|
||||
i,
|
||||
table.IcdEntries[i].Type & 0x00FFFFFF);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Markup.Escape("table.icdEntries[{0}].start = {1}"),
|
||||
i,
|
||||
table.IcdEntries[i].Start);
|
||||
Markup.Escape("table.icdEntries[{0}].start = {1}"),
|
||||
i,
|
||||
table.IcdEntries[i].Start);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Markup.Escape("table.icdEntries[{0}].length = {1}"),
|
||||
i,
|
||||
table.IcdEntries[i].Length);
|
||||
Markup.Escape("table.icdEntries[{0}].length = {1}"),
|
||||
i,
|
||||
table.IcdEntries[i].Length);
|
||||
}
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "table.size = {0}", table.Size);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
for(var i = 0; i < 4; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Markup.Escape("table.entries[{0}].flag = 0x{1:X2}"),
|
||||
i,
|
||||
(table.Entries[i].Type & 0xFF000000) >> 24);
|
||||
Markup.Escape("table.entries[{0}].flag = 0x{1:X2}"),
|
||||
i,
|
||||
(table.Entries[i].Type & 0xFF000000) >> 24);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Markup.Escape("table.entries[{0}].type = 0x{1:X6}"),
|
||||
i,
|
||||
table.Entries[i].Type & 0x00FFFFFF);
|
||||
Markup.Escape("table.entries[{0}].type = 0x{1:X6}"),
|
||||
i,
|
||||
table.Entries[i].Type & 0x00FFFFFF);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, Markup.Escape("table.entries[{0}].start = {1}"), i, table.Entries[i].Start);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Markup.Escape("table.entries[{0}].start = {1}"),
|
||||
i,
|
||||
table.Entries[i].Start);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Markup.Escape("table.entries[{0}].length = {1}"),
|
||||
i,
|
||||
table.Entries[i].Length);
|
||||
Markup.Escape("table.entries[{0}].length = {1}"),
|
||||
i,
|
||||
table.Entries[i].Length);
|
||||
}
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "table.badStart = {0}", table.BadStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "table.badLength = {0}", table.BadLength);
|
||||
AaruLogging.Debug(MODULE_NAME, "table.checksum = 0x{0:X4}", table.Checksum);
|
||||
|
||||
bool validTable = false;
|
||||
var validTable = false;
|
||||
ulong partitionSequence = 0;
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
for(var i = 0; i < 4; i++)
|
||||
{
|
||||
uint type = table.Entries[i].Type & 0x00FFFFFF;
|
||||
|
||||
@@ -196,14 +232,14 @@ public sealed class AtariPartitions : IPartition
|
||||
if(table.Entries[i].Start + table.Entries[i].Length > imagePlugin.Info.Sectors)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Localization.WARNING_End_of_partition_goes_beyond_device_size);
|
||||
Localization.WARNING_End_of_partition_goes_beyond_device_size);
|
||||
}
|
||||
|
||||
ulong sectorSize = imagePlugin.Info.SectorSize;
|
||||
|
||||
if(sectorSize is 2448 or 2352) sectorSize = 2048;
|
||||
|
||||
byte[] partType = new byte[3];
|
||||
var partType = new byte[3];
|
||||
partType[0] = (byte)((type & 0xFF0000) >> 16);
|
||||
partType[1] = (byte)((type & 0x00FF00) >> 8);
|
||||
partType[2] = (byte)(type & 0x0000FF);
|
||||
@@ -240,7 +276,7 @@ public sealed class AtariPartitions : IPartition
|
||||
|
||||
break;
|
||||
case TYPE_EXTENDED:
|
||||
errno = imagePlugin.ReadSector(table.Entries[i].Start, out byte[] extendedSector);
|
||||
errno = imagePlugin.ReadSector(table.Entries[i].Start, out byte[] extendedSector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) break;
|
||||
|
||||
@@ -249,7 +285,7 @@ public sealed class AtariPartitions : IPartition
|
||||
Entries = new AtariEntry[4]
|
||||
};
|
||||
|
||||
for(int j = 0; j < 4; j++)
|
||||
for(var j = 0; j < 4; j++)
|
||||
{
|
||||
extendedTable.Entries[j].Type =
|
||||
BigEndianBitConverter.ToUInt32(extendedSector, 454 + j * 12 + 0);
|
||||
@@ -261,7 +297,7 @@ public sealed class AtariPartitions : IPartition
|
||||
BigEndianBitConverter.ToUInt32(extendedSector, 454 + j * 12 + 8);
|
||||
}
|
||||
|
||||
for(int j = 0; j < 4; j++)
|
||||
for(var j = 0; j < 4; j++)
|
||||
{
|
||||
uint extendedType = extendedTable.Entries[j].Type & 0x00FFFFFF;
|
||||
|
||||
@@ -285,14 +321,14 @@ public sealed class AtariPartitions : IPartition
|
||||
if(extendedTable.Entries[j].Start + extendedTable.Entries[j].Length > imagePlugin.Info.Sectors)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Localization.WARNING_End_of_partition_goes_beyond_device_size);
|
||||
Localization.WARNING_End_of_partition_goes_beyond_device_size);
|
||||
}
|
||||
|
||||
ulong sectorSize = imagePlugin.Info.SectorSize;
|
||||
|
||||
if(sectorSize is 2448 or 2352) sectorSize = 2048;
|
||||
|
||||
byte[] partType = new byte[3];
|
||||
var partType = new byte[3];
|
||||
partType[0] = (byte)((extendedType & 0xFF0000) >> 16);
|
||||
partType[1] = (byte)((extendedType & 0x00FF00) >> 8);
|
||||
partType[2] = (byte)(extendedType & 0x0000FF);
|
||||
@@ -333,7 +369,7 @@ public sealed class AtariPartitions : IPartition
|
||||
|
||||
if(!validTable) return partitions.Count > 0;
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
for(var i = 0; i < 8; i++)
|
||||
{
|
||||
uint type = table.IcdEntries[i].Type & 0x00FFFFFF;
|
||||
|
||||
@@ -359,7 +395,7 @@ public sealed class AtariPartitions : IPartition
|
||||
|
||||
if(sectorSize is 2448 or 2352) sectorSize = 2048;
|
||||
|
||||
byte[] partType = new byte[3];
|
||||
var partType = new byte[3];
|
||||
partType[0] = (byte)((type & 0xFF0000) >> 16);
|
||||
partType[1] = (byte)((type & 0x00FF00) >> 8);
|
||||
partType[2] = (byte)(type & 0x0000FF);
|
||||
@@ -397,44 +433,5 @@ public sealed class AtariPartitions : IPartition
|
||||
return partitions.Count > 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: AtariEntry
|
||||
|
||||
/// <summary>Atari partition entry</summary>
|
||||
struct AtariEntry
|
||||
{
|
||||
/// <summary>First byte flag, three bytes type in ASCII. Flag bit 0 = active Flag bit 7 = bootable</summary>
|
||||
public uint Type;
|
||||
/// <summary>Starting sector</summary>
|
||||
public uint Start;
|
||||
/// <summary>Length in sectors</summary>
|
||||
public uint Length;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: AtariTable
|
||||
|
||||
struct AtariTable
|
||||
{
|
||||
/// <summary>Boot code for 342 bytes</summary>
|
||||
public byte[] Boot;
|
||||
/// <summary>8 extra entries for ICDPro driver</summary>
|
||||
public AtariEntry[] IcdEntries;
|
||||
/// <summary>Unused, 12 bytes</summary>
|
||||
public byte[] Unused;
|
||||
/// <summary>Disk size in sectors</summary>
|
||||
public uint Size;
|
||||
/// <summary>4 partition entries</summary>
|
||||
public AtariEntry[] Entries;
|
||||
/// <summary>Starting sector of bad block list</summary>
|
||||
public uint BadStart;
|
||||
/// <summary>Length in sectors of bad block list</summary>
|
||||
public uint BadLength;
|
||||
/// <summary>Checksum for bootable disks</summary>
|
||||
public ushort Checksum;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -79,20 +79,20 @@ public sealed partial class BSD : IPartition
|
||||
|
||||
if((MAX_LABEL_SIZE + _labelOffsets.Last()) % imagePlugin.Info.SectorSize > 0) run++;
|
||||
|
||||
var dl = new DiskLabel();
|
||||
bool found = false;
|
||||
var dl = new DiskLabel();
|
||||
var found = false;
|
||||
|
||||
foreach(ulong location in _labelLocations)
|
||||
{
|
||||
if(location + run + sectorOffset >= imagePlugin.Info.Sectors) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSectors(location + sectorOffset, run, out byte[] tmp);
|
||||
ErrorNumber errno = imagePlugin.ReadSectors(location + sectorOffset, run, out byte[] tmp, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) continue;
|
||||
|
||||
foreach(uint offset in _labelOffsets)
|
||||
{
|
||||
byte[] sector = new byte[MAX_LABEL_SIZE];
|
||||
var sector = new byte[MAX_LABEL_SIZE];
|
||||
|
||||
if(offset + MAX_LABEL_SIZE > tmp.Length) break;
|
||||
|
||||
@@ -160,9 +160,9 @@ public sealed partial class BSD : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "dl.d_sbsize = {0}", dl.d_sbsize);
|
||||
|
||||
ulong counter = 0;
|
||||
bool addSectorOffset = false;
|
||||
var addSectorOffset = false;
|
||||
|
||||
for(int i = 0; i < dl.d_npartitions && i < 22; i++)
|
||||
for(var i = 0; i < dl.d_npartitions && i < 22; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME, "dl.d_partitions[i].p_offset = {0}", dl.d_partitions[i].p_offset);
|
||||
|
||||
|
||||
@@ -47,6 +47,32 @@ public sealed class DEC : IPartition
|
||||
const int PT_MAGIC = 0x032957;
|
||||
const int PT_VALID = 1;
|
||||
|
||||
#region Nested type: Label
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Label
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 440)]
|
||||
public readonly byte[] padding;
|
||||
public readonly int pt_magic;
|
||||
public readonly int pt_valid;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public readonly Partition[] pt_part;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Partition
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Partition
|
||||
{
|
||||
public readonly int pi_nblocks;
|
||||
public readonly uint pi_blkoff;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -65,7 +91,7 @@ public sealed class DEC : IPartition
|
||||
|
||||
if(31 + sectorOffset >= imagePlugin.Info.Sectors) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(31 + sectorOffset, out byte[] sector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(31 + sectorOffset, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return false;
|
||||
|
||||
@@ -93,31 +119,5 @@ public sealed class DEC : IPartition
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Label
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Label
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 440)]
|
||||
public readonly byte[] padding;
|
||||
public readonly int pt_magic;
|
||||
public readonly int pt_valid;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public readonly Partition[] pt_part;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Partition
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Partition
|
||||
{
|
||||
public readonly int pi_nblocks;
|
||||
public readonly uint pi_blkoff;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public sealed class DragonFlyBSD : IPartition
|
||||
|
||||
if(sectorOffset + nSectors >= imagePlugin.Info.Sectors) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSectors(sectorOffset, nSectors, out byte[] sectors);
|
||||
ErrorNumber errno = imagePlugin.ReadSectors(sectorOffset, nSectors, out byte[] sectors, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sectors.Length < 2048) return false;
|
||||
|
||||
|
||||
@@ -71,14 +71,14 @@ public sealed class GuidPartitionTable : IPartition
|
||||
|
||||
if(sectorOffset + 2 >= imagePlugin.Info.Sectors) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(1 + sectorOffset, out byte[] hdrBytes);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(1 + sectorOffset, out byte[] hdrBytes, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
Header hdr;
|
||||
|
||||
ulong signature = BitConverter.ToUInt64(hdrBytes, 0);
|
||||
bool misaligned = false;
|
||||
var signature = BitConverter.ToUInt64(hdrBytes, 0);
|
||||
var misaligned = false;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "hdr.signature = 0x{0:X16}", signature);
|
||||
|
||||
@@ -86,7 +86,7 @@ public sealed class GuidPartitionTable : IPartition
|
||||
{
|
||||
if(imagePlugin.Info.MetadataMediaType == MetadataMediaType.OpticalDisc)
|
||||
{
|
||||
errno = imagePlugin.ReadSector(sectorOffset, out hdrBytes);
|
||||
errno = imagePlugin.ReadSector(sectorOffset, out hdrBytes, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
@@ -96,7 +96,7 @@ public sealed class GuidPartitionTable : IPartition
|
||||
if(signature == GPT_MAGIC)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME, Localization.Found_unaligned_signature, signature);
|
||||
byte[] real = new byte[512];
|
||||
var real = new byte[512];
|
||||
Array.Copy(hdrBytes, 512, real, 0, 512);
|
||||
hdrBytes = real;
|
||||
misaligned = true;
|
||||
@@ -156,19 +156,19 @@ public sealed class GuidPartitionTable : IPartition
|
||||
|
||||
if(hdr.entries * hdr.entriesSize % imagePlugin.Info.SectorSize > 0) totalEntriesSectors++;
|
||||
|
||||
errno = imagePlugin.ReadSectors(hdr.entryLBA / divisor, totalEntriesSectors + modulo, out byte[] temp);
|
||||
errno = imagePlugin.ReadSectors(hdr.entryLBA / divisor, totalEntriesSectors + modulo, out byte[] temp, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
byte[] entriesBytes = new byte[temp.Length - modulo * 512];
|
||||
var entriesBytes = new byte[temp.Length - modulo * 512];
|
||||
Array.Copy(temp, modulo * 512, entriesBytes, 0, entriesBytes.Length);
|
||||
List<Entry> entries = [];
|
||||
|
||||
for(int i = 0; i < hdr.entries; i++)
|
||||
for(var i = 0; i < hdr.entries; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] entryBytes = new byte[hdr.entriesSize];
|
||||
var entryBytes = new byte[hdr.entriesSize];
|
||||
Array.Copy(entriesBytes, hdr.entriesSize * i, entryBytes, 0, hdr.entriesSize);
|
||||
entries.Add(Marshal.ByteArrayToStructureLittleEndian<Entry>(entryBytes));
|
||||
}
|
||||
|
||||
@@ -52,6 +52,36 @@ public sealed partial class Human68K : IPartition
|
||||
const uint X68K_MAGIC = 0x5836384B;
|
||||
const string MODULE_NAME = "Human68k partitions plugin";
|
||||
|
||||
#region Nested type: Entry
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[SwapEndian]
|
||||
partial struct Entry
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] name;
|
||||
public uint stateStart;
|
||||
public uint length;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Table
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[SwapEndian]
|
||||
partial struct Table
|
||||
{
|
||||
public uint magic;
|
||||
public uint size;
|
||||
public uint size2;
|
||||
public uint unknown;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public Entry[] entries;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -79,17 +109,17 @@ public sealed partial class Human68K : IPartition
|
||||
switch(imagePlugin.Info.SectorSize)
|
||||
{
|
||||
case 256:
|
||||
errno = imagePlugin.ReadSector(4 + sectorOffset, out sector);
|
||||
errno = imagePlugin.ReadSector(4 + sectorOffset, out sector, out _);
|
||||
sectsPerUnit = 1;
|
||||
|
||||
break;
|
||||
case 512:
|
||||
errno = imagePlugin.ReadSector(4 + sectorOffset, out sector);
|
||||
errno = imagePlugin.ReadSector(4 + sectorOffset, out sector, out _);
|
||||
sectsPerUnit = 2;
|
||||
|
||||
break;
|
||||
case 1024:
|
||||
errno = imagePlugin.ReadSector(2 + sectorOffset, out sector);
|
||||
errno = imagePlugin.ReadSector(2 + sectorOffset, out sector, out _);
|
||||
sectsPerUnit = 1;
|
||||
|
||||
break;
|
||||
@@ -143,35 +173,5 @@ public sealed partial class Human68K : IPartition
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Entry
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[SwapEndian]
|
||||
partial struct Entry
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] name;
|
||||
public uint stateStart;
|
||||
public uint length;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Table
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[SwapEndian]
|
||||
partial struct Table
|
||||
{
|
||||
public uint magic;
|
||||
public uint size;
|
||||
public uint size2;
|
||||
public uint unknown;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public Entry[] entries;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -303,362 +303,12 @@ public sealed class MBR : IPartition
|
||||
Localization.Xenix_bad_block
|
||||
];
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.MBR_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("5E8A34E8-4F1A-59E6-4BF7-7EA647063A76");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NATALIA_PORTILLO;
|
||||
|
||||
/// <inheritdoc />
|
||||
[SuppressMessage("ReSharper", "UnusedVariable")]
|
||||
public bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset)
|
||||
{
|
||||
ulong counter = 0;
|
||||
|
||||
partitions = [];
|
||||
|
||||
if(imagePlugin.Info.SectorSize < 512) return false;
|
||||
|
||||
uint sectorSize = imagePlugin.Info.SectorSize;
|
||||
|
||||
// Divider of sector size in MBR between real sector size
|
||||
ulong divider = 1;
|
||||
|
||||
if(imagePlugin.Info.MetadataMediaType == MetadataMediaType.OpticalDisc)
|
||||
{
|
||||
sectorSize = 512;
|
||||
divider = 4;
|
||||
}
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sector);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
MasterBootRecord mbr = Marshal.ByteArrayToStructureLittleEndian<MasterBootRecord>(sector);
|
||||
TimedMasterBootRecord mbrTime = Marshal.ByteArrayToStructureLittleEndian<TimedMasterBootRecord>(sector);
|
||||
|
||||
SerializedMasterBootRecord mbrSerial =
|
||||
Marshal.ByteArrayToStructureLittleEndian<SerializedMasterBootRecord>(sector);
|
||||
|
||||
ModernMasterBootRecord mbrModern = Marshal.ByteArrayToStructureLittleEndian<ModernMasterBootRecord>(sector);
|
||||
NecMasterBootRecord mbrNec = Marshal.ByteArrayToStructureLittleEndian<NecMasterBootRecord>(sector);
|
||||
|
||||
DiskManagerMasterBootRecord mbrOntrack =
|
||||
Marshal.ByteArrayToStructureLittleEndian<DiskManagerMasterBootRecord>(sector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "xmlmedia = {0}", imagePlugin.Info.MetadataMediaType);
|
||||
AaruLogging.Debug(MODULE_NAME, "mbr.magic = {0:X4}", mbr.magic);
|
||||
|
||||
if(mbr.magic != MBR_MAGIC) return false; // Not MBR
|
||||
|
||||
errno = imagePlugin.ReadSector(1 + sectorOffset, out byte[] hdrBytes);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
ulong signature = BitConverter.ToUInt64(hdrBytes, 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "gpt.signature = 0x{0:X16}", signature);
|
||||
|
||||
if(signature == GPT_MAGIC) return false;
|
||||
|
||||
if(imagePlugin.Info.MetadataMediaType == MetadataMediaType.OpticalDisc)
|
||||
{
|
||||
errno = imagePlugin.ReadSector(sectorOffset, out hdrBytes);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
signature = BitConverter.ToUInt64(hdrBytes, 512);
|
||||
AaruLogging.Debug(MODULE_NAME, "gpt.signature @ 0x200 = 0x{0:X16}", signature);
|
||||
|
||||
if(signature == GPT_MAGIC) return false;
|
||||
}
|
||||
|
||||
PartitionEntry[] entries;
|
||||
|
||||
if(mbrOntrack.dm_magic == DM_MAGIC)
|
||||
entries = mbrOntrack.entries;
|
||||
else if(mbrNec.nec_magic == NEC_MAGIC)
|
||||
entries = mbrNec.entries;
|
||||
else
|
||||
entries = mbr.entries;
|
||||
|
||||
foreach(PartitionEntry entry in entries)
|
||||
{
|
||||
byte startSector = (byte)(entry.start_sector & 0x3F);
|
||||
ushort startCylinder = (ushort)((entry.start_sector & 0xC0) << 2 | entry.start_cylinder);
|
||||
byte endSector = (byte)(entry.end_sector & 0x3F);
|
||||
ushort endCylinder = (ushort)((entry.end_sector & 0xC0) << 2 | entry.end_cylinder);
|
||||
ulong lbaStart = entry.lba_start;
|
||||
ulong lbaSectors = entry.lba_sectors;
|
||||
|
||||
// Let's start the fun...
|
||||
|
||||
bool valid = true;
|
||||
bool extended = false;
|
||||
bool minix = false;
|
||||
|
||||
if(entry.status != 0x00 && entry.status != 0x80) return false; // Maybe a FAT filesystem
|
||||
|
||||
valid &= entry.type != 0x00;
|
||||
|
||||
if(entry.type is 0x05 or 0x0F or 0x15 or 0x1F or 0x85 or 0x91 or 0x9B or 0xC5 or 0xCF or 0xD5)
|
||||
{
|
||||
valid = false;
|
||||
extended = true; // Extended partition
|
||||
}
|
||||
|
||||
minix |= entry.type is 0x81 or 0x80; // MINIX partition
|
||||
|
||||
valid &= entry.lba_start != 0 ||
|
||||
entry.lba_sectors != 0 ||
|
||||
entry.start_cylinder != 0 ||
|
||||
entry.start_head != 0 ||
|
||||
entry.start_sector != 0 ||
|
||||
entry.end_cylinder != 0 ||
|
||||
entry.end_head != 0 ||
|
||||
entry.end_sector != 0;
|
||||
|
||||
if(entry is { lba_start: 0, lba_sectors: 0 } && valid)
|
||||
{
|
||||
lbaStart = CHS.ToLBA(startCylinder,
|
||||
entry.start_head,
|
||||
startSector,
|
||||
imagePlugin.Info.Heads,
|
||||
imagePlugin.Info.SectorsPerTrack);
|
||||
|
||||
lbaSectors = CHS.ToLBA(endCylinder,
|
||||
entry.end_head,
|
||||
entry.end_sector,
|
||||
imagePlugin.Info.Heads,
|
||||
imagePlugin.Info.SectorsPerTrack) -
|
||||
lbaStart;
|
||||
}
|
||||
|
||||
// For optical media
|
||||
lbaStart /= divider;
|
||||
lbaSectors /= divider;
|
||||
|
||||
if(minix && lbaStart == sectorOffset) minix = false;
|
||||
|
||||
if(lbaStart > imagePlugin.Info.Sectors)
|
||||
{
|
||||
valid = false;
|
||||
extended = false;
|
||||
}
|
||||
|
||||
// Some buggy implementations do some rounding errors getting a few sectors beyond device size
|
||||
if(lbaStart + lbaSectors > imagePlugin.Info.Sectors) lbaSectors = imagePlugin.Info.Sectors - lbaStart;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.status {0}", entry.status);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.type {0}", entry.type);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.lba_start {0}", entry.lba_start);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.lba_sectors {0}", entry.lba_sectors);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.start_cylinder {0}", startCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.start_head {0}", entry.start_head);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.start_sector {0}", startSector);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.end_cylinder {0}", endCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.end_head {0}", entry.end_head);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.end_sector {0}", endSector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.minix = {0}", minix);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "lba_start {0}", lbaStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "lba_sectors {0}", lbaSectors);
|
||||
|
||||
if(valid && minix) // Let's mix the fun
|
||||
{
|
||||
if(GetMinix(imagePlugin, lbaStart, divider, sectorOffset, sectorSize, out List<Partition> mnxParts))
|
||||
partitions.AddRange(mnxParts);
|
||||
else
|
||||
minix = false;
|
||||
}
|
||||
|
||||
if(valid && !minix)
|
||||
{
|
||||
var part = new Partition();
|
||||
|
||||
if((lbaStart > 0 || imagePlugin.Info.MetadataMediaType == MetadataMediaType.OpticalDisc) &&
|
||||
lbaSectors > 0)
|
||||
{
|
||||
part.Start = lbaStart + sectorOffset;
|
||||
part.Length = lbaSectors;
|
||||
part.Offset = part.Start * sectorSize;
|
||||
part.Size = part.Length * sectorSize;
|
||||
}
|
||||
else
|
||||
valid = false;
|
||||
|
||||
if(valid)
|
||||
{
|
||||
part.Type = $"0x{entry.type:X2}";
|
||||
part.Name = DecodeMbrType(entry.type);
|
||||
part.Sequence = counter;
|
||||
part.Description = entry.status == 0x80 ? Localization.Partition_is_bootable : "";
|
||||
part.Scheme = Name;
|
||||
|
||||
counter++;
|
||||
|
||||
partitions.Add(part);
|
||||
}
|
||||
}
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.extended = {0}", extended);
|
||||
|
||||
if(!extended) continue;
|
||||
|
||||
bool processingExtended = true;
|
||||
ulong chainStart = lbaStart;
|
||||
|
||||
while(processingExtended)
|
||||
{
|
||||
errno = imagePlugin.ReadSector(lbaStart, out sector);
|
||||
|
||||
if(errno != ErrorNumber.NoError) break;
|
||||
|
||||
ExtendedBootRecord ebr = Marshal.ByteArrayToStructureLittleEndian<ExtendedBootRecord>(sector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr.magic == MBR_Magic = {0}", ebr.magic == MBR_MAGIC);
|
||||
|
||||
if(ebr.magic != MBR_MAGIC) break;
|
||||
|
||||
ulong nextStart = 0;
|
||||
|
||||
foreach(PartitionEntry ebrEntry in ebr.entries)
|
||||
{
|
||||
bool extValid = true;
|
||||
startSector = (byte)(ebrEntry.start_sector & 0x3F);
|
||||
startCylinder = (ushort)((ebrEntry.start_sector & 0xC0) << 2 | ebrEntry.start_cylinder);
|
||||
endSector = (byte)(ebrEntry.end_sector & 0x3F);
|
||||
endCylinder = (ushort)((ebrEntry.end_sector & 0xC0) << 2 | ebrEntry.end_cylinder);
|
||||
ulong extStart = ebrEntry.lba_start;
|
||||
ulong extSectors = ebrEntry.lba_sectors;
|
||||
bool extMinix = false;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.status {0}", ebrEntry.status);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.type {0}", ebrEntry.type);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.lba_start {0}", ebrEntry.lba_start);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.lba_sectors {0}", ebrEntry.lba_sectors);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.start_cylinder {0}", startCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.start_head {0}", ebrEntry.start_head);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.start_sector {0}", startSector);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.end_cylinder {0}", endCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.end_head {0}", ebrEntry.end_head);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.end_sector {0}", endSector);
|
||||
|
||||
// Let's start the fun...
|
||||
extValid &= ebrEntry.status is 0x00 or 0x80;
|
||||
extValid &= ebrEntry.type != 0x00;
|
||||
|
||||
extValid &= ebrEntry.lba_start != 0 ||
|
||||
ebrEntry.lba_sectors != 0 ||
|
||||
ebrEntry.start_cylinder != 0 ||
|
||||
ebrEntry.start_head != 0 ||
|
||||
ebrEntry.start_sector != 0 ||
|
||||
ebrEntry.end_cylinder != 0 ||
|
||||
ebrEntry.end_head != 0 ||
|
||||
ebrEntry.end_sector != 0;
|
||||
|
||||
if(ebrEntry is { lba_start: 0, lba_sectors: 0 } && extValid)
|
||||
{
|
||||
extStart = CHS.ToLBA(startCylinder,
|
||||
ebrEntry.start_head,
|
||||
startSector,
|
||||
imagePlugin.Info.Heads,
|
||||
imagePlugin.Info.SectorsPerTrack);
|
||||
|
||||
extSectors = CHS.ToLBA(endCylinder,
|
||||
ebrEntry.end_head,
|
||||
ebrEntry.end_sector,
|
||||
imagePlugin.Info.Heads,
|
||||
imagePlugin.Info.SectorsPerTrack) -
|
||||
extStart;
|
||||
}
|
||||
|
||||
extMinix |= ebrEntry.type is 0x81 or 0x80;
|
||||
|
||||
// For optical media
|
||||
extStart /= divider;
|
||||
extSectors /= divider;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "ext_start {0}", extStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "ext_sectors {0}", extSectors);
|
||||
|
||||
if(ebrEntry.type is 0x05 or 0x0F or 0x15 or 0x1F or 0x85 or 0x91 or 0x9B or 0xC5 or 0xCF or 0xD5)
|
||||
{
|
||||
extValid = false;
|
||||
nextStart = chainStart + extStart;
|
||||
}
|
||||
|
||||
extStart += lbaStart;
|
||||
extValid &= extStart <= imagePlugin.Info.Sectors;
|
||||
|
||||
// Some buggy implementations do some rounding errors getting a few sectors beyond device size
|
||||
if(extStart + extSectors > imagePlugin.Info.Sectors)
|
||||
extSectors = imagePlugin.Info.Sectors - extStart;
|
||||
|
||||
if(extValid && extMinix) // Let's mix the fun
|
||||
{
|
||||
if(GetMinix(imagePlugin,
|
||||
lbaStart,
|
||||
divider,
|
||||
sectorOffset,
|
||||
sectorSize,
|
||||
out List<Partition> mnxParts))
|
||||
partitions.AddRange(mnxParts);
|
||||
else
|
||||
extMinix = false;
|
||||
}
|
||||
|
||||
if(!extValid || extMinix) continue;
|
||||
|
||||
var part = new Partition();
|
||||
|
||||
if(extStart > 0 && extSectors > 0)
|
||||
{
|
||||
part.Start = extStart + sectorOffset;
|
||||
part.Length = extSectors;
|
||||
part.Offset = part.Start * sectorSize;
|
||||
part.Size = part.Length * sectorSize;
|
||||
}
|
||||
else
|
||||
extValid = false;
|
||||
|
||||
if(!extValid) continue;
|
||||
|
||||
part.Type = $"0x{ebrEntry.type:X2}";
|
||||
part.Name = DecodeMbrType(ebrEntry.type);
|
||||
part.Sequence = counter;
|
||||
part.Description = ebrEntry.status == 0x80 ? Localization.Partition_is_bootable : "";
|
||||
part.Scheme = Name;
|
||||
counter++;
|
||||
|
||||
partitions.Add(part);
|
||||
}
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "next_start {0}", nextStart);
|
||||
processingExtended &= nextStart != 0;
|
||||
processingExtended &= nextStart <= imagePlugin.Info.Sectors;
|
||||
lbaStart = nextStart;
|
||||
}
|
||||
}
|
||||
|
||||
// An empty MBR may exist, NeXT creates one and then hardcodes its disklabel
|
||||
return partitions.Count != 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static bool GetMinix(IMediaImage imagePlugin, ulong start, ulong divider, ulong sectorOffset, uint sectorSize,
|
||||
out List<Partition> partitions)
|
||||
{
|
||||
partitions = [];
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(start, out byte[] sector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(start, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
@@ -668,17 +318,17 @@ public sealed class MBR : IPartition
|
||||
|
||||
if(mnx.magic != MBR_MAGIC) return false;
|
||||
|
||||
bool anyMnx = false;
|
||||
var anyMnx = false;
|
||||
|
||||
foreach(PartitionEntry mnxEntry in mnx.entries)
|
||||
{
|
||||
bool mnxValid = true;
|
||||
byte startSector = (byte)(mnxEntry.start_sector & 0x3F);
|
||||
ushort startCylinder = (ushort)((mnxEntry.start_sector & 0xC0) << 2 | mnxEntry.start_cylinder);
|
||||
byte endSector = (byte)(mnxEntry.end_sector & 0x3F);
|
||||
ushort endCylinder = (ushort)((mnxEntry.end_sector & 0xC0) << 2 | mnxEntry.end_cylinder);
|
||||
ulong mnxStart = mnxEntry.lba_start;
|
||||
ulong mnxSectors = mnxEntry.lba_sectors;
|
||||
var mnxValid = true;
|
||||
var startSector = (byte)(mnxEntry.start_sector & 0x3F);
|
||||
var startCylinder = (ushort)((mnxEntry.start_sector & 0xC0) << 2 | mnxEntry.start_cylinder);
|
||||
var endSector = (byte)(mnxEntry.end_sector & 0x3F);
|
||||
var endCylinder = (ushort)((mnxEntry.end_sector & 0xC0) << 2 | mnxEntry.end_cylinder);
|
||||
ulong mnxStart = mnxEntry.lba_start;
|
||||
ulong mnxSectors = mnxEntry.lba_sectors;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "mnx_entry.status {0}", mnxEntry.status);
|
||||
AaruLogging.Debug(MODULE_NAME, "mnx_entry.type {0}", mnxEntry.type);
|
||||
@@ -959,5 +609,355 @@ public sealed class MBR : IPartition
|
||||
public readonly ushort magic;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.MBR_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("5E8A34E8-4F1A-59E6-4BF7-7EA647063A76");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NATALIA_PORTILLO;
|
||||
|
||||
/// <inheritdoc />
|
||||
[SuppressMessage("ReSharper", "UnusedVariable")]
|
||||
public bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset)
|
||||
{
|
||||
ulong counter = 0;
|
||||
|
||||
partitions = [];
|
||||
|
||||
if(imagePlugin.Info.SectorSize < 512) return false;
|
||||
|
||||
uint sectorSize = imagePlugin.Info.SectorSize;
|
||||
|
||||
// Divider of sector size in MBR between real sector size
|
||||
ulong divider = 1;
|
||||
|
||||
if(imagePlugin.Info.MetadataMediaType == MetadataMediaType.OpticalDisc)
|
||||
{
|
||||
sectorSize = 512;
|
||||
divider = 4;
|
||||
}
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
MasterBootRecord mbr = Marshal.ByteArrayToStructureLittleEndian<MasterBootRecord>(sector);
|
||||
TimedMasterBootRecord mbrTime = Marshal.ByteArrayToStructureLittleEndian<TimedMasterBootRecord>(sector);
|
||||
|
||||
SerializedMasterBootRecord mbrSerial =
|
||||
Marshal.ByteArrayToStructureLittleEndian<SerializedMasterBootRecord>(sector);
|
||||
|
||||
ModernMasterBootRecord mbrModern = Marshal.ByteArrayToStructureLittleEndian<ModernMasterBootRecord>(sector);
|
||||
NecMasterBootRecord mbrNec = Marshal.ByteArrayToStructureLittleEndian<NecMasterBootRecord>(sector);
|
||||
|
||||
DiskManagerMasterBootRecord mbrOntrack =
|
||||
Marshal.ByteArrayToStructureLittleEndian<DiskManagerMasterBootRecord>(sector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "xmlmedia = {0}", imagePlugin.Info.MetadataMediaType);
|
||||
AaruLogging.Debug(MODULE_NAME, "mbr.magic = {0:X4}", mbr.magic);
|
||||
|
||||
if(mbr.magic != MBR_MAGIC) return false; // Not MBR
|
||||
|
||||
errno = imagePlugin.ReadSector(1 + sectorOffset, out byte[] hdrBytes, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
var signature = BitConverter.ToUInt64(hdrBytes, 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "gpt.signature = 0x{0:X16}", signature);
|
||||
|
||||
if(signature == GPT_MAGIC) return false;
|
||||
|
||||
if(imagePlugin.Info.MetadataMediaType == MetadataMediaType.OpticalDisc)
|
||||
{
|
||||
errno = imagePlugin.ReadSector(sectorOffset, out hdrBytes, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
signature = BitConverter.ToUInt64(hdrBytes, 512);
|
||||
AaruLogging.Debug(MODULE_NAME, "gpt.signature @ 0x200 = 0x{0:X16}", signature);
|
||||
|
||||
if(signature == GPT_MAGIC) return false;
|
||||
}
|
||||
|
||||
PartitionEntry[] entries;
|
||||
|
||||
if(mbrOntrack.dm_magic == DM_MAGIC)
|
||||
entries = mbrOntrack.entries;
|
||||
else if(mbrNec.nec_magic == NEC_MAGIC)
|
||||
entries = mbrNec.entries;
|
||||
else
|
||||
entries = mbr.entries;
|
||||
|
||||
foreach(PartitionEntry entry in entries)
|
||||
{
|
||||
var startSector = (byte)(entry.start_sector & 0x3F);
|
||||
var startCylinder = (ushort)((entry.start_sector & 0xC0) << 2 | entry.start_cylinder);
|
||||
var endSector = (byte)(entry.end_sector & 0x3F);
|
||||
var endCylinder = (ushort)((entry.end_sector & 0xC0) << 2 | entry.end_cylinder);
|
||||
ulong lbaStart = entry.lba_start;
|
||||
ulong lbaSectors = entry.lba_sectors;
|
||||
|
||||
// Let's start the fun...
|
||||
|
||||
var valid = true;
|
||||
var extended = false;
|
||||
var minix = false;
|
||||
|
||||
if(entry.status != 0x00 && entry.status != 0x80) return false; // Maybe a FAT filesystem
|
||||
|
||||
valid &= entry.type != 0x00;
|
||||
|
||||
if(entry.type is 0x05 or 0x0F or 0x15 or 0x1F or 0x85 or 0x91 or 0x9B or 0xC5 or 0xCF or 0xD5)
|
||||
{
|
||||
valid = false;
|
||||
extended = true; // Extended partition
|
||||
}
|
||||
|
||||
minix |= entry.type is 0x81 or 0x80; // MINIX partition
|
||||
|
||||
valid &= entry.lba_start != 0 ||
|
||||
entry.lba_sectors != 0 ||
|
||||
entry.start_cylinder != 0 ||
|
||||
entry.start_head != 0 ||
|
||||
entry.start_sector != 0 ||
|
||||
entry.end_cylinder != 0 ||
|
||||
entry.end_head != 0 ||
|
||||
entry.end_sector != 0;
|
||||
|
||||
if(entry is { lba_start: 0, lba_sectors: 0 } && valid)
|
||||
{
|
||||
lbaStart = CHS.ToLBA(startCylinder,
|
||||
entry.start_head,
|
||||
startSector,
|
||||
imagePlugin.Info.Heads,
|
||||
imagePlugin.Info.SectorsPerTrack);
|
||||
|
||||
lbaSectors = CHS.ToLBA(endCylinder,
|
||||
entry.end_head,
|
||||
entry.end_sector,
|
||||
imagePlugin.Info.Heads,
|
||||
imagePlugin.Info.SectorsPerTrack) -
|
||||
lbaStart;
|
||||
}
|
||||
|
||||
// For optical media
|
||||
lbaStart /= divider;
|
||||
lbaSectors /= divider;
|
||||
|
||||
if(minix && lbaStart == sectorOffset) minix = false;
|
||||
|
||||
if(lbaStart > imagePlugin.Info.Sectors)
|
||||
{
|
||||
valid = false;
|
||||
extended = false;
|
||||
}
|
||||
|
||||
// Some buggy implementations do some rounding errors getting a few sectors beyond device size
|
||||
if(lbaStart + lbaSectors > imagePlugin.Info.Sectors) lbaSectors = imagePlugin.Info.Sectors - lbaStart;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.status {0}", entry.status);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.type {0}", entry.type);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.lba_start {0}", entry.lba_start);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.lba_sectors {0}", entry.lba_sectors);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.start_cylinder {0}", startCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.start_head {0}", entry.start_head);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.start_sector {0}", startSector);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.end_cylinder {0}", endCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.end_head {0}", entry.end_head);
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.end_sector {0}", endSector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.minix = {0}", minix);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "lba_start {0}", lbaStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "lba_sectors {0}", lbaSectors);
|
||||
|
||||
if(valid && minix) // Let's mix the fun
|
||||
{
|
||||
if(GetMinix(imagePlugin, lbaStart, divider, sectorOffset, sectorSize, out List<Partition> mnxParts))
|
||||
partitions.AddRange(mnxParts);
|
||||
else
|
||||
minix = false;
|
||||
}
|
||||
|
||||
if(valid && !minix)
|
||||
{
|
||||
var part = new Partition();
|
||||
|
||||
if((lbaStart > 0 || imagePlugin.Info.MetadataMediaType == MetadataMediaType.OpticalDisc) &&
|
||||
lbaSectors > 0)
|
||||
{
|
||||
part.Start = lbaStart + sectorOffset;
|
||||
part.Length = lbaSectors;
|
||||
part.Offset = part.Start * sectorSize;
|
||||
part.Size = part.Length * sectorSize;
|
||||
}
|
||||
else
|
||||
valid = false;
|
||||
|
||||
if(valid)
|
||||
{
|
||||
part.Type = $"0x{entry.type:X2}";
|
||||
part.Name = DecodeMbrType(entry.type);
|
||||
part.Sequence = counter;
|
||||
part.Description = entry.status == 0x80 ? Localization.Partition_is_bootable : "";
|
||||
part.Scheme = Name;
|
||||
|
||||
counter++;
|
||||
|
||||
partitions.Add(part);
|
||||
}
|
||||
}
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.extended = {0}", extended);
|
||||
|
||||
if(!extended) continue;
|
||||
|
||||
var processingExtended = true;
|
||||
ulong chainStart = lbaStart;
|
||||
|
||||
while(processingExtended)
|
||||
{
|
||||
errno = imagePlugin.ReadSector(lbaStart, out sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) break;
|
||||
|
||||
ExtendedBootRecord ebr = Marshal.ByteArrayToStructureLittleEndian<ExtendedBootRecord>(sector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr.magic == MBR_Magic = {0}", ebr.magic == MBR_MAGIC);
|
||||
|
||||
if(ebr.magic != MBR_MAGIC) break;
|
||||
|
||||
ulong nextStart = 0;
|
||||
|
||||
foreach(PartitionEntry ebrEntry in ebr.entries)
|
||||
{
|
||||
var extValid = true;
|
||||
startSector = (byte)(ebrEntry.start_sector & 0x3F);
|
||||
startCylinder = (ushort)((ebrEntry.start_sector & 0xC0) << 2 | ebrEntry.start_cylinder);
|
||||
endSector = (byte)(ebrEntry.end_sector & 0x3F);
|
||||
endCylinder = (ushort)((ebrEntry.end_sector & 0xC0) << 2 | ebrEntry.end_cylinder);
|
||||
ulong extStart = ebrEntry.lba_start;
|
||||
ulong extSectors = ebrEntry.lba_sectors;
|
||||
var extMinix = false;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.status {0}", ebrEntry.status);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.type {0}", ebrEntry.type);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.lba_start {0}", ebrEntry.lba_start);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.lba_sectors {0}", ebrEntry.lba_sectors);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.start_cylinder {0}", startCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.start_head {0}", ebrEntry.start_head);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.start_sector {0}", startSector);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.end_cylinder {0}", endCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.end_head {0}", ebrEntry.end_head);
|
||||
AaruLogging.Debug(MODULE_NAME, "ebr_entry.end_sector {0}", endSector);
|
||||
|
||||
// Let's start the fun...
|
||||
extValid &= ebrEntry.status is 0x00 or 0x80;
|
||||
extValid &= ebrEntry.type != 0x00;
|
||||
|
||||
extValid &= ebrEntry.lba_start != 0 ||
|
||||
ebrEntry.lba_sectors != 0 ||
|
||||
ebrEntry.start_cylinder != 0 ||
|
||||
ebrEntry.start_head != 0 ||
|
||||
ebrEntry.start_sector != 0 ||
|
||||
ebrEntry.end_cylinder != 0 ||
|
||||
ebrEntry.end_head != 0 ||
|
||||
ebrEntry.end_sector != 0;
|
||||
|
||||
if(ebrEntry is { lba_start: 0, lba_sectors: 0 } && extValid)
|
||||
{
|
||||
extStart = CHS.ToLBA(startCylinder,
|
||||
ebrEntry.start_head,
|
||||
startSector,
|
||||
imagePlugin.Info.Heads,
|
||||
imagePlugin.Info.SectorsPerTrack);
|
||||
|
||||
extSectors = CHS.ToLBA(endCylinder,
|
||||
ebrEntry.end_head,
|
||||
ebrEntry.end_sector,
|
||||
imagePlugin.Info.Heads,
|
||||
imagePlugin.Info.SectorsPerTrack) -
|
||||
extStart;
|
||||
}
|
||||
|
||||
extMinix |= ebrEntry.type is 0x81 or 0x80;
|
||||
|
||||
// For optical media
|
||||
extStart /= divider;
|
||||
extSectors /= divider;
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "ext_start {0}", extStart);
|
||||
AaruLogging.Debug(MODULE_NAME, "ext_sectors {0}", extSectors);
|
||||
|
||||
if(ebrEntry.type is 0x05 or 0x0F or 0x15 or 0x1F or 0x85 or 0x91 or 0x9B or 0xC5 or 0xCF or 0xD5)
|
||||
{
|
||||
extValid = false;
|
||||
nextStart = chainStart + extStart;
|
||||
}
|
||||
|
||||
extStart += lbaStart;
|
||||
extValid &= extStart <= imagePlugin.Info.Sectors;
|
||||
|
||||
// Some buggy implementations do some rounding errors getting a few sectors beyond device size
|
||||
if(extStart + extSectors > imagePlugin.Info.Sectors)
|
||||
extSectors = imagePlugin.Info.Sectors - extStart;
|
||||
|
||||
if(extValid && extMinix) // Let's mix the fun
|
||||
{
|
||||
if(GetMinix(imagePlugin,
|
||||
lbaStart,
|
||||
divider,
|
||||
sectorOffset,
|
||||
sectorSize,
|
||||
out List<Partition> mnxParts))
|
||||
partitions.AddRange(mnxParts);
|
||||
else
|
||||
extMinix = false;
|
||||
}
|
||||
|
||||
if(!extValid || extMinix) continue;
|
||||
|
||||
var part = new Partition();
|
||||
|
||||
if(extStart > 0 && extSectors > 0)
|
||||
{
|
||||
part.Start = extStart + sectorOffset;
|
||||
part.Length = extSectors;
|
||||
part.Offset = part.Start * sectorSize;
|
||||
part.Size = part.Length * sectorSize;
|
||||
}
|
||||
else
|
||||
extValid = false;
|
||||
|
||||
if(!extValid) continue;
|
||||
|
||||
part.Type = $"0x{ebrEntry.type:X2}";
|
||||
part.Name = DecodeMbrType(ebrEntry.type);
|
||||
part.Sequence = counter;
|
||||
part.Description = ebrEntry.status == 0x80 ? Localization.Partition_is_bootable : "";
|
||||
part.Scheme = Name;
|
||||
counter++;
|
||||
|
||||
partitions.Add(part);
|
||||
}
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "next_start {0}", nextStart);
|
||||
processingExtended &= nextStart != 0;
|
||||
processingExtended &= nextStart <= imagePlugin.Info.Sectors;
|
||||
lbaStart = nextStart;
|
||||
}
|
||||
}
|
||||
|
||||
// An empty MBR may exist, NeXT creates one and then hardcodes its disklabel
|
||||
return partitions.Count != 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -95,7 +95,7 @@ public sealed partial class NeXTDisklabel : IPartition
|
||||
0, 4, 15, 16
|
||||
}.TakeWhile(i => i + sectorOffset < imagePlugin.Info.Sectors))
|
||||
{
|
||||
errno = imagePlugin.ReadSector(i + sectorOffset, out labelSector);
|
||||
errno = imagePlugin.ReadSector(i + sectorOffset, out labelSector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) continue;
|
||||
|
||||
@@ -115,7 +115,7 @@ public sealed partial class NeXTDisklabel : IPartition
|
||||
|
||||
if(7680 % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
|
||||
|
||||
errno = imagePlugin.ReadSectors(labelPosition, sectorsToRead, out labelSector);
|
||||
errno = imagePlugin.ReadSectors(labelPosition, sectorsToRead, out labelSector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
|
||||
@@ -48,6 +48,61 @@ public sealed class PC98 : IPartition
|
||||
{
|
||||
const string MODULE_NAME = "PC-98 partitions plugin";
|
||||
|
||||
static string DecodePC98Sid(byte sid)
|
||||
{
|
||||
return (sid & 0x7F) switch
|
||||
{
|
||||
0x01 => Localization.FAT12,
|
||||
0x04 => Localization.PC_UX,
|
||||
0x06 => Localization.N88_BASIC_86,
|
||||
|
||||
// Supposedly for FAT16 < 32 MiB, seen in bigger partitions
|
||||
0x11 or 0x21 => Localization.FAT16,
|
||||
0x28 or 0x41 or 0x48 => Localization.Windows_Volume_Set,
|
||||
0x44 => Localization.FreeBSD,
|
||||
0x61 => Localization.FAT32,
|
||||
0x62 => Localization.Linux,
|
||||
_ => Localization.Unknown_partition_type
|
||||
};
|
||||
}
|
||||
|
||||
#region Nested type: Partition
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Partition
|
||||
{
|
||||
/// <summary>Some ID, if 0x80 bit is set, it is bootable</summary>
|
||||
public readonly byte dp_mid;
|
||||
/// <summary>Some ID, if 0x80 bit is set, it is active</summary>
|
||||
public readonly byte dp_sid;
|
||||
public readonly byte dp_dum1;
|
||||
public readonly byte dp_dum2;
|
||||
public readonly byte dp_ipl_sct;
|
||||
public readonly byte dp_ipl_head;
|
||||
public readonly ushort dp_ipl_cyl;
|
||||
public readonly byte dp_ssect;
|
||||
public readonly byte dp_shd;
|
||||
public readonly ushort dp_scyl;
|
||||
public readonly byte dp_esect;
|
||||
public readonly byte dp_ehd;
|
||||
public readonly ushort dp_ecyl;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public readonly byte[] dp_name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Table
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Table
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public readonly Partition[] entries;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -66,11 +121,11 @@ public sealed class PC98 : IPartition
|
||||
|
||||
if(sectorOffset != 0) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] bootSector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] bootSector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || bootSector[^2] != 0x55 || bootSector[^1] != 0xAA) return false;
|
||||
|
||||
errno = imagePlugin.ReadSector(1, out byte[] sector);
|
||||
errno = imagePlugin.ReadSector(1, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
@@ -98,8 +153,8 @@ public sealed class PC98 : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "entry.dp_ecyl = {0}", entry.dp_ecyl);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"entry.dp_name = \"{0}\"",
|
||||
StringHandlers.CToString(entry.dp_name, Encoding.GetEncoding(932)));
|
||||
"entry.dp_name = \"{0}\"",
|
||||
StringHandlers.CToString(entry.dp_name, Encoding.GetEncoding(932)));
|
||||
|
||||
if(entry.dp_scyl == entry.dp_ecyl ||
|
||||
entry.dp_ecyl <= 0 ||
|
||||
@@ -156,60 +211,5 @@ public sealed class PC98 : IPartition
|
||||
return partitions.Count > 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static string DecodePC98Sid(byte sid)
|
||||
{
|
||||
return (sid & 0x7F) switch
|
||||
{
|
||||
0x01 => Localization.FAT12,
|
||||
0x04 => Localization.PC_UX,
|
||||
0x06 => Localization.N88_BASIC_86,
|
||||
|
||||
// Supposedly for FAT16 < 32 MiB, seen in bigger partitions
|
||||
0x11 or 0x21 => Localization.FAT16,
|
||||
0x28 or 0x41 or 0x48 => Localization.Windows_Volume_Set,
|
||||
0x44 => Localization.FreeBSD,
|
||||
0x61 => Localization.FAT32,
|
||||
0x62 => Localization.Linux,
|
||||
_ => Localization.Unknown_partition_type
|
||||
};
|
||||
}
|
||||
|
||||
#region Nested type: Partition
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Partition
|
||||
{
|
||||
/// <summary>Some ID, if 0x80 bit is set, it is bootable</summary>
|
||||
public readonly byte dp_mid;
|
||||
/// <summary>Some ID, if 0x80 bit is set, it is active</summary>
|
||||
public readonly byte dp_sid;
|
||||
public readonly byte dp_dum1;
|
||||
public readonly byte dp_dum2;
|
||||
public readonly byte dp_ipl_sct;
|
||||
public readonly byte dp_ipl_head;
|
||||
public readonly ushort dp_ipl_cyl;
|
||||
public readonly byte dp_ssect;
|
||||
public readonly byte dp_shd;
|
||||
public readonly ushort dp_scyl;
|
||||
public readonly byte dp_esect;
|
||||
public readonly byte dp_ehd;
|
||||
public readonly ushort dp_ecyl;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public readonly byte[] dp_name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Table
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Table
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public readonly Partition[] entries;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public sealed class Plan9 : IPartition
|
||||
|
||||
if(sectorOffset + 2 >= imagePlugin.Info.Sectors) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset + 1, out byte[] sector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset + 1, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
{
|
||||
partitions = [];
|
||||
ulong rdbBlock = 0;
|
||||
bool foundRdb = false;
|
||||
var foundRdb = false;
|
||||
ErrorNumber errno;
|
||||
|
||||
while(rdbBlock < 16)
|
||||
@@ -203,7 +203,7 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
|
||||
if(rdbBlock + sectorOffset >= imagePlugin.Info.Sectors) break;
|
||||
|
||||
errno = imagePlugin.ReadSector(rdbBlock + sectorOffset, out byte[] tmpSector);
|
||||
errno = imagePlugin.ReadSector(rdbBlock + sectorOffset, out byte[] tmpSector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError)
|
||||
{
|
||||
@@ -212,7 +212,7 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
continue;
|
||||
}
|
||||
|
||||
uint magic = BigEndianBitConverter.ToUInt32(tmpSector, 0);
|
||||
var magic = BigEndianBitConverter.ToUInt32(tmpSector, 0);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, Localization.Possible_magic_at_block_0_is_1_X8, rdbBlock, magic);
|
||||
|
||||
@@ -234,7 +234,7 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
|
||||
var rdb = new RigidDiskBlock();
|
||||
|
||||
errno = imagePlugin.ReadSector(rdbBlock, out byte[] sector);
|
||||
errno = imagePlugin.ReadSector(rdbBlock, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
@@ -279,7 +279,7 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
rdb.HighCylinder = BigEndianBitConverter.ToUInt32(sector, 0x98);
|
||||
rdb.Reserved15 = BigEndianBitConverter.ToUInt32(sector, 0x9C);
|
||||
|
||||
byte[] tmpString = new byte[8];
|
||||
var tmpString = new byte[8];
|
||||
Array.Copy(sector, 0xA0, tmpString, 0, 8);
|
||||
rdb.DiskVendor = StringHandlers.SpacePaddedToString(tmpString);
|
||||
tmpString = new byte[16];
|
||||
@@ -372,15 +372,13 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
|
||||
while(nextBlock != 0xFFFFFFFF)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Localization.Going_to_block_0_in_search_of_a_BadBlock_block,
|
||||
nextBlock);
|
||||
AaruLogging.Debug(MODULE_NAME, Localization.Going_to_block_0_in_search_of_a_BadBlock_block, nextBlock);
|
||||
|
||||
errno = imagePlugin.ReadSector(nextBlock, out sector);
|
||||
errno = imagePlugin.ReadSector(nextBlock, out sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) break;
|
||||
|
||||
uint magic = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||
var magic = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||
|
||||
if(magic != BAD_BLOCK_LIST_MAGIC) break;
|
||||
|
||||
@@ -402,9 +400,9 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "chainEntry.magic = 0x{0:X8}", chainEntry.Magic);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"chainEntry.size = {0} longs, {1} bytes",
|
||||
chainEntry.Size,
|
||||
chainEntry.Size * 4);
|
||||
"chainEntry.size = {0} longs, {1} bytes",
|
||||
chainEntry.Size,
|
||||
chainEntry.Size * 4);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "chainEntry.checksum = 0x{0:X8}", chainEntry.Checksum);
|
||||
AaruLogging.Debug(MODULE_NAME, "chainEntry.targetID = {0}", chainEntry.TargetId);
|
||||
@@ -418,9 +416,9 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
chainEntry.BlockPairs[i].GoodBlock = BigEndianBitConverter.ToUInt32(sector, (int)(0x18 + i * 8 + 4));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Localization.Bad_block_at_0_replaced_with_good_block_at_1,
|
||||
chainEntry.BlockPairs[i].BadBlock,
|
||||
chainEntry.BlockPairs[i].GoodBlock);
|
||||
Localization.Bad_block_at_0_replaced_with_good_block_at_1,
|
||||
chainEntry.BlockPairs[i].BadBlock,
|
||||
chainEntry.BlockPairs[i].GoodBlock);
|
||||
}
|
||||
|
||||
badBlockChain.Add(chainEntry);
|
||||
@@ -434,14 +432,14 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
while(nextBlock != 0xFFFFFFFF)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Localization.Going_to_block_0_in_search_of_a_PartitionEntry_block,
|
||||
nextBlock + sectorOffset);
|
||||
Localization.Going_to_block_0_in_search_of_a_PartitionEntry_block,
|
||||
nextBlock + sectorOffset);
|
||||
|
||||
errno = imagePlugin.ReadSector(nextBlock + sectorOffset, out sector);
|
||||
errno = imagePlugin.ReadSector(nextBlock + sectorOffset, out sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) break;
|
||||
|
||||
uint magic = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||
var magic = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||
|
||||
if(magic != PARTITION_BLOCK_MAGIC) break;
|
||||
|
||||
@@ -499,16 +497,13 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
}
|
||||
};
|
||||
|
||||
byte[] driveName = new byte[32];
|
||||
var driveName = new byte[32];
|
||||
Array.Copy(sector, 0x24, driveName, 0, 32);
|
||||
partEntry.DriveName = StringHandlers.PascalToString(driveName, Encoding.GetEncoding("iso-8859-1"));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.magic = 0x{0:X8}", partEntry.Magic);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.size = {0} longs, {1} bytes",
|
||||
partEntry.Size,
|
||||
partEntry.Size * 4);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.size = {0} longs, {1} bytes", partEntry.Size, partEntry.Size * 4);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.checksum = 0x{0:X8}", partEntry.Checksum);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.targetID = {0}", partEntry.TargetId);
|
||||
@@ -536,18 +531,16 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.reserved17 = 0x{0:X8}", partEntry.Reserved17);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.size = {0} longs, {1} bytes",
|
||||
partEntry.DosEnvVec.Size,
|
||||
partEntry.DosEnvVec.Size * 4);
|
||||
"partEntry.dosEnvVec.size = {0} longs, {1} bytes",
|
||||
partEntry.DosEnvVec.Size,
|
||||
partEntry.DosEnvVec.Size * 4);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.block_size = {0} longs, {1} bytes",
|
||||
partEntry.DosEnvVec.BlockSize,
|
||||
partEntry.DosEnvVec.BlockSize * 4);
|
||||
"partEntry.dosEnvVec.block_size = {0} longs, {1} bytes",
|
||||
partEntry.DosEnvVec.BlockSize,
|
||||
partEntry.DosEnvVec.BlockSize * 4);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.sec_org = 0x{0:X8}",
|
||||
partEntry.DosEnvVec.SecOrg);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.sec_org = 0x{0:X8}", partEntry.DosEnvVec.SecOrg);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.surfaces = {0}", partEntry.DosEnvVec.Surfaces);
|
||||
|
||||
@@ -556,54 +549,36 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.bpt = {0}", partEntry.DosEnvVec.Bpt);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.reservedblocks = {0}",
|
||||
partEntry.DosEnvVec.Reservedblocks);
|
||||
"partEntry.dosEnvVec.reservedblocks = {0}",
|
||||
partEntry.DosEnvVec.Reservedblocks);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.prealloc = {0}", partEntry.DosEnvVec.Prealloc);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.interleave = {0}",
|
||||
partEntry.DosEnvVec.Interleave);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.interleave = {0}", partEntry.DosEnvVec.Interleave);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.lowCylinder = {0}",
|
||||
partEntry.DosEnvVec.LowCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.lowCylinder = {0}", partEntry.DosEnvVec.LowCylinder);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.highCylinder = {0}",
|
||||
partEntry.DosEnvVec.HighCylinder);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.highCylinder = {0}", partEntry.DosEnvVec.HighCylinder);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.numBuffer = {0}",
|
||||
partEntry.DosEnvVec.NumBuffer);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.numBuffer = {0}", partEntry.DosEnvVec.NumBuffer);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.bufMemType = {0}",
|
||||
partEntry.DosEnvVec.BufMemType);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.bufMemType = {0}", partEntry.DosEnvVec.BufMemType);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.maxTransfer = {0}",
|
||||
partEntry.DosEnvVec.MaxTransfer);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.maxTransfer = {0}", partEntry.DosEnvVec.MaxTransfer);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.Mask = 0x{0:X8}", partEntry.DosEnvVec.Mask);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.bootPriority = {0}",
|
||||
partEntry.DosEnvVec.BootPriority);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.bootPriority = {0}", partEntry.DosEnvVec.BootPriority);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.dosType = {0}",
|
||||
AmigaDosTypeToString(partEntry.DosEnvVec.DosType));
|
||||
"partEntry.dosEnvVec.dosType = {0}",
|
||||
AmigaDosTypeToString(partEntry.DosEnvVec.DosType));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.baud = {0}", partEntry.DosEnvVec.Baud);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.control = 0x{0:X8}",
|
||||
partEntry.DosEnvVec.Control);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.control = 0x{0:X8}", partEntry.DosEnvVec.Control);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"partEntry.dosEnvVec.bootBlocks = {0}",
|
||||
partEntry.DosEnvVec.BootBlocks);
|
||||
AaruLogging.Debug(MODULE_NAME, "partEntry.dosEnvVec.bootBlocks = {0}", partEntry.DosEnvVec.BootBlocks);
|
||||
|
||||
partitionEntries.Add(partEntry);
|
||||
nextBlock = partEntry.NextPtr;
|
||||
@@ -617,14 +592,14 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
while(nextBlock != 0xFFFFFFFF)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Localization.Going_to_block_0_in_search_of_a_FileSystemHeader_block,
|
||||
nextBlock);
|
||||
Localization.Going_to_block_0_in_search_of_a_FileSystemHeader_block,
|
||||
nextBlock);
|
||||
|
||||
errno = imagePlugin.ReadSector(nextBlock, out sector);
|
||||
errno = imagePlugin.ReadSector(nextBlock, out sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) break;
|
||||
|
||||
uint magic = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||
var magic = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||
|
||||
if(magic != FILESYSTEM_HEADER_MAGIC) break;
|
||||
|
||||
@@ -671,10 +646,10 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "FSHD.dosType = {0}", AmigaDosTypeToString(fshd.DosType));
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"FSHD.version = {0:D2}.{1:D2} (0x{2:X8})",
|
||||
(fshd.Version & 0xFFFF0000) >> 16,
|
||||
fshd.Version & 0xFFFF,
|
||||
fshd.Version);
|
||||
"FSHD.version = {0:D2}.{1:D2} (0x{2:X8})",
|
||||
(fshd.Version & 0xFFFF0000) >> 16,
|
||||
fshd.Version & 0xFFFF,
|
||||
fshd.Version);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "FSHD.patchFlags = 0x{0:X8}", fshd.PatchFlags);
|
||||
|
||||
@@ -690,20 +665,20 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "FSHD.dnode.global_vec = 0x{0:X8}", fshd.Dnode.GlobalVec);
|
||||
|
||||
nextBlock = fshd.Dnode.SeglistPtr;
|
||||
bool thereAreLoadSegments = false;
|
||||
var sha1Ctx = new Sha1Context();
|
||||
var thereAreLoadSegments = false;
|
||||
var sha1Ctx = new Sha1Context();
|
||||
|
||||
while(nextBlock != 0xFFFFFFFF)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
Localization.Going_to_block_0_in_search_of_a_LoadSegment_block,
|
||||
nextBlock);
|
||||
Localization.Going_to_block_0_in_search_of_a_LoadSegment_block,
|
||||
nextBlock);
|
||||
|
||||
errno = imagePlugin.ReadSector(nextBlock, out sector);
|
||||
errno = imagePlugin.ReadSector(nextBlock, out sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) break;
|
||||
|
||||
uint magicSeg = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||
var magicSeg = BigEndianBitConverter.ToUInt32(sector, 0);
|
||||
|
||||
if(magicSeg != LOAD_SEG_MAGIC) break;
|
||||
|
||||
@@ -725,10 +700,7 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "loadSeg.magic = 0x{0:X8}", loadSeg.Magic);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"loadSeg.size = {0} longs, {1} bytes",
|
||||
loadSeg.Size,
|
||||
loadSeg.Size * 4);
|
||||
AaruLogging.Debug(MODULE_NAME, "loadSeg.size = {0} longs, {1} bytes", loadSeg.Size, loadSeg.Size * 4);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "loadSeg.checksum = 0x{0:X8}", loadSeg.Checksum);
|
||||
AaruLogging.Debug(MODULE_NAME, "loadSeg.targetID = {0}", loadSeg.TargetId);
|
||||
@@ -941,7 +913,7 @@ public sealed class AmigaRigidDiskBlock : IPartition
|
||||
|
||||
static string AmigaDosTypeToString(uint amigaDosType, bool quoted = true)
|
||||
{
|
||||
byte[] textPart = new byte[3];
|
||||
var textPart = new byte[3];
|
||||
|
||||
textPart[0] = (byte)((amigaDosType & 0xFF000000) >> 24);
|
||||
textPart[1] = (byte)((amigaDosType & 0x00FF0000) >> 16);
|
||||
|
||||
@@ -48,50 +48,6 @@ public sealed class RioKarma : IPartition
|
||||
const ushort KARMA_MAGIC = 0xAB56;
|
||||
const byte ENTRY_MAGIC = 0x4D;
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.RioKarma_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("246A6D93-4F1A-1F8A-344D-50187A5513A9");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NATALIA_PORTILLO;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset)
|
||||
{
|
||||
partitions = null;
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sector);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return false;
|
||||
|
||||
Table table = Marshal.ByteArrayToStructureLittleEndian<Table>(sector);
|
||||
|
||||
if(table.magic != KARMA_MAGIC) return false;
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
partitions = (from entry in table.entries
|
||||
let part = new Partition
|
||||
{
|
||||
Start = entry.offset,
|
||||
Offset = (ulong)(entry.offset * sector.Length),
|
||||
Size = entry.size,
|
||||
Length = (ulong)(entry.size * sector.Length),
|
||||
Type = Localization.Rio_Karma,
|
||||
Sequence = counter++,
|
||||
Scheme = Name
|
||||
}
|
||||
where entry.type == ENTRY_MAGIC
|
||||
select part).ToList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Entry
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
@@ -121,5 +77,49 @@ public sealed class RioKarma : IPartition
|
||||
public readonly ushort magic;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => Localization.RioKarma_Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid Id => new("246A6D93-4F1A-1F8A-344D-50187A5513A9");
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Author => Authors.NATALIA_PORTILLO;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool GetInformation(IMediaImage imagePlugin, out List<Partition> partitions, ulong sectorOffset)
|
||||
{
|
||||
partitions = null;
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return false;
|
||||
|
||||
Table table = Marshal.ByteArrayToStructureLittleEndian<Table>(sector);
|
||||
|
||||
if(table.magic != KARMA_MAGIC) return false;
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
partitions = (from entry in table.entries
|
||||
let part = new Partition
|
||||
{
|
||||
Start = entry.offset,
|
||||
Offset = (ulong)(entry.offset * sector.Length),
|
||||
Size = entry.size,
|
||||
Length = (ulong)(entry.size * sector.Length),
|
||||
Type = Localization.Rio_Karma,
|
||||
Sequence = counter++,
|
||||
Scheme = Name
|
||||
}
|
||||
where entry.type == ENTRY_MAGIC
|
||||
select part).ToList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public sealed partial class SGI : IPartition
|
||||
{
|
||||
partitions = [];
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return false;
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
|
||||
bool useDkl = false, useDkl8 = false, useDkl16 = false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sunSector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(sectorOffset, out byte[] sunSector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
@@ -130,7 +130,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
|
||||
if(!useDkl && !useDkl8 && !useDkl16)
|
||||
{
|
||||
errno = imagePlugin.ReadSector(sectorOffset + 1, out sunSector);
|
||||
errno = imagePlugin.ReadSector(sectorOffset + 1, out sunSector, out _);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
@@ -170,7 +170,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
|
||||
if(useDkl)
|
||||
{
|
||||
ulong sectorsPerCylinder = (ulong)(dkl.dkl_nsect * dkl.dkl_nhead);
|
||||
var sectorsPerCylinder = (ulong)(dkl.dkl_nsect * dkl.dkl_nhead);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"dkl.dkl_asciilabel = \"{0}\"",
|
||||
@@ -189,7 +189,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "dkl.dkl_bhead = {0}", dkl.dkl_bhead);
|
||||
AaruLogging.Debug(MODULE_NAME, "dkl.dkl_ppart = {0}", dkl.dkl_ppart);
|
||||
|
||||
for(int i = 0; i < NDKMAP; i++)
|
||||
for(var i = 0; i < NDKMAP; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME, "dkl.dkl_map[{0}].dkl_cylno = {1}", i, dkl.dkl_map[i].dkl_cylno);
|
||||
|
||||
@@ -200,7 +200,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "dkl.dkl_cksum = 0x{0:X4}", dkl.dkl_cksum);
|
||||
AaruLogging.Debug(MODULE_NAME, "sectorsPerCylinder = {0}", sectorsPerCylinder);
|
||||
|
||||
for(int i = 0; i < NDKMAP; i++)
|
||||
for(var i = 0; i < NDKMAP; i++)
|
||||
{
|
||||
if(dkl.dkl_map[i].dkl_cylno <= 0 || dkl.dkl_map[i].dkl_nblk <= 0) continue;
|
||||
|
||||
@@ -222,7 +222,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
}
|
||||
else if(useDkl8)
|
||||
{
|
||||
ulong sectorsPerCylinder = (ulong)(dkl8.dkl_nsect * dkl8.dkl_nhead);
|
||||
var sectorsPerCylinder = (ulong)(dkl8.dkl_nsect * dkl8.dkl_nhead);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"dkl8.dkl_asciilabel = \"{0}\"",
|
||||
@@ -251,7 +251,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
AaruLogging.Debug(MODULE_NAME, "dkl8.dkl_obs3 = {0}", dkl8.dkl_obs3);
|
||||
AaruLogging.Debug(MODULE_NAME, "dkl8.dkl_obs4 = {0}", dkl8.dkl_obs4);
|
||||
|
||||
for(int i = 0; i < NDKMAP; i++)
|
||||
for(var i = 0; i < NDKMAP; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME, "dkl8.dkl_map[{0}].dkl_cylno = {1}", i, dkl8.dkl_map[i].dkl_cylno);
|
||||
|
||||
@@ -281,7 +281,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
|
||||
if(dkl8.dkl_vtoc.v_nparts > NDKMAP) return false;
|
||||
|
||||
for(int i = 0; i < dkl8.dkl_vtoc.v_nparts; i++)
|
||||
for(var i = 0; i < dkl8.dkl_vtoc.v_nparts; i++)
|
||||
{
|
||||
if(dkl8.dkl_map[i].dkl_nblk <= 0 ||
|
||||
dkl8.dkl_vtoc.v_part[i].p_tag == SunTag.SunEmpty ||
|
||||
@@ -344,7 +344,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME, "dkl16.dkl_read_reinstruct = {0}", dkl16.dkl_read_reinstruct);
|
||||
|
||||
for(int i = 0; i < NDKMAP16; i++)
|
||||
for(var i = 0; i < NDKMAP16; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"dkl16.dkl_vtoc.v_part[{0}].p_start = {1}",
|
||||
@@ -379,7 +379,7 @@ public sealed partial class SunDisklabel : IPartition
|
||||
|
||||
if(dkl16.dkl_vtoc.v_nparts > NDKMAP16) return false;
|
||||
|
||||
for(int i = 0; i < dkl16.dkl_vtoc.v_nparts; i++)
|
||||
for(var i = 0; i < dkl16.dkl_vtoc.v_nparts; i++)
|
||||
{
|
||||
if(dkl16.dkl_vtoc.v_part[i].p_size <= 0 ||
|
||||
dkl16.dkl_vtoc.v_part[i].p_tag == SunTag.SunEmpty ||
|
||||
|
||||
@@ -86,7 +86,7 @@ public sealed partial class VTOC : IPartition
|
||||
0, 1, 8, 29
|
||||
}.TakeWhile(i => i + sectorOffset < imagePlugin.Info.Sectors))
|
||||
{
|
||||
errno = imagePlugin.ReadSector(i + sectorOffset, out pdsector);
|
||||
errno = imagePlugin.ReadSector(i + sectorOffset, out pdsector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) continue;
|
||||
|
||||
@@ -169,7 +169,7 @@ public sealed partial class VTOC : IPartition
|
||||
|
||||
magicFound = false;
|
||||
var useOld = false;
|
||||
errno = imagePlugin.ReadSector(pdloc + sectorOffset + 1, out byte[] vtocsector);
|
||||
errno = imagePlugin.ReadSector(pdloc + sectorOffset + 1, out byte[] vtocsector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
@@ -249,7 +249,7 @@ public sealed partial class VTOC : IPartition
|
||||
return false;
|
||||
}
|
||||
|
||||
errno = imagePlugin.ReadSectors(relSecPtr + sectorOffset, secCount, out byte[] tmp);
|
||||
errno = imagePlugin.ReadSectors(relSecPtr + sectorOffset, secCount, out byte[] tmp, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
|
||||
@@ -53,6 +53,29 @@ public sealed class XENIX : IPartition
|
||||
const uint XENIX_OFFSET = 977;
|
||||
const string MODULE_NAME = "XENIX partitions plugin";
|
||||
|
||||
#region Nested type: Partable
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Partable
|
||||
{
|
||||
public readonly ushort p_magic; /* magic number validity indicator */
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXPARTS)]
|
||||
public readonly Partition[] p; /*partition headers*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Partition
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Partition
|
||||
{
|
||||
public readonly int p_off; /*start 1K block no of partition*/
|
||||
public readonly int p_size; /*# of 1K blocks in partition*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IPartition Members
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -71,20 +94,17 @@ public sealed class XENIX : IPartition
|
||||
|
||||
if(42 + sectorOffset >= imagePlugin.Info.Sectors) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(42 + sectorOffset, out byte[] tblsector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(42 + sectorOffset, out byte[] tblsector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
Partable xnxtbl = Marshal.ByteArrayToStructureLittleEndian<Partable>(tblsector);
|
||||
|
||||
AaruLogging.Debug(MODULE_NAME,
|
||||
"xnxtbl.p_magic = 0x{0:X4} (should be 0x{1:X4})",
|
||||
xnxtbl.p_magic,
|
||||
PAMAGIC);
|
||||
AaruLogging.Debug(MODULE_NAME, "xnxtbl.p_magic = 0x{0:X4} (should be 0x{1:X4})", xnxtbl.p_magic, PAMAGIC);
|
||||
|
||||
if(xnxtbl.p_magic != PAMAGIC) return false;
|
||||
|
||||
for(int i = 0; i < MAXPARTS; i++)
|
||||
for(var i = 0; i < MAXPARTS; i++)
|
||||
{
|
||||
AaruLogging.Debug(MODULE_NAME, "xnxtbl.p[{0}].p_off = {1}", i, xnxtbl.p[i].p_off);
|
||||
AaruLogging.Debug(MODULE_NAME, "xnxtbl.p[{0}].p_size = {1}", i, xnxtbl.p[i].p_size);
|
||||
@@ -111,28 +131,5 @@ public sealed class XENIX : IPartition
|
||||
return partitions.Count > 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Partable
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Partable
|
||||
{
|
||||
public readonly ushort p_magic; /* magic number validity indicator */
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXPARTS)]
|
||||
public readonly Partition[] p; /*partition headers*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: Partition
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
readonly struct Partition
|
||||
{
|
||||
public readonly int p_off; /*start 1K block no of partition*/
|
||||
public readonly int p_size; /*# of 1K blocks in partition*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -84,12 +84,11 @@ public sealed partial class Xbox : IPartition
|
||||
// Xbox partitions always start on 0
|
||||
if(sectorOffset != 0) return false;
|
||||
|
||||
ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector);
|
||||
ErrorNumber errno = imagePlugin.ReadSector(0, out byte[] sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError || sector.Length < 512) return false;
|
||||
|
||||
Xbox360DevKitPartitionTable table =
|
||||
Marshal.ByteArrayToStructureBigEndian<Xbox360DevKitPartitionTable>(sector);
|
||||
Xbox360DevKitPartitionTable table = Marshal.ByteArrayToStructureBigEndian<Xbox360DevKitPartitionTable>(sector);
|
||||
|
||||
if(table.magic == XBOX360_DEVKIT_MAGIC &&
|
||||
table.contentOff + table.contentLen <= imagePlugin.Info.Sectors &&
|
||||
@@ -127,7 +126,9 @@ public sealed partial class Xbox : IPartition
|
||||
|
||||
if(imagePlugin.Info.Sectors > (ulong)(MEMORY_UNIT_DATA_OFF / imagePlugin.Info.SectorSize))
|
||||
{
|
||||
errno = imagePlugin.ReadSector((ulong)(MEMORY_UNIT_DATA_OFF / imagePlugin.Info.SectorSize), out sector);
|
||||
errno = imagePlugin.ReadSector((ulong)(MEMORY_UNIT_DATA_OFF / imagePlugin.Info.SectorSize),
|
||||
out sector,
|
||||
out _);
|
||||
|
||||
if(errno == ErrorNumber.NoError)
|
||||
{
|
||||
@@ -168,7 +169,7 @@ public sealed partial class Xbox : IPartition
|
||||
if(imagePlugin.Info.Sectors <= (ulong)(XBOX_360DATA_OFF / imagePlugin.Info.SectorSize)) return false;
|
||||
|
||||
{
|
||||
errno = imagePlugin.ReadSector((ulong)(XBOX_360DATA_OFF / imagePlugin.Info.SectorSize), out sector);
|
||||
errno = imagePlugin.ReadSector((ulong)(XBOX_360DATA_OFF / imagePlugin.Info.SectorSize), out sector, out _);
|
||||
|
||||
if(errno != ErrorNumber.NoError) return false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user