mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
Add more boot code hashes to FAT.
This commit is contained in:
@@ -52,12 +52,6 @@ namespace DiscImageChef.Filesystems
|
||||
const uint FSINFO_SIGNATURE2 = 0x61417272;
|
||||
const uint FSINFO_SIGNATURE3 = 0xAA550000;
|
||||
|
||||
public FileSystemType XmlFsType { get; private set; }
|
||||
|
||||
public Encoding Encoding { get; private set; }
|
||||
public string Name => "Microsoft File Allocation Table";
|
||||
public Guid Id => new Guid("33513B2C-0D26-0D2D-32C3-79D8611158E0");
|
||||
|
||||
(string hash, string name)[] knownBootHashes =
|
||||
{
|
||||
("b639b4d5b25f63560e3b34a3a0feb732aa65486f", "Amstrad MS-DOS 3.20 (8-sector floppy)"),
|
||||
@@ -139,9 +133,22 @@ namespace DiscImageChef.Filesystems
|
||||
("3cea1921d29fcd3343d36c090cb3e3dba926781d", "Windows 98, Me"),
|
||||
("037f9c8caed602d93c88f7e9d8f13a732b3ada76", "Windows NT"),
|
||||
("a63806bfe11140c873082318dd4da834068be327", "Windows Vista"),
|
||||
("8f024b3d501c39ee6e3f8ca28173ad6a780d3eb0", "Windows Vista, 8, 10")
|
||||
("8f024b3d501c39ee6e3f8ca28173ad6a780d3eb0", "Windows Vista, 8, 10"),
|
||||
("d3e93f8b82ef250db216037d827a4896dc97d2be", "TracerST"), // OEM ID: "TracerST"
|
||||
//("b741f85ef40288ccc8887de1f6e849009097e1c9", "Norton Utilities"), // OEM ID: "IBM PNCI", need to confirm
|
||||
("c49b275537ac7237cac64d83f34d2024ae0ca96a", "Windows NT (Spanish)"
|
||||
), // Need to check Windows >= 2000 (Spanish)
|
||||
//("a48b0e4b696317eed829e960d1aa576562a4f185", "TracerST"), // Unknown OEM ID, apparently Tracer, unconfirmed
|
||||
("fe477972602ba76658ff7143859045b3c4036ca5", "iomega"
|
||||
) // OEM ID: "SHIPDISK", contains timedate on boot code may not be unique
|
||||
};
|
||||
|
||||
public FileSystemType XmlFsType { get; private set; }
|
||||
|
||||
public Encoding Encoding { get; private set; }
|
||||
public string Name => "Microsoft File Allocation Table";
|
||||
public Guid Id => new Guid("33513B2C-0D26-0D2D-32C3-79D8611158E0");
|
||||
|
||||
public bool Identify(IMediaImage imagePlugin, Partition partition)
|
||||
{
|
||||
if(2 + partition.Start >= partition.End) return false;
|
||||
@@ -188,13 +195,16 @@ namespace DiscImageChef.Filesystems
|
||||
int bitsInBps = CountBits.Count(bps);
|
||||
if(imagePlugin.Info.SectorSize >= 512) bootable = BitConverter.ToUInt16(bpbSector, 0x1FE);
|
||||
|
||||
bool correctSpc = spc == 1 || spc == 2 || spc == 4 || spc == 8 || spc == 16 || spc == 32 || spc == 64;
|
||||
bool correctSpc =
|
||||
spc == 1 || spc == 2 || spc == 4 || spc == 8 || spc == 16 || spc == 32 || spc == 64;
|
||||
string msxString = Encoding.ASCII.GetString(msxId);
|
||||
string fat32String = Encoding.ASCII.GetString(fat32Id);
|
||||
bool atariOemCorrect = atariOem[0] >= 0x20 && atariOem[1] >= 0x20 && atariOem[2] >= 0x20 &&
|
||||
atariOem[3] >= 0x20 && atariOem[4] >= 0x20 && atariOem[5] >= 0x20;
|
||||
bool dosOemCorrect = dosOem[0] >= 0x20 && dosOem[1] >= 0x20 && dosOem[2] >= 0x20 && dosOem[3] >= 0x20 &&
|
||||
dosOem[4] >= 0x20 && dosOem[5] >= 0x20 && dosOem[6] >= 0x20 && dosOem[7] >= 0x20;
|
||||
bool dosOemCorrect = dosOem[0] >= 0x20 && dosOem[1] >= 0x20 && dosOem[2] >= 0x20 &&
|
||||
dosOem[3] >= 0x20 &&
|
||||
dosOem[4] >= 0x20 && dosOem[5] >= 0x20 && dosOem[6] >= 0x20 &&
|
||||
dosOem[7] >= 0x20;
|
||||
string atariString = Encoding.ASCII.GetString(atariOem);
|
||||
string oemString = Encoding.ASCII.GetString(dosOem);
|
||||
|
||||
@@ -226,7 +236,8 @@ namespace DiscImageChef.Filesystems
|
||||
ushort apricotSectors = BitConverter.ToUInt16(bpbSector, 0x58);
|
||||
byte apricotMediaDescriptor = bpbSector[0x5A];
|
||||
ushort apricotFatSectors = BitConverter.ToUInt16(bpbSector, 0x5B);
|
||||
bool apricotCorrectSpc = apricotSpc == 1 || apricotSpc == 2 || apricotSpc == 4 || apricotSpc == 8 ||
|
||||
bool apricotCorrectSpc = apricotSpc == 1 || apricotSpc == 2 || apricotSpc == 4 ||
|
||||
apricotSpc == 8 ||
|
||||
apricotSpc == 16 || apricotSpc == 32 || apricotSpc == 64;
|
||||
int bitsInApricotBps = CountBits.Count(apricotBps);
|
||||
byte apricotPartitions = bpbSector[0x0C];
|
||||
@@ -302,9 +313,12 @@ namespace DiscImageChef.Filesystems
|
||||
}
|
||||
|
||||
// Apricot BPB
|
||||
if(bitsInApricotBps == 1 && apricotCorrectSpc && apricotReservedSecs < partition.End - partition.Start &&
|
||||
apricotFatsNo <= 2 && apricotRootEntries > 0 && apricotFatSectors > 0 &&
|
||||
apricotSectors <= partition.End - partition.Start + 1 && apricotPartitions == 0) return true;
|
||||
if(bitsInApricotBps == 1 && apricotCorrectSpc &&
|
||||
apricotReservedSecs < partition.End - partition.Start &&
|
||||
apricotFatsNo <= 2 &&
|
||||
apricotRootEntries > 0 && apricotFatSectors > 0 &&
|
||||
apricotSectors <= partition.End - partition.Start + 1 &&
|
||||
apricotPartitions == 0) return true;
|
||||
|
||||
// All FAT12 without BPB can only be used on floppies, without partitions.
|
||||
if(partition.Start != 0) return false;
|
||||
@@ -332,7 +346,8 @@ namespace DiscImageChef.Filesystems
|
||||
{
|
||||
for(int c = 0; c < 11; c++)
|
||||
if(rootDir[c + e] < 0x20 && rootDir[c + e] != 0x00 && rootDir[c + e] != 0x05 ||
|
||||
rootDir[c + e] == 0xFF || rootDir[c + e] == 0x2E)
|
||||
rootDir[c + e] == 0xFF ||
|
||||
rootDir[c + e] == 0x2E)
|
||||
{
|
||||
validRootDir = false;
|
||||
break;
|
||||
@@ -361,15 +376,21 @@ namespace DiscImageChef.Filesystems
|
||||
break;
|
||||
case 0xFD:
|
||||
if(imagePlugin.Info.Sectors == 4004 && imagePlugin.Info.SectorSize == 128) fat2SectorNo = 7;
|
||||
else if(imagePlugin.Info.Sectors == 2002 && imagePlugin.Info.SectorSize == 128) fat2SectorNo = 7;
|
||||
else if(imagePlugin.Info.Sectors == 2002 && imagePlugin.Info.SectorSize == 128)
|
||||
fat2SectorNo = 7;
|
||||
break;
|
||||
case 0xFE:
|
||||
if(imagePlugin.Info.Sectors == 320 && imagePlugin.Info.SectorSize == 512) fat2SectorNo = 2;
|
||||
else if(imagePlugin.Info.Sectors == 2002 && imagePlugin.Info.SectorSize == 128) fat2SectorNo = 7;
|
||||
else if(imagePlugin.Info.Sectors == 1232 && imagePlugin.Info.SectorSize == 1024) fat2SectorNo = 3;
|
||||
else if(imagePlugin.Info.Sectors == 616 && imagePlugin.Info.SectorSize == 1024) fat2SectorNo = 2;
|
||||
else if(imagePlugin.Info.Sectors == 720 && imagePlugin.Info.SectorSize == 128) fat2SectorNo = 5;
|
||||
else if(imagePlugin.Info.Sectors == 640 && imagePlugin.Info.SectorSize == 512) fat2SectorNo = 2;
|
||||
else if(imagePlugin.Info.Sectors == 2002 && imagePlugin.Info.SectorSize == 128)
|
||||
fat2SectorNo = 7;
|
||||
else if(imagePlugin.Info.Sectors == 1232 && imagePlugin.Info.SectorSize == 1024)
|
||||
fat2SectorNo = 3;
|
||||
else if(imagePlugin.Info.Sectors == 616 && imagePlugin.Info.SectorSize == 1024)
|
||||
fat2SectorNo = 2;
|
||||
else if(imagePlugin.Info.Sectors == 720 && imagePlugin.Info.SectorSize == 128)
|
||||
fat2SectorNo = 5;
|
||||
else if(imagePlugin.Info.Sectors == 640 && imagePlugin.Info.SectorSize == 512)
|
||||
fat2SectorNo = 2;
|
||||
break;
|
||||
case 0xFF:
|
||||
if(imagePlugin.Info.Sectors == 640 && imagePlugin.Info.SectorSize == 512) fat2SectorNo = 2;
|
||||
@@ -446,7 +467,8 @@ namespace DiscImageChef.Filesystems
|
||||
dos32Bpb = (BiosParameterBlock32)Marshal.PtrToStructure(bpbPtr, typeof(BiosParameterBlock32));
|
||||
dos33Bpb = (BiosParameterBlock33)Marshal.PtrToStructure(bpbPtr, typeof(BiosParameterBlock33));
|
||||
shortEbpb =
|
||||
(BiosParameterBlockShortEbpb)Marshal.PtrToStructure(bpbPtr, typeof(BiosParameterBlockShortEbpb));
|
||||
(BiosParameterBlockShortEbpb)
|
||||
Marshal.PtrToStructure(bpbPtr, typeof(BiosParameterBlockShortEbpb));
|
||||
ebpb = (BiosParameterBlockEbpb)Marshal.PtrToStructure(bpbPtr, typeof(BiosParameterBlockEbpb));
|
||||
shortFat32Bpb =
|
||||
(Fat32ParameterBlockShort)Marshal.PtrToStructure(bpbPtr, typeof(Fat32ParameterBlockShort));
|
||||
@@ -470,9 +492,11 @@ namespace DiscImageChef.Filesystems
|
||||
bool correctSpcAtari = atariBpb.spc == 1 || atariBpb.spc == 2 || atariBpb.spc == 4 ||
|
||||
atariBpb.spc == 8 || atariBpb.spc == 16 || atariBpb.spc == 32 ||
|
||||
atariBpb.spc == 64;
|
||||
bool correctSpcMsx = msxBpb.spc == 1 || msxBpb.spc == 2 || msxBpb.spc == 4 || msxBpb.spc == 8 ||
|
||||
bool correctSpcMsx = msxBpb.spc == 1 || msxBpb.spc == 2 || msxBpb.spc == 4 ||
|
||||
msxBpb.spc == 8 ||
|
||||
msxBpb.spc == 16 || msxBpb.spc == 32 || msxBpb.spc == 64;
|
||||
bool correctSpcDos20 = dos2Bpb.spc == 1 || dos2Bpb.spc == 2 || dos2Bpb.spc == 4 || dos2Bpb.spc == 8 ||
|
||||
bool correctSpcDos20 = dos2Bpb.spc == 1 || dos2Bpb.spc == 2 || dos2Bpb.spc == 4 ||
|
||||
dos2Bpb.spc == 8 ||
|
||||
dos2Bpb.spc == 16 || dos2Bpb.spc == 32 || dos2Bpb.spc == 64;
|
||||
bool correctSpcDos30 = dos30Bpb.spc == 1 || dos30Bpb.spc == 2 || dos30Bpb.spc == 4 ||
|
||||
dos30Bpb.spc == 8 || dos30Bpb.spc == 16 || dos30Bpb.spc == 32 ||
|
||||
@@ -486,7 +510,8 @@ namespace DiscImageChef.Filesystems
|
||||
bool correctSpcDos34 = shortEbpb.spc == 1 || shortEbpb.spc == 2 || shortEbpb.spc == 4 ||
|
||||
shortEbpb.spc == 8 || shortEbpb.spc == 16 || shortEbpb.spc == 32 ||
|
||||
shortEbpb.spc == 64;
|
||||
bool correctSpcDos40 = ebpb.spc == 1 || ebpb.spc == 2 || ebpb.spc == 4 || ebpb.spc == 8 ||
|
||||
bool correctSpcDos40 = ebpb.spc == 1 || ebpb.spc == 2 || ebpb.spc == 4 ||
|
||||
ebpb.spc == 8 ||
|
||||
ebpb.spc == 16 || ebpb.spc == 32 || ebpb.spc == 64;
|
||||
bool correctSpcFat32Short = shortFat32Bpb.spc == 1 || shortFat32Bpb.spc == 2 ||
|
||||
shortFat32Bpb.spc == 4 || shortFat32Bpb.spc == 8 ||
|
||||
@@ -527,7 +552,8 @@ namespace DiscImageChef.Filesystems
|
||||
dos33Bpb.oem_name[4] >= 0x20 && dos33Bpb.oem_name[5] >= 0x20 &&
|
||||
dos33Bpb.oem_name[6] >= 0x20 && dos33Bpb.oem_name[7] >= 0x20;
|
||||
|
||||
if(bitsInBpsFat32 == 1 && correctSpcFat32 && fat32Bpb.fats_no <= 2 && fat32Bpb.sectors == 0 &&
|
||||
if(bitsInBpsFat32 == 1 && correctSpcFat32 && fat32Bpb.fats_no <= 2 &&
|
||||
fat32Bpb.sectors == 0 &&
|
||||
fat32Bpb.spfat == 0 && fat32Bpb.signature == 0x29 &&
|
||||
Encoding.ASCII.GetString(fat32Bpb.fs_type) == "FAT32 ")
|
||||
{
|
||||
@@ -536,7 +562,8 @@ namespace DiscImageChef.Filesystems
|
||||
minBootNearJump = 0x58;
|
||||
}
|
||||
else if(bitsInBpsFat32Short == 1 && correctSpcFat32Short && shortFat32Bpb.fats_no <= 2 &&
|
||||
shortFat32Bpb.sectors == 0 && shortFat32Bpb.spfat == 0 && shortFat32Bpb.signature == 0x28)
|
||||
shortFat32Bpb.sectors == 0 && shortFat32Bpb.spfat == 0 &&
|
||||
shortFat32Bpb.signature == 0x28)
|
||||
{
|
||||
DicConsole.DebugWriteLine("FAT plugin", "Using short FAT32 BPB");
|
||||
useShortFat32 = shortFat32Bpb.big_sectors == 0
|
||||
@@ -544,23 +571,28 @@ namespace DiscImageChef.Filesystems
|
||||
: shortFat32Bpb.big_sectors <= partition.End - partition.Start + 1;
|
||||
minBootNearJump = 0x57;
|
||||
}
|
||||
else if(bitsInBpsMsx == 1 && correctSpcMsx && msxBpb.fats_no <= 2 && msxBpb.root_ent > 0 &&
|
||||
msxBpb.sectors <= partition.End - partition.Start + 1 && msxBpb.spfat > 0 &&
|
||||
else if(bitsInBpsMsx == 1 &&
|
||||
correctSpcMsx && msxBpb.fats_no <= 2 && msxBpb.root_ent > 0 &&
|
||||
msxBpb.sectors <= partition.End - partition.Start + 1 &&
|
||||
msxBpb.spfat > 0 &&
|
||||
Encoding.ASCII.GetString(msxBpb.vol_id) == "VOL_ID")
|
||||
{
|
||||
DicConsole.DebugWriteLine("FAT plugin", "Using MSX BPB");
|
||||
useMsxBpb = true;
|
||||
}
|
||||
else if(bitsInBpsApricot == 1 && correctSpcApricot && apricotBpb.mainBPB.fats_no <= 2 &&
|
||||
else if(bitsInBpsApricot == 1 && correctSpcApricot &&
|
||||
apricotBpb.mainBPB.fats_no <= 2 &&
|
||||
apricotBpb.mainBPB.root_ent > 0 &&
|
||||
apricotBpb.mainBPB.sectors <= partition.End - partition.Start + 1 &&
|
||||
apricotBpb.mainBPB.spfat > 0 && apricotBpb.partitionCount == 0)
|
||||
apricotBpb.mainBPB.spfat > 0 &&
|
||||
apricotBpb.partitionCount == 0)
|
||||
{
|
||||
DicConsole.DebugWriteLine("FAT plugin", "Using Apricot BPB");
|
||||
useApricotBpb = true;
|
||||
}
|
||||
else if(bitsInBpsDos40 == 1 && correctSpcDos40 && ebpb.fats_no <= 2 && ebpb.root_ent > 0 &&
|
||||
ebpb.spfat > 0 && (ebpb.signature == 0x28 || ebpb.signature == 0x29 || andosOemCorrect))
|
||||
ebpb.spfat > 0 && (ebpb.signature == 0x28 || ebpb.signature == 0x29 ||
|
||||
andosOemCorrect))
|
||||
{
|
||||
if(ebpb.sectors == 0)
|
||||
{
|
||||
@@ -592,18 +624,25 @@ namespace DiscImageChef.Filesystems
|
||||
minBootNearJump = 0x29;
|
||||
}
|
||||
}
|
||||
else if(bitsInBpsDos33 == 1 && correctSpcDos33 && dos33Bpb.rsectors < partition.End - partition.Start &&
|
||||
dos33Bpb.fats_no <= 2 && dos33Bpb.root_ent > 0 && dos33Bpb.spfat > 0)
|
||||
if(dos33Bpb.sectors == 0 && dos33Bpb.hsectors <= partition.Start && dos33Bpb.big_sectors > 0 &&
|
||||
else if(bitsInBpsDos33 == 1 && correctSpcDos33 &&
|
||||
dos33Bpb.rsectors < partition.End - partition.Start &&
|
||||
dos33Bpb.fats_no <= 2 &&
|
||||
dos33Bpb.root_ent > 0 &&
|
||||
dos33Bpb.spfat > 0)
|
||||
if(dos33Bpb.sectors == 0 &&
|
||||
dos33Bpb.hsectors <= partition.Start &&
|
||||
dos33Bpb.big_sectors > 0 &&
|
||||
dos33Bpb.big_sectors <= partition.End - partition.Start + 1)
|
||||
{
|
||||
DicConsole.DebugWriteLine("FAT plugin", "Using DOS 3.3 BPB");
|
||||
useDos33Bpb = true;
|
||||
minBootNearJump = 0x22;
|
||||
}
|
||||
else if(dos33Bpb.big_sectors == 0 && dos33Bpb.hsectors <= partition.Start && dos33Bpb.sectors > 0 &&
|
||||
else if(dos33Bpb.big_sectors == 0 && dos33Bpb.hsectors <= partition.Start &&
|
||||
dos33Bpb.sectors > 0 &&
|
||||
dos33Bpb.sectors <= partition.End - partition.Start + 1)
|
||||
if(atariBpb.jump[0] == 0x60 || atariBpb.jump[0] == 0xE9 && atariBpb.jump[1] == 0x00 &&
|
||||
if(atariBpb.jump[0] == 0x60 || atariBpb.jump[0] == 0xE9 &&
|
||||
atariBpb.jump[1] == 0x00 &&
|
||||
Encoding.ASCII.GetString(dos33Bpb.oem_name) != "NEXT ")
|
||||
{
|
||||
DicConsole.DebugWriteLine("FAT plugin", "Using Atari BPB");
|
||||
@@ -624,8 +663,10 @@ namespace DiscImageChef.Filesystems
|
||||
useDos32Bpb = true;
|
||||
minBootNearJump = 0x1E;
|
||||
}
|
||||
else if(dos30Bpb.sptrk > 0 && dos30Bpb.sptrk < 64 && dos30Bpb.heads > 0 && dos30Bpb.heads < 256)
|
||||
if(atariBpb.jump[0] == 0x60 || atariBpb.jump[0] == 0xE9 && atariBpb.jump[1] == 0x00 &&
|
||||
else if(dos30Bpb.sptrk > 0 && dos30Bpb.sptrk < 64 &&
|
||||
dos30Bpb.heads > 0 && dos30Bpb.heads < 256)
|
||||
if(atariBpb.jump[0] == 0x60 || atariBpb.jump[0] == 0xE9 &&
|
||||
atariBpb.jump[1] == 0x00 &&
|
||||
Encoding.ASCII.GetString(dos33Bpb.oem_name) != "NEXT ")
|
||||
{
|
||||
DicConsole.DebugWriteLine("FAT plugin", "Using Atari BPB");
|
||||
@@ -639,7 +680,8 @@ namespace DiscImageChef.Filesystems
|
||||
}
|
||||
else
|
||||
{
|
||||
if(atariBpb.jump[0] == 0x60 || atariBpb.jump[0] == 0xE9 && atariBpb.jump[1] == 0x00 &&
|
||||
if(atariBpb.jump[0] == 0x60 || atariBpb.jump[0] == 0xE9 &&
|
||||
atariBpb.jump[1] == 0x00 &&
|
||||
Encoding.ASCII.GetString(dos33Bpb.oem_name) != "NEXT ")
|
||||
{
|
||||
DicConsole.DebugWriteLine("FAT plugin", "Using Atari BPB");
|
||||
@@ -672,7 +714,8 @@ namespace DiscImageChef.Filesystems
|
||||
|
||||
// DEC Rainbow, lacks a BPB but has a very concrete structure...
|
||||
if(imagePlugin.Info.Sectors == 800 && imagePlugin.Info.SectorSize == 512 && !useAtariBpb && !useMsxBpb &&
|
||||
!useDos2Bpb && !useDos3Bpb && !useDos32Bpb && !useDos33Bpb && !userShortExtendedBpb && !useExtendedBpb &&
|
||||
!useDos2Bpb && !useDos3Bpb && !useDos32Bpb && !useDos33Bpb &&
|
||||
!userShortExtendedBpb && !useExtendedBpb &&
|
||||
!useShortFat32 && !useLongFat32 && !useApricotBpb)
|
||||
{
|
||||
// DEC Rainbow boots up with a Z80, first byte should be DI (disable interrupts)
|
||||
@@ -695,7 +738,8 @@ namespace DiscImageChef.Filesystems
|
||||
{
|
||||
for(int c = 0; c < 11; c++)
|
||||
if(rootDir[c + e] < 0x20 && rootDir[c + e] != 0x00 && rootDir[c + e] != 0x05 ||
|
||||
rootDir[c + e] == 0xFF || rootDir[c + e] == 0x2E)
|
||||
rootDir[c + e] == 0xFF ||
|
||||
rootDir[c + e] == 0x2E)
|
||||
{
|
||||
validRootDir = false;
|
||||
break;
|
||||
@@ -726,7 +770,8 @@ namespace DiscImageChef.Filesystems
|
||||
}
|
||||
}
|
||||
|
||||
if(!useAtariBpb && !useMsxBpb && !useDos2Bpb && !useDos3Bpb && !useDos32Bpb && !useDos33Bpb &&
|
||||
if(!useAtariBpb && !useMsxBpb && !useDos2Bpb && !useDos3Bpb && !useDos32Bpb &&
|
||||
!useDos33Bpb &&
|
||||
!userShortExtendedBpb && !useExtendedBpb && !useShortFat32 && !useLongFat32 && !useApricotBpb &&
|
||||
!useDecRainbowBpb)
|
||||
{
|
||||
@@ -750,6 +795,7 @@ namespace DiscImageChef.Filesystems
|
||||
fakeBpb.hsectors = 0;
|
||||
fakeBpb.spfat = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0xFD:
|
||||
if(imagePlugin.Info.Sectors == 4004 && imagePlugin.Info.SectorSize == 128)
|
||||
@@ -782,6 +828,7 @@ namespace DiscImageChef.Filesystems
|
||||
fakeBpb.hsectors = 0;
|
||||
fakeBpb.spfat = 6;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0xFE:
|
||||
if(imagePlugin.Info.Sectors == 320 && imagePlugin.Info.SectorSize == 512)
|
||||
@@ -873,6 +920,7 @@ namespace DiscImageChef.Filesystems
|
||||
fakeBpb.hsectors = 0;
|
||||
fakeBpb.spfat = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case 0xFF:
|
||||
if(imagePlugin.Info.Sectors == 640 && imagePlugin.Info.SectorSize == 512)
|
||||
@@ -890,12 +938,15 @@ namespace DiscImageChef.Filesystems
|
||||
fakeBpb.hsectors = 0;
|
||||
fakeBpb.spfat = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// This assumes a bootable sector will jump somewhere or disable interrupts in x86 code
|
||||
XmlFsType.Bootable |= bpbSector[0] == 0xFA || (bpbSector[0] == 0xEB && bpbSector[1] <= 0x7F) ||
|
||||
(bpbSector[0] == 0xE9 && BitConverter.ToUInt16(bpbSector, 1) <= 0x1FC);
|
||||
XmlFsType.Bootable |= bpbSector[0] == 0xFA ||
|
||||
bpbSector[0] == 0xEB && bpbSector[1] <= 0x7F ||
|
||||
bpbSector[0] == 0xE9 &&
|
||||
BitConverter.ToUInt16(bpbSector, 1) <= 0x1FC;
|
||||
fakeBpb.boot_code = bpbSector;
|
||||
}
|
||||
else if(useShortFat32 || useLongFat32)
|
||||
@@ -926,7 +977,8 @@ namespace DiscImageChef.Filesystems
|
||||
if(fat32Bpb.oem_name != null)
|
||||
if(fat32Bpb.oem_name[5] == 0x49 && fat32Bpb.oem_name[6] == 0x48 && fat32Bpb.oem_name[7] == 0x43)
|
||||
sb.AppendLine("Volume has been modified by Windows 9x/Me Volume Tracker.");
|
||||
else XmlFsType.SystemIdentifier = StringHandlers.CToString(fat32Bpb.oem_name);
|
||||
else
|
||||
XmlFsType.SystemIdentifier = StringHandlers.CToString(fat32Bpb.oem_name);
|
||||
|
||||
if(!string.IsNullOrEmpty(XmlFsType.SystemIdentifier))
|
||||
sb.AppendFormat("OEM Name: {0}", XmlFsType.SystemIdentifier.Trim()).AppendLine();
|
||||
@@ -946,6 +998,7 @@ namespace DiscImageChef.Filesystems
|
||||
fat32Bpb.big_sectors * fat32Bpb.bps).AppendLine();
|
||||
XmlFsType.Clusters = fat32Bpb.big_sectors / fat32Bpb.spc;
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0} clusters on volume.", XmlFsType.Clusters).AppendLine();
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", fat32Bpb.media).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per FAT.", fat32Bpb.big_spfat).AppendLine();
|
||||
@@ -966,6 +1019,7 @@ namespace DiscImageChef.Filesystems
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
XmlFsType.Dirty = true;
|
||||
}
|
||||
|
||||
if((fat32Bpb.flags & 0x02) == 0x02) sb.AppendLine("Disk surface should be on next mount.");
|
||||
}
|
||||
|
||||
@@ -974,7 +1028,8 @@ namespace DiscImageChef.Filesystems
|
||||
.AppendLine();
|
||||
else sb.AppendLine("All copies of FAT are the same.");
|
||||
|
||||
if((fat32Bpb.mirror_flags & 0x6F20) == 0x6F20) sb.AppendLine("DR-DOS will boot this FAT32 using CHS.");
|
||||
if((fat32Bpb.mirror_flags & 0x6F20) == 0x6F20)
|
||||
sb.AppendLine("DR-DOS will boot this FAT32 using CHS.");
|
||||
else if((fat32Bpb.mirror_flags & 0x4F20) == 0x4F20)
|
||||
sb.AppendLine("DR-DOS will boot this FAT32 using LBA.");
|
||||
|
||||
@@ -988,8 +1043,13 @@ namespace DiscImageChef.Filesystems
|
||||
|
||||
// Check that jumps to a correct boot code position and has boot signature set.
|
||||
// This will mean that the volume will boot, even if just to say "this is not bootable change disk"......
|
||||
XmlFsType.Bootable |= ((fat32Bpb.jump[0] == 0xEB && fat32Bpb.jump[1] >= minBootNearJump && fat32Bpb.jump[1] < 0x80) ||
|
||||
(fat32Bpb.jump[0] == 0xE9 && fat32Bpb.jump.Length >= 3 && BitConverter.ToUInt16(fat32Bpb.jump, 1) >= minBootNearJump && BitConverter.ToUInt16(fat32Bpb.jump, 1) <= 0x1FC));
|
||||
XmlFsType.Bootable |=
|
||||
fat32Bpb.jump[0] == 0xEB &&
|
||||
fat32Bpb.jump[1] >= minBootNearJump && fat32Bpb.jump[1] < 0x80 ||
|
||||
fat32Bpb.jump[0] == 0xE9 &&
|
||||
fat32Bpb.jump.Length >= 3 &&
|
||||
BitConverter.ToUInt16(fat32Bpb.jump, 1) >= minBootNearJump &&
|
||||
BitConverter.ToUInt16(fat32Bpb.jump, 1) <= 0x1FC;
|
||||
|
||||
sectorsPerRealSector = fat32Bpb.bps / imagePlugin.Info.SectorSize;
|
||||
// First root directory sector
|
||||
@@ -1021,7 +1081,8 @@ namespace DiscImageChef.Filesystems
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(useExtendedBpb) fakeBpb = ebpb;
|
||||
else if(useExtendedBpb)
|
||||
fakeBpb = ebpb;
|
||||
else if(userShortExtendedBpb)
|
||||
{
|
||||
fakeBpb.jump = shortEbpb.jump;
|
||||
@@ -1246,8 +1307,10 @@ namespace DiscImageChef.Filesystems
|
||||
if(isFat12)
|
||||
{
|
||||
if(useAtariBpb) sb.AppendLine("Atari FAT12");
|
||||
else if(useApricotBpb) sb.AppendLine("Apricot FAT12");
|
||||
else sb.AppendLine("Microsoft FAT12");
|
||||
else if(useApricotBpb)
|
||||
sb.AppendLine("Apricot FAT12");
|
||||
else
|
||||
sb.AppendLine("Microsoft FAT12");
|
||||
XmlFsType.Type = "FAT12";
|
||||
}
|
||||
else if(isFat16)
|
||||
@@ -1264,7 +1327,8 @@ namespace DiscImageChef.Filesystems
|
||||
XmlFsType.VolumeSerial =
|
||||
$"{atariBpb.serial_no[0]:X2}{atariBpb.serial_no[1]:X2}{atariBpb.serial_no[2]:X2}";
|
||||
|
||||
XmlFsType.SystemIdentifier = StringHandlers.CToString(atariBpb.oem_name);
|
||||
XmlFsType.SystemIdentifier =
|
||||
StringHandlers.CToString(atariBpb.oem_name);
|
||||
if(string.IsNullOrEmpty(XmlFsType.SystemIdentifier)) XmlFsType.SystemIdentifier = null;
|
||||
}
|
||||
else if(fakeBpb.oem_name != null)
|
||||
@@ -1304,15 +1368,18 @@ namespace DiscImageChef.Filesystems
|
||||
if(fakeBpb.sectors == 0)
|
||||
{
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes).", fakeBpb.big_sectors,
|
||||
fakeBpb.big_sectors * fakeBpb.bps).AppendLine();
|
||||
fakeBpb.big_sectors * fakeBpb.bps)
|
||||
.AppendLine();
|
||||
XmlFsType.Clusters = fakeBpb.spc == 0 ? fakeBpb.big_sectors : fakeBpb.big_sectors / fakeBpb.spc;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes).", fakeBpb.sectors,
|
||||
fakeBpb.sectors * fakeBpb.bps).AppendLine();
|
||||
fakeBpb.sectors * fakeBpb.bps)
|
||||
.AppendLine();
|
||||
XmlFsType.Clusters = fakeBpb.spc == 0 ? fakeBpb.sectors : fakeBpb.sectors / fakeBpb.spc;
|
||||
}
|
||||
|
||||
sb.AppendFormat("{0} sectors per cluster.", fakeBpb.spc).AppendLine();
|
||||
sb.AppendFormat("{0} clusters on volume.", XmlFsType.Clusters).AppendLine();
|
||||
XmlFsType.ClusterSize = fakeBpb.bps * fakeBpb.spc;
|
||||
@@ -1329,6 +1396,7 @@ namespace DiscImageChef.Filesystems
|
||||
sb.AppendFormat("{0} sectors per track.", fakeBpb.sptrk).AppendLine();
|
||||
sb.AppendFormat("{0} heads.", fakeBpb.heads).AppendLine();
|
||||
}
|
||||
|
||||
if(fakeBpb.hsectors <= partition.Start)
|
||||
sb.AppendFormat("{0} hidden sectors before BPB.", fakeBpb.hsectors).AppendLine();
|
||||
|
||||
@@ -1346,6 +1414,7 @@ namespace DiscImageChef.Filesystems
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
XmlFsType.Dirty = true;
|
||||
}
|
||||
|
||||
if((fakeBpb.flags & 0x02) == 0x02) sb.AppendLine("Disk surface should be on next mount.");
|
||||
}
|
||||
|
||||
@@ -1366,14 +1435,21 @@ namespace DiscImageChef.Filesystems
|
||||
// Check that jumps to a correct boot code position and has boot signature set.
|
||||
// This will mean that the volume will boot, even if just to say "this is not bootable change disk"......
|
||||
if(XmlFsType.Bootable == false && fakeBpb.jump != null)
|
||||
XmlFsType.Bootable |= (fakeBpb.jump[0] == 0xEB && fakeBpb.jump[1] >= minBootNearJump && fakeBpb.jump[1] < 0x80) ||
|
||||
(fakeBpb.jump[0] == 0xE9 && fakeBpb.jump.Length >= 3 && BitConverter.ToUInt16(fakeBpb.jump, 1) >= minBootNearJump && BitConverter.ToUInt16(fakeBpb.jump, 1) <= 0x1FC);
|
||||
XmlFsType.Bootable |=
|
||||
fakeBpb.jump[0] == 0xEB &&
|
||||
fakeBpb.jump[1] >= minBootNearJump && fakeBpb.jump[1] < 0x80 ||
|
||||
fakeBpb.jump[0] == 0xE9 &&
|
||||
fakeBpb.jump.Length >= 3 &&
|
||||
BitConverter.ToUInt16(fakeBpb.jump, 1) >= minBootNearJump &&
|
||||
BitConverter.ToUInt16(fakeBpb.jump, 1) <= 0x1FC;
|
||||
|
||||
sectorsPerRealSector = fakeBpb.bps / imagePlugin.Info.SectorSize;
|
||||
// First root directory sector
|
||||
rootDirectorySector =
|
||||
(ulong)(fakeBpb.spfat * fakeBpb.fats_no + fakeBpb.rsectors) * sectorsPerRealSector;
|
||||
sectorsForRootDirectory = (uint)(fakeBpb.root_ent * 32 / imagePlugin.Info.SectorSize);
|
||||
(ulong)(fakeBpb.spfat * fakeBpb.fats_no + fakeBpb.rsectors) *
|
||||
sectorsPerRealSector;
|
||||
sectorsForRootDirectory =
|
||||
(uint)(fakeBpb.root_ent * 32 / imagePlugin.Info.SectorSize);
|
||||
}
|
||||
|
||||
if(extraInfo != null) sb.Append(extraInfo);
|
||||
@@ -1460,18 +1536,19 @@ namespace DiscImageChef.Filesystems
|
||||
{
|
||||
int sigSize = bpbSector[510] == 0x55 && bpbSector[511] == 0xAA ? 2 : 0;
|
||||
byte[] bootCode = new byte[512 - sigSize - BitConverter.ToUInt16(bpbSector, 1) - 3];
|
||||
Array.Copy(bpbSector, BitConverter.ToUInt16(bpbSector, 1) + 3, bootCode, 0, bootCode.Length);
|
||||
Array.Copy(bpbSector, BitConverter.ToUInt16(bpbSector, 1) + 3, bootCode, 0,
|
||||
bootCode.Length);
|
||||
sha1Ctx = new Sha1Context();
|
||||
sha1Ctx.Init();
|
||||
sha1Ctx.Update(bootCode);
|
||||
bootChk = sha1Ctx.End();
|
||||
}
|
||||
|
||||
sb.AppendLine("Volume is bootable");
|
||||
sb.AppendFormat("Boot code's SHA1: {0}", bootChk).AppendLine();
|
||||
string bootName = knownBootHashes.FirstOrDefault(t => t.hash == bootChk).name;
|
||||
if(string.IsNullOrWhiteSpace(bootName)) sb.AppendLine("Unknown boot code.");
|
||||
else
|
||||
sb.AppendFormat("Boot code corresponds to {0}", bootName).AppendLine();
|
||||
else sb.AppendFormat("Boot code corresponds to {0}", bootName).AppendLine();
|
||||
}
|
||||
|
||||
information = sb.ToString();
|
||||
@@ -1484,11 +1561,14 @@ namespace DiscImageChef.Filesystems
|
||||
struct AtariParameterBlock
|
||||
{
|
||||
/// <summary>68000 BRA.S jump or x86 loop</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 6 bytes, space-padded, "Loader" for Atari ST boot loader</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Volume serial number</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] serial_no;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] serial_no;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1531,11 +1611,13 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Unknown.</summary>
|
||||
public ushort unknown;
|
||||
/// <summary>Filename to be loaded for booting.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] fname;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
|
||||
public byte[] fname;
|
||||
/// <summary>Reserved</summary>
|
||||
public ushort reserved;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 455)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 455)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Big endian word to make big endian sum of all sector words be equal to 0x1234 if disk is bootable.</summary>
|
||||
public ushort checksum;
|
||||
}
|
||||
@@ -1547,9 +1629,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct MsxParameterBlock
|
||||
{
|
||||
/// <summary>x86 loop</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1575,17 +1659,20 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Jump for MSX-DOS 1 boot code</summary>
|
||||
public ushort msxdos_jmp;
|
||||
/// <summary>Set to "VOL_ID" by MSX-DOS 2</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] vol_id;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
|
||||
public byte[] vol_id;
|
||||
/// <summary>Bigger than 0 if there are deleted files (MSX-DOS 2)</summary>
|
||||
public byte undelete_flag;
|
||||
/// <summary>Volume serial number (MSX-DOS 2)</summary>
|
||||
public uint serial_no;
|
||||
/// <summary>Reserved (MSX-DOS 2)</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
public byte[] reserved;
|
||||
/// <summary>Jump for MSX-DOS 2 boot code (MSX-DOS 2)</summary>
|
||||
public ushort msxdos2_jmp;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 460)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 460)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Always 0x55 0xAA.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1595,9 +1682,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct BiosParameterBlock2
|
||||
{
|
||||
/// <summary>x86 jump</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1615,7 +1704,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Sectors per FAT</summary>
|
||||
public ushort spfat;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 486)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 486)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>0x55 0xAA if bootable.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1625,9 +1715,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct BiosParameterBlock30
|
||||
{
|
||||
/// <summary>x86 jump</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1651,7 +1743,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Hidden sectors before BPB</summary>
|
||||
public ushort hsectors;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 480)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 480)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Always 0x55 0xAA.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1661,9 +1754,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct BiosParameterBlock32
|
||||
{
|
||||
/// <summary>x86 jump</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1689,7 +1784,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Total sectors including hidden ones</summary>
|
||||
public ushort total_sectors;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 478)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 478)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Always 0x55 0xAA.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1699,9 +1795,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct BiosParameterBlock33
|
||||
{
|
||||
/// <summary>x86 jump</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1727,7 +1825,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Sectors in volume if > 65535</summary>
|
||||
public uint big_sectors;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 474)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 474)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Always 0x55 0xAA.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1737,9 +1836,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct BiosParameterBlockShortEbpb
|
||||
{
|
||||
/// <summary>x86 jump</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1773,7 +1874,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Volume serial number</summary>
|
||||
public uint serial_no;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 467)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 467)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Always 0x55 0xAA.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1783,9 +1885,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct BiosParameterBlockEbpb
|
||||
{
|
||||
/// <summary>x86 jump</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1819,11 +1923,14 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Volume serial number</summary>
|
||||
public uint serial_no;
|
||||
/// <summary>Volume label, 11 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] volume_label;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
|
||||
public byte[] volume_label;
|
||||
/// <summary>Filesystem type, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] fs_type;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] fs_type;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 448)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 448)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Always 0x55 0xAA.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1833,9 +1940,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct Fat32ParameterBlockShort
|
||||
{
|
||||
/// <summary>x86 jump</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1873,7 +1982,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Sector of FAT32PB backup</summary>
|
||||
public ushort backup_sector;
|
||||
/// <summary>Reserved</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] reserved;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||
public byte[] reserved;
|
||||
/// <summary>Drive number</summary>
|
||||
public byte drive_no;
|
||||
/// <summary>Volume flags</summary>
|
||||
@@ -1883,11 +1993,13 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Volume serial number</summary>
|
||||
public uint serial_no;
|
||||
/// <summary>Volume label, 11 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] reserved2;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
|
||||
public byte[] reserved2;
|
||||
/// <summary>Sectors in volume if <see cref="big_sectors" /> equals 0</summary>
|
||||
public ulong huge_sectors;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 420)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 420)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Always 0x55 0xAA.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1897,9 +2009,11 @@ namespace DiscImageChef.Filesystems
|
||||
struct Fat32ParameterBlock
|
||||
{
|
||||
/// <summary>x86 jump</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] jump;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] jump;
|
||||
/// <summary>OEM Name, 8 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] oem_name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] oem_name;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public ushort bps;
|
||||
/// <summary>Sectors per cluster</summary>
|
||||
@@ -1937,7 +2051,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Sector of FAT32PB backup</summary>
|
||||
public ushort backup_sector;
|
||||
/// <summary>Reserved</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] reserved;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||
public byte[] reserved;
|
||||
/// <summary>Drive number</summary>
|
||||
public byte drive_no;
|
||||
/// <summary>Volume flags</summary>
|
||||
@@ -1947,11 +2062,14 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Volume serial number</summary>
|
||||
public uint serial_no;
|
||||
/// <summary>Volume label, 11 bytes, space-padded</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] volume_label;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
|
||||
public byte[] volume_label;
|
||||
/// <summary>Filesystem type, 8 bytes, space-padded, must be "FAT32 "</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] fs_type;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] fs_type;
|
||||
/// <summary>Boot code.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 419)] public byte[] boot_code;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 419)]
|
||||
public byte[] boot_code;
|
||||
/// <summary>Always 0x55 0xAA.</summary>
|
||||
public ushort boot_signature;
|
||||
}
|
||||
@@ -1961,7 +2079,8 @@ namespace DiscImageChef.Filesystems
|
||||
struct ApricotLabel
|
||||
{
|
||||
/// <summary>Version of format which created disk</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] version;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] version;
|
||||
/// <summary>Operating system.</summary>
|
||||
public byte operatingSystem;
|
||||
/// <summary>Software write protection.</summary>
|
||||
@@ -2005,17 +2124,22 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Maximum number of copies.</summary>
|
||||
public ushort maxCopies;
|
||||
/// <summary>Serial number.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] serialNumber;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] serialNumber;
|
||||
/// <summary>Part number.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] partNumber;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] partNumber;
|
||||
/// <summary>Copyright.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public byte[] copyright;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
|
||||
public byte[] copyright;
|
||||
/// <summary>BPB for whole disk.</summary>
|
||||
public ApricotParameterBlock mainBPB;
|
||||
/// <summary>Name of FONT file.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] fontName;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public byte[] fontName;
|
||||
/// <summary>Name of KEYBOARD file.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] keyboardName;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public byte[] keyboardName;
|
||||
/// <summary>Minor BIOS version.</summary>
|
||||
public byte biosMinorVersion;
|
||||
/// <summary>Major BIOS version.</summary>
|
||||
@@ -2053,7 +2177,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Microscreen mode.</summary>
|
||||
public byte microscreenMode;
|
||||
/// <summary>Spare area for keyboard values expansion.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] spareKeyboard;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
|
||||
public byte[] spareKeyboard;
|
||||
/// <summary>Screen line mode.</summary>
|
||||
public byte lineMode;
|
||||
/// <summary>Screen line width.</summary>
|
||||
@@ -2061,7 +2186,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Screen disabled?.</summary>
|
||||
[MarshalAs(UnmanagedType.U1)] public bool imageOff;
|
||||
/// <summary>Spare area for screen values expansion.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] public byte[] spareScreen;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
|
||||
public byte[] spareScreen;
|
||||
/// <summary>TX baud rate.</summary>
|
||||
public byte txBaudRate;
|
||||
/// <summary>RX baud rate.</summary>
|
||||
@@ -2099,7 +2225,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>BIOS error report in serial port.</summary>
|
||||
[MarshalAs(UnmanagedType.U1)] public bool biosErrorReportSerial;
|
||||
/// <summary>Spare area for serial port values expansion.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] public byte[] spareSerial;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
|
||||
public byte[] spareSerial;
|
||||
/// <summary>Send LF after CR in parallel port.</summary>
|
||||
[MarshalAs(UnmanagedType.U1)] public bool lfAfterCrParallel;
|
||||
/// <summary>Select line supported?.</summary>
|
||||
@@ -2111,21 +2238,27 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>BIOS error report in parallel port.</summary>
|
||||
[MarshalAs(UnmanagedType.U1)] public bool biosErrorReportParallel;
|
||||
/// <summary>Spare area for parallel port values expansion.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] spareParallel;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
|
||||
public byte[] spareParallel;
|
||||
/// <summary>Spare area for Winchester values expansion.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public byte[] spareWinchester;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
|
||||
public byte[] spareWinchester;
|
||||
/// <summary>Parking enabled?.</summary>
|
||||
[MarshalAs(UnmanagedType.U1)] public bool parkingEnabled;
|
||||
/// <summary>Format protection?.</summary>
|
||||
[MarshalAs(UnmanagedType.U1)] public bool formatProtection;
|
||||
/// <summary>Spare area for RAM disk values expansion.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] spareRamDisk;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public byte[] spareRamDisk;
|
||||
/// <summary>List of bad blocks.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public ushort[] badBlocks;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public ushort[] badBlocks;
|
||||
/// <summary>Array of partition BPBs.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public ApricotParameterBlock[] partitions;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public ApricotParameterBlock[] partitions;
|
||||
/// <summary>Spare area.</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 63)] public byte[] spare;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 63)]
|
||||
public byte[] spare;
|
||||
/// <summary>CP/M double side indicator?.</summary>
|
||||
public bool cpmDoubleSided;
|
||||
}
|
||||
@@ -2162,7 +2295,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary>Signature must be <see cref="FAT.FSINFO_SIGNATURE1" /></summary>
|
||||
public uint signature1;
|
||||
/// <summary>Reserved</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 480)] public byte[] reserved1;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 480)]
|
||||
public byte[] reserved1;
|
||||
/// <summary>Signature must be <see cref="FAT.FSINFO_SIGNATURE2" /></summary>
|
||||
public uint signature2;
|
||||
/// <summary>Free clusters</summary>
|
||||
@@ -2170,7 +2304,8 @@ namespace DiscImageChef.Filesystems
|
||||
/// <summary> cated cluster</summary>
|
||||
public uint last_cluster;
|
||||
/// <summary>Reserved</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] reserved2;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||
public byte[] reserved2;
|
||||
/// <summary>Signature must be <see cref="FAT.FSINFO_SIGNATURE3" /></summary>
|
||||
public uint signature3;
|
||||
}
|
||||
@@ -2192,8 +2327,10 @@ namespace DiscImageChef.Filesystems
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct DirectoryEntry
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] filename;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] extension;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] filename;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] extension;
|
||||
public FatAttributes attributes;
|
||||
public byte caseinfo;
|
||||
public byte ctime_ms;
|
||||
|
||||
Reference in New Issue
Block a user