mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Reformatted.
This commit is contained in:
@@ -85,12 +85,12 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if (partitionStart >= imagePlugin.GetSectors())
|
||||
if(partitionStart >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
ulong sbSector;
|
||||
|
||||
if (imagePlugin.GetSectorSize() > ADFS_SB_POS)
|
||||
if(imagePlugin.GetSectorSize() > ADFS_SB_POS)
|
||||
sbSector = 0;
|
||||
else
|
||||
sbSector = ADFS_SB_POS / imagePlugin.GetSectorSize();
|
||||
@@ -109,24 +109,24 @@ namespace DiscImageChef.Plugins
|
||||
return false;
|
||||
}
|
||||
|
||||
if (drSb.log2secsize < 8 || drSb.log2secsize > 10)
|
||||
if(drSb.log2secsize < 8 || drSb.log2secsize > 10)
|
||||
return false;
|
||||
|
||||
if (drSb.idlen < (drSb.log2secsize + 3) || drSb.idlen > 19)
|
||||
if(drSb.idlen < (drSb.log2secsize + 3) || drSb.idlen > 19)
|
||||
return false;
|
||||
|
||||
if ((drSb.disc_size_high >> drSb.log2secsize) != 0)
|
||||
if((drSb.disc_size_high >> drSb.log2secsize) != 0)
|
||||
return false;
|
||||
|
||||
if (!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved))
|
||||
if(!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved))
|
||||
return false;
|
||||
|
||||
ulong bytes = drSb.disc_size_high;
|
||||
bytes *= 0x100000000;
|
||||
bytes += drSb.disc_size;
|
||||
|
||||
if (bytes > (imagePlugin.GetSectors() * (ulong)imagePlugin.GetSectorSize()))
|
||||
return false;
|
||||
if(bytes > (imagePlugin.GetSectors() * (ulong)imagePlugin.GetSectorSize()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -138,7 +138,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
ulong sbSector;
|
||||
|
||||
if (imagePlugin.GetSectorSize() > ADFS_SB_POS)
|
||||
if(imagePlugin.GetSectorSize() > ADFS_SB_POS)
|
||||
sbSector = 0;
|
||||
else
|
||||
sbSector = ADFS_SB_POS / imagePlugin.GetSectorSize();
|
||||
@@ -171,16 +171,16 @@ namespace DiscImageChef.Plugins
|
||||
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.format_version = {0}", drSb.format_version);
|
||||
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root_size = {0}", drSb.root_size);
|
||||
|
||||
if (drSb.log2secsize < 8 || drSb.log2secsize > 10)
|
||||
if(drSb.log2secsize < 8 || drSb.log2secsize > 10)
|
||||
return;
|
||||
|
||||
if (drSb.idlen < (drSb.log2secsize + 3) || drSb.idlen > 19)
|
||||
if(drSb.idlen < (drSb.log2secsize + 3) || drSb.idlen > 19)
|
||||
return;
|
||||
|
||||
if ((drSb.disc_size_high >> drSb.log2secsize) != 0)
|
||||
if((drSb.disc_size_high >> drSb.log2secsize) != 0)
|
||||
return;
|
||||
|
||||
if (!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved))
|
||||
if(!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved))
|
||||
return;
|
||||
|
||||
ulong bytes = drSb.disc_size_high;
|
||||
@@ -191,7 +191,7 @@ namespace DiscImageChef.Plugins
|
||||
zones *= 0x100000000;
|
||||
zones += drSb.nzones;
|
||||
|
||||
if (bytes > (imagePlugin.GetSectors() * (ulong)imagePlugin.GetSectorSize()))
|
||||
if(bytes > (imagePlugin.GetSectors() * (ulong)imagePlugin.GetSectorSize()))
|
||||
return;
|
||||
|
||||
string discname = StringHandlers.CToString(drSb.disc_name);
|
||||
|
||||
@@ -186,7 +186,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if (partitionStart >= imagePlugin.GetSectors())
|
||||
if(partitionStart >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||
@@ -195,7 +195,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
UInt32 magic = BigEndianBitConverter.ToUInt32(sector, 0x00);
|
||||
|
||||
if ((magic & 0x6D754600) != 0x6D754600 &&
|
||||
if((magic & 0x6D754600) != 0x6D754600 &&
|
||||
(magic & 0x444F5300) != 0x444F5300)
|
||||
return false;
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
DicConsole.DebugWriteLine("AmigaDOS plugin", "Nonetheless, going to block {0} for Rootblock", root_ptr);
|
||||
|
||||
if (root_ptr >= imagePlugin.GetSectors())
|
||||
if(root_ptr >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
sector = imagePlugin.ReadSector(root_ptr);
|
||||
@@ -214,7 +214,7 @@ namespace DiscImageChef.Plugins
|
||||
UInt32 type = BigEndianBitConverter.ToUInt32(sector, 0x00);
|
||||
UInt32 hashTableSize = BigEndianBitConverter.ToUInt32(sector, 0x0C);
|
||||
|
||||
if ((0x18 + hashTableSize * 4 + 196) > sector.Length)
|
||||
if((0x18 + hashTableSize * 4 + 196) > sector.Length)
|
||||
return false;
|
||||
|
||||
UInt32 sec_type = BigEndianBitConverter.ToUInt32(sector, (int)(0x18 + hashTableSize * 4 + 196));
|
||||
@@ -257,13 +257,13 @@ namespace DiscImageChef.Plugins
|
||||
rootBlk.checksum = BigEndianBitConverter.ToUInt32(RootBlockSector, 0x14);
|
||||
rootBlk.hashTable = new uint[rootBlk.hashTableSize];
|
||||
|
||||
for (int i = 0; i < rootBlk.hashTableSize; i++)
|
||||
for(int i = 0; i < rootBlk.hashTableSize; i++)
|
||||
rootBlk.hashTable[i] = BigEndianBitConverter.ToUInt32(RootBlockSector, 0x18 + i * 4);
|
||||
|
||||
rootBlk.bitmapFlag = BigEndianBitConverter.ToUInt32(RootBlockSector, (int)(0x18 + rootBlk.hashTableSize * 4 + 0));
|
||||
rootBlk.bitmapPages = new uint[25];
|
||||
|
||||
for (int i = 0; i < 25; i++)
|
||||
for(int i = 0; i < 25; i++)
|
||||
rootBlk.bitmapPages[i] = BigEndianBitConverter.ToUInt32(RootBlockSector, (int)(0x18 + rootBlk.hashTableSize * 4 + 4 + i * 4));
|
||||
|
||||
rootBlk.bitmapExtensionBlock = BigEndianBitConverter.ToUInt32(RootBlockSector, (int)(0x18 + rootBlk.hashTableSize * 4 + 104));
|
||||
@@ -290,7 +290,7 @@ namespace DiscImageChef.Plugins
|
||||
DicConsole.DebugWriteLine("AmigaDOS plugin", "Stored root block checksum is 0x{0:X8}", rootBlk.checksum);
|
||||
DicConsole.DebugWriteLine("AmigaDOS plugin", "Probably incorrect calculated root block checksum is 0x{0:X8}", AmigaChecksum(RootBlockSector));
|
||||
|
||||
switch (bootBlk.diskType & 0xFF)
|
||||
switch(bootBlk.diskType & 0xFF)
|
||||
{
|
||||
case 0:
|
||||
sbInformation.Append("Amiga Original File System");
|
||||
@@ -326,12 +326,12 @@ namespace DiscImageChef.Plugins
|
||||
break;
|
||||
}
|
||||
|
||||
if ((bootBlk.diskType & 0x6D754600) == 0x6D754600)
|
||||
if((bootBlk.diskType & 0x6D754600) == 0x6D754600)
|
||||
sbInformation.Append(", with multi-user patches");
|
||||
|
||||
sbInformation.AppendLine();
|
||||
|
||||
if ((bootBlk.diskType & 0xFF) == 6 || (bootBlk.diskType & 0xFF) == 7)
|
||||
if((bootBlk.diskType & 0xFF) == 6 || (bootBlk.diskType & 0xFF) == 7)
|
||||
{
|
||||
sbInformation.AppendLine("AFFS v2, following information may be completely incorrect or garbage.");
|
||||
xmlFSType.Type = "Amiga FFS2";
|
||||
@@ -339,13 +339,13 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
sbInformation.AppendFormat("Volume name: {0}", rootBlk.diskName).AppendLine();
|
||||
|
||||
if (rootBlk.bitmapFlag == 0xFFFFFFFF)
|
||||
if(rootBlk.bitmapFlag == 0xFFFFFFFF)
|
||||
sbInformation.AppendLine("Volume bitmap is valid");
|
||||
|
||||
if (rootBlk.bitmapExtensionBlock != 0x00000000 && rootBlk.bitmapExtensionBlock != 0xFFFFFFFF)
|
||||
if(rootBlk.bitmapExtensionBlock != 0x00000000 && rootBlk.bitmapExtensionBlock != 0xFFFFFFFF)
|
||||
sbInformation.AppendFormat("Bitmap extension at block {0}", rootBlk.bitmapExtensionBlock).AppendLine();
|
||||
|
||||
if ((bootBlk.diskType & 0xFF) == 4 || (bootBlk.diskType & 0xFF) == 5)
|
||||
if((bootBlk.diskType & 0xFF) == 4 || (bootBlk.diskType & 0xFF) == 5)
|
||||
sbInformation.AppendFormat("Directory cache starts at block {0}", rootBlk.extension).AppendLine();
|
||||
|
||||
sbInformation.AppendFormat("Volume created on {0}", DateHandlers.AmigaToDateTime(rootBlk.cDays, rootBlk.cMins, rootBlk.cTicks)).AppendLine();
|
||||
@@ -368,7 +368,7 @@ namespace DiscImageChef.Plugins
|
||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||
UInt32 sum = 0;
|
||||
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
for(int i = 0; i < data.Length; i += 4)
|
||||
sum += BigEndianBitConverter.ToUInt32(data, i);
|
||||
|
||||
return sum;
|
||||
|
||||
@@ -70,18 +70,18 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte[] mdb_sector;
|
||||
UInt16 drSigWord;
|
||||
|
||||
if (imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448 || imagePlugin.GetSectorSize() == 2048)
|
||||
if(imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448 || imagePlugin.GetSectorSize() == 2048)
|
||||
{
|
||||
mdb_sector = imagePlugin.ReadSector(2 + partitionStart);
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
||||
|
||||
if (drSigWord == HFS_MAGIC)
|
||||
if(drSigWord == HFS_MAGIC)
|
||||
{
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x7C); // Seek to embedded HFS+ signature
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace DiscImageChef.Plugins
|
||||
mdb_sector = Read2048SectorAs512(imagePlugin, 2 + partitionStart);
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
||||
|
||||
if (drSigWord == HFS_MAGIC)
|
||||
if(drSigWord == HFS_MAGIC)
|
||||
{
|
||||
DicConsole.DebugWriteLine("HFS plugin", "HFS sector size is 512 bytes, but device's 2048");
|
||||
|
||||
@@ -104,10 +104,10 @@ namespace DiscImageChef.Plugins
|
||||
mdb_sector = imagePlugin.ReadSector(2 + partitionStart);
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
||||
|
||||
if (drSigWord == HFS_MAGIC)
|
||||
if(drSigWord == HFS_MAGIC)
|
||||
{
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x7C); // Seek to embedded HFS+ signature
|
||||
|
||||
|
||||
return drSigWord != HFSP_MAGIC;
|
||||
}
|
||||
}
|
||||
@@ -117,9 +117,9 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
HFS_MasterDirectoryBlock MDB = new HFS_MasterDirectoryBlock();
|
||||
HFS_BootBlock BB = new HFS_BootBlock();
|
||||
|
||||
@@ -131,12 +131,12 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
bool APMFromHDDOnCD = false;
|
||||
|
||||
if (imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448 || imagePlugin.GetSectorSize() == 2048)
|
||||
if(imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448 || imagePlugin.GetSectorSize() == 2048)
|
||||
{
|
||||
mdb_sector = imagePlugin.ReadSector(2 + partitionStart);
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
||||
|
||||
if (drSigWord == HFS_MAGIC)
|
||||
if(drSigWord == HFS_MAGIC)
|
||||
{
|
||||
bb_sector = imagePlugin.ReadSector(partitionStart);
|
||||
}
|
||||
@@ -145,7 +145,7 @@ namespace DiscImageChef.Plugins
|
||||
mdb_sector = Read2048SectorAs512(imagePlugin, 2 + partitionStart);
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
||||
|
||||
if (drSigWord == HFS_MAGIC)
|
||||
if(drSigWord == HFS_MAGIC)
|
||||
{
|
||||
bb_sector = Read2048SectorAs512(imagePlugin, partitionStart);
|
||||
APMFromHDDOnCD = true;
|
||||
@@ -159,16 +159,16 @@ namespace DiscImageChef.Plugins
|
||||
mdb_sector = imagePlugin.ReadSector(2 + partitionStart);
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
||||
|
||||
if (drSigWord == HFS_MAGIC)
|
||||
if(drSigWord == HFS_MAGIC)
|
||||
bb_sector = imagePlugin.ReadSector(partitionStart);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
MDB.drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x000);
|
||||
if (MDB.drSigWord != HFS_MAGIC)
|
||||
if(MDB.drSigWord != HFS_MAGIC)
|
||||
return;
|
||||
|
||||
|
||||
MDB.drCrDate = BigEndianBitConverter.ToUInt32(mdb_sector, 0x002);
|
||||
MDB.drLsMod = BigEndianBitConverter.ToUInt32(mdb_sector, 0x006);
|
||||
MDB.drAtrb = BigEndianBitConverter.ToUInt16(mdb_sector, 0x00A);
|
||||
@@ -184,7 +184,7 @@ namespace DiscImageChef.Plugins
|
||||
pString = new byte[28];
|
||||
Array.Copy(mdb_sector, 0x024, pString, 0, 28);
|
||||
MDB.drVN = StringHandlers.PascalToString(pString);
|
||||
|
||||
|
||||
MDB.drVolBkUp = BigEndianBitConverter.ToUInt32(mdb_sector, 0x040);
|
||||
MDB.drVSeqNum = BigEndianBitConverter.ToUInt16(mdb_sector, 0x044);
|
||||
MDB.drWrCnt = BigEndianBitConverter.ToUInt32(mdb_sector, 0x046);
|
||||
@@ -193,7 +193,7 @@ namespace DiscImageChef.Plugins
|
||||
MDB.drNmRtDirs = BigEndianBitConverter.ToUInt16(mdb_sector, 0x052);
|
||||
MDB.drFilCnt = BigEndianBitConverter.ToUInt32(mdb_sector, 0x054);
|
||||
MDB.drDirCnt = BigEndianBitConverter.ToUInt32(mdb_sector, 0x058);
|
||||
|
||||
|
||||
MDB.drFndrInfo0 = BigEndianBitConverter.ToUInt32(mdb_sector, 0x05C);
|
||||
MDB.drFndrInfo1 = BigEndianBitConverter.ToUInt32(mdb_sector, 0x060);
|
||||
MDB.drFndrInfo2 = BigEndianBitConverter.ToUInt32(mdb_sector, 0x064);
|
||||
@@ -211,18 +211,18 @@ namespace DiscImageChef.Plugins
|
||||
MDB.drEmbedSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x07C);
|
||||
MDB.xdrStABNt = BigEndianBitConverter.ToUInt16(mdb_sector, 0x07E);
|
||||
MDB.xdrNumABlks = BigEndianBitConverter.ToUInt16(mdb_sector, 0x080);
|
||||
|
||||
|
||||
MDB.drXTFlSize = BigEndianBitConverter.ToUInt32(mdb_sector, 0x082);
|
||||
MDB.drCTFlSize = BigEndianBitConverter.ToUInt32(mdb_sector, 0x092);
|
||||
|
||||
|
||||
BB.signature = BigEndianBitConverter.ToUInt16(bb_sector, 0x000);
|
||||
|
||||
if (BB.signature == HFSBB_MAGIC)
|
||||
|
||||
if(BB.signature == HFSBB_MAGIC)
|
||||
{
|
||||
BB.branch = BigEndianBitConverter.ToUInt32(bb_sector, 0x002);
|
||||
BB.boot_flags = bb_sector[0x006];
|
||||
BB.boot_version = bb_sector[0x007];
|
||||
|
||||
|
||||
BB.sec_sv_pages = BigEndianBitConverter.ToInt16(bb_sector, 0x008);
|
||||
|
||||
pString = new byte[16];
|
||||
@@ -246,7 +246,7 @@ namespace DiscImageChef.Plugins
|
||||
pString = new byte[16];
|
||||
Array.Copy(bb_sector, 0x06A, pString, 0, 16);
|
||||
BB.clipbrd_name = StringHandlers.PascalToString(pString);
|
||||
|
||||
|
||||
BB.max_files = BigEndianBitConverter.ToUInt16(bb_sector, 0x07A);
|
||||
BB.queue_size = BigEndianBitConverter.ToUInt16(bb_sector, 0x07C);
|
||||
BB.heap_128k = BigEndianBitConverter.ToUInt32(bb_sector, 0x07E);
|
||||
@@ -255,44 +255,44 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
else
|
||||
BB.signature = 0x0000;
|
||||
|
||||
|
||||
sb.AppendLine("Apple Hierarchical File System");
|
||||
sb.AppendLine();
|
||||
if (APMFromHDDOnCD)
|
||||
if(APMFromHDDOnCD)
|
||||
sb.AppendLine("HFS uses 512 bytes/sector while devices uses 2048 bytes/sector.").AppendLine();
|
||||
sb.AppendLine("Master Directory Block:");
|
||||
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(MDB.drCrDate)).AppendLine();
|
||||
sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(MDB.drLsMod)).AppendLine();
|
||||
sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(MDB.drVolBkUp)).AppendLine();
|
||||
sb.AppendFormat("Backup sequence number: {0}", MDB.drVSeqNum).AppendLine();
|
||||
|
||||
if ((MDB.drAtrb & 0x80) == 0x80)
|
||||
|
||||
if((MDB.drAtrb & 0x80) == 0x80)
|
||||
sb.AppendLine("Volume is locked by hardware.");
|
||||
if ((MDB.drAtrb & 0x100) == 0x100)
|
||||
if((MDB.drAtrb & 0x100) == 0x100)
|
||||
sb.AppendLine("Volume was unmonted.");
|
||||
else
|
||||
sb.AppendLine("Volume is mounted.");
|
||||
if ((MDB.drAtrb & 0x200) == 0x200)
|
||||
if((MDB.drAtrb & 0x200) == 0x200)
|
||||
sb.AppendLine("Volume has spared bad blocks.");
|
||||
if ((MDB.drAtrb & 0x400) == 0x400)
|
||||
if((MDB.drAtrb & 0x400) == 0x400)
|
||||
sb.AppendLine("Volume does not need cache.");
|
||||
if ((MDB.drAtrb & 0x800) == 0x800)
|
||||
if((MDB.drAtrb & 0x800) == 0x800)
|
||||
sb.AppendLine("Boot volume is inconsistent.");
|
||||
if ((MDB.drAtrb & 0x1000) == 0x1000)
|
||||
if((MDB.drAtrb & 0x1000) == 0x1000)
|
||||
sb.AppendLine("There are reused CNIDs.");
|
||||
if ((MDB.drAtrb & 0x2000) == 0x2000)
|
||||
if((MDB.drAtrb & 0x2000) == 0x2000)
|
||||
sb.AppendLine("Volume is journaled.");
|
||||
if ((MDB.drAtrb & 0x4000) == 0x4000)
|
||||
if((MDB.drAtrb & 0x4000) == 0x4000)
|
||||
sb.AppendLine("Volume is seriously inconsistent.");
|
||||
if ((MDB.drAtrb & 0x8000) == 0x8000)
|
||||
if((MDB.drAtrb & 0x8000) == 0x8000)
|
||||
sb.AppendLine("Volume is locked by software.");
|
||||
|
||||
|
||||
sb.AppendFormat("{0} files on root directory", MDB.drNmFls).AppendLine();
|
||||
sb.AppendFormat("{0} directories on root directory", MDB.drNmRtDirs).AppendLine();
|
||||
sb.AppendFormat("{0} files on volume", MDB.drFilCnt).AppendLine();
|
||||
sb.AppendFormat("{0} directories on volume", MDB.drDirCnt).AppendLine();
|
||||
sb.AppendFormat("Volume write count: {0}", MDB.drWrCnt).AppendLine();
|
||||
|
||||
|
||||
sb.AppendFormat("Volume bitmap starting sector (in 512-bytes): {0}", MDB.drVBMSt).AppendLine();
|
||||
sb.AppendFormat("Next allocation block: {0}.", MDB.drAllocPtr).AppendLine();
|
||||
sb.AppendFormat("{0} volume allocation blocks.", MDB.drNmAlBlks).AppendLine();
|
||||
@@ -303,12 +303,12 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Sector of first allocation block: {0}", MDB.drAlBlSt).AppendLine();
|
||||
sb.AppendFormat("Next unused CNID: {0}", MDB.drNxtCNID).AppendLine();
|
||||
sb.AppendFormat("{0} unused allocation blocks.", MDB.drFreeBks).AppendLine();
|
||||
|
||||
|
||||
sb.AppendFormat("{0} bytes in the Extents B-Tree", MDB.drXTFlSize).AppendLine();
|
||||
sb.AppendFormat("{0} bytes in the Catalog B-Tree", MDB.drCTFlSize).AppendLine();
|
||||
|
||||
sb.AppendFormat("Volume name: {0}", MDB.drVN).AppendLine();
|
||||
|
||||
|
||||
sb.AppendLine("Finder info:");
|
||||
sb.AppendFormat("CNID of bootable system's directory: {0}", MDB.drFndrInfo0).AppendLine();
|
||||
sb.AppendFormat("CNID of first-run application's directory: {0}", MDB.drFndrInfo1).AppendLine();
|
||||
@@ -316,8 +316,8 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", MDB.drFndrInfo3).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", MDB.drFndrInfo5).AppendLine();
|
||||
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", MDB.drFndrInfo6, MDB.drFndrInfo7).AppendLine();
|
||||
|
||||
if (MDB.drEmbedSigWord == HFSP_MAGIC)
|
||||
|
||||
if(MDB.drEmbedSigWord == HFSP_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume wraps a HFS+ volume.");
|
||||
sb.AppendFormat("Starting block of the HFS+ volume: {0}", MDB.xdrStABNt).AppendLine();
|
||||
@@ -329,25 +329,25 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("{0} blocks in volume bitmap cache", MDB.drVBMCSize).AppendLine();
|
||||
sb.AppendFormat("{0} blocks in volume common cache", MDB.drCtlCSize).AppendLine();
|
||||
}
|
||||
|
||||
if (BB.signature == HFSBB_MAGIC)
|
||||
|
||||
if(BB.signature == HFSBB_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume is bootable.");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Boot Block:");
|
||||
if ((BB.boot_flags & 0x40) == 0x40)
|
||||
if((BB.boot_flags & 0x40) == 0x40)
|
||||
sb.AppendLine("Boot block should be executed.");
|
||||
if ((BB.boot_flags & 0x80) == 0x80)
|
||||
if((BB.boot_flags & 0x80) == 0x80)
|
||||
{
|
||||
sb.AppendLine("Boot block is in new unknown format.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BB.sec_sv_pages > 0)
|
||||
if(BB.sec_sv_pages > 0)
|
||||
sb.AppendLine("Allocate secondary sound buffer at boot.");
|
||||
else if (BB.sec_sv_pages < 0)
|
||||
else if(BB.sec_sv_pages < 0)
|
||||
sb.AppendLine("Allocate secondary sound and video buffers at boot.");
|
||||
|
||||
|
||||
sb.AppendFormat("System filename: {0}", BB.system_name).AppendLine();
|
||||
sb.AppendFormat("Finder filename: {0}", BB.finder_name).AppendLine();
|
||||
sb.AppendFormat("Debugger filename: {0}", BB.debug_name).AppendLine();
|
||||
@@ -364,11 +364,11 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
else
|
||||
sb.AppendLine("Volume is not bootable.");
|
||||
|
||||
|
||||
information = sb.ToString();
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
if (MDB.drVolBkUp > 0)
|
||||
if(MDB.drVolBkUp > 0)
|
||||
{
|
||||
xmlFSType.BackupDate = DateHandlers.MacToDateTime(MDB.drVolBkUp);
|
||||
xmlFSType.BackupDateSpecified = true;
|
||||
@@ -376,7 +376,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.Bootable = BB.signature == HFSBB_MAGIC;
|
||||
xmlFSType.Clusters = MDB.drNmAlBlks;
|
||||
xmlFSType.ClusterSize = (int)MDB.drAlBlkSiz;
|
||||
if (MDB.drCrDate > 0)
|
||||
if(MDB.drCrDate > 0)
|
||||
{
|
||||
xmlFSType.CreationDate = DateHandlers.MacToDateTime(MDB.drCrDate);
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
@@ -386,16 +386,16 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.FilesSpecified = true;
|
||||
xmlFSType.FreeClusters = MDB.drFreeBks;
|
||||
xmlFSType.FreeClustersSpecified = true;
|
||||
if (MDB.drLsMod > 0)
|
||||
if(MDB.drLsMod > 0)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.MacToDateTime(MDB.drLsMod);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
}
|
||||
xmlFSType.Type = "HFS";
|
||||
xmlFSType.VolumeName = MDB.drVN;
|
||||
if (MDB.drFndrInfo6 != 0 && MDB.drFndrInfo7 != 0)
|
||||
if(MDB.drFndrInfo6 != 0 && MDB.drFndrInfo7 != 0)
|
||||
xmlFSType.VolumeSerial = String.Format("{0:X8}{1:x8}", MDB.drFndrInfo6, MDB.drFndrInfo7);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,33 +66,33 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
UInt16 drSigWord;
|
||||
UInt16 xdrStABNt;
|
||||
UInt16 drAlBlSt;
|
||||
UInt32 drAlBlkSiz;
|
||||
|
||||
|
||||
byte[] vh_sector;
|
||||
ulong hfsp_offset;
|
||||
|
||||
vh_sector = imagePlugin.ReadSector(2 + partitionStart); // Read volume header, of HFS Wrapper MDB
|
||||
|
||||
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0); // Check for HFS Wrapper MDB
|
||||
|
||||
if (drSigWord == HFS_MAGIC) // "BD"
|
||||
|
||||
if(drSigWord == HFS_MAGIC) // "BD"
|
||||
{
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x07C); // Read embedded HFS+ signature
|
||||
|
||||
if (drSigWord == HFSP_MAGIC) // "H+"
|
||||
|
||||
if(drSigWord == HFSP_MAGIC) // "H+"
|
||||
{
|
||||
xdrStABNt = BigEndianBitConverter.ToUInt16(vh_sector, 0x07E); // Starting block number of embedded HFS+ volume
|
||||
|
||||
|
||||
drAlBlkSiz = BigEndianBitConverter.ToUInt32(vh_sector, 0x014); // Block size
|
||||
|
||||
|
||||
drAlBlSt = BigEndianBitConverter.ToUInt16(vh_sector, 0x01C); // Start of allocated blocks (in 512-byte/block)
|
||||
|
||||
|
||||
hfsp_offset = (drAlBlSt + xdrStABNt * (drAlBlkSiz / 512)) * (imagePlugin.GetSectorSize() / 512);
|
||||
}
|
||||
else
|
||||
@@ -104,11 +104,11 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
vh_sector = imagePlugin.ReadSector(2 + partitionStart + hfsp_offset); // Read volume header
|
||||
|
||||
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0);
|
||||
if (drSigWord == HFSP_MAGIC || drSigWord == HFSX_MAGIC)
|
||||
if(drSigWord == HFSP_MAGIC || drSigWord == HFSX_MAGIC)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -116,26 +116,26 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
UInt16 drSigWord;
|
||||
UInt16 xdrStABNt;
|
||||
UInt16 drAlBlSt;
|
||||
UInt32 drAlBlkSiz;
|
||||
HFSPlusVolumeHeader HPVH = new HFSPlusVolumeHeader();
|
||||
|
||||
|
||||
ulong hfsp_offset;
|
||||
bool wrapped;
|
||||
byte[] vh_sector;
|
||||
|
||||
|
||||
vh_sector = imagePlugin.ReadSector(2 + partitionStart); // Read volume header, of HFS Wrapper MDB
|
||||
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0); // Check for HFS Wrapper MDB
|
||||
|
||||
if (drSigWord == HFS_MAGIC) // "BD"
|
||||
|
||||
if(drSigWord == HFS_MAGIC) // "BD"
|
||||
{
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x07C); // Read embedded HFS+ signature
|
||||
|
||||
if (drSigWord == HFSP_MAGIC) // "H+"
|
||||
|
||||
if(drSigWord == HFSP_MAGIC) // "H+"
|
||||
{
|
||||
xdrStABNt = BigEndianBitConverter.ToUInt16(vh_sector, 0x07E); // Starting block number of embedded HFS+ volume
|
||||
|
||||
@@ -157,47 +157,47 @@ namespace DiscImageChef.Plugins
|
||||
hfsp_offset = 0;
|
||||
wrapped = false;
|
||||
}
|
||||
|
||||
|
||||
vh_sector = imagePlugin.ReadSector(2 + partitionStart + hfsp_offset); // Read volume header
|
||||
|
||||
|
||||
HPVH.signature = BigEndianBitConverter.ToUInt16(vh_sector, 0x000);
|
||||
if (HPVH.signature == HFSP_MAGIC || HPVH.signature == HFSX_MAGIC)
|
||||
if(HPVH.signature == HFSP_MAGIC || HPVH.signature == HFSX_MAGIC)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (HPVH.signature == 0x482B)
|
||||
if(HPVH.signature == 0x482B)
|
||||
sb.AppendLine("HFS+ filesystem.");
|
||||
if (HPVH.signature == 0x4858)
|
||||
if(HPVH.signature == 0x4858)
|
||||
sb.AppendLine("HFSX filesystem.");
|
||||
if (wrapped)
|
||||
if(wrapped)
|
||||
sb.AppendLine("Volume is wrapped inside an HFS volume.");
|
||||
|
||||
|
||||
HPVH.version = BigEndianBitConverter.ToUInt16(vh_sector, 0x002);
|
||||
|
||||
if (HPVH.version == 4 || HPVH.version == 5)
|
||||
|
||||
if(HPVH.version == 4 || HPVH.version == 5)
|
||||
{
|
||||
HPVH.attributes = BigEndianBitConverter.ToUInt32(vh_sector, 0x004);
|
||||
byte[] lastMountedVersion_b = new byte[4];
|
||||
Array.Copy(vh_sector, 0x008, lastMountedVersion_b, 0, 4);
|
||||
HPVH.lastMountedVersion = Encoding.ASCII.GetString(lastMountedVersion_b);
|
||||
HPVH.journalInfoBlock = BigEndianBitConverter.ToUInt32(vh_sector, 0x00C);
|
||||
HPVH.lastMountedVersion = Encoding.ASCII.GetString(lastMountedVersion_b);
|
||||
HPVH.journalInfoBlock = BigEndianBitConverter.ToUInt32(vh_sector, 0x00C);
|
||||
|
||||
HPVH.createDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x010);
|
||||
HPVH.modifyDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x018);
|
||||
HPVH.backupDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x020);
|
||||
HPVH.checkedDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x028);
|
||||
HPVH.createDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x010);
|
||||
HPVH.modifyDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x018);
|
||||
HPVH.backupDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x020);
|
||||
HPVH.checkedDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x028);
|
||||
|
||||
HPVH.fileCount = BigEndianBitConverter.ToUInt32(vh_sector, 0x030);
|
||||
HPVH.folderCount = BigEndianBitConverter.ToUInt32(vh_sector, 0x034);
|
||||
HPVH.fileCount = BigEndianBitConverter.ToUInt32(vh_sector, 0x030);
|
||||
HPVH.folderCount = BigEndianBitConverter.ToUInt32(vh_sector, 0x034);
|
||||
|
||||
HPVH.blockSize = BigEndianBitConverter.ToUInt32(vh_sector, 0x038);
|
||||
HPVH.totalBlocks = BigEndianBitConverter.ToUInt32(vh_sector, 0x03C);
|
||||
HPVH.freeBlocks = BigEndianBitConverter.ToUInt32(vh_sector, 0x040);
|
||||
HPVH.blockSize = BigEndianBitConverter.ToUInt32(vh_sector, 0x038);
|
||||
HPVH.totalBlocks = BigEndianBitConverter.ToUInt32(vh_sector, 0x03C);
|
||||
HPVH.freeBlocks = BigEndianBitConverter.ToUInt32(vh_sector, 0x040);
|
||||
|
||||
HPVH.nextAllocation = BigEndianBitConverter.ToUInt32(vh_sector, 0x044);
|
||||
HPVH.rsrcClumpSize = BigEndianBitConverter.ToUInt32(vh_sector, 0x048);
|
||||
HPVH.dataClumpSize = BigEndianBitConverter.ToUInt32(vh_sector, 0x04C);
|
||||
HPVH.nextCatalogID = BigEndianBitConverter.ToUInt32(vh_sector, 0x050);
|
||||
HPVH.nextAllocation = BigEndianBitConverter.ToUInt32(vh_sector, 0x044);
|
||||
HPVH.rsrcClumpSize = BigEndianBitConverter.ToUInt32(vh_sector, 0x048);
|
||||
HPVH.dataClumpSize = BigEndianBitConverter.ToUInt32(vh_sector, 0x04C);
|
||||
HPVH.nextCatalogID = BigEndianBitConverter.ToUInt32(vh_sector, 0x050);
|
||||
|
||||
HPVH.writeCount = BigEndianBitConverter.ToUInt32(vh_sector, 0x054);
|
||||
|
||||
@@ -208,34 +208,34 @@ namespace DiscImageChef.Plugins
|
||||
HPVH.drFndrInfo5 = BigEndianBitConverter.ToUInt32(vh_sector, 0x074);
|
||||
HPVH.drFndrInfo6 = BigEndianBitConverter.ToUInt32(vh_sector, 0x078);
|
||||
HPVH.drFndrInfo7 = BigEndianBitConverter.ToUInt32(vh_sector, 0x07C);
|
||||
|
||||
|
||||
HPVH.allocationFile_logicalSize = BigEndianBitConverter.ToUInt64(vh_sector, 0x080);
|
||||
HPVH.extentsFile_logicalSize = BigEndianBitConverter.ToUInt64(vh_sector, 0x0D0);
|
||||
HPVH.catalogFile_logicalSize = BigEndianBitConverter.ToUInt64(vh_sector, 0x120);
|
||||
HPVH.attributesFile_logicalSize = BigEndianBitConverter.ToUInt64(vh_sector, 0x170);
|
||||
HPVH.startupFile_logicalSize = BigEndianBitConverter.ToUInt64(vh_sector, 0x1C0);
|
||||
|
||||
|
||||
sb.AppendFormat("Filesystem version is {0}.", HPVH.version).AppendLine();
|
||||
|
||||
if ((HPVH.attributes & 0x80) == 0x80)
|
||||
if((HPVH.attributes & 0x80) == 0x80)
|
||||
sb.AppendLine("Volume is locked on hardware.");
|
||||
if ((HPVH.attributes & 0x100) == 0x100)
|
||||
if((HPVH.attributes & 0x100) == 0x100)
|
||||
sb.AppendLine("Volume is unmounted.");
|
||||
if ((HPVH.attributes & 0x200) == 0x200)
|
||||
if((HPVH.attributes & 0x200) == 0x200)
|
||||
sb.AppendLine("There are bad blocks in the extents file.");
|
||||
if ((HPVH.attributes & 0x400) == 0x400)
|
||||
if((HPVH.attributes & 0x400) == 0x400)
|
||||
sb.AppendLine("Volume does not require cache.");
|
||||
if ((HPVH.attributes & 0x800) == 0x800)
|
||||
if((HPVH.attributes & 0x800) == 0x800)
|
||||
sb.AppendLine("Volume state is inconsistent.");
|
||||
if ((HPVH.attributes & 0x1000) == 0x1000)
|
||||
if((HPVH.attributes & 0x1000) == 0x1000)
|
||||
sb.AppendLine("CNIDs are reused.");
|
||||
if ((HPVH.attributes & 0x2000) == 0x2000)
|
||||
if((HPVH.attributes & 0x2000) == 0x2000)
|
||||
sb.AppendLine("Volume is journaled.");
|
||||
if ((HPVH.attributes & 0x8000) == 0x8000)
|
||||
if((HPVH.attributes & 0x8000) == 0x8000)
|
||||
sb.AppendLine("Volume is locked on software.");
|
||||
|
||||
sb.AppendFormat("Implementation that last mounted the volume: \"{0}\".", HPVH.lastMountedVersion).AppendLine();
|
||||
if ((HPVH.attributes & 0x2000) == 0x2000)
|
||||
if((HPVH.attributes & 0x2000) == 0x2000)
|
||||
sb.AppendFormat("Journal starts at allocation block {0}.", HPVH.journalInfoBlock).AppendLine();
|
||||
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(HPVH.createDate)).AppendLine();
|
||||
sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(HPVH.modifyDate)).AppendLine();
|
||||
@@ -265,7 +265,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", HPVH.drFndrInfo6, HPVH.drFndrInfo7).AppendLine();
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
if (HPVH.backupDate > 0)
|
||||
if(HPVH.backupDate > 0)
|
||||
{
|
||||
xmlFSType.BackupDate = DateHandlers.MacToDateTime(HPVH.backupDate);
|
||||
xmlFSType.BackupDateSpecified = true;
|
||||
@@ -274,7 +274,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.Bootable = true;
|
||||
xmlFSType.Clusters = HPVH.totalBlocks;
|
||||
xmlFSType.ClusterSize = (int)HPVH.blockSize;
|
||||
if (HPVH.createDate > 0)
|
||||
if(HPVH.createDate > 0)
|
||||
{
|
||||
xmlFSType.CreationDate = DateHandlers.MacToDateTime(HPVH.createDate);
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
@@ -284,7 +284,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.FilesSpecified = true;
|
||||
xmlFSType.FreeClusters = HPVH.freeBlocks;
|
||||
xmlFSType.FreeClustersSpecified = true;
|
||||
if (HPVH.modifyDate > 0)
|
||||
if(HPVH.modifyDate > 0)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.MacToDateTime(HPVH.modifyDate);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
@@ -293,7 +293,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.Type = "HFS+";
|
||||
if(HPVH.signature == 0x4858)
|
||||
xmlFSType.Type = "HFSX";
|
||||
if (HPVH.drFndrInfo6 != 0 && HPVH.drFndrInfo7 != 0)
|
||||
if(HPVH.drFndrInfo6 != 0 && HPVH.drFndrInfo7 != 0)
|
||||
xmlFSType.VolumeSerial = String.Format("{0:X8}{1:x8}", HPVH.drFndrInfo6, HPVH.drFndrInfo7);
|
||||
}
|
||||
else
|
||||
@@ -301,7 +301,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Filesystem version is {0}.", HPVH.version).AppendLine();
|
||||
sb.AppendLine("This version is not supported yet.");
|
||||
}
|
||||
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -59,25 +59,25 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
UInt16 drSigWord;
|
||||
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte[] mdb_sector = imagePlugin.ReadSector(2 + partitionStart);
|
||||
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x000);
|
||||
|
||||
|
||||
return drSigWord == MFS_MAGIC;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
MFS_MasterDirectoryBlock MDB = new MFS_MasterDirectoryBlock();
|
||||
MFS_BootBlock BB = new MFS_BootBlock();
|
||||
|
||||
|
||||
byte[] pString = new byte[16];
|
||||
byte[] variable_size;
|
||||
|
||||
@@ -85,9 +85,9 @@ namespace DiscImageChef.Plugins
|
||||
byte[] bb_sector = imagePlugin.ReadSector(0 + partitionStart);
|
||||
|
||||
MDB.drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x000);
|
||||
if (MDB.drSigWord != MFS_MAGIC)
|
||||
if(MDB.drSigWord != MFS_MAGIC)
|
||||
return;
|
||||
|
||||
|
||||
MDB.drCrDate = BigEndianBitConverter.ToUInt32(mdb_sector, 0x002);
|
||||
MDB.drLsBkUp = BigEndianBitConverter.ToUInt32(mdb_sector, 0x006);
|
||||
MDB.drAtrb = BigEndianBitConverter.ToUInt16(mdb_sector, 0x00A);
|
||||
@@ -104,15 +104,15 @@ namespace DiscImageChef.Plugins
|
||||
variable_size = new byte[MDB.drVNSiz];
|
||||
Array.Copy(mdb_sector, 0x025, variable_size, 0, MDB.drVNSiz);
|
||||
MDB.drVN = Encoding.ASCII.GetString(variable_size);
|
||||
|
||||
|
||||
BB.signature = BigEndianBitConverter.ToUInt16(bb_sector, 0x000);
|
||||
|
||||
if (BB.signature == MFSBB_MAGIC)
|
||||
|
||||
if(BB.signature == MFSBB_MAGIC)
|
||||
{
|
||||
BB.branch = BigEndianBitConverter.ToUInt32(bb_sector, 0x002);
|
||||
BB.boot_flags = bb_sector[0x006];
|
||||
BB.boot_version = bb_sector[0x007];
|
||||
|
||||
|
||||
BB.sec_sv_pages = BigEndianBitConverter.ToInt16(bb_sector, 0x008);
|
||||
|
||||
Array.Copy(mdb_sector, 0x00A, pString, 0, 16);
|
||||
@@ -138,15 +138,15 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
else
|
||||
BB.signature = 0x0000;
|
||||
|
||||
|
||||
sb.AppendLine("Apple Macintosh File System");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Master Directory Block:");
|
||||
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(MDB.drCrDate)).AppendLine();
|
||||
sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(MDB.drLsBkUp)).AppendLine();
|
||||
if ((MDB.drAtrb & 0x80) == 0x80)
|
||||
if((MDB.drAtrb & 0x80) == 0x80)
|
||||
sb.AppendLine("Volume is locked by hardware.");
|
||||
if ((MDB.drAtrb & 0x8000) == 0x8000)
|
||||
if((MDB.drAtrb & 0x8000) == 0x8000)
|
||||
sb.AppendLine("Volume is locked by software.");
|
||||
sb.AppendFormat("{0} files on volume", MDB.drNmFls).AppendLine();
|
||||
sb.AppendFormat("First directory block: {0}", MDB.drDirSt).AppendLine();
|
||||
@@ -158,25 +158,25 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Next unused file number: {0}", MDB.drNxtFNum).AppendLine();
|
||||
sb.AppendFormat("{0} unused allocation blocks.", MDB.drFreeBks).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", MDB.drVN).AppendLine();
|
||||
|
||||
if (BB.signature == MFSBB_MAGIC)
|
||||
|
||||
if(BB.signature == MFSBB_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume is bootable.");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Boot Block:");
|
||||
if ((BB.boot_flags & 0x40) == 0x40)
|
||||
if((BB.boot_flags & 0x40) == 0x40)
|
||||
sb.AppendLine("Boot block should be executed.");
|
||||
if ((BB.boot_flags & 0x80) == 0x80)
|
||||
if((BB.boot_flags & 0x80) == 0x80)
|
||||
{
|
||||
sb.AppendLine("Boot block is in new unknown format.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BB.sec_sv_pages > 0)
|
||||
if(BB.sec_sv_pages > 0)
|
||||
sb.AppendLine("Allocate secondary sound buffer at boot.");
|
||||
else if (BB.sec_sv_pages < 0)
|
||||
else if(BB.sec_sv_pages < 0)
|
||||
sb.AppendLine("Allocate secondary sound and video buffers at boot.");
|
||||
|
||||
|
||||
sb.AppendFormat("System filename: {0}", BB.system_name).AppendLine();
|
||||
sb.AppendFormat("Finder filename: {0}", BB.finder_name).AppendLine();
|
||||
sb.AppendFormat("Debugger filename: {0}", BB.debug_name).AppendLine();
|
||||
@@ -193,11 +193,11 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
else
|
||||
sb.AppendLine("Volume is not bootable.");
|
||||
|
||||
|
||||
information = sb.ToString();
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
if (MDB.drLsBkUp > 0)
|
||||
if(MDB.drLsBkUp > 0)
|
||||
{
|
||||
xmlFSType.BackupDate = DateHandlers.MacToDateTime(MDB.drLsBkUp);
|
||||
xmlFSType.BackupDateSpecified = true;
|
||||
@@ -205,7 +205,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.Bootable = BB.signature == MFSBB_MAGIC;
|
||||
xmlFSType.Clusters = MDB.drNmAlBlks;
|
||||
xmlFSType.ClusterSize = (int)MDB.drAlBlkSiz;
|
||||
if (MDB.drCrDate > 0)
|
||||
if(MDB.drCrDate > 0)
|
||||
{
|
||||
xmlFSType.CreationDate = DateHandlers.MacToDateTime(MDB.drCrDate);
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
@@ -216,7 +216,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.FreeClustersSpecified = true;
|
||||
xmlFSType.Type = "MFS";
|
||||
xmlFSType.VolumeName = MDB.drVN;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
UInt32 magic;
|
||||
@@ -76,24 +76,24 @@ namespace DiscImageChef.Plugins
|
||||
magic = BitConverter.ToUInt32(sb_sector, 0x20);
|
||||
magic_be = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
|
||||
if (magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
if(magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
return true;
|
||||
|
||||
if (sb_sector.Length >= 0x400)
|
||||
if(sb_sector.Length >= 0x400)
|
||||
{
|
||||
magic = BitConverter.ToUInt32(sb_sector, 0x220);
|
||||
magic_be = BigEndianBitConverter.ToUInt32(sb_sector, 0x220);
|
||||
}
|
||||
|
||||
if (magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
if(magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
return true;
|
||||
|
||||
sb_sector = imagePlugin.ReadSector(1 + partitionStart);
|
||||
|
||||
|
||||
magic = BitConverter.ToUInt32(sb_sector, 0x20);
|
||||
magic_be = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
|
||||
if (magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
if(magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace DiscImageChef.Plugins
|
||||
byte[] name_bytes = new byte[32];
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
BeSuperBlock besb = new BeSuperBlock();
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector(0 + partitionStart);
|
||||
@@ -112,7 +112,7 @@ namespace DiscImageChef.Plugins
|
||||
BigEndianBitConverter.IsLittleEndian = true; // Default for little-endian
|
||||
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
if (besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // Magic is at offset
|
||||
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // Magic is at offset
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian &= besb.magic1 != BEFS_CIGAM1;
|
||||
}
|
||||
@@ -120,20 +120,20 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
sb_sector = imagePlugin.ReadSector(1 + partitionStart);
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
|
||||
if (besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
||||
|
||||
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian &= besb.magic1 != BEFS_CIGAM1;
|
||||
}
|
||||
else if (sb_sector.Length >= 0x400)
|
||||
else if(sb_sector.Length >= 0x400)
|
||||
{
|
||||
byte[] temp = imagePlugin.ReadSector(0 + partitionStart);
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32(temp, 0x220);
|
||||
|
||||
if (besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
||||
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian &= besb.magic1 != BEFS_CIGAM1;
|
||||
sb_sector = new byte[0x200];
|
||||
sb_sector = new byte[0x200];
|
||||
Array.Copy(temp, 0x200, sb_sector, 0, 0x200);
|
||||
}
|
||||
else
|
||||
@@ -169,13 +169,13 @@ namespace DiscImageChef.Plugins
|
||||
besb.indices_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x7C);
|
||||
besb.indices_start = BigEndianBitConverter.ToUInt16(sb_sector, 0x80);
|
||||
besb.indices_len = BigEndianBitConverter.ToUInt16(sb_sector, 0x82);
|
||||
|
||||
if (!BigEndianBitConverter.IsLittleEndian) // Big-endian filesystem
|
||||
sb.AppendLine("Little-endian BeFS");
|
||||
|
||||
if(!BigEndianBitConverter.IsLittleEndian) // Big-endian filesystem
|
||||
sb.AppendLine("Little-endian BeFS");
|
||||
else
|
||||
sb.AppendLine("Big-endian BeFS");
|
||||
|
||||
if (besb.magic1 != BEFS_MAGIC1 || besb.fs_byte_order != BEFS_ENDIAN ||
|
||||
|
||||
if(besb.magic1 != BEFS_MAGIC1 || besb.fs_byte_order != BEFS_ENDIAN ||
|
||||
besb.magic2 != BEFS_MAGIC2 || besb.magic3 != BEFS_MAGIC3 ||
|
||||
besb.root_dir_len != 1 || besb.indices_len != 1 ||
|
||||
(1 << (int)besb.block_shift) != besb.block_size)
|
||||
@@ -190,19 +190,19 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("1 << block_shift == block_size => 1 << {0} == {1} (Should be {2})", besb.block_shift,
|
||||
1 << (int)besb.block_shift, besb.block_size).AppendLine();
|
||||
}
|
||||
|
||||
if (besb.flags == BEFS_CLEAN)
|
||||
|
||||
if(besb.flags == BEFS_CLEAN)
|
||||
{
|
||||
if (besb.log_start == besb.log_end)
|
||||
if(besb.log_start == besb.log_end)
|
||||
sb.AppendLine("Filesystem is clean");
|
||||
else
|
||||
sb.AppendLine("Filesystem is dirty");
|
||||
}
|
||||
else if (besb.flags == BEFS_DIRTY)
|
||||
else if(besb.flags == BEFS_DIRTY)
|
||||
sb.AppendLine("Filesystem is dirty");
|
||||
else
|
||||
sb.AppendFormat("Unknown flags: {0:X8}", besb.flags).AppendLine();
|
||||
|
||||
|
||||
sb.AppendFormat("Volume name: {0}", besb.name).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per block", besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} blocks in volume ({1} bytes)", besb.num_blocks, besb.num_blocks * besb.block_size).AppendLine();
|
||||
@@ -217,7 +217,7 @@ namespace DiscImageChef.Plugins
|
||||
besb.root_dir_ag, besb.root_dir_len, besb.root_dir_len * besb.block_size).AppendLine();
|
||||
sb.AppendFormat("Indices' i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)", besb.indices_start,
|
||||
besb.indices_ag, besb.indices_len, besb.indices_len * besb.block_size).AppendLine();
|
||||
|
||||
|
||||
information = sb.ToString();
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte media_descriptor; // Not present on DOS <= 3, present on TOS but != of first FAT entry
|
||||
@@ -75,17 +75,17 @@ namespace DiscImageChef.Plugins
|
||||
media_descriptor = bpb_sector[0x015]; // Media Descriptor if present is in 0x15
|
||||
Array.Copy(bpb_sector, 0x52, fat32_signature, 0, 8); // FAT32 signature, if present, is in 0x52
|
||||
bps = BitConverter.ToUInt16(bpb_sector, 0x00B); // Bytes per sector
|
||||
if (bps == 0)
|
||||
if(bps == 0)
|
||||
bps = 0x200;
|
||||
rsectors = BitConverter.ToUInt16(bpb_sector, 0x00E); // Sectors between BPB and FAT, including the BPB sector => [BPB,FAT)
|
||||
if (rsectors == 0)
|
||||
if(rsectors == 0)
|
||||
rsectors = 1;
|
||||
if (imagePlugin.GetSectors() > ((ulong)rsectors + partitionStart))
|
||||
if(imagePlugin.GetSectors() > ((ulong)rsectors + partitionStart))
|
||||
fat_sector = imagePlugin.ReadSector(rsectors + partitionStart); // First FAT entry
|
||||
else
|
||||
bpb_found=false;
|
||||
else
|
||||
bpb_found = false;
|
||||
|
||||
if (bpb_found)
|
||||
if(bpb_found)
|
||||
{
|
||||
first_fat_entry = BitConverter.ToUInt32(fat_sector, 0); // Easier to manage
|
||||
|
||||
@@ -95,19 +95,19 @@ namespace DiscImageChef.Plugins
|
||||
DicConsole.DebugWriteLine("FAT plugin", "bps = {0}", bps);
|
||||
DicConsole.DebugWriteLine("FAT plugin", "first_fat_entry = 0x{0:X8}", first_fat_entry);
|
||||
|
||||
if (fats_no > 2) // Must be 1 or 2, but as TOS makes strange things and I have not checked if it puts this to 0, ignore if 0. MUST NOT BE BIGGER THAN 2!
|
||||
return false;
|
||||
if(fats_no > 2) // Must be 1 or 2, but as TOS makes strange things and I have not checked if it puts this to 0, ignore if 0. MUST NOT BE BIGGER THAN 2!
|
||||
return false;
|
||||
|
||||
// Let's start the fun
|
||||
if (Encoding.ASCII.GetString(fat32_signature) == "FAT32 ")
|
||||
if(Encoding.ASCII.GetString(fat32_signature) == "FAT32 ")
|
||||
return true; // Seems easy, check reading
|
||||
|
||||
if ((first_fat_entry & 0xFFFFFFF0) == 0xFFFFFFF0) // Seems to be FAT16
|
||||
|
||||
if((first_fat_entry & 0xFFFFFFF0) == 0xFFFFFFF0) // Seems to be FAT16
|
||||
{
|
||||
if ((first_fat_entry & 0xFF) == media_descriptor)
|
||||
if((first_fat_entry & 0xFF) == media_descriptor)
|
||||
return true; // It MUST be FAT16, or... maybe not :S
|
||||
}
|
||||
else if ((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
else if((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
{
|
||||
//if((first_fat_entry & 0xFF) == media_descriptor) // Pre DOS<4 does not implement this, TOS does and is !=
|
||||
return true; // It MUST be FAT12, or... maybe not :S
|
||||
@@ -120,20 +120,20 @@ namespace DiscImageChef.Plugins
|
||||
first_fat_entry = BitConverter.ToUInt32(fat_sector, 0);
|
||||
byte fat_id = fat_sector[0];
|
||||
|
||||
if ((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
if((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
{
|
||||
if (fat_id == 0xFF)
|
||||
if(fat_id == 0xFF)
|
||||
{
|
||||
if (imagePlugin.GetSectorSize() == 512 && imagePlugin.GetSectors() == 640)
|
||||
if(imagePlugin.GetSectorSize() == 512 && imagePlugin.GetSectors() == 640)
|
||||
return true;
|
||||
if (imagePlugin.GetSectorSize() == 128)
|
||||
if(imagePlugin.GetSectorSize() == 128)
|
||||
{
|
||||
if(imagePlugin.GetSectors() == 2002)
|
||||
return true;
|
||||
if(imagePlugin.GetSectors() == 4004)
|
||||
return true;
|
||||
}
|
||||
if (imagePlugin.GetSectorSize() == 1024)
|
||||
if(imagePlugin.GetSectorSize() == 1024)
|
||||
{
|
||||
if(imagePlugin.GetSectors() == 616)
|
||||
return true;
|
||||
@@ -143,18 +143,18 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
return false;
|
||||
}
|
||||
if (fat_id == 0xFE)
|
||||
if(fat_id == 0xFE)
|
||||
{
|
||||
if (imagePlugin.GetSectorSize() == 512 && imagePlugin.GetSectors() == 320)
|
||||
if(imagePlugin.GetSectorSize() == 512 && imagePlugin.GetSectors() == 320)
|
||||
return true;
|
||||
if (imagePlugin.GetSectorSize() == 128)
|
||||
if(imagePlugin.GetSectorSize() == 128)
|
||||
{
|
||||
if(imagePlugin.GetSectors() == 2002)
|
||||
return true;
|
||||
if(imagePlugin.GetSectors() == 4004)
|
||||
return true;
|
||||
}
|
||||
if (imagePlugin.GetSectorSize() == 1024)
|
||||
if(imagePlugin.GetSectorSize() == 1024)
|
||||
{
|
||||
if(imagePlugin.GetSectors() == 616)
|
||||
return true;
|
||||
@@ -164,7 +164,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
return false;
|
||||
}
|
||||
if (fat_id == 0xFD && imagePlugin.GetSectors() == 2002)
|
||||
if(fat_id == 0xFD && imagePlugin.GetSectors() == 2002)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
|
||||
@@ -197,39 +197,39 @@ namespace DiscImageChef.Plugins
|
||||
Array.Copy(bpb_sector, 0x52, dosString, 0, 8); // FAT32 signature, if present, is in 0x52
|
||||
fat32_signature = Encoding.ASCII.GetString(dosString);
|
||||
bps = BitConverter.ToUInt16(bpb_sector, 0x00B); // Bytes per sector
|
||||
if (bps == 0)
|
||||
if(bps == 0)
|
||||
bps = 0x200;
|
||||
rsectors = BitConverter.ToUInt16(bpb_sector, 0x00E); // Sectors between BPB and FAT, including the BPB sector => [BPB,FAT)
|
||||
if (rsectors == 0)
|
||||
if(rsectors == 0)
|
||||
rsectors = 1;
|
||||
if (imagePlugin.GetSectors() > ((ulong)rsectors + partitionStart))
|
||||
if(imagePlugin.GetSectors() > ((ulong)rsectors + partitionStart))
|
||||
fat_sector = imagePlugin.ReadSector(rsectors + partitionStart); // First FAT entry
|
||||
else
|
||||
bpb_found=false;
|
||||
bpb_found = false;
|
||||
|
||||
if (bpb_found)
|
||||
if(bpb_found)
|
||||
{
|
||||
first_fat_entry = BitConverter.ToUInt32(fat_sector, 0); // Easier to manage
|
||||
|
||||
if (fats_no > 2) // Must be 1 or 2, but as TOS makes strange things and I have not checked if it puts this to 0, ignore if 0. MUST NOT BE BIGGER THAN 2!
|
||||
return;
|
||||
if(fats_no > 2) // Must be 1 or 2, but as TOS makes strange things and I have not checked if it puts this to 0, ignore if 0. MUST NOT BE BIGGER THAN 2!
|
||||
return;
|
||||
|
||||
// Let's start the fun
|
||||
if (fat32_signature == "FAT32 ")
|
||||
if(fat32_signature == "FAT32 ")
|
||||
{
|
||||
sb.AppendLine("Microsoft FAT32"); // Seems easy, check reading
|
||||
xmlFSType.Type = "FAT32";
|
||||
isFAT32 = true;
|
||||
}
|
||||
else if ((first_fat_entry & 0xFFFFFFF0) == 0xFFFFFFF0) // Seems to be FAT16
|
||||
else if((first_fat_entry & 0xFFFFFFF0) == 0xFFFFFFF0) // Seems to be FAT16
|
||||
{
|
||||
if ((first_fat_entry & 0xFF) == media_descriptor)
|
||||
if((first_fat_entry & 0xFF) == media_descriptor)
|
||||
{
|
||||
sb.AppendLine("Microsoft FAT16"); // It MUST be FAT16, or... maybe not :S
|
||||
xmlFSType.Type = "FAT16";
|
||||
}
|
||||
}
|
||||
else if ((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
else if((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
{
|
||||
//if((first_fat_entry & 0xFF) == media_descriptor) // Pre DOS<4 does not implement this, TOS does and is !=
|
||||
sb.AppendLine("Microsoft FAT12"); // It MUST be FAT12, or... maybe not :S
|
||||
@@ -237,11 +237,11 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
|
||||
BIOSParameterBlock BPB = new BIOSParameterBlock();
|
||||
ExtendedParameterBlock EPB = new ExtendedParameterBlock();
|
||||
FAT32ParameterBlock FAT32PB = new FAT32ParameterBlock();
|
||||
|
||||
|
||||
dosString = new byte[8];
|
||||
Array.Copy(bpb_sector, 0x03, dosString, 0, 8);
|
||||
BPB.OEMName = StringHandlers.CToString(dosString);
|
||||
@@ -257,8 +257,8 @@ namespace DiscImageChef.Plugins
|
||||
BPB.heads = BitConverter.ToUInt16(bpb_sector, 0x1A);
|
||||
BPB.hsectors = BitConverter.ToUInt32(bpb_sector, 0x1C);
|
||||
BPB.big_sectors = BitConverter.ToUInt32(bpb_sector, 0x20);
|
||||
|
||||
if (isFAT32)
|
||||
|
||||
if(isFAT32)
|
||||
{
|
||||
FAT32PB.spfat = BitConverter.ToUInt32(bpb_sector, 0x24);
|
||||
FAT32PB.fat_flags = BitConverter.ToUInt16(bpb_sector, 0x28);
|
||||
@@ -290,7 +290,7 @@ namespace DiscImageChef.Plugins
|
||||
Array.Copy(bpb_sector, 0x36, dosString, 0, 8);
|
||||
EPB.fs_type = StringHandlers.CToString(dosString);
|
||||
}
|
||||
|
||||
|
||||
sb.AppendFormat("OEM Name: {0}", BPB.OEMName).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector.", BPB.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster.", BPB.spc).AppendLine();
|
||||
@@ -298,7 +298,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("{0} sectors reserved between BPB and FAT.", BPB.rsectors).AppendLine();
|
||||
sb.AppendFormat("{0} FATs.", BPB.fats_no).AppendLine();
|
||||
sb.AppendFormat("{0} entries on root directory.", BPB.root_ent).AppendLine();
|
||||
if (BPB.sectors == 0)
|
||||
if(BPB.sectors == 0)
|
||||
{
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes).", BPB.big_sectors, BPB.big_sectors * BPB.bps).AppendLine();
|
||||
xmlFSType.Clusters = BPB.big_sectors / BPB.spc;
|
||||
@@ -308,17 +308,17 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes).", BPB.sectors, BPB.sectors * BPB.bps).AppendLine();
|
||||
xmlFSType.Clusters = BPB.sectors / BPB.spc;
|
||||
}
|
||||
if ((BPB.media & 0xF0) == 0xF0)
|
||||
if((BPB.media & 0xF0) == 0xF0)
|
||||
sb.AppendFormat("Media format: 0x{0:X2}", BPB.media).AppendLine();
|
||||
if (fat32_signature == "FAT32 ")
|
||||
if(fat32_signature == "FAT32 ")
|
||||
sb.AppendFormat("{0} sectors per FAT.", FAT32PB.spfat).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} sectors per FAT.", BPB.spfat).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track.", BPB.sptrk).AppendLine();
|
||||
sb.AppendFormat("{0} heads.", BPB.heads).AppendLine();
|
||||
sb.AppendFormat("{0} hidden sectors before BPB.", BPB.hsectors).AppendLine();
|
||||
|
||||
if (isFAT32)
|
||||
|
||||
if(isFAT32)
|
||||
{
|
||||
sb.AppendFormat("Cluster of root directory: {0}", FAT32PB.root_cluster).AppendLine();
|
||||
sb.AppendFormat("Sector of FSINFO structure: {0}", FAT32PB.fsinfo_sector).AppendLine();
|
||||
@@ -326,34 +326,34 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Drive number: 0x{0:X2}", FAT32PB.drive_no).AppendLine();
|
||||
sb.AppendFormat("Volume Serial Number: 0x{0:X8}", FAT32PB.serial_no).AppendLine();
|
||||
xmlFSType.VolumeSerial = String.Format("{0:X8}", FAT32PB.serial_no);
|
||||
if ((FAT32PB.nt_flags & 0x01) == 0x01)
|
||||
if((FAT32PB.nt_flags & 0x01) == 0x01)
|
||||
{
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
if ((EPB.nt_flags & 0x02) == 0x02)
|
||||
sb.AppendLine("Disk surface should be checked also.");
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
if((EPB.nt_flags & 0x02) == 0x02)
|
||||
sb.AppendLine("Disk surface should be checked also.");
|
||||
xmlFSType.Dirty = true;
|
||||
}
|
||||
|
||||
|
||||
sb.AppendFormat("Volume label: {0}", EPB.volume_label).AppendLine();
|
||||
if(!string.IsNullOrEmpty(EPB.volume_label))
|
||||
xmlFSType.VolumeName = EPB.volume_label;
|
||||
sb.AppendFormat("Filesystem type: {0}", EPB.fs_type).AppendLine();
|
||||
}
|
||||
else if (EPB.signature == 0x28 || EPB.signature == 0x29)
|
||||
else if(EPB.signature == 0x28 || EPB.signature == 0x29)
|
||||
{
|
||||
sb.AppendFormat("Drive number: 0x{0:X2}", EPB.drive_no).AppendLine();
|
||||
sb.AppendFormat("Volume Serial Number: 0x{0:X8}", EPB.serial_no).AppendLine();
|
||||
xmlFSType.VolumeSerial = String.Format("{0:X8}", EPB.serial_no);
|
||||
if (EPB.signature == 0x29)
|
||||
if(EPB.signature == 0x29)
|
||||
{
|
||||
if ((EPB.nt_flags & 0x01) == 0x01)
|
||||
if((EPB.nt_flags & 0x01) == 0x01)
|
||||
{
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
if ((EPB.nt_flags & 0x02) == 0x02)
|
||||
sb.AppendLine("Disk surface should be checked also.");
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
if((EPB.nt_flags & 0x02) == 0x02)
|
||||
sb.AppendLine("Disk surface should be checked also.");
|
||||
xmlFSType.Dirty = true;
|
||||
}
|
||||
|
||||
|
||||
sb.AppendFormat("Volume label: {0}", EPB.volume_label).AppendLine();
|
||||
if(!string.IsNullOrEmpty(EPB.volume_label))
|
||||
xmlFSType.VolumeName = EPB.volume_label;
|
||||
@@ -368,10 +368,10 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendLine("This may be a false positive.");
|
||||
sb.AppendFormat("Disk image identifies disk type as {0}.", imagePlugin.GetMediaType()).AppendLine();
|
||||
}
|
||||
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>FAT's BIOS Parameter Block.</summary>
|
||||
public struct BIOSParameterBlock
|
||||
{
|
||||
|
||||
@@ -56,60 +56,60 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
UInt32 magic;
|
||||
uint sb_size_in_sectors;
|
||||
byte[] ufs_sb_sectors;
|
||||
|
||||
if (imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
sb_size_in_sectors = block_size / 2048;
|
||||
else
|
||||
sb_size_in_sectors = block_size / imagePlugin.GetSectorSize();
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_floppy * sb_size_in_sectors + sb_size_in_sectors))
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_floppy * sb_size_in_sectors + sb_size_in_sectors))
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_floppy * sb_size_in_sectors, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_ufs1 * sb_size_in_sectors + sb_size_in_sectors))
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_ufs1 * sb_size_in_sectors + sb_size_in_sectors))
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_ufs1 * sb_size_in_sectors, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_ufs2 * sb_size_in_sectors + sb_size_in_sectors))
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_ufs2 * sb_size_in_sectors + sb_size_in_sectors))
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_ufs2 * sb_size_in_sectors, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_piggy * sb_size_in_sectors + sb_size_in_sectors))
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_piggy * sb_size_in_sectors + sb_size_in_sectors))
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_piggy * sb_size_in_sectors, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_atari / imagePlugin.GetSectorSize() + sb_size_in_sectors))
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_atari / imagePlugin.GetSectorSize() + sb_size_in_sectors))
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + (sb_start_atari / imagePlugin.GetSectorSize()), sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -133,67 +133,67 @@ namespace DiscImageChef.Plugins
|
||||
bool fs_type_sun = false;
|
||||
bool fs_type_sun86 = false;
|
||||
|
||||
if (imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
sb_size_in_sectors = block_size / 2048;
|
||||
else
|
||||
sb_size_in_sectors = block_size / imagePlugin.GetSectorSize();
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_floppy * sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
|
||||
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_floppy * sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_floppy * sb_size_in_sectors, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
sb_offset = partitionStart + sb_start_floppy * sb_size_in_sectors;
|
||||
else
|
||||
magic = 0;
|
||||
}
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_ufs1 * sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_ufs1 * sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_ufs1 * sb_size_in_sectors, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
sb_offset = partitionStart + sb_start_ufs1 * sb_size_in_sectors;
|
||||
else
|
||||
magic = 0;
|
||||
}
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_ufs2 * sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_ufs2 * sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_ufs2 * sb_size_in_sectors, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
sb_offset = partitionStart + sb_start_ufs2 * sb_size_in_sectors;
|
||||
else
|
||||
magic = 0;
|
||||
}
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_piggy * sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_piggy * sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_piggy * sb_size_in_sectors, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
sb_offset = partitionStart + sb_start_piggy * sb_size_in_sectors;
|
||||
else
|
||||
magic = 0;
|
||||
}
|
||||
|
||||
if (imagePlugin.GetSectors() > (partitionStart + sb_start_atari / imagePlugin.GetSectorSize() + sb_size_in_sectors) && magic == 0)
|
||||
{
|
||||
if(imagePlugin.GetSectors() > (partitionStart + sb_start_atari / imagePlugin.GetSectorSize() + sb_size_in_sectors) && magic == 0)
|
||||
{
|
||||
ufs_sb_sectors = imagePlugin.ReadSectors(partitionStart + sb_start_atari / imagePlugin.GetSectorSize(), sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
|
||||
|
||||
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
if(magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
|
||||
sb_offset = partitionStart + sb_start_atari / imagePlugin.GetSectorSize();
|
||||
else
|
||||
magic = 0;
|
||||
}
|
||||
|
||||
if (magic == 0)
|
||||
if(magic == 0)
|
||||
{
|
||||
information = "Not a UFS filesystem, I shouldn't have arrived here!";
|
||||
return;
|
||||
@@ -201,7 +201,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
|
||||
switch (magic)
|
||||
switch(magic)
|
||||
{
|
||||
case UFS_MAGIC:
|
||||
sbInformation.AppendLine("UFS filesystem");
|
||||
@@ -549,7 +549,7 @@ namespace DiscImageChef.Plugins
|
||||
sbInformation.AppendLine("There are a lot of variants of UFS using overlapped values on same fields");
|
||||
sbInformation.AppendLine("I will try to guess which one it is, but unless it's UFS2, I may be surely wrong");
|
||||
|
||||
if (ufs_sb.fs_magic == UFS2_MAGIC)
|
||||
if(ufs_sb.fs_magic == UFS2_MAGIC)
|
||||
{
|
||||
fs_type_ufs2 = true;
|
||||
}
|
||||
@@ -559,13 +559,13 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
fs_type_43bsd = true; // There is no way of knowing this is the version, but there is of knowing it is not.
|
||||
|
||||
if (ufs_sb.fs_link_42bsd > 0)
|
||||
if(ufs_sb.fs_link_42bsd > 0)
|
||||
{
|
||||
fs_type_42bsd = true; // It was used in 4.2BSD
|
||||
fs_type_43bsd = false;
|
||||
}
|
||||
|
||||
if (ufs_sb.fs_state_t_sun > SunOSEpoch && DateHandlers.UNIXUnsignedToDateTime(ufs_sb.fs_state_t_sun) < DateTime.Now)
|
||||
if(ufs_sb.fs_state_t_sun > SunOSEpoch && DateHandlers.UNIXUnsignedToDateTime(ufs_sb.fs_state_t_sun) < DateTime.Now)
|
||||
{
|
||||
fs_type_42bsd = false;
|
||||
fs_type_sun = true;
|
||||
@@ -573,7 +573,7 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
|
||||
// This is for sure, as it is shared with a sectors/track with non-x86 SunOS, Epoch is absurdly high for that
|
||||
if (ufs_sb.fs_state_t_sun86 > SunOSEpoch && DateHandlers.UNIXUnsignedToDateTime(ufs_sb.fs_state_t_sun) < DateTime.Now)
|
||||
if(ufs_sb.fs_state_t_sun86 > SunOSEpoch && DateHandlers.UNIXUnsignedToDateTime(ufs_sb.fs_state_t_sun) < DateTime.Now)
|
||||
{
|
||||
fs_type_42bsd = false;
|
||||
fs_type_sun86 = true;
|
||||
@@ -581,7 +581,7 @@ namespace DiscImageChef.Plugins
|
||||
fs_type_43bsd = false;
|
||||
}
|
||||
|
||||
if (ufs_sb.fs_cgrotor_ufs1 > 0x00000000 && ufs_sb.fs_cgrotor_ufs1 < 0xFFFFFFFF)
|
||||
if(ufs_sb.fs_cgrotor_ufs1 > 0x00000000 && ufs_sb.fs_cgrotor_ufs1 < 0xFFFFFFFF)
|
||||
{
|
||||
fs_type_42bsd = false;
|
||||
fs_type_sun = false;
|
||||
@@ -597,24 +597,24 @@ namespace DiscImageChef.Plugins
|
||||
fs_type_44bsd |= ufs_sb.fs_inodefmt_44bsd == 2;
|
||||
}
|
||||
|
||||
if (fs_type_42bsd)
|
||||
if(fs_type_42bsd)
|
||||
sbInformation.AppendLine("Guessed as 42BSD FFS");
|
||||
if (fs_type_43bsd)
|
||||
if(fs_type_43bsd)
|
||||
sbInformation.AppendLine("Guessed as 43BSD FFS");
|
||||
if (fs_type_44bsd)
|
||||
if(fs_type_44bsd)
|
||||
sbInformation.AppendLine("Guessed as 44BSD FFS");
|
||||
if (fs_type_sun)
|
||||
if(fs_type_sun)
|
||||
sbInformation.AppendLine("Guessed as SunOS FFS");
|
||||
if (fs_type_sun86)
|
||||
if(fs_type_sun86)
|
||||
sbInformation.AppendLine("Guessed as SunOS/x86 FFS");
|
||||
if (fs_type_ufs)
|
||||
if(fs_type_ufs)
|
||||
sbInformation.AppendLine("Guessed as UFS");
|
||||
if (fs_type_ufs2)
|
||||
if(fs_type_ufs2)
|
||||
sbInformation.AppendLine("Guessed as UFS2");
|
||||
|
||||
if (fs_type_42bsd)
|
||||
if(fs_type_42bsd)
|
||||
sbInformation.AppendFormat("Linked list of filesystems: 0x{0:X8}", ufs_sb.fs_link_42bsd).AppendLine();
|
||||
else if (fs_type_sun)
|
||||
else if(fs_type_sun)
|
||||
sbInformation.AppendFormat("Filesystem state flag: 0x{0:X8}", ufs_sb.fs_state_sun).AppendLine();
|
||||
sbInformation.AppendFormat("Superblock LBA: {0}", ufs_sb.fs_sblkno).AppendLine();
|
||||
sbInformation.AppendFormat("Cylinder-block LBA: {0}", ufs_sb.fs_cblkno).AppendLine();
|
||||
@@ -633,34 +633,34 @@ namespace DiscImageChef.Plugins
|
||||
sbInformation.AppendFormat("{0}% of blocks must be free", ufs_sb.fs_minfree).AppendLine();
|
||||
sbInformation.AppendFormat("{0}ms for optimal next block", ufs_sb.fs_rotdelay).AppendLine();
|
||||
sbInformation.AppendFormat("disk rotates {0} times per second ({1}rpm)", ufs_sb.fs_rps, ufs_sb.fs_rps * 60).AppendLine();
|
||||
/* sbInformation.AppendFormat("fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask).AppendLine();
|
||||
sbInformation.AppendFormat("fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask).AppendLine();
|
||||
sbInformation.AppendFormat("fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift).AppendLine();
|
||||
sbInformation.AppendFormat("fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift).AppendLine();*/
|
||||
/* sbInformation.AppendFormat("fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask).AppendLine();
|
||||
sbInformation.AppendFormat("fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask).AppendLine();
|
||||
sbInformation.AppendFormat("fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift).AppendLine();
|
||||
sbInformation.AppendFormat("fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift).AppendLine();*/
|
||||
sbInformation.AppendFormat("{0} contiguous blocks at maximum", ufs_sb.fs_maxcontig).AppendLine();
|
||||
sbInformation.AppendFormat("{0} blocks per cylinder group at maximum", ufs_sb.fs_maxbpg).AppendLine();
|
||||
sbInformation.AppendFormat("Superblock is {0} bytes", ufs_sb.fs_sbsize).AppendLine();
|
||||
sbInformation.AppendFormat("NINDIR: 0x{0:X8}", ufs_sb.fs_nindir).AppendLine();
|
||||
sbInformation.AppendFormat("INOPB: 0x{0:X8}", ufs_sb.fs_inopb).AppendLine();
|
||||
sbInformation.AppendFormat("NSPF: 0x{0:X8}", ufs_sb.fs_nspf).AppendLine();
|
||||
if (ufs_sb.fs_optim == 0)
|
||||
if(ufs_sb.fs_optim == 0)
|
||||
sbInformation.AppendLine("Filesystem will minimize allocation time");
|
||||
else if (ufs_sb.fs_optim == 1)
|
||||
else if(ufs_sb.fs_optim == 1)
|
||||
sbInformation.AppendLine("Filesystem will minimize volume fragmentation");
|
||||
else
|
||||
sbInformation.AppendFormat("Unknown optimization value: 0x{0:X8}", ufs_sb.fs_optim).AppendLine();
|
||||
if (fs_type_sun)
|
||||
if(fs_type_sun)
|
||||
sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_npsect_sun).AppendLine();
|
||||
else if (fs_type_sun86)
|
||||
else if(fs_type_sun86)
|
||||
sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UNIXUnsignedToDateTime(ufs_sb.fs_state_t_sun86)).AppendLine();
|
||||
sbInformation.AppendFormat("Hardware sector interleave: {0}", ufs_sb.fs_interleave).AppendLine();
|
||||
sbInformation.AppendFormat("Sector 0 skew: {0}/track", ufs_sb.fs_trackskew).AppendLine();
|
||||
if (!fs_type_43bsd && ufs_sb.fs_id_1 > 0 && ufs_sb.fs_id_2 > 0)
|
||||
if(!fs_type_43bsd && ufs_sb.fs_id_1 > 0 && ufs_sb.fs_id_2 > 0)
|
||||
{
|
||||
sbInformation.AppendFormat("Volume ID: 0x{0:X8}{1:X8}", ufs_sb.fs_id_1, ufs_sb.fs_id_2).AppendLine();
|
||||
xmlFSType.VolumeSerial = String.Format("{0:X8}{1:x8}", ufs_sb.fs_id_1, ufs_sb.fs_id_2);
|
||||
}
|
||||
else if (fs_type_43bsd && ufs_sb.fs_headswitch_43bsd > 0 && ufs_sb.fs_trkseek_43bsd > 0)
|
||||
else if(fs_type_43bsd && ufs_sb.fs_headswitch_43bsd > 0 && ufs_sb.fs_trkseek_43bsd > 0)
|
||||
{
|
||||
sbInformation.AppendFormat("{0} µsec for head switch", ufs_sb.fs_headswitch_43bsd).AppendLine();
|
||||
sbInformation.AppendFormat("{0} µsec for track-to-track seek", ufs_sb.fs_trkseek_43bsd).AppendLine();
|
||||
@@ -681,22 +681,22 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.FreeClustersSpecified = true;
|
||||
sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_cstotal_nifree).AppendLine();
|
||||
sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_cstotal_nffree).AppendLine();
|
||||
if (ufs_sb.fs_fmod == 1)
|
||||
if(ufs_sb.fs_fmod == 1)
|
||||
{
|
||||
sbInformation.AppendLine("Superblock is under modification");
|
||||
xmlFSType.Dirty = true;
|
||||
}
|
||||
if (ufs_sb.fs_clean == 1)
|
||||
if(ufs_sb.fs_clean == 1)
|
||||
sbInformation.AppendLine("Volume is clean");
|
||||
if (ufs_sb.fs_ronly == 1)
|
||||
if(ufs_sb.fs_ronly == 1)
|
||||
sbInformation.AppendLine("Volume is read-only");
|
||||
sbInformation.AppendFormat("Volume flags: 0x{0:X2}", ufs_sb.fs_flags).AppendLine();
|
||||
if (fs_type_ufs)
|
||||
if(fs_type_ufs)
|
||||
{
|
||||
sbInformation.AppendFormat("Volume last mounted on \"{0}\"", ufs_sb.fs_fsmnt_ufs1).AppendLine();
|
||||
sbInformation.AppendFormat("Last searched cylinder group: {0}", ufs_sb.fs_cgrotor_ufs1).AppendLine();
|
||||
}
|
||||
else if (fs_type_ufs2)
|
||||
else if(fs_type_ufs2)
|
||||
{
|
||||
sbInformation.AppendFormat("Volume last mounted on \"{0}\"", ufs_sb.fs_fsmnt_ufs2).AppendLine();
|
||||
sbInformation.AppendFormat("Volume name: \"{0}\"", ufs_sb.fs_volname_ufs2).AppendLine();
|
||||
@@ -723,15 +723,15 @@ namespace DiscImageChef.Plugins
|
||||
sbInformation.AppendFormat("{0} blocks pending of being freed", ufs_sb.fs_pendingblocks_ufs2).AppendLine();
|
||||
sbInformation.AppendFormat("{0} inodes pending of being freed", ufs_sb.fs_pendinginodes_ufs2).AppendLine();
|
||||
}
|
||||
if (fs_type_sun)
|
||||
if(fs_type_sun)
|
||||
{
|
||||
sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UNIXUnsignedToDateTime(ufs_sb.fs_state_t_sun)).AppendLine();
|
||||
}
|
||||
else if (fs_type_sun86)
|
||||
else if(fs_type_sun86)
|
||||
{
|
||||
sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_npsect_sun86).AppendLine();
|
||||
}
|
||||
else if (fs_type_44bsd)
|
||||
else if(fs_type_44bsd)
|
||||
{
|
||||
sbInformation.AppendFormat("{0} blocks on cluster summary array", ufs_sb.fs_contigsumsize_44bsd).AppendLine();
|
||||
sbInformation.AppendFormat("Maximum length of a symbolic link: {0}", ufs_sb.fs_maxsymlinklen_44bsd).AppendLine();
|
||||
|
||||
@@ -54,16 +54,16 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
UInt32 magic1, magic2;
|
||||
|
||||
|
||||
byte[] hpfs_sb_sector = imagePlugin.ReadSector(16 + partitionStart); // Seek to superblock, on logical sector 16
|
||||
magic1 = BitConverter.ToUInt32(hpfs_sb_sector, 0x000);
|
||||
magic2 = BitConverter.ToUInt32(hpfs_sb_sector, 0x004);
|
||||
|
||||
if (magic1 == 0xF995E849 && magic2 == 0xFA53E9C5)
|
||||
|
||||
if(magic1 == 0xF995E849 && magic2 == 0xFA53E9C5)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -71,16 +71,16 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
HPFS_BIOSParameterBlock hpfs_bpb = new HPFS_BIOSParameterBlock();
|
||||
HPFS_SuperBlock hpfs_sb = new HPFS_SuperBlock();
|
||||
HPFS_SpareBlock hpfs_sp = new HPFS_SpareBlock();
|
||||
|
||||
|
||||
byte[] oem_name = new byte[8];
|
||||
byte[] volume_name = new byte[11];
|
||||
|
||||
|
||||
byte[] hpfs_bpb_sector = imagePlugin.ReadSector(0 + partitionStart); // Seek to BIOS parameter block, on logical sector 0
|
||||
byte[] hpfs_sb_sector = imagePlugin.ReadSector(16 + partitionStart); // Seek to superblock, on logical sector 16
|
||||
byte[] hpfs_sp_sector = imagePlugin.ReadSector(17 + partitionStart); // Seek to spareblock, on logical sector 17
|
||||
@@ -109,7 +109,7 @@ namespace DiscImageChef.Plugins
|
||||
hpfs_bpb.volume_label = StringHandlers.CToString(volume_name);
|
||||
Array.Copy(hpfs_bpb_sector, 0x03A, oem_name, 0, 8);
|
||||
hpfs_bpb.fs_type = StringHandlers.CToString(oem_name);
|
||||
|
||||
|
||||
hpfs_sb.magic1 = BitConverter.ToUInt32(hpfs_sb_sector, 0x000);
|
||||
hpfs_sb.magic2 = BitConverter.ToUInt32(hpfs_sb_sector, 0x004);
|
||||
hpfs_sb.version = hpfs_sb_sector[0x008];
|
||||
@@ -148,8 +148,8 @@ namespace DiscImageChef.Plugins
|
||||
hpfs_sp.codepages = BitConverter.ToUInt32(hpfs_sp_sector, 0x024);
|
||||
hpfs_sp.sb_crc32 = BitConverter.ToUInt32(hpfs_sp_sector, 0x028);
|
||||
hpfs_sp.sp_crc32 = BitConverter.ToUInt32(hpfs_sp_sector, 0x02C);
|
||||
|
||||
if (hpfs_bpb.fs_type != "HPFS " ||
|
||||
|
||||
if(hpfs_bpb.fs_type != "HPFS " ||
|
||||
hpfs_sb.magic1 != 0xF995E849 || hpfs_sb.magic2 != 0xFA53E9C5 ||
|
||||
hpfs_sp.magic1 != 0xF9911849 || hpfs_sp.magic2 != 0xFA5229C5)
|
||||
{
|
||||
@@ -160,39 +160,39 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Spareblock magic1: 0x{0:X8} (Should be 0xF9911849)", hpfs_sp.magic1).AppendLine();
|
||||
sb.AppendFormat("Spareblock magic2: 0x{0:X8} (Should be 0xFA5229C5)", hpfs_sp.magic2).AppendLine();
|
||||
}
|
||||
|
||||
|
||||
sb.AppendFormat("OEM name: {0}", hpfs_bpb.OEMName).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector", hpfs_bpb.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster", hpfs_bpb.spc).AppendLine();
|
||||
// sb.AppendFormat("{0} reserved sectors", hpfs_bpb.rsectors).AppendLine();
|
||||
// sb.AppendFormat("{0} FATs", hpfs_bpb.fats_no).AppendLine();
|
||||
// sb.AppendFormat("{0} entries on root directory", hpfs_bpb.root_ent).AppendLine();
|
||||
// sb.AppendFormat("{0} mini sectors on volume", hpfs_bpb.sectors).AppendLine();
|
||||
// sb.AppendFormat("{0} reserved sectors", hpfs_bpb.rsectors).AppendLine();
|
||||
// sb.AppendFormat("{0} FATs", hpfs_bpb.fats_no).AppendLine();
|
||||
// sb.AppendFormat("{0} entries on root directory", hpfs_bpb.root_ent).AppendLine();
|
||||
// sb.AppendFormat("{0} mini sectors on volume", hpfs_bpb.sectors).AppendLine();
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", hpfs_bpb.media).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per FAT", hpfs_bpb.spfat).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per track", hpfs_bpb.sptrk).AppendLine();
|
||||
// sb.AppendFormat("{0} heads", hpfs_bpb.heads).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per FAT", hpfs_bpb.spfat).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per track", hpfs_bpb.sptrk).AppendLine();
|
||||
// sb.AppendFormat("{0} heads", hpfs_bpb.heads).AppendLine();
|
||||
sb.AppendFormat("{0} sectors hidden before BPB", hpfs_bpb.hsectors).AppendLine();
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfs_bpb.big_sectors, hpfs_bpb.big_sectors * hpfs_bpb.bps).AppendLine();
|
||||
sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", hpfs_bpb.drive_no).AppendLine();
|
||||
// sb.AppendFormat("NT Flags: 0x{0:X2}", hpfs_bpb.nt_flags).AppendLine();
|
||||
// sb.AppendFormat("NT Flags: 0x{0:X2}", hpfs_bpb.nt_flags).AppendLine();
|
||||
sb.AppendFormat("Signature: 0x{0:X2}", hpfs_bpb.signature).AppendLine();
|
||||
sb.AppendFormat("Serial number: 0x{0:X8}", hpfs_bpb.serial_no).AppendLine();
|
||||
sb.AppendFormat("Volume label: {0}", hpfs_bpb.volume_label).AppendLine();
|
||||
// sb.AppendFormat("Filesystem type: \"{0}\"", hpfs_bpb.fs_type).AppendLine();
|
||||
|
||||
// sb.AppendFormat("Filesystem type: \"{0}\"", hpfs_bpb.fs_type).AppendLine();
|
||||
|
||||
DateTime last_chk = DateHandlers.UNIXToDateTime(hpfs_sb.last_chkdsk);
|
||||
DateTime last_optim = DateHandlers.UNIXToDateTime(hpfs_sb.last_optim);
|
||||
|
||||
|
||||
sb.AppendFormat("HPFS version: {0}", hpfs_sb.version).AppendLine();
|
||||
sb.AppendFormat("Functional version: {0}", hpfs_sb.func_version).AppendLine();
|
||||
sb.AppendFormat("Sector of root directory FNode: {0}", hpfs_sb.root_fnode).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume", hpfs_sb.sectors).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume", hpfs_sb.sectors).AppendLine();
|
||||
sb.AppendFormat("{0} sectors are marked bad", hpfs_sb.badblocks).AppendLine();
|
||||
sb.AppendFormat("Sector of free space bitmaps: {0}", hpfs_sb.bitmap_lsn).AppendLine();
|
||||
sb.AppendFormat("Sector of bad blocks list: {0}", hpfs_sb.badblock_lsn).AppendLine();
|
||||
sb.AppendFormat("Date of last integrity check: {0}", last_chk).AppendLine();
|
||||
if (hpfs_sb.last_optim > 0)
|
||||
if(hpfs_sb.last_optim > 0)
|
||||
sb.AppendFormat("Date of last optimization {0}", last_optim).AppendLine();
|
||||
else
|
||||
sb.AppendLine("Filesystem has never been optimized");
|
||||
@@ -201,7 +201,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Directory band ends at sector {0}", hpfs_sb.dband_last).AppendLine();
|
||||
sb.AppendFormat("Sector of directory band bitmap: {0}", hpfs_sb.dband_bitmap).AppendLine();
|
||||
sb.AppendFormat("Sector of ACL directory: {0}", hpfs_sb.acl_start).AppendLine();
|
||||
|
||||
|
||||
sb.AppendFormat("Sector of Hotfix directory: {0}", hpfs_sp.hotfix_start).AppendLine();
|
||||
sb.AppendFormat("{0} used Hotfix entries", hpfs_sp.hotfix_used).AppendLine();
|
||||
sb.AppendFormat("{0} total Hotfix entries", hpfs_sp.hotfix_entries).AppendLine();
|
||||
@@ -211,41 +211,41 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("{0} codepages used in the volume", hpfs_sp.codepages).AppendLine();
|
||||
sb.AppendFormat("SuperBlock CRC32: {0:X8}", hpfs_sp.sb_crc32).AppendLine();
|
||||
sb.AppendFormat("SpareBlock CRC32: {0:X8}", hpfs_sp.sp_crc32).AppendLine();
|
||||
|
||||
|
||||
sb.AppendLine("Flags:");
|
||||
if ((hpfs_sp.flags1 & 0x01) == 0x01)
|
||||
if((hpfs_sp.flags1 & 0x01) == 0x01)
|
||||
sb.AppendLine("Filesystem is dirty.");
|
||||
else
|
||||
sb.AppendLine("Filesystem is clean.");
|
||||
if ((hpfs_sp.flags1 & 0x02) == 0x02)
|
||||
if((hpfs_sp.flags1 & 0x02) == 0x02)
|
||||
sb.AppendLine("Spare directory blocks are in use");
|
||||
if ((hpfs_sp.flags1 & 0x04) == 0x04)
|
||||
if((hpfs_sp.flags1 & 0x04) == 0x04)
|
||||
sb.AppendLine("Hotfixes are in use");
|
||||
if ((hpfs_sp.flags1 & 0x08) == 0x08)
|
||||
if((hpfs_sp.flags1 & 0x08) == 0x08)
|
||||
sb.AppendLine("Disk contains bad sectors");
|
||||
if ((hpfs_sp.flags1 & 0x10) == 0x10)
|
||||
if((hpfs_sp.flags1 & 0x10) == 0x10)
|
||||
sb.AppendLine("Disk has a bad bitmap");
|
||||
if ((hpfs_sp.flags1 & 0x20) == 0x20)
|
||||
if((hpfs_sp.flags1 & 0x20) == 0x20)
|
||||
sb.AppendLine("Filesystem was formatted fast");
|
||||
if ((hpfs_sp.flags1 & 0x40) == 0x40)
|
||||
if((hpfs_sp.flags1 & 0x40) == 0x40)
|
||||
sb.AppendLine("Unknown flag 0x40 on flags1 is active");
|
||||
if ((hpfs_sp.flags1 & 0x80) == 0x80)
|
||||
if((hpfs_sp.flags1 & 0x80) == 0x80)
|
||||
sb.AppendLine("Filesystem has been mounted by an old IFS");
|
||||
if ((hpfs_sp.flags2 & 0x01) == 0x01)
|
||||
if((hpfs_sp.flags2 & 0x01) == 0x01)
|
||||
sb.AppendLine("Install DASD limits");
|
||||
if ((hpfs_sp.flags2 & 0x02) == 0x02)
|
||||
if((hpfs_sp.flags2 & 0x02) == 0x02)
|
||||
sb.AppendLine("Resync DASD limits");
|
||||
if ((hpfs_sp.flags2 & 0x04) == 0x04)
|
||||
if((hpfs_sp.flags2 & 0x04) == 0x04)
|
||||
sb.AppendLine("DASD limits are operational");
|
||||
if ((hpfs_sp.flags2 & 0x08) == 0x08)
|
||||
if((hpfs_sp.flags2 & 0x08) == 0x08)
|
||||
sb.AppendLine("Multimedia is active");
|
||||
if ((hpfs_sp.flags2 & 0x10) == 0x10)
|
||||
if((hpfs_sp.flags2 & 0x10) == 0x10)
|
||||
sb.AppendLine("DCE ACLs are active");
|
||||
if ((hpfs_sp.flags2 & 0x20) == 0x20)
|
||||
if((hpfs_sp.flags2 & 0x20) == 0x20)
|
||||
sb.AppendLine("DASD limits are dirty");
|
||||
if ((hpfs_sp.flags2 & 0x40) == 0x40)
|
||||
if((hpfs_sp.flags2 & 0x40) == 0x40)
|
||||
sb.AppendLine("Unknown flag 0x40 on flags2 is active");
|
||||
if ((hpfs_sp.flags2 & 0x80) == 0x80)
|
||||
if((hpfs_sp.flags2 & 0x80) == 0x80)
|
||||
sb.AppendLine("Unknown flag 0x80 on flags2 is active");
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
@@ -255,7 +255,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.Type = "HPFS";
|
||||
xmlFSType.VolumeName = hpfs_bpb.volume_label;
|
||||
xmlFSType.VolumeSerial = String.Format("{0:X8}", hpfs_bpb.serial_no);
|
||||
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,13 +52,13 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
class ISO9660Plugin : Plugin
|
||||
{
|
||||
//static bool alreadyLaunched;
|
||||
//static bool alreadyLaunched;
|
||||
|
||||
public ISO9660Plugin()
|
||||
{
|
||||
Name = "ISO9660 Filesystem";
|
||||
PluginUUID = new Guid("d812f4d3-c357-400d-90fd-3b22ef786aa8");
|
||||
//alreadyLaunched = false;
|
||||
//alreadyLaunched = false;
|
||||
}
|
||||
|
||||
struct DecodedVolumeDescriptor
|
||||
@@ -80,43 +80,43 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
/* if (alreadyLaunched)
|
||||
return false;
|
||||
alreadyLaunched = true;*/
|
||||
/* if (alreadyLaunched)
|
||||
return false;
|
||||
alreadyLaunched = true;*/
|
||||
|
||||
byte VDType;
|
||||
|
||||
// ISO9660 is designed for 2048 bytes/sector devices
|
||||
if (imagePlugin.GetSectorSize() < 2048)
|
||||
if(imagePlugin.GetSectorSize() < 2048)
|
||||
return false;
|
||||
|
||||
// ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size.
|
||||
if (imagePlugin.GetSectors() <= (16 + partitionStart))
|
||||
if(imagePlugin.GetSectors() <= (16 + partitionStart))
|
||||
return false;
|
||||
|
||||
// Read to Volume Descriptor
|
||||
byte[] vd_sector = imagePlugin.ReadSector(16 + partitionStart);
|
||||
|
||||
int xa_off = 0;
|
||||
if (vd_sector.Length == 2336)
|
||||
if(vd_sector.Length == 2336)
|
||||
xa_off = 8;
|
||||
|
||||
VDType = vd_sector[0 + xa_off];
|
||||
byte[] VDMagic = new byte[5];
|
||||
|
||||
// Wrong, VDs can be any order!
|
||||
if (VDType == 255) // Supposedly we are in the PVD.
|
||||
return false;
|
||||
if(VDType == 255) // Supposedly we are in the PVD.
|
||||
return false;
|
||||
|
||||
Array.Copy(vd_sector, 0x001 + xa_off, VDMagic, 0, 5);
|
||||
|
||||
DicConsole.DebugWriteLine("ISO9660 plugin", "VDMagic = {0}", Encoding.ASCII.GetString(VDMagic));
|
||||
|
||||
return Encoding.ASCII.GetString(VDMagic) == "CD001";
|
||||
return Encoding.ASCII.GetString(VDMagic) == "CD001";
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
StringBuilder ISOMetadata = new StringBuilder();
|
||||
bool Joliet = false;
|
||||
@@ -154,23 +154,23 @@ namespace DiscImageChef.Plugins
|
||||
byte[] RootDirectoryLocation = new byte[4];
|
||||
|
||||
// ISO9660 is designed for 2048 bytes/sector devices
|
||||
if (imagePlugin.GetSectorSize() < 2048)
|
||||
if(imagePlugin.GetSectorSize() < 2048)
|
||||
return;
|
||||
|
||||
// ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size.
|
||||
if (imagePlugin.GetSectors() < 16)
|
||||
if(imagePlugin.GetSectors() < 16)
|
||||
return;
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
while (true)
|
||||
while(true)
|
||||
{
|
||||
DicConsole.DebugWriteLine("ISO9660 plugin", "Processing VD loop no. {0}", counter);
|
||||
// Seek to Volume Descriptor
|
||||
DicConsole.DebugWriteLine("ISO9660 plugin", "Reading sector {0}", 16 + counter + partitionStart);
|
||||
byte[] vd_sector_tmp = imagePlugin.ReadSector(16 + counter + partitionStart);
|
||||
byte[] vd_sector;
|
||||
if (vd_sector_tmp.Length == 2336)
|
||||
if(vd_sector_tmp.Length == 2336)
|
||||
{
|
||||
vd_sector = new byte[2336 - 8];
|
||||
Array.Copy(vd_sector_tmp, 8, vd_sector, 0, 2336 - 8);
|
||||
@@ -181,18 +181,18 @@ namespace DiscImageChef.Plugins
|
||||
VDType = vd_sector[0];
|
||||
DicConsole.DebugWriteLine("ISO9660 plugin", "VDType = {0}", VDType);
|
||||
|
||||
if (VDType == 255) // Supposedly we are in the PVD.
|
||||
if(VDType == 255) // Supposedly we are in the PVD.
|
||||
{
|
||||
if (counter == 0)
|
||||
if(counter == 0)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
Array.Copy(vd_sector, 0x001, VDMagic, 0, 5);
|
||||
|
||||
if (Encoding.ASCII.GetString(VDMagic) != "CD001") // Recognized, it is an ISO9660, now check for rest of data.
|
||||
if(Encoding.ASCII.GetString(VDMagic) != "CD001") // Recognized, it is an ISO9660, now check for rest of data.
|
||||
{
|
||||
if (counter == 0)
|
||||
if(counter == 0)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
@@ -207,7 +207,7 @@ namespace DiscImageChef.Plugins
|
||||
// Read to boot system identifier
|
||||
Array.Copy(vd_sector, 0x007, BootSysId, 0, 32);
|
||||
|
||||
if (Encoding.ASCII.GetString(BootSysId).Substring(0, 23) == "EL TORITO SPECIFICATION")
|
||||
if(Encoding.ASCII.GetString(BootSysId).Substring(0, 23) == "EL TORITO SPECIFICATION")
|
||||
BootSpec = "El Torito";
|
||||
|
||||
break;
|
||||
@@ -239,9 +239,9 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
// Check if this is Joliet
|
||||
Array.Copy(vd_sector, 0x058, JolietMagic, 0, 3);
|
||||
if (JolietMagic[0] == '%' && JolietMagic[1] == '/')
|
||||
if(JolietMagic[0] == '%' && JolietMagic[1] == '/')
|
||||
{
|
||||
if (JolietMagic[2] == '@' || JolietMagic[2] == 'C' || JolietMagic[2] == 'E')
|
||||
if(JolietMagic[2] == '@' || JolietMagic[2] == 'C' || JolietMagic[2] == 'E')
|
||||
{
|
||||
Joliet = true;
|
||||
}
|
||||
@@ -276,19 +276,19 @@ namespace DiscImageChef.Plugins
|
||||
counter++;
|
||||
}
|
||||
|
||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||
DecodedVolumeDescriptor decodedJolietVD = new DecodedVolumeDescriptor();
|
||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||
DecodedVolumeDescriptor decodedJolietVD = new DecodedVolumeDescriptor();
|
||||
|
||||
decodedVD = DecodeVolumeDescriptor(VDSysId, VDVolId, VDVolSetId, VDPubId, VDDataPrepId, VDAppId, VCTime, VMTime, VXTime, VETime);
|
||||
if(Joliet)
|
||||
decodedJolietVD = DecodeJolietDescriptor(JolietSysId, JolietVolId, JolietVolSetId, JolietPubId, JolietDataPrepId, JolietAppId, JolietCTime, JolietMTime, JolietXTime, JolietETime);
|
||||
decodedVD = DecodeVolumeDescriptor(VDSysId, VDVolId, VDVolSetId, VDPubId, VDDataPrepId, VDAppId, VCTime, VMTime, VXTime, VETime);
|
||||
if(Joliet)
|
||||
decodedJolietVD = DecodeJolietDescriptor(JolietSysId, JolietVolId, JolietVolSetId, JolietPubId, JolietDataPrepId, JolietAppId, JolietCTime, JolietMTime, JolietXTime, JolietETime);
|
||||
|
||||
|
||||
ulong i = (ulong)BitConverter.ToInt32(VDPathTableStart, 0);
|
||||
DicConsole.DebugWriteLine("ISO9660 plugin", "VDPathTableStart = {0} + {1} = {2}", i, partitionStart, i + partitionStart);
|
||||
DicConsole.DebugWriteLine("ISO9660 plugin", "VDPathTableStart = {0} + {1} = {2}", i, partitionStart, i + partitionStart);
|
||||
|
||||
// TODO: Check this
|
||||
if ((i + partitionStart) < imagePlugin.GetSectors())
|
||||
if((i + partitionStart) < imagePlugin.GetSectors())
|
||||
{
|
||||
|
||||
byte[] path_table = imagePlugin.ReadSector(i + partitionStart);
|
||||
@@ -300,7 +300,7 @@ namespace DiscImageChef.Plugins
|
||||
byte[] RRMagic = new byte[2];
|
||||
|
||||
Array.Copy(root_dir, 0x22, SUSPMagic, 0, 2);
|
||||
if (Encoding.ASCII.GetString(SUSPMagic) == "SP")
|
||||
if(Encoding.ASCII.GetString(SUSPMagic) == "SP")
|
||||
{
|
||||
Array.Copy(root_dir, 0x29, RRMagic, 0, 2);
|
||||
RockRidge |= Encoding.ASCII.GetString(RRMagic) == "RR";
|
||||
@@ -308,7 +308,7 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
|
||||
#region SEGA IP.BIN Read and decoding
|
||||
|
||||
|
||||
bool SegaCD = false;
|
||||
bool Saturn = false;
|
||||
bool Dreamcast = false;
|
||||
@@ -320,7 +320,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
DicConsole.DebugWriteLine("ISO9660 plugin", "SegaHardwareID = \"{0}\"", Encoding.ASCII.GetString(SegaHardwareID));
|
||||
|
||||
switch (Encoding.ASCII.GetString(SegaHardwareID))
|
||||
switch(Encoding.ASCII.GetString(SegaHardwareID))
|
||||
{
|
||||
case "SEGADISCSYSTEM ":
|
||||
case "SEGADATADISC ":
|
||||
@@ -389,7 +389,7 @@ namespace DiscImageChef.Plugins
|
||||
Array.Copy(ipbin_sector, 0x060, system_reserved, 0, 160); // System Reserved Area
|
||||
Array.Copy(ipbin_sector, 0x100, hardware_id, 0, 16); // Hardware ID
|
||||
Array.Copy(ipbin_sector, 0x110, copyright, 0, 3); // "(C)" -- Can be the developer code directly!, if that is the code release date will be displaced
|
||||
if (Encoding.ASCII.GetString(copyright) == "(C)")
|
||||
if(Encoding.ASCII.GetString(copyright) == "(C)")
|
||||
Array.Copy(ipbin_sector, 0x113, developer_code, 0, 5); // "SEGA" or "T-xx"
|
||||
else
|
||||
Array.Copy(ipbin_sector, 0x110, developer_code, 0, 5); // "SEGA" or "T-xx"
|
||||
@@ -439,7 +439,7 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
ipbindate = DateTime.ParseExact(Encoding.ASCII.GetString(release_date2), "yyyy.MMM", provider);
|
||||
}
|
||||
catch {}
|
||||
catch { }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -524,9 +524,9 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
}
|
||||
IPBinInformation.AppendLine("Regions supported:");
|
||||
foreach (byte region in region_codes)
|
||||
foreach(byte region in region_codes)
|
||||
{
|
||||
switch ((char)region)
|
||||
switch((char)region)
|
||||
{
|
||||
case 'J':
|
||||
IPBinInformation.AppendLine("Japanese NTSC.");
|
||||
@@ -609,9 +609,9 @@ namespace DiscImageChef.Plugins
|
||||
IPBinInformation.AppendFormat("Disc number {0} of {1}", Encoding.ASCII.GetString(disc_no), Encoding.ASCII.GetString(disc_total_nos)).AppendLine();
|
||||
|
||||
IPBinInformation.AppendFormat("Peripherals:").AppendLine();
|
||||
foreach (byte peripheral in peripherals)
|
||||
foreach(byte peripheral in peripherals)
|
||||
{
|
||||
switch ((char)peripheral)
|
||||
switch((char)peripheral)
|
||||
{
|
||||
case 'A':
|
||||
IPBinInformation.AppendLine("Game supports analog controller.");
|
||||
@@ -639,9 +639,9 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
}
|
||||
IPBinInformation.AppendLine("Regions supported:");
|
||||
foreach (byte region in region_codes)
|
||||
foreach(byte region in region_codes)
|
||||
{
|
||||
switch ((char)region)
|
||||
switch((char)region)
|
||||
{
|
||||
case 'J':
|
||||
IPBinInformation.AppendLine("Japanese NTSC.");
|
||||
@@ -740,7 +740,7 @@ namespace DiscImageChef.Plugins
|
||||
IPBinInformation.AppendFormat("Disc media: {0}", Encoding.ASCII.GetString(dreamcast_media)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Disc number {0} of {1}", Encoding.ASCII.GetString(disc_no), Encoding.ASCII.GetString(disc_total_nos)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine();
|
||||
switch (Encoding.ASCII.GetString(boot_filename))
|
||||
switch(Encoding.ASCII.GetString(boot_filename))
|
||||
{
|
||||
case "1ST_READ.BIN":
|
||||
IPBinInformation.AppendLine("Disc boots natively.");
|
||||
@@ -753,9 +753,9 @@ namespace DiscImageChef.Plugins
|
||||
break;
|
||||
}
|
||||
IPBinInformation.AppendLine("Regions supported:");
|
||||
foreach (byte region in region_codes)
|
||||
foreach(byte region in region_codes)
|
||||
{
|
||||
switch ((char)region)
|
||||
switch((char)region)
|
||||
{
|
||||
case 'J':
|
||||
IPBinInformation.AppendLine("Japanese NTSC.");
|
||||
@@ -781,47 +781,47 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
IPBinInformation.AppendFormat("Peripherals:").AppendLine();
|
||||
|
||||
if ((iPeripherals & 0x00000010) == 0x00000010)
|
||||
if((iPeripherals & 0x00000010) == 0x00000010)
|
||||
IPBinInformation.AppendLine("Game supports the VGA Box.");
|
||||
if ((iPeripherals & 0x00000100) == 0x00000100)
|
||||
if((iPeripherals & 0x00000100) == 0x00000100)
|
||||
IPBinInformation.AppendLine("Game supports other expansion.");
|
||||
if ((iPeripherals & 0x00000200) == 0x00000200)
|
||||
if((iPeripherals & 0x00000200) == 0x00000200)
|
||||
IPBinInformation.AppendLine("Game supports Puru Puru pack.");
|
||||
if ((iPeripherals & 0x00000400) == 0x00000400)
|
||||
if((iPeripherals & 0x00000400) == 0x00000400)
|
||||
IPBinInformation.AppendLine("Game supports Mike Device.");
|
||||
if ((iPeripherals & 0x00000800) == 0x00000800)
|
||||
if((iPeripherals & 0x00000800) == 0x00000800)
|
||||
IPBinInformation.AppendLine("Game supports Memory Card.");
|
||||
if ((iPeripherals & 0x00001000) == 0x00001000)
|
||||
if((iPeripherals & 0x00001000) == 0x00001000)
|
||||
IPBinInformation.AppendLine("Game requires A + B + Start buttons and D-Pad.");
|
||||
if ((iPeripherals & 0x00002000) == 0x00002000)
|
||||
if((iPeripherals & 0x00002000) == 0x00002000)
|
||||
IPBinInformation.AppendLine("Game requires C button.");
|
||||
if ((iPeripherals & 0x00004000) == 0x00004000)
|
||||
if((iPeripherals & 0x00004000) == 0x00004000)
|
||||
IPBinInformation.AppendLine("Game requires D button.");
|
||||
if ((iPeripherals & 0x00008000) == 0x00008000)
|
||||
if((iPeripherals & 0x00008000) == 0x00008000)
|
||||
IPBinInformation.AppendLine("Game requires X button.");
|
||||
if ((iPeripherals & 0x00010000) == 0x00010000)
|
||||
if((iPeripherals & 0x00010000) == 0x00010000)
|
||||
IPBinInformation.AppendLine("Game requires Y button.");
|
||||
if ((iPeripherals & 0x00020000) == 0x00020000)
|
||||
if((iPeripherals & 0x00020000) == 0x00020000)
|
||||
IPBinInformation.AppendLine("Game requires Z button.");
|
||||
if ((iPeripherals & 0x00040000) == 0x00040000)
|
||||
if((iPeripherals & 0x00040000) == 0x00040000)
|
||||
IPBinInformation.AppendLine("Game requires expanded direction buttons.");
|
||||
if ((iPeripherals & 0x00080000) == 0x00080000)
|
||||
if((iPeripherals & 0x00080000) == 0x00080000)
|
||||
IPBinInformation.AppendLine("Game requires analog R trigger.");
|
||||
if ((iPeripherals & 0x00100000) == 0x00100000)
|
||||
if((iPeripherals & 0x00100000) == 0x00100000)
|
||||
IPBinInformation.AppendLine("Game requires analog L trigger.");
|
||||
if ((iPeripherals & 0x00200000) == 0x00200000)
|
||||
if((iPeripherals & 0x00200000) == 0x00200000)
|
||||
IPBinInformation.AppendLine("Game requires analog horizontal controller.");
|
||||
if ((iPeripherals & 0x00400000) == 0x00400000)
|
||||
if((iPeripherals & 0x00400000) == 0x00400000)
|
||||
IPBinInformation.AppendLine("Game requires analog vertical controller.");
|
||||
if ((iPeripherals & 0x00800000) == 0x00800000)
|
||||
if((iPeripherals & 0x00800000) == 0x00800000)
|
||||
IPBinInformation.AppendLine("Game requires expanded analog horizontal controller.");
|
||||
if ((iPeripherals & 0x01000000) == 0x01000000)
|
||||
if((iPeripherals & 0x01000000) == 0x01000000)
|
||||
IPBinInformation.AppendLine("Game requires expanded analog vertical controller.");
|
||||
if ((iPeripherals & 0x02000000) == 0x02000000)
|
||||
if((iPeripherals & 0x02000000) == 0x02000000)
|
||||
IPBinInformation.AppendLine("Game supports Gun.");
|
||||
if ((iPeripherals & 0x04000000) == 0x04000000)
|
||||
if((iPeripherals & 0x04000000) == 0x04000000)
|
||||
IPBinInformation.AppendLine("Game supports Keyboard.");
|
||||
if ((iPeripherals & 0x08000000) == 0x08000000)
|
||||
if((iPeripherals & 0x08000000) == 0x08000000)
|
||||
IPBinInformation.AppendLine("Game supports Mouse.");
|
||||
|
||||
if((iPeripherals & 0xEE) != 0)
|
||||
@@ -835,21 +835,21 @@ namespace DiscImageChef.Plugins
|
||||
ISOMetadata.AppendFormat("ISO9660 file system").AppendLine();
|
||||
if(Joliet)
|
||||
ISOMetadata.AppendFormat("Joliet extensions present.").AppendLine();
|
||||
if (RockRidge)
|
||||
if(RockRidge)
|
||||
ISOMetadata.AppendFormat("Rock Ridge Interchange Protocol present.").AppendLine();
|
||||
if (Bootable)
|
||||
if(Bootable)
|
||||
ISOMetadata.AppendFormat("Disc bootable following {0} specifications.", BootSpec).AppendLine();
|
||||
if (SegaCD)
|
||||
if(SegaCD)
|
||||
{
|
||||
ISOMetadata.AppendLine("This is a SegaCD / MegaCD disc.");
|
||||
ISOMetadata.AppendLine(IPBinInformation.ToString());
|
||||
}
|
||||
if (Saturn)
|
||||
if(Saturn)
|
||||
{
|
||||
ISOMetadata.AppendLine("This is a Sega Saturn disc.");
|
||||
ISOMetadata.AppendLine(IPBinInformation.ToString());
|
||||
}
|
||||
if (Dreamcast)
|
||||
if(Dreamcast)
|
||||
{
|
||||
ISOMetadata.AppendLine("This is a Sega Dreamcast disc.");
|
||||
ISOMetadata.AppendLine(IPBinInformation.ToString());
|
||||
@@ -864,49 +864,49 @@ namespace DiscImageChef.Plugins
|
||||
ISOMetadata.AppendFormat("Data preparer identifier: {0}", decodedVD.DataPreparerIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Application identifier: {0}", decodedVD.ApplicationIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedVD.CreationTime).AppendLine();
|
||||
if (decodedVD.HasModificationTime)
|
||||
if(decodedVD.HasModificationTime)
|
||||
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedVD.ModificationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has not been modified.").AppendLine();
|
||||
if (decodedVD.HasExpirationTime)
|
||||
if(decodedVD.HasExpirationTime)
|
||||
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedVD.ExpirationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume does not expire.").AppendLine();
|
||||
if (decodedVD.HasEffectiveTime)
|
||||
if(decodedVD.HasEffectiveTime)
|
||||
ISOMetadata.AppendFormat("Volume effective date: {0}", decodedVD.EffectiveTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
||||
|
||||
if(Joliet)
|
||||
{
|
||||
ISOMetadata.AppendLine("---------------------------------------");
|
||||
ISOMetadata.AppendLine("JOLIET VOLUME DESCRIPTOR INFORMATION:");
|
||||
ISOMetadata.AppendLine("---------------------------------------");
|
||||
ISOMetadata.AppendFormat("System identifier: {0}", decodedJolietVD.SystemIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume identifier: {0}", decodedJolietVD.VolumeIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume set identifier: {0}", decodedJolietVD.VolumeSetIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Publisher identifier: {0}", decodedJolietVD.PublisherIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Data preparer identifier: {0}", decodedJolietVD.DataPreparerIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Application identifier: {0}", decodedJolietVD.ApplicationIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedJolietVD.CreationTime).AppendLine();
|
||||
if (decodedJolietVD.HasModificationTime)
|
||||
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedJolietVD.ModificationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has not been modified.").AppendLine();
|
||||
if (decodedJolietVD.HasExpirationTime)
|
||||
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedJolietVD.ExpirationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume does not expire.").AppendLine();
|
||||
if (decodedJolietVD.HasEffectiveTime)
|
||||
if(Joliet)
|
||||
{
|
||||
ISOMetadata.AppendLine("---------------------------------------");
|
||||
ISOMetadata.AppendLine("JOLIET VOLUME DESCRIPTOR INFORMATION:");
|
||||
ISOMetadata.AppendLine("---------------------------------------");
|
||||
ISOMetadata.AppendFormat("System identifier: {0}", decodedJolietVD.SystemIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume identifier: {0}", decodedJolietVD.VolumeIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume set identifier: {0}", decodedJolietVD.VolumeSetIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Publisher identifier: {0}", decodedJolietVD.PublisherIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Data preparer identifier: {0}", decodedJolietVD.DataPreparerIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Application identifier: {0}", decodedJolietVD.ApplicationIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedJolietVD.CreationTime).AppendLine();
|
||||
if(decodedJolietVD.HasModificationTime)
|
||||
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedJolietVD.ModificationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has not been modified.").AppendLine();
|
||||
if(decodedJolietVD.HasExpirationTime)
|
||||
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedJolietVD.ExpirationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume does not expire.").AppendLine();
|
||||
if(decodedJolietVD.HasEffectiveTime)
|
||||
ISOMetadata.AppendFormat("Volume effective date: {0}", decodedJolietVD.EffectiveTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
||||
}
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
||||
}
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
xmlFSType.Type = "ISO9660";
|
||||
|
||||
if (Joliet)
|
||||
if(Joliet)
|
||||
{
|
||||
xmlFSType.VolumeName = decodedJolietVD.VolumeIdentifier;
|
||||
|
||||
@@ -914,22 +914,22 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.SystemIdentifier = decodedVD.SystemIdentifier;
|
||||
else
|
||||
xmlFSType.SystemIdentifier = decodedJolietVD.SystemIdentifier;
|
||||
|
||||
|
||||
if(decodedJolietVD.VolumeSetIdentifier == null || decodedVD.VolumeSetIdentifier.Length > decodedJolietVD.VolumeSetIdentifier.Length)
|
||||
xmlFSType.VolumeSetIdentifier = decodedVD.VolumeSetIdentifier;
|
||||
else
|
||||
xmlFSType.VolumeSetIdentifier = decodedJolietVD.VolumeSetIdentifier;
|
||||
|
||||
|
||||
if(decodedJolietVD.PublisherIdentifier == null || decodedVD.PublisherIdentifier.Length > decodedJolietVD.PublisherIdentifier.Length)
|
||||
xmlFSType.PublisherIdentifier = decodedVD.PublisherIdentifier;
|
||||
else
|
||||
xmlFSType.PublisherIdentifier = decodedJolietVD.PublisherIdentifier;
|
||||
|
||||
|
||||
if(decodedJolietVD.DataPreparerIdentifier == null || decodedVD.DataPreparerIdentifier.Length > decodedJolietVD.DataPreparerIdentifier.Length)
|
||||
xmlFSType.DataPreparerIdentifier = decodedVD.DataPreparerIdentifier;
|
||||
else
|
||||
xmlFSType.DataPreparerIdentifier = decodedJolietVD.SystemIdentifier;
|
||||
|
||||
|
||||
if(decodedJolietVD.ApplicationIdentifier == null || decodedVD.ApplicationIdentifier.Length > decodedJolietVD.ApplicationIdentifier.Length)
|
||||
xmlFSType.ApplicationIdentifier = decodedVD.ApplicationIdentifier;
|
||||
else
|
||||
@@ -937,17 +937,17 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
xmlFSType.CreationDate = decodedJolietVD.CreationTime;
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
if (decodedJolietVD.HasModificationTime)
|
||||
if(decodedJolietVD.HasModificationTime)
|
||||
{
|
||||
xmlFSType.ModificationDate = decodedJolietVD.ModificationTime;
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
}
|
||||
if (decodedJolietVD.HasExpirationTime)
|
||||
if(decodedJolietVD.HasExpirationTime)
|
||||
{
|
||||
xmlFSType.ExpirationDate = decodedJolietVD.ExpirationTime;
|
||||
xmlFSType.ExpirationDateSpecified = true;
|
||||
}
|
||||
if (decodedJolietVD.HasEffectiveTime)
|
||||
if(decodedJolietVD.HasEffectiveTime)
|
||||
{
|
||||
xmlFSType.EffectiveDate = decodedJolietVD.EffectiveTime;
|
||||
xmlFSType.EffectiveDateSpecified = true;
|
||||
@@ -963,17 +963,17 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.ApplicationIdentifier = decodedVD.ApplicationIdentifier;
|
||||
xmlFSType.CreationDate = decodedVD.CreationTime;
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
if (decodedVD.HasModificationTime)
|
||||
if(decodedVD.HasModificationTime)
|
||||
{
|
||||
xmlFSType.ModificationDate = decodedVD.ModificationTime;
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
}
|
||||
if (decodedVD.HasExpirationTime)
|
||||
if(decodedVD.HasExpirationTime)
|
||||
{
|
||||
xmlFSType.ExpirationDate = decodedVD.ExpirationTime;
|
||||
xmlFSType.ExpirationDateSpecified = true;
|
||||
}
|
||||
if (decodedVD.HasEffectiveTime)
|
||||
if(decodedVD.HasEffectiveTime)
|
||||
{
|
||||
xmlFSType.EffectiveDate = decodedVD.EffectiveTime;
|
||||
xmlFSType.EffectiveDateSpecified = true;
|
||||
@@ -991,93 +991,93 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||
|
||||
decodedVD.SystemIdentifier = Encoding.BigEndianUnicode.GetString(VDSysId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.VolumeIdentifier = Encoding.BigEndianUnicode.GetString(VDVolId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.VolumeSetIdentifier = Encoding.BigEndianUnicode.GetString(VDVolSetId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.PublisherIdentifier = Encoding.BigEndianUnicode.GetString(VDPubId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.DataPreparerIdentifier = Encoding.BigEndianUnicode.GetString(VDDataPrepId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.ApplicationIdentifier = Encoding.BigEndianUnicode.GetString(VDAppId).TrimEnd().Trim(new []{'\u0000'});
|
||||
if (VCTime[0] == '0' || VCTime[0] == 0x00)
|
||||
decodedVD.SystemIdentifier = Encoding.BigEndianUnicode.GetString(VDSysId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.VolumeIdentifier = Encoding.BigEndianUnicode.GetString(VDVolId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.VolumeSetIdentifier = Encoding.BigEndianUnicode.GetString(VDVolSetId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.PublisherIdentifier = Encoding.BigEndianUnicode.GetString(VDPubId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.DataPreparerIdentifier = Encoding.BigEndianUnicode.GetString(VDDataPrepId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.ApplicationIdentifier = Encoding.BigEndianUnicode.GetString(VDAppId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
if(VCTime[0] == '0' || VCTime[0] == 0x00)
|
||||
decodedVD.CreationTime = DateTime.MinValue;
|
||||
else
|
||||
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(VCTime);
|
||||
|
||||
if (VMTime[0] == '0' || VMTime[0] == 0x00)
|
||||
if(VMTime[0] == '0' || VMTime[0] == 0x00)
|
||||
{
|
||||
decodedVD.HasModificationTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
decodedVD.HasModificationTime = true;
|
||||
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(VMTime);
|
||||
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(VMTime);
|
||||
}
|
||||
|
||||
if (VXTime[0] == '0' || VXTime[0] == 0x00)
|
||||
if(VXTime[0] == '0' || VXTime[0] == 0x00)
|
||||
{
|
||||
decodedVD.HasExpirationTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
decodedVD.HasExpirationTime = true;
|
||||
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(VXTime);
|
||||
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(VXTime);
|
||||
}
|
||||
|
||||
if (VETime[0] == '0' || VETime[0] == 0x00)
|
||||
if(VETime[0] == '0' || VETime[0] == 0x00)
|
||||
{
|
||||
decodedVD.HasEffectiveTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
decodedVD.HasEffectiveTime = true;
|
||||
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(VETime);
|
||||
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(VETime);
|
||||
}
|
||||
|
||||
return decodedVD;
|
||||
}
|
||||
|
||||
static DecodedVolumeDescriptor DecodeVolumeDescriptor(byte[] VDSysId, byte[] VDVolId, byte[] VDVolSetId, byte[] VDPubId, byte[] VDDataPrepId, byte[] VDAppId, byte[] VCTime, byte[] VMTime, byte[] VXTime, byte[] VETime)
|
||||
static DecodedVolumeDescriptor DecodeVolumeDescriptor(byte[] VDSysId, byte[] VDVolId, byte[] VDVolSetId, byte[] VDPubId, byte[] VDDataPrepId, byte[] VDAppId, byte[] VCTime, byte[] VMTime, byte[] VXTime, byte[] VETime)
|
||||
{
|
||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||
|
||||
decodedVD.SystemIdentifier = Encoding.ASCII.GetString(VDSysId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.VolumeIdentifier = Encoding.ASCII.GetString(VDVolId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.VolumeSetIdentifier = Encoding.ASCII.GetString(VDVolSetId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.PublisherIdentifier = Encoding.ASCII.GetString(VDPubId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.DataPreparerIdentifier = Encoding.ASCII.GetString(VDDataPrepId).TrimEnd().Trim(new []{'\u0000'});
|
||||
decodedVD.ApplicationIdentifier = Encoding.ASCII.GetString(VDAppId).TrimEnd().Trim(new []{'\u0000'});
|
||||
if (VCTime[0] == '0' || VCTime[0] == 0x00)
|
||||
decodedVD.SystemIdentifier = Encoding.ASCII.GetString(VDSysId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.VolumeIdentifier = Encoding.ASCII.GetString(VDVolId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.VolumeSetIdentifier = Encoding.ASCII.GetString(VDVolSetId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.PublisherIdentifier = Encoding.ASCII.GetString(VDPubId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.DataPreparerIdentifier = Encoding.ASCII.GetString(VDDataPrepId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
decodedVD.ApplicationIdentifier = Encoding.ASCII.GetString(VDAppId).TrimEnd().Trim(new[] { '\u0000' });
|
||||
if(VCTime[0] == '0' || VCTime[0] == 0x00)
|
||||
decodedVD.CreationTime = DateTime.MinValue;
|
||||
else
|
||||
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(VCTime);
|
||||
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(VCTime);
|
||||
|
||||
if (VMTime[0] == '0' || VMTime[0] == 0x00)
|
||||
if(VMTime[0] == '0' || VMTime[0] == 0x00)
|
||||
{
|
||||
decodedVD.HasModificationTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
decodedVD.HasModificationTime = true;
|
||||
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(VMTime);
|
||||
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(VMTime);
|
||||
}
|
||||
|
||||
if (VXTime[0] == '0' || VXTime[0] == 0x00)
|
||||
if(VXTime[0] == '0' || VXTime[0] == 0x00)
|
||||
{
|
||||
decodedVD.HasExpirationTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
decodedVD.HasExpirationTime = true;
|
||||
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(VXTime);
|
||||
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(VXTime);
|
||||
}
|
||||
|
||||
if (VETime[0] == '0' || VETime[0] == 0x00)
|
||||
if(VETime[0] == '0' || VETime[0] == 0x00)
|
||||
{
|
||||
decodedVD.HasEffectiveTime = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
decodedVD.HasEffectiveTime = true;
|
||||
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(VETime);
|
||||
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(VETime);
|
||||
}
|
||||
|
||||
return decodedVD;
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
try
|
||||
{
|
||||
if(imagePlugin.ImageInfo.readableSectorTags==null)
|
||||
if(imagePlugin.ImageInfo.readableSectorTags == null)
|
||||
return false;
|
||||
|
||||
if(!imagePlugin.ImageInfo.readableSectorTags.Contains(SectorTagType.AppleSectorTag))
|
||||
@@ -86,18 +86,18 @@ namespace DiscImageChef.Plugins
|
||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||
|
||||
// Minimal LisaOS disk is 3.5" single sided double density, 800 sectors
|
||||
if (imagePlugin.GetSectors() < 800)
|
||||
if(imagePlugin.GetSectors() < 800)
|
||||
return false;
|
||||
|
||||
// LisaOS searches sectors until tag tells MDDF resides there, so we'll search 100 sectors
|
||||
for (int i = 0; i < 100; i++)
|
||||
for(int i = 0; i < 100; i++)
|
||||
{
|
||||
byte[] tag = imagePlugin.ReadSectorTag((ulong)i, SectorTagType.AppleSectorTag);
|
||||
UInt16 fileid = BigEndianBitConverter.ToUInt16(tag, 0x04);
|
||||
|
||||
DicConsole.DebugWriteLine("LisaFS plugin", "Sector {0}, file ID 0x{1:X4}", i, fileid);
|
||||
|
||||
if (fileid == FILEID_MDDF)
|
||||
if(fileid == FILEID_MDDF)
|
||||
{
|
||||
byte[] sector = imagePlugin.ReadSector((ulong)i);
|
||||
Lisa_MDDF mddf = new Lisa_MDDF();
|
||||
@@ -119,25 +119,25 @@ namespace DiscImageChef.Plugins
|
||||
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.blocksize = {0} bytes", mddf.blocksize);
|
||||
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.datasize = {0} bytes", mddf.datasize);
|
||||
|
||||
if (mddf.mddf_block != i)
|
||||
if(mddf.mddf_block != i)
|
||||
return false;
|
||||
|
||||
if (mddf.vol_size > imagePlugin.GetSectors())
|
||||
if(mddf.vol_size > imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
if (mddf.vol_size - 1 != mddf.volsize_minus_one)
|
||||
if(mddf.vol_size - 1 != mddf.volsize_minus_one)
|
||||
return false;
|
||||
|
||||
if (mddf.vol_size - i - 1 != mddf.volsize_minus_mddf_minus_one)
|
||||
if(mddf.vol_size - i - 1 != mddf.volsize_minus_mddf_minus_one)
|
||||
return false;
|
||||
|
||||
if (mddf.datasize > mddf.blocksize)
|
||||
if(mddf.datasize > mddf.blocksize)
|
||||
return false;
|
||||
|
||||
if (mddf.blocksize < imagePlugin.GetSectorSize())
|
||||
if(mddf.blocksize < imagePlugin.GetSectorSize())
|
||||
return false;
|
||||
|
||||
if (mddf.datasize != imagePlugin.GetSectorSize())
|
||||
if(mddf.datasize != imagePlugin.GetSectorSize())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -146,7 +146,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch(Exception ex)
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Exception {0}, {1}, {2}", ex.Message, ex.InnerException, ex.StackTrace);
|
||||
return false;
|
||||
@@ -160,7 +160,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
try
|
||||
{
|
||||
if(imagePlugin.ImageInfo.readableSectorTags==null)
|
||||
if(imagePlugin.ImageInfo.readableSectorTags == null)
|
||||
return;
|
||||
|
||||
if(!imagePlugin.ImageInfo.readableSectorTags.Contains(SectorTagType.AppleSectorTag))
|
||||
@@ -170,18 +170,18 @@ namespace DiscImageChef.Plugins
|
||||
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
|
||||
|
||||
// Minimal LisaOS disk is 3.5" single sided double density, 800 sectors
|
||||
if (imagePlugin.GetSectors() < 800)
|
||||
if(imagePlugin.GetSectors() < 800)
|
||||
return;
|
||||
|
||||
// LisaOS searches sectors until tag tells MDDF resides there, so we'll search 100 sectors
|
||||
for (int i = 0; i < 100; i++)
|
||||
for(int i = 0; i < 100; i++)
|
||||
{
|
||||
byte[] tag = imagePlugin.ReadSectorTag((ulong)i, SectorTagType.AppleSectorTag);
|
||||
UInt16 fileid = BigEndianBitConverter.ToUInt16(tag, 0x04);
|
||||
|
||||
DicConsole.DebugWriteLine("LisaFS plugin", "Sector {0}, file ID 0x{1:X4}", i, fileid);
|
||||
|
||||
if (fileid == FILEID_MDDF)
|
||||
if(fileid == FILEID_MDDF)
|
||||
{
|
||||
byte[] sector = imagePlugin.ReadSector((ulong)i);
|
||||
Lisa_MDDF mddf = new Lisa_MDDF();
|
||||
@@ -196,7 +196,7 @@ namespace DiscImageChef.Plugins
|
||||
mddf.unknown1 = sector[0x2D];
|
||||
Array.Copy(sector, 0x2E, pString, 0, 33);
|
||||
// Prevent garbage
|
||||
if (pString[0] <= 32)
|
||||
if(pString[0] <= 32)
|
||||
mddf.password = StringHandlers.PascalToString(pString);
|
||||
else
|
||||
mddf.password = "";
|
||||
@@ -309,28 +309,28 @@ namespace DiscImageChef.Plugins
|
||||
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown38 = 0x{0:X8} ({0})", mddf.unknown38);
|
||||
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown_timestamp = 0x{0:X8} ({0}, {1})", mddf.unknown_timestamp, DateHandlers.LisaToDateTime(mddf.unknown_timestamp));
|
||||
|
||||
if (mddf.mddf_block != i)
|
||||
if(mddf.mddf_block != i)
|
||||
return;
|
||||
|
||||
if (mddf.vol_size > imagePlugin.GetSectors())
|
||||
if(mddf.vol_size > imagePlugin.GetSectors())
|
||||
return;
|
||||
|
||||
if (mddf.vol_size - 1 != mddf.volsize_minus_one)
|
||||
if(mddf.vol_size - 1 != mddf.volsize_minus_one)
|
||||
return;
|
||||
|
||||
if (mddf.vol_size - i - 1 != mddf.volsize_minus_mddf_minus_one)
|
||||
if(mddf.vol_size - i - 1 != mddf.volsize_minus_mddf_minus_one)
|
||||
return;
|
||||
|
||||
if (mddf.datasize > mddf.blocksize)
|
||||
if(mddf.datasize > mddf.blocksize)
|
||||
return;
|
||||
|
||||
if (mddf.blocksize < imagePlugin.GetSectorSize())
|
||||
if(mddf.blocksize < imagePlugin.GetSectorSize())
|
||||
return;
|
||||
|
||||
if (mddf.datasize != imagePlugin.GetSectorSize())
|
||||
if(mddf.datasize != imagePlugin.GetSectorSize())
|
||||
return;
|
||||
|
||||
switch (mddf.fsversion)
|
||||
switch(mddf.fsversion)
|
||||
{
|
||||
case LisaFSv1:
|
||||
sb.AppendLine("LisaFS v1");
|
||||
@@ -379,7 +379,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Boot environment: 0x{0:X8}", mddf.boot_environ).AppendLine();
|
||||
sb.AppendFormat("Overmount stamp: 0x{0:X16}", mddf.overmount_stamp).AppendLine();
|
||||
|
||||
if (mddf.vol_left_mounted == 0)
|
||||
if(mddf.vol_left_mounted == 0)
|
||||
sb.AppendLine("Volume is clean");
|
||||
else
|
||||
sb.AppendLine("Volume is dirty");
|
||||
@@ -414,7 +414,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch(Exception ex)
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Exception {0}, {1}, {2}", ex.Message, ex.InnerException, ex.StackTrace);
|
||||
return;
|
||||
|
||||
@@ -75,20 +75,20 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
UInt16 magic;
|
||||
byte[] minix_sb_sector = imagePlugin.ReadSector(2 + partitionStart);
|
||||
|
||||
magic = BitConverter.ToUInt16(minix_sb_sector, 0x010); // Here should reside magic number on Minix V1 & V2
|
||||
|
||||
if (magic == MINIX_MAGIC || magic == MINIX_MAGIC2 || magic == MINIX2_MAGIC || magic == MINIX2_MAGIC2 ||
|
||||
|
||||
if(magic == MINIX_MAGIC || magic == MINIX_MAGIC2 || magic == MINIX2_MAGIC || magic == MINIX2_MAGIC2 ||
|
||||
magic == MINIX_CIGAM || magic == MINIX_CIGAM2 || magic == MINIX2_CIGAM || magic == MINIX2_CIGAM2)
|
||||
return true;
|
||||
magic = BitConverter.ToUInt16(minix_sb_sector, 0x018); // Here should reside magic number on Minix V3
|
||||
|
||||
if (magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||
if(magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -96,7 +96,7 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
bool minix3 = false;
|
||||
@@ -109,7 +109,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
|
||||
if (magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||
if(magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||
{
|
||||
filenamesize = 60;
|
||||
minixVersion = "Minix V3 filesystem";
|
||||
@@ -123,7 +123,7 @@ namespace DiscImageChef.Plugins
|
||||
{
|
||||
magic = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x010);
|
||||
|
||||
switch (magic)
|
||||
switch(magic)
|
||||
{
|
||||
case MINIX_MAGIC:
|
||||
filenamesize = 14;
|
||||
@@ -178,7 +178,7 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
}
|
||||
|
||||
if (minix3)
|
||||
if(minix3)
|
||||
{
|
||||
Minix3SuperBlock mnx_sb = new Minix3SuperBlock();
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace DiscImageChef.Plugins
|
||||
else
|
||||
{
|
||||
MinixSuperBlock mnx_sb = new MinixSuperBlock();
|
||||
|
||||
|
||||
mnx_sb.s_ninodes = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x00);
|
||||
mnx_sb.s_nzones = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x02);
|
||||
mnx_sb.s_imap_blocks = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x04);
|
||||
@@ -228,8 +228,8 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
sb.AppendLine(minixVersion);
|
||||
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
||||
if (mnx_sb.s_zones > 0) // On V2
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_zones, mnx_sb.s_zones * 1024).AppendLine();
|
||||
if(mnx_sb.s_zones > 0) // On V2
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_zones, mnx_sb.s_zones * 1024).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_nzones, mnx_sb.s_nzones * 1024).AppendLine();
|
||||
sb.AppendFormat("{0} inodes on volume", mnx_sb.s_ninodes).AppendLine();
|
||||
|
||||
@@ -53,49 +53,49 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte[] eigth_bytes = new byte[8];
|
||||
byte fats_no;
|
||||
UInt16 spfat, signature;
|
||||
string oem_name;
|
||||
|
||||
|
||||
byte[] ntfs_bpb = imagePlugin.ReadSector(0 + partitionStart);
|
||||
|
||||
|
||||
Array.Copy(ntfs_bpb, 0x003, eigth_bytes, 0, 8);
|
||||
oem_name = StringHandlers.CToString(eigth_bytes);
|
||||
|
||||
if (oem_name != "NTFS ")
|
||||
|
||||
if(oem_name != "NTFS ")
|
||||
return false;
|
||||
|
||||
|
||||
fats_no = ntfs_bpb[0x010];
|
||||
|
||||
if (fats_no != 0)
|
||||
|
||||
if(fats_no != 0)
|
||||
return false;
|
||||
|
||||
|
||||
spfat = BitConverter.ToUInt16(ntfs_bpb, 0x016);
|
||||
|
||||
if (spfat != 0)
|
||||
|
||||
if(spfat != 0)
|
||||
return false;
|
||||
|
||||
|
||||
signature = BitConverter.ToUInt16(ntfs_bpb, 0x1FE);
|
||||
|
||||
|
||||
return signature == 0xAA55;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
byte[] ntfs_bpb = imagePlugin.ReadSector(0 + partitionStart);
|
||||
|
||||
|
||||
NTFS_BootBlock ntfs_bb = new NTFS_BootBlock();
|
||||
|
||||
|
||||
byte[] oem_name = new byte[8];
|
||||
|
||||
|
||||
ntfs_bb.jmp1 = ntfs_bpb[0x000];
|
||||
ntfs_bb.jmp2 = BitConverter.ToUInt16(ntfs_bpb, 0x001);
|
||||
Array.Copy(ntfs_bpb, 0x003, oem_name, 0, 8);
|
||||
@@ -127,46 +127,46 @@ namespace DiscImageChef.Plugins
|
||||
ntfs_bb.dummy5 = BitConverter.ToUInt16(ntfs_bpb, 0x046);
|
||||
ntfs_bb.serial_no = BitConverter.ToUInt64(ntfs_bpb, 0x048);
|
||||
ntfs_bb.signature2 = BitConverter.ToUInt16(ntfs_bpb, 0x1FE);
|
||||
|
||||
|
||||
sb.AppendFormat("{0} bytes per sector", ntfs_bb.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster ({1} bytes)", ntfs_bb.spc, ntfs_bb.spc * ntfs_bb.bps).AppendLine();
|
||||
// sb.AppendFormat("{0} reserved sectors", ntfs_bb.rsectors).AppendLine();
|
||||
// sb.AppendFormat("{0} FATs", ntfs_bb.fats_no).AppendLine();
|
||||
// sb.AppendFormat("{0} entries in the root folder", ntfs_bb.root_ent).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume (small)", ntfs_bb.sml_sectors).AppendLine();
|
||||
// sb.AppendFormat("{0} reserved sectors", ntfs_bb.rsectors).AppendLine();
|
||||
// sb.AppendFormat("{0} FATs", ntfs_bb.fats_no).AppendLine();
|
||||
// sb.AppendFormat("{0} entries in the root folder", ntfs_bb.root_ent).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume (small)", ntfs_bb.sml_sectors).AppendLine();
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", ntfs_bb.media).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per FAT", ntfs_bb.spfat).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per FAT", ntfs_bb.spfat).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track", ntfs_bb.sptrk).AppendLine();
|
||||
sb.AppendFormat("{0} heads", ntfs_bb.heads).AppendLine();
|
||||
sb.AppendFormat("{0} hidden sectors before filesystem", ntfs_bb.hsectors).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume (big)", ntfs_bb.big_sectors).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume (big)", ntfs_bb.big_sectors).AppendLine();
|
||||
sb.AppendFormat("BIOS drive number: 0x{0:X2}", ntfs_bb.drive_no).AppendLine();
|
||||
// sb.AppendFormat("NT flags: 0x{0:X2}", ntfs_bb.nt_flags).AppendLine();
|
||||
// sb.AppendFormat("Signature 1: 0x{0:X2}", ntfs_bb.signature1).AppendLine();
|
||||
// sb.AppendFormat("NT flags: 0x{0:X2}", ntfs_bb.nt_flags).AppendLine();
|
||||
// sb.AppendFormat("Signature 1: 0x{0:X2}", ntfs_bb.signature1).AppendLine();
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", ntfs_bb.sectors, ntfs_bb.sectors * ntfs_bb.bps).AppendLine();
|
||||
sb.AppendFormat("Sectors where $MFT starts: {0}", ntfs_bb.mft_lsn).AppendLine();
|
||||
sb.AppendFormat("Sectors where $MFTMirr starts: {0}", ntfs_bb.mftmirror_lsn).AppendLine();
|
||||
|
||||
if (ntfs_bb.mft_rc_clusters > 0)
|
||||
if(ntfs_bb.mft_rc_clusters > 0)
|
||||
sb.AppendFormat("{0} clusters per MFT record ({1} bytes)", ntfs_bb.mft_rc_clusters,
|
||||
ntfs_bb.mft_rc_clusters * ntfs_bb.bps * ntfs_bb.spc).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} bytes per MFT record", 1 << -ntfs_bb.mft_rc_clusters).AppendLine();
|
||||
if (ntfs_bb.index_blk_cts > 0)
|
||||
if(ntfs_bb.index_blk_cts > 0)
|
||||
sb.AppendFormat("{0} clusters per Index block ({1} bytes)", ntfs_bb.index_blk_cts,
|
||||
ntfs_bb.index_blk_cts * ntfs_bb.bps * ntfs_bb.spc).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} bytes per Index block", 1 << -ntfs_bb.index_blk_cts).AppendLine();
|
||||
|
||||
sb.AppendFormat("Volume serial number: {0:X16}", ntfs_bb.serial_no).AppendLine();
|
||||
// sb.AppendFormat("Signature 2: 0x{0:X4}", ntfs_bb.signature2).AppendLine();
|
||||
// sb.AppendFormat("Signature 2: 0x{0:X4}", ntfs_bb.signature2).AppendLine();
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
xmlFSType.ClusterSize = ntfs_bb.spc * ntfs_bb.bps;
|
||||
xmlFSType.Clusters = ntfs_bb.sectors / ntfs_bb.spc;
|
||||
xmlFSType.VolumeSerial = String.Format("{0:X16}", ntfs_bb.serial_no);
|
||||
xmlFSType.Type = "NTFS";
|
||||
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace DiscImageChef.Plugins
|
||||
for(int i = 0; i < fields.fourthPartitions.Length; i++)
|
||||
sbInformation.AppendFormat("Fourth {0} partition starts at sector {1}", PartitionTypeToString(fields.fourthPartitions[i].type), fields.fourthPartitions[i].offset / 2048).AppendLine();
|
||||
|
||||
// sbInformation.AppendFormat("Region byte is {0}", fields.region).AppendLine();
|
||||
// sbInformation.AppendFormat("Region byte is {0}", fields.region).AppendLine();
|
||||
if((fields.japanAge & 0x80) != 0x80)
|
||||
sbInformation.AppendFormat("Japan age rating is {0}", fields.japanAge).AppendLine();
|
||||
if((fields.usaAge & 0x80) != 0x80)
|
||||
|
||||
@@ -60,10 +60,10 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
if (imagePlugin.GetSectorSize() < 512)
|
||||
if(imagePlugin.GetSectorSize() < 512)
|
||||
return false;
|
||||
|
||||
byte[] magic_b = new byte[12];
|
||||
@@ -72,22 +72,22 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
Array.Copy(hb_sector, 0x1F0, magic_b, 0, 12);
|
||||
magic = Encoding.ASCII.GetString(magic_b);
|
||||
|
||||
|
||||
return magic == "DECFILE11A " || magic == "DECFILE11B ";
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
ODSHomeBlock homeblock = new ODSHomeBlock();
|
||||
byte[] temp_string = new byte[12];
|
||||
homeblock.min_class = new byte[20];
|
||||
homeblock.max_class = new byte[20];
|
||||
|
||||
|
||||
byte[] hb_sector = imagePlugin.ReadSector(1 + partitionStart);
|
||||
|
||||
|
||||
homeblock.homelbn = BitConverter.ToUInt32(hb_sector, 0x000);
|
||||
homeblock.alhomelbn = BitConverter.ToUInt32(hb_sector, 0x004);
|
||||
homeblock.altidxlbn = BitConverter.ToUInt32(hb_sector, 0x008);
|
||||
@@ -136,12 +136,12 @@ namespace DiscImageChef.Plugins
|
||||
Array.Copy(hb_sector, 0x1F0, temp_string, 0, 12);
|
||||
homeblock.format = StringHandlers.CToString(temp_string);
|
||||
homeblock.checksum2 = BitConverter.ToUInt16(hb_sector, 0x1FE);
|
||||
|
||||
if ((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 || homeblock.format != "DECFILE11B ")
|
||||
|
||||
if((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 || homeblock.format != "DECFILE11B ")
|
||||
sb.AppendLine("The following information may be incorrect for this volume.");
|
||||
if (homeblock.resfiles < 5 || homeblock.devtype != 0)
|
||||
if(homeblock.resfiles < 5 || homeblock.devtype != 0)
|
||||
sb.AppendLine("This volume may be corrupted.");
|
||||
|
||||
|
||||
sb.AppendFormat("Volume format is {0}", homeblock.format).AppendLine();
|
||||
sb.AppendFormat("Volume is Level {0} revision {1}", (homeblock.struclev & 0xFF00) >> 8, homeblock.struclev & 0xFF).AppendLine();
|
||||
sb.AppendFormat("Lowest structure in the volume is Level {0}, revision {1}", (homeblock.lowstruclev & 0xFF00) >> 8, homeblock.lowstruclev & 0xFF).AppendLine();
|
||||
@@ -154,121 +154,121 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Backup INDEXF.SYS;1 is in sector {0} (cluster {1})", homeblock.altidxlbn, homeblock.altidxvbn).AppendLine();
|
||||
sb.AppendFormat("{0} maximum files on the volume", homeblock.maxfiles).AppendLine();
|
||||
sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();
|
||||
if (homeblock.rvn > 0 && homeblock.setcount > 0 && homeblock.strucname != " ")
|
||||
if(homeblock.rvn > 0 && homeblock.setcount > 0 && homeblock.strucname != " ")
|
||||
sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount, homeblock.strucname).AppendLine();
|
||||
sb.AppendFormat("Volume owner is \"{0}\" (ID 0x{1:X8})", homeblock.ownername, homeblock.volowner).AppendLine();
|
||||
sb.AppendFormat("Volume label: \"{0}\"", homeblock.volname).AppendLine();
|
||||
sb.AppendFormat("Drive serial number: 0x{0:X8}", homeblock.serialnum).AppendLine();
|
||||
sb.AppendFormat("Volume was created on {0}", DateHandlers.VMSToDateTime(homeblock.credate)).AppendLine();
|
||||
if (homeblock.revdate > 0)
|
||||
if(homeblock.revdate > 0)
|
||||
sb.AppendFormat("Volume was last modified on {0}", DateHandlers.VMSToDateTime(homeblock.revdate)).AppendLine();
|
||||
if (homeblock.copydate > 0)
|
||||
if(homeblock.copydate > 0)
|
||||
sb.AppendFormat("Volume copied on {0}", DateHandlers.VMSToDateTime(homeblock.copydate)).AppendLine();
|
||||
sb.AppendFormat("Checksums: 0x{0:X4} and 0x{1:X4}", homeblock.checksum1, homeblock.checksum2).AppendLine();
|
||||
sb.AppendLine("Flags:");
|
||||
sb.AppendFormat("Window: {0}", homeblock.window).AppendLine();
|
||||
sb.AppendFormat("Cached directores: {0}", homeblock.lru_lim).AppendLine();
|
||||
sb.AppendFormat("Default allocation: {0} blocks", homeblock.extend).AppendLine();
|
||||
if ((homeblock.volchar & 0x01) == 0x01)
|
||||
if((homeblock.volchar & 0x01) == 0x01)
|
||||
sb.AppendLine("Readings should be verified");
|
||||
if ((homeblock.volchar & 0x02) == 0x02)
|
||||
if((homeblock.volchar & 0x02) == 0x02)
|
||||
sb.AppendLine("Writings should be verified");
|
||||
if ((homeblock.volchar & 0x04) == 0x04)
|
||||
if((homeblock.volchar & 0x04) == 0x04)
|
||||
sb.AppendLine("Files should be erased or overwritten when deleted");
|
||||
if ((homeblock.volchar & 0x08) == 0x08)
|
||||
if((homeblock.volchar & 0x08) == 0x08)
|
||||
sb.AppendLine("Highwater mark is to be disabled");
|
||||
if ((homeblock.volchar & 0x10) == 0x10)
|
||||
if((homeblock.volchar & 0x10) == 0x10)
|
||||
sb.AppendLine("Classification checks are enabled");
|
||||
sb.AppendLine("Volume permissions (r = read, w = write, c = create, d = delete)");
|
||||
sb.AppendLine("System, owner, group, world");
|
||||
// System
|
||||
if ((homeblock.protect & 0x1000) == 0x1000)
|
||||
if((homeblock.protect & 0x1000) == 0x1000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if ((homeblock.protect & 0x2000) == 0x2000)
|
||||
if((homeblock.protect & 0x2000) == 0x2000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if ((homeblock.protect & 0x4000) == 0x4000)
|
||||
if((homeblock.protect & 0x4000) == 0x4000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if ((homeblock.protect & 0x8000) == 0x8000)
|
||||
if((homeblock.protect & 0x8000) == 0x8000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// Owner
|
||||
if ((homeblock.protect & 0x100) == 0x100)
|
||||
if((homeblock.protect & 0x100) == 0x100)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if ((homeblock.protect & 0x200) == 0x200)
|
||||
if((homeblock.protect & 0x200) == 0x200)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if ((homeblock.protect & 0x400) == 0x400)
|
||||
if((homeblock.protect & 0x400) == 0x400)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if ((homeblock.protect & 0x800) == 0x800)
|
||||
if((homeblock.protect & 0x800) == 0x800)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// Group
|
||||
if ((homeblock.protect & 0x10) == 0x10)
|
||||
if((homeblock.protect & 0x10) == 0x10)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if ((homeblock.protect & 0x20) == 0x20)
|
||||
if((homeblock.protect & 0x20) == 0x20)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if ((homeblock.protect & 0x40) == 0x40)
|
||||
if((homeblock.protect & 0x40) == 0x40)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if ((homeblock.protect & 0x80) == 0x80)
|
||||
if((homeblock.protect & 0x80) == 0x80)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// World (other)
|
||||
if ((homeblock.protect & 0x1) == 0x1)
|
||||
if((homeblock.protect & 0x1) == 0x1)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if ((homeblock.protect & 0x2) == 0x2)
|
||||
if((homeblock.protect & 0x2) == 0x2)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if ((homeblock.protect & 0x4) == 0x4)
|
||||
if((homeblock.protect & 0x4) == 0x4)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if ((homeblock.protect & 0x8) == 0x8)
|
||||
if((homeblock.protect & 0x8) == 0x8)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
|
||||
sb.AppendLine("Unknown structures:");
|
||||
sb.AppendFormat("Security mask: 0x{0:X8}", homeblock.sec_mask).AppendLine();
|
||||
sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine();
|
||||
sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine();
|
||||
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
xmlFSType.Type = "FILES-11";
|
||||
xmlFSType.ClusterSize = homeblock.cluster * 512;
|
||||
xmlFSType.Clusters = homeblock.cluster;
|
||||
xmlFSType.VolumeName = homeblock.volname;
|
||||
xmlFSType.VolumeSerial = String.Format("{0:X8}", homeblock.serialnum);
|
||||
if (homeblock.credate > 0)
|
||||
if(homeblock.credate > 0)
|
||||
{
|
||||
xmlFSType.CreationDate = DateHandlers.VMSToDateTime(homeblock.credate);
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
}
|
||||
if (homeblock.revdate > 0)
|
||||
if(homeblock.revdate > 0)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.VMSToDateTime(homeblock.revdate);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector(0 + partitionStart);
|
||||
@@ -61,15 +61,15 @@ namespace DiscImageChef.Plugins
|
||||
byte record_type;
|
||||
byte[] sync_bytes = new byte[5];
|
||||
byte record_version;
|
||||
|
||||
|
||||
record_type = sb_sector[0x000];
|
||||
Array.Copy(sb_sector, 0x001, sync_bytes, 0, 5);
|
||||
record_version = sb_sector[0x006];
|
||||
|
||||
if (record_type != 1 || record_version != 1)
|
||||
|
||||
if(record_type != 1 || record_version != 1)
|
||||
return false;
|
||||
return Encoding.ASCII.GetString(sync_bytes) == "ZZZZZ";
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
@@ -99,15 +99,15 @@ namespace DiscImageChef.Plugins
|
||||
sb.rootdir_bsize = BigEndianBitConverter.ToInt32(sb_sector, 0x05C);
|
||||
sb.last_root_copy = BigEndianBitConverter.ToInt32(sb_sector, 0x060);
|
||||
|
||||
if (sb.record_type != 1 || sb.record_version != 1)
|
||||
if(sb.record_type != 1 || sb.record_version != 1)
|
||||
return;
|
||||
if (Encoding.ASCII.GetString(sb.sync_bytes) != "ZZZZZ")
|
||||
if(Encoding.ASCII.GetString(sb.sync_bytes) != "ZZZZZ")
|
||||
return;
|
||||
|
||||
if (sb.volume_comment.Length == 0)
|
||||
if(sb.volume_comment.Length == 0)
|
||||
sb.volume_comment = "Not set.";
|
||||
|
||||
if (sb.volume_label.Length == 0)
|
||||
if(sb.volume_label.Length == 0)
|
||||
sb.volume_label = "Not set.";
|
||||
|
||||
SuperBlockMetadata.AppendFormat("Opera filesystem disc.").AppendLine();
|
||||
@@ -115,15 +115,15 @@ namespace DiscImageChef.Plugins
|
||||
SuperBlockMetadata.AppendFormat("Volume comment: {0}", sb.volume_comment).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Volume identifier: 0x{0:X8}", sb.volume_id).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Block size: {0} bytes", sb.block_size).AppendLine();
|
||||
if (imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
{
|
||||
if (sb.block_size != 2048)
|
||||
if(sb.block_size != 2048)
|
||||
SuperBlockMetadata.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block", sb.block_size, 2048);
|
||||
}
|
||||
else if (imagePlugin.GetSectorSize() != sb.block_size)
|
||||
else if(imagePlugin.GetSectorSize() != sb.block_size)
|
||||
SuperBlockMetadata.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block", sb.block_size, imagePlugin.GetSectorSize());
|
||||
SuperBlockMetadata.AppendFormat("Volume size: {0} blocks, {1} bytes", sb.block_count, sb.block_size * sb.block_count).AppendLine();
|
||||
if ((ulong)sb.block_count > imagePlugin.GetSectors())
|
||||
if((ulong)sb.block_count > imagePlugin.GetSectors())
|
||||
SuperBlockMetadata.AppendFormat("WARNING: Filesystem indicates {0} blocks while device indicates {1} blocks", sb.block_count, imagePlugin.GetSectors());
|
||||
SuperBlockMetadata.AppendFormat("Root directory identifier: 0x{0:X8}", sb.root_dirid).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Root directory block size: {0} bytes", sb.rootdir_bsize).AppendLine();
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte[] system_descriptor = new byte[23];
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace DiscImageChef.Plugins
|
||||
/// Abstract class to implement filesystem plugins.
|
||||
/// </summary>
|
||||
public abstract class Plugin
|
||||
{
|
||||
{
|
||||
/// <summary>Plugin name.</summary>
|
||||
public string Name;
|
||||
/// <summary>Plugin UUID.</summary>
|
||||
@@ -66,7 +66,7 @@ namespace DiscImageChef.Plugins
|
||||
protected Plugin()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the filesystem in the specified LBA
|
||||
/// </summary>
|
||||
@@ -84,6 +84,6 @@ namespace DiscImageChef.Plugins
|
||||
/// <param name="partitionEnd">Partition end sector (LBA).</param>
|
||||
/// <param name="information">Filesystem information.</param>
|
||||
public abstract void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,30 +94,30 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if (imagePlugin.GetSectors() < 3)
|
||||
if(imagePlugin.GetSectors() < 3)
|
||||
return false;
|
||||
|
||||
// Blocks 0 and 1 are boot code
|
||||
byte[] rootDirectoryKeyBlock = imagePlugin.ReadSector(2 + partitionStart);
|
||||
|
||||
UInt16 prePointer = BitConverter.ToUInt16(rootDirectoryKeyBlock, 0);
|
||||
if (prePointer != 0)
|
||||
if(prePointer != 0)
|
||||
return false;
|
||||
|
||||
byte storage_type = (byte)((rootDirectoryKeyBlock[0x04] & ProDOSStorageTypeMask) >> 4);
|
||||
if (storage_type != RootDirectoryType)
|
||||
if(storage_type != RootDirectoryType)
|
||||
return false;
|
||||
|
||||
byte entry_length = rootDirectoryKeyBlock[0x23];
|
||||
if (entry_length != ProDOSEntryLength)
|
||||
if(entry_length != ProDOSEntryLength)
|
||||
return false;
|
||||
|
||||
byte entries_per_block = rootDirectoryKeyBlock[0x24];
|
||||
if (entries_per_block != ProDOSEntriesPerBlock)
|
||||
if(entries_per_block != ProDOSEntriesPerBlock)
|
||||
return false;
|
||||
|
||||
UInt16 bit_map_pointer = BitConverter.ToUInt16(rootDirectoryKeyBlock, 0x27);
|
||||
if (bit_map_pointer > imagePlugin.GetSectors())
|
||||
if(bit_map_pointer > imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
UInt16 total_blocks = BitConverter.ToUInt16(rootDirectoryKeyBlock, 0x29);
|
||||
@@ -157,7 +157,7 @@ namespace DiscImageChef.Plugins
|
||||
hour = (int)((temp_timestamp & ProDOSHourMask) >> 8);
|
||||
minute = (int)(temp_timestamp & ProDOSMinuteMask);
|
||||
year += 1900;
|
||||
if (year < 1940)
|
||||
if(year < 1940)
|
||||
year += 100;
|
||||
|
||||
DicConsole.DebugWriteLine("ProDOS plugin", "temp_timestamp_left = 0x{0:X4}", temp_timestamp_left);
|
||||
@@ -177,18 +177,18 @@ namespace DiscImageChef.Plugins
|
||||
rootDirectoryKeyBlock.header.bit_map_pointer = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x27);
|
||||
rootDirectoryKeyBlock.header.total_blocks = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x29);
|
||||
|
||||
if (rootDirectoryKeyBlock.header.version != ProDOSVersion1 || rootDirectoryKeyBlock.header.min_version != ProDOSVersion1)
|
||||
if(rootDirectoryKeyBlock.header.version != ProDOSVersion1 || rootDirectoryKeyBlock.header.min_version != ProDOSVersion1)
|
||||
{
|
||||
sbInformation.AppendLine("Warning! Detected unknown ProDOS version ProDOS filesystem.");
|
||||
sbInformation.AppendLine("All of the following information may be incorrect");
|
||||
}
|
||||
|
||||
if (rootDirectoryKeyBlock.header.version == ProDOSVersion1)
|
||||
if(rootDirectoryKeyBlock.header.version == ProDOSVersion1)
|
||||
sbInformation.AppendLine("ProDOS version 1 used to create this volume.");
|
||||
else
|
||||
sbInformation.AppendFormat("Unknown ProDOS version with field {0} used to create this volume.", rootDirectoryKeyBlock.header.version).AppendLine();
|
||||
|
||||
if (rootDirectoryKeyBlock.header.min_version == ProDOSVersion1)
|
||||
if(rootDirectoryKeyBlock.header.min_version == ProDOSVersion1)
|
||||
sbInformation.AppendLine("ProDOS version 1 at least required for reading this volume.");
|
||||
else
|
||||
sbInformation.AppendFormat("Unknown ProDOS version with field {0} is at least required for reading this volume.", rootDirectoryKeyBlock.header.min_version).AppendLine();
|
||||
@@ -201,25 +201,25 @@ namespace DiscImageChef.Plugins
|
||||
sbInformation.AppendFormat("{0} blocks in volume", rootDirectoryKeyBlock.header.total_blocks).AppendLine();
|
||||
sbInformation.AppendFormat("Bitmap starts at block {0}", rootDirectoryKeyBlock.header.bit_map_pointer).AppendLine();
|
||||
|
||||
if ((rootDirectoryKeyBlock.header.access & ProDOSReadAttribute) == ProDOSReadAttribute)
|
||||
if((rootDirectoryKeyBlock.header.access & ProDOSReadAttribute) == ProDOSReadAttribute)
|
||||
sbInformation.AppendLine("Volume can be read");
|
||||
if ((rootDirectoryKeyBlock.header.access & ProDOSWriteAttribute) == ProDOSWriteAttribute)
|
||||
if((rootDirectoryKeyBlock.header.access & ProDOSWriteAttribute) == ProDOSWriteAttribute)
|
||||
sbInformation.AppendLine("Volume can be written");
|
||||
if ((rootDirectoryKeyBlock.header.access & ProDOSRenameAttribute) == ProDOSRenameAttribute)
|
||||
if((rootDirectoryKeyBlock.header.access & ProDOSRenameAttribute) == ProDOSRenameAttribute)
|
||||
sbInformation.AppendLine("Volume can be renamed");
|
||||
if ((rootDirectoryKeyBlock.header.access & ProDOSDestroyAttribute) == ProDOSDestroyAttribute)
|
||||
if((rootDirectoryKeyBlock.header.access & ProDOSDestroyAttribute) == ProDOSDestroyAttribute)
|
||||
sbInformation.AppendLine("Volume can be destroyed");
|
||||
if ((rootDirectoryKeyBlock.header.access & ProDOSBackupAttribute) == ProDOSBackupAttribute)
|
||||
if((rootDirectoryKeyBlock.header.access & ProDOSBackupAttribute) == ProDOSBackupAttribute)
|
||||
sbInformation.AppendLine("Volume must be backed up");
|
||||
|
||||
if ((rootDirectoryKeyBlock.header.access & ProDOSReservedAttributeMask) != 0)
|
||||
if((rootDirectoryKeyBlock.header.access & ProDOSReservedAttributeMask) != 0)
|
||||
DicConsole.DebugWriteLine("ProDOS plugin", "Reserved attributes are set: {0:X2}", rootDirectoryKeyBlock.header.access);
|
||||
|
||||
information = sbInformation.ToString();
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
xmlFSType.VolumeName = rootDirectoryKeyBlock.header.volume_name;
|
||||
if (year != 0 || month != 0 || day != 0 || hour != 0 || minute != 0)
|
||||
if(year != 0 || month != 0 || day != 0 || hour != 0 || minute != 0)
|
||||
{
|
||||
xmlFSType.CreationDate = rootDirectoryKeyBlock.header.creation_time;
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte signature; /// <summary>0x29
|
||||
@@ -70,7 +70,7 @@ namespace DiscImageChef.Plugins
|
||||
Array.Copy(bpb, 0x35, fs_type_b, 0, 8);
|
||||
fs_type = StringHandlers.CToString(fs_type_b);
|
||||
|
||||
if (signature == 0x29 && fs_type == "SOL_FS ")
|
||||
if(signature == 0x29 && fs_type == "SOL_FS ")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] bpb_sector = imagePlugin.ReadSector(0 + partitionStart);
|
||||
byte[] bpb_strings;
|
||||
@@ -131,19 +131,19 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendLine("Solar_OS filesystem");
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", BPB.media).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector", BPB.bps).AppendLine();
|
||||
if (imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
{
|
||||
if (BPB.bps != imagePlugin.GetSectorSize())
|
||||
if(BPB.bps != imagePlugin.GetSectorSize())
|
||||
{
|
||||
sb.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector", BPB.bps, 2048).AppendLine();
|
||||
}
|
||||
}
|
||||
else if (BPB.bps != imagePlugin.GetSectorSize())
|
||||
else if(BPB.bps != imagePlugin.GetSectorSize())
|
||||
{
|
||||
sb.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector", BPB.bps, imagePlugin.GetSectorSize()).AppendLine();
|
||||
}
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", BPB.sectors, BPB.sectors * BPB.bps).AppendLine();
|
||||
if (BPB.sectors > imagePlugin.GetSectors())
|
||||
if(BPB.sectors > imagePlugin.GetSectors())
|
||||
sb.AppendFormat("WARNING: Filesystem describes a {0} sectors volume, bigger than device ({1} sectors)", BPB.sectors, imagePlugin.GetSectors());
|
||||
sb.AppendFormat("{0} heads", BPB.heads).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track", BPB.sptrk).AppendLine();
|
||||
|
||||
@@ -370,4 +370,4 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
UInt32 magic;
|
||||
@@ -98,27 +98,27 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
byte sb_size_in_sectors;
|
||||
|
||||
if (imagePlugin.GetSectorSize() <= 0x400) // Check if underlying device sector size is smaller than SuperBlock size
|
||||
if(imagePlugin.GetSectorSize() <= 0x400) // Check if underlying device sector size is smaller than SuperBlock size
|
||||
sb_size_in_sectors = (byte)(0x400 / imagePlugin.GetSectorSize());
|
||||
else
|
||||
sb_size_in_sectors = 1; // If not a single sector can store it
|
||||
|
||||
if (imagePlugin.GetSectors() <= (partitionStart + 4 * (ulong)sb_size_in_sectors + (ulong)sb_size_in_sectors)) // Device must be bigger than SB location + SB size + offset
|
||||
if(imagePlugin.GetSectors() <= (partitionStart + 4 * (ulong)sb_size_in_sectors + (ulong)sb_size_in_sectors)) // Device must be bigger than SB location + SB size + offset
|
||||
return false;
|
||||
|
||||
// Superblock can start on 0x000, 0x200, 0x600 and 0x800, not aligned, so we assume 16 (128 bytes/sector) sectors as a safe value
|
||||
for (int i = 0; i <= 16; i++)
|
||||
for(int i = 0; i <= 16; i++)
|
||||
{
|
||||
byte[] sb_sector = imagePlugin.ReadSectors((ulong)i + partitionStart, sb_size_in_sectors);
|
||||
|
||||
magic = BitConverter.ToUInt32(sb_sector, 0x3F8); // XENIX magic location
|
||||
|
||||
if (magic == XENIX_MAGIC || magic == XENIX_CIGAM)
|
||||
if(magic == XENIX_MAGIC || magic == XENIX_CIGAM)
|
||||
return true;
|
||||
|
||||
magic = BitConverter.ToUInt32(sb_sector, 0x1F8); // System V magic location
|
||||
|
||||
if (magic == SYSV_MAGIC || magic == SYSV_CIGAM)
|
||||
if(magic == SYSV_MAGIC || magic == SYSV_CIGAM)
|
||||
return true;
|
||||
|
||||
byte[] coherent_string = new byte[6];
|
||||
@@ -127,7 +127,7 @@ namespace DiscImageChef.Plugins
|
||||
Array.Copy(sb_sector, 0x1EE, coherent_string, 0, 6); // Coherent UNIX s_fpack location
|
||||
s_fpack = StringHandlers.CToString(coherent_string);
|
||||
|
||||
if (s_fname == COH_FNAME || s_fpack == COH_FPACK)
|
||||
if(s_fname == COH_FNAME || s_fpack == COH_FPACK)
|
||||
return true;
|
||||
|
||||
// Now try to identify 7th edition
|
||||
@@ -135,9 +135,9 @@ namespace DiscImageChef.Plugins
|
||||
s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); // 7th edition's s_nfree
|
||||
s_ninode = BitConverter.ToUInt16(sb_sector, 0x0D0); // 7th edition's s_ninode
|
||||
|
||||
if (s_fsize > 0 && s_fsize < 0xFFFFFFFF && s_nfree > 0 && s_nfree < 0xFFFF && s_ninode > 0 && s_ninode < 0xFFFF)
|
||||
if(s_fsize > 0 && s_fsize < 0xFFFFFFFF && s_nfree > 0 && s_nfree < 0xFFFF && s_ninode > 0 && s_ninode < 0xFFFF)
|
||||
{
|
||||
if ((s_fsize & 0xFF) == 0x00 && (s_nfree & 0xFF) == 0x00 && (s_ninode & 0xFF) == 0x00)
|
||||
if((s_fsize & 0xFF) == 0x00 && (s_nfree & 0xFF) == 0x00 && (s_ninode & 0xFF) == 0x00)
|
||||
{
|
||||
// Byteswap
|
||||
s_fsize = ((s_fsize & 0xFF) << 24) + ((s_fsize & 0xFF00) << 8) + ((s_fsize & 0xFF0000) >> 8) + ((s_fsize & 0xFF000000) >> 24);
|
||||
@@ -145,11 +145,11 @@ namespace DiscImageChef.Plugins
|
||||
s_ninode = (UInt16)(s_ninode >> 8);
|
||||
}
|
||||
|
||||
if ((s_fsize & 0xFF000000) == 0x00 && (s_nfree & 0xFF00) == 0x00 && (s_ninode & 0xFF00) == 0x00)
|
||||
if((s_fsize & 0xFF000000) == 0x00 && (s_nfree & 0xFF00) == 0x00 && (s_ninode & 0xFF00) == 0x00)
|
||||
{
|
||||
if (s_fsize < V7_MAXSIZE && s_nfree < V7_NICFREE && s_ninode < V7_NICINOD)
|
||||
if(s_fsize < V7_MAXSIZE && s_nfree < V7_NICFREE && s_ninode < V7_NICINOD)
|
||||
{
|
||||
if ((s_fsize * 1024) == (imagePlugin.GetSectors() * imagePlugin.GetSectorSize()) || (s_fsize * 512) == (imagePlugin.GetSectors() * imagePlugin.GetSectorSize()))
|
||||
if((s_fsize * 1024) == (imagePlugin.GetSectors() * imagePlugin.GetSectorSize()) || (s_fsize * 512) == (imagePlugin.GetSectors() * imagePlugin.GetSectorSize()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -162,7 +162,7 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
BigEndianBitConverter.IsLittleEndian = true; // Start in little endian until we know what are we handling here
|
||||
int start;
|
||||
@@ -178,24 +178,24 @@ namespace DiscImageChef.Plugins
|
||||
byte[] sb_sector;
|
||||
byte sb_size_in_sectors;
|
||||
|
||||
if (imagePlugin.GetSectorSize() <= 0x400) // Check if underlying device sector size is smaller than SuperBlock size
|
||||
if(imagePlugin.GetSectorSize() <= 0x400) // Check if underlying device sector size is smaller than SuperBlock size
|
||||
sb_size_in_sectors = (byte)(0x400 / imagePlugin.GetSectorSize());
|
||||
else
|
||||
sb_size_in_sectors = 1; // If not a single sector can store it
|
||||
|
||||
// Superblock can start on 0x000, 0x200, 0x600 and 0x800, not aligned, so we assume 16 (128 bytes/sector) sectors as a safe value
|
||||
for (start = 0; start <= 16; start++)
|
||||
for(start = 0; start <= 16; start++)
|
||||
{
|
||||
sb_sector = imagePlugin.ReadSectors((ulong)start + partitionStart, sb_size_in_sectors);
|
||||
magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x3F8); // XENIX magic location
|
||||
|
||||
if (magic == XENIX_MAGIC)
|
||||
|
||||
if(magic == XENIX_MAGIC)
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian = true; // Little endian
|
||||
xenix = true;
|
||||
break;
|
||||
}
|
||||
if (magic == XENIX_CIGAM)
|
||||
if(magic == XENIX_CIGAM)
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian = false; // Big endian
|
||||
xenix = true;
|
||||
@@ -203,14 +203,14 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
|
||||
magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8); // XENIX magic location
|
||||
|
||||
if (magic == SYSV_MAGIC)
|
||||
|
||||
if(magic == SYSV_MAGIC)
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian = true; // Little endian
|
||||
sysv = true;
|
||||
break;
|
||||
}
|
||||
if (magic == SYSV_CIGAM)
|
||||
if(magic == SYSV_CIGAM)
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian = false; // Big endian
|
||||
sysv = true;
|
||||
@@ -222,8 +222,8 @@ namespace DiscImageChef.Plugins
|
||||
s_fname = StringHandlers.CToString(coherent_string);
|
||||
Array.Copy(sb_sector, 0x1EE, coherent_string, 0, 6); // Coherent UNIX s_fpack location
|
||||
s_fpack = StringHandlers.CToString(coherent_string);
|
||||
|
||||
if (s_fname == COH_FNAME || s_fpack == COH_FPACK)
|
||||
|
||||
if(s_fname == COH_FNAME || s_fpack == COH_FPACK)
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian = true; // Coherent is in PDP endianness, use helper for that
|
||||
coherent = true;
|
||||
@@ -235,21 +235,21 @@ namespace DiscImageChef.Plugins
|
||||
s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); // 7th edition's s_nfree
|
||||
s_ninode = BitConverter.ToUInt16(sb_sector, 0x0D0); // 7th edition's s_ninode
|
||||
|
||||
if (s_fsize > 0 && s_fsize < 0xFFFFFFFF && s_nfree > 0 && s_nfree < 0xFFFF && s_ninode > 0 && s_ninode < 0xFFFF)
|
||||
if(s_fsize > 0 && s_fsize < 0xFFFFFFFF && s_nfree > 0 && s_nfree < 0xFFFF && s_ninode > 0 && s_ninode < 0xFFFF)
|
||||
{
|
||||
if ((s_fsize & 0xFF) == 0x00 && (s_nfree & 0xFF) == 0x00 && (s_ninode & 0xFF) == 0x00)
|
||||
if((s_fsize & 0xFF) == 0x00 && (s_nfree & 0xFF) == 0x00 && (s_ninode & 0xFF) == 0x00)
|
||||
{
|
||||
// Byteswap
|
||||
s_fsize = ((s_fsize & 0xFF) << 24) + ((s_fsize & 0xFF00) << 8) + ((s_fsize & 0xFF0000) >> 8) + ((s_fsize & 0xFF000000) >> 24);
|
||||
s_nfree = (UInt16)(s_nfree >> 8);
|
||||
s_ninode = (UInt16)(s_ninode >> 8);
|
||||
}
|
||||
|
||||
if ((s_fsize & 0xFF000000) == 0x00 && (s_nfree & 0xFF00) == 0x00 && (s_ninode & 0xFF00) == 0x00)
|
||||
|
||||
if((s_fsize & 0xFF000000) == 0x00 && (s_nfree & 0xFF00) == 0x00 && (s_ninode & 0xFF00) == 0x00)
|
||||
{
|
||||
if (s_fsize < V7_MAXSIZE && s_nfree < V7_NICFREE && s_ninode < V7_NICINOD)
|
||||
if(s_fsize < V7_MAXSIZE && s_nfree < V7_NICFREE && s_ninode < V7_NICINOD)
|
||||
{
|
||||
if ((s_fsize * 1024) == (imagePlugin.GetSectors() * imagePlugin.GetSectorSize()) || (s_fsize * 512) == (imagePlugin.GetSectors() * imagePlugin.GetSectorSize()))
|
||||
if((s_fsize * 1024) == (imagePlugin.GetSectors() * imagePlugin.GetSectorSize()) || (s_fsize * 512) == (imagePlugin.GetSectors() * imagePlugin.GetSectorSize()))
|
||||
{
|
||||
sys7th = true;
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
@@ -259,17 +259,17 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!sys7th && !sysv && !coherent && !xenix)
|
||||
if(!sys7th && !sysv && !coherent && !xenix)
|
||||
return;
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
|
||||
if (xenix)
|
||||
if(xenix)
|
||||
{
|
||||
byte[] xenix_strings = new byte[6];
|
||||
XenixSuperBlock xnx_sb = new XenixSuperBlock();
|
||||
sb_sector = imagePlugin.ReadSectors((ulong)start + partitionStart, sb_size_in_sectors);
|
||||
|
||||
|
||||
xnx_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000);
|
||||
xnx_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002);
|
||||
xnx_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x006);
|
||||
@@ -296,7 +296,7 @@ namespace DiscImageChef.Plugins
|
||||
UInt32 bs = 512;
|
||||
sb.AppendLine("XENIX filesystem");
|
||||
xmlFSType.Type = "XENIX fs";
|
||||
switch (xnx_sb.s_type)
|
||||
switch(xnx_sb.s_type)
|
||||
{
|
||||
case 1:
|
||||
sb.AppendLine("512 bytes per block");
|
||||
@@ -316,14 +316,14 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Unknown s_type value: 0x{0:X8}", xnx_sb.s_type).AppendLine();
|
||||
break;
|
||||
}
|
||||
if (imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
{
|
||||
if (bs != 2048)
|
||||
if(bs != 2048)
|
||||
sb.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", bs, 2048).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bs != imagePlugin.GetSectorSize())
|
||||
if(bs != imagePlugin.GetSectorSize())
|
||||
sb.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", bs, imagePlugin.GetSectorSize()).AppendLine();
|
||||
}
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", xnx_sb.s_fsize, xnx_sb.s_fsize * bs).AppendLine();
|
||||
@@ -334,16 +334,16 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("First data zone: {0}", xnx_sb.s_isize).AppendLine();
|
||||
sb.AppendFormat("{0} free inodes on volume", xnx_sb.s_tinode).AppendLine();
|
||||
sb.AppendFormat("{0} free inodes on list", xnx_sb.s_ninode).AppendLine();
|
||||
if (xnx_sb.s_flock > 0)
|
||||
if(xnx_sb.s_flock > 0)
|
||||
sb.AppendLine("Free block list is locked");
|
||||
if (xnx_sb.s_ilock > 0)
|
||||
if(xnx_sb.s_ilock > 0)
|
||||
sb.AppendLine("inode cache is locked");
|
||||
if (xnx_sb.s_fmod > 0)
|
||||
if(xnx_sb.s_fmod > 0)
|
||||
sb.AppendLine("Superblock is being modified");
|
||||
if (xnx_sb.s_ronly > 0)
|
||||
if(xnx_sb.s_ronly > 0)
|
||||
sb.AppendLine("Volume is mounted read-only");
|
||||
sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UNIXUnsignedToDateTime(xnx_sb.s_time)).AppendLine();
|
||||
if (xnx_sb.s_time != 0)
|
||||
if(xnx_sb.s_time != 0)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.UNIXUnsignedToDateTime(xnx_sb.s_time);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
@@ -351,7 +351,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Volume name: {0}", xnx_sb.s_fname).AppendLine();
|
||||
xmlFSType.VolumeName = xnx_sb.s_fname;
|
||||
sb.AppendFormat("Pack name: {0}", xnx_sb.s_fpack).AppendLine();
|
||||
if (xnx_sb.s_clean == 0x46)
|
||||
if(xnx_sb.s_clean == 0x46)
|
||||
sb.AppendLine("Volume is clean");
|
||||
else
|
||||
{
|
||||
@@ -360,7 +360,7 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
}
|
||||
|
||||
if (sysv)
|
||||
if(sysv)
|
||||
{
|
||||
sb_sector = imagePlugin.ReadSectors((ulong)start + partitionStart, sb_size_in_sectors);
|
||||
UInt16 pad0, pad1, pad2;
|
||||
@@ -381,7 +381,7 @@ namespace DiscImageChef.Plugins
|
||||
sysv_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8);
|
||||
sysv_sb.s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x1FC);
|
||||
|
||||
if (sysvr4)
|
||||
if(sysvr4)
|
||||
{
|
||||
sysv_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x004);
|
||||
sysv_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x008);
|
||||
@@ -425,7 +425,7 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
|
||||
UInt32 bs = 512;
|
||||
if (sysvr4)
|
||||
if(sysvr4)
|
||||
{
|
||||
sb.AppendLine("System V Release 4 filesystem");
|
||||
xmlFSType.Type = "SVR4 fs";
|
||||
@@ -435,7 +435,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendLine("System V Release 2 filesystem");
|
||||
xmlFSType.Type = "SVR2 fs";
|
||||
}
|
||||
switch (sysv_sb.s_type)
|
||||
switch(sysv_sb.s_type)
|
||||
{
|
||||
case 1:
|
||||
sb.AppendLine("512 bytes per block");
|
||||
@@ -455,14 +455,14 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Unknown s_type value: 0x{0:X8}", sysv_sb.s_type).AppendLine();
|
||||
break;
|
||||
}
|
||||
if (imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
{
|
||||
if (bs != 2048)
|
||||
if(bs != 2048)
|
||||
sb.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", bs, 2048).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bs != imagePlugin.GetSectorSize())
|
||||
if(bs != imagePlugin.GetSectorSize())
|
||||
sb.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", bs, imagePlugin.GetSectorSize()).AppendLine();
|
||||
}
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", sysv_sb.s_fsize, sysv_sb.s_fsize * bs).AppendLine();
|
||||
@@ -473,16 +473,16 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("First data zone: {0}", sysv_sb.s_isize).AppendLine();
|
||||
sb.AppendFormat("{0} free inodes on volume", sysv_sb.s_tinode).AppendLine();
|
||||
sb.AppendFormat("{0} free inodes on list", sysv_sb.s_ninode).AppendLine();
|
||||
if (sysv_sb.s_flock > 0)
|
||||
if(sysv_sb.s_flock > 0)
|
||||
sb.AppendLine("Free block list is locked");
|
||||
if (sysv_sb.s_ilock > 0)
|
||||
if(sysv_sb.s_ilock > 0)
|
||||
sb.AppendLine("inode cache is locked");
|
||||
if (sysv_sb.s_fmod > 0)
|
||||
if(sysv_sb.s_fmod > 0)
|
||||
sb.AppendLine("Superblock is being modified");
|
||||
if (sysv_sb.s_ronly > 0)
|
||||
if(sysv_sb.s_ronly > 0)
|
||||
sb.AppendLine("Volume is mounted read-only");
|
||||
sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UNIXUnsignedToDateTime(sysv_sb.s_time)).AppendLine();
|
||||
if (sysv_sb.s_time != 0)
|
||||
if(sysv_sb.s_time != 0)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.UNIXUnsignedToDateTime(sysv_sb.s_time);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
@@ -490,7 +490,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Volume name: {0}", sysv_sb.s_fname).AppendLine();
|
||||
xmlFSType.VolumeName = sysv_sb.s_fname;
|
||||
sb.AppendFormat("Pack name: {0}", sysv_sb.s_fpack).AppendLine();
|
||||
if (sysv_sb.s_state == (0x7C269D38 - sysv_sb.s_time))
|
||||
if(sysv_sb.s_state == (0x7C269D38 - sysv_sb.s_time))
|
||||
sb.AppendLine("Volume is clean");
|
||||
else
|
||||
{
|
||||
@@ -499,7 +499,7 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
}
|
||||
|
||||
if (coherent)
|
||||
if(coherent)
|
||||
{
|
||||
sb_sector = imagePlugin.ReadSectors((ulong)start + partitionStart, sb_size_in_sectors);
|
||||
CoherentSuperBlock coh_sb = new CoherentSuperBlock();
|
||||
@@ -527,7 +527,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.ClusterSize = 512;
|
||||
|
||||
sb.AppendLine("Coherent UNIX filesystem");
|
||||
if (imagePlugin.GetSectorSize() != 512)
|
||||
if(imagePlugin.GetSectorSize() != 512)
|
||||
sb.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", 512, 2048).AppendLine();
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", coh_sb.s_fsize, coh_sb.s_fsize * 512).AppendLine();
|
||||
sb.AppendFormat("{0} free zones on volume ({1} bytes)", coh_sb.s_tfree, coh_sb.s_tfree * 512).AppendLine();
|
||||
@@ -535,16 +535,16 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("First data zone: {0}", coh_sb.s_isize).AppendLine();
|
||||
sb.AppendFormat("{0} free inodes on volume", coh_sb.s_tinode).AppendLine();
|
||||
sb.AppendFormat("{0} free inodes on list", coh_sb.s_ninode).AppendLine();
|
||||
if (coh_sb.s_flock > 0)
|
||||
if(coh_sb.s_flock > 0)
|
||||
sb.AppendLine("Free block list is locked");
|
||||
if (coh_sb.s_ilock > 0)
|
||||
if(coh_sb.s_ilock > 0)
|
||||
sb.AppendLine("inode cache is locked");
|
||||
if (coh_sb.s_fmod > 0)
|
||||
if(coh_sb.s_fmod > 0)
|
||||
sb.AppendLine("Superblock is being modified");
|
||||
if (coh_sb.s_ronly > 0)
|
||||
if(coh_sb.s_ronly > 0)
|
||||
sb.AppendLine("Volume is mounted read-only");
|
||||
sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UNIXUnsignedToDateTime(coh_sb.s_time)).AppendLine();
|
||||
if (coh_sb.s_time != 0)
|
||||
if(coh_sb.s_time != 0)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.UNIXUnsignedToDateTime(coh_sb.s_time);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
@@ -554,7 +554,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("Pack name: {0}", coh_sb.s_fpack).AppendLine();
|
||||
}
|
||||
|
||||
if (sys7th)
|
||||
if(sys7th)
|
||||
{
|
||||
sb_sector = imagePlugin.ReadSectors((ulong)start + partitionStart, sb_size_in_sectors);
|
||||
UNIX7thEditionSuperBlock v7_sb = new UNIX7thEditionSuperBlock();
|
||||
@@ -581,7 +581,7 @@ namespace DiscImageChef.Plugins
|
||||
xmlFSType.Type = "UNIX 7th Edition fs";
|
||||
xmlFSType.ClusterSize = 512;
|
||||
sb.AppendLine("UNIX 7th Edition filesystem");
|
||||
if (imagePlugin.GetSectorSize() != 512)
|
||||
if(imagePlugin.GetSectorSize() != 512)
|
||||
sb.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", 512, 2048).AppendLine();
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", v7_sb.s_fsize, v7_sb.s_fsize * 512).AppendLine();
|
||||
sb.AppendFormat("{0} free zones on volume ({1} bytes)", v7_sb.s_tfree, v7_sb.s_tfree * 512).AppendLine();
|
||||
@@ -589,16 +589,16 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendFormat("First data zone: {0}", v7_sb.s_isize).AppendLine();
|
||||
sb.AppendFormat("{0} free inodes on volume", v7_sb.s_tinode).AppendLine();
|
||||
sb.AppendFormat("{0} free inodes on list", v7_sb.s_ninode).AppendLine();
|
||||
if (v7_sb.s_flock > 0)
|
||||
if(v7_sb.s_flock > 0)
|
||||
sb.AppendLine("Free block list is locked");
|
||||
if (v7_sb.s_ilock > 0)
|
||||
if(v7_sb.s_ilock > 0)
|
||||
sb.AppendLine("inode cache is locked");
|
||||
if (v7_sb.s_fmod > 0)
|
||||
if(v7_sb.s_fmod > 0)
|
||||
sb.AppendLine("Superblock is being modified");
|
||||
if (v7_sb.s_ronly > 0)
|
||||
if(v7_sb.s_ronly > 0)
|
||||
sb.AppendLine("Volume is mounted read-only");
|
||||
sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UNIXUnsignedToDateTime(v7_sb.s_time)).AppendLine();
|
||||
if (v7_sb.s_time != 0)
|
||||
if(v7_sb.s_time != 0)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.UNIXUnsignedToDateTime(v7_sb.s_time);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
UInt32 magic;
|
||||
@@ -71,7 +71,7 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] bfs_sb_sector = imagePlugin.ReadSector(0 + partitionStart);
|
||||
byte[] sb_strings = new byte[6];
|
||||
|
||||
@@ -53,14 +53,14 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector(2 + partitionStart);
|
||||
|
||||
UInt16 magic = BitConverter.ToUInt16(sb_sector, 0x038);
|
||||
|
||||
if (magic == ext2FSMagic || magic == ext2OldFSMagic)
|
||||
|
||||
if(magic == ext2FSMagic || magic == ext2OldFSMagic)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -68,7 +68,7 @@ namespace DiscImageChef.Plugins
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
ext2FSSuperBlock supblk = new ext2FSSuperBlock();
|
||||
@@ -82,12 +82,12 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
uint sb_size_in_sectors;
|
||||
|
||||
if (imagePlugin.GetSectorSize() < 1024)
|
||||
if(imagePlugin.GetSectorSize() < 1024)
|
||||
sb_size_in_sectors = 1024 / imagePlugin.GetSectorSize();
|
||||
else
|
||||
sb_size_in_sectors = 1;
|
||||
|
||||
if (sb_size_in_sectors == 0)
|
||||
if(sb_size_in_sectors == 0)
|
||||
{
|
||||
information = "Error calculating size in sectors of ext2/3/4 superblocks";
|
||||
return;
|
||||
@@ -227,16 +227,16 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
xmlFSType = new Schemas.FileSystemType();
|
||||
|
||||
if (supblk.magic == ext2OldFSMagic)
|
||||
if(supblk.magic == ext2OldFSMagic)
|
||||
{
|
||||
sb.AppendLine("ext2 (old) filesystem");
|
||||
xmlFSType.Type = "ext2";
|
||||
}
|
||||
else if (supblk.magic == ext2FSMagic)
|
||||
else if(supblk.magic == ext2FSMagic)
|
||||
{
|
||||
ext3 |= (supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL || (supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) == EXT3_FEATURE_INCOMPAT_RECOVER || (supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV;
|
||||
|
||||
if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) == EXT4_FEATURE_RO_COMPAT_HUGE_FILE ||
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) == EXT4_FEATURE_RO_COMPAT_HUGE_FILE ||
|
||||
(supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) == EXT4_FEATURE_RO_COMPAT_GDT_CSUM ||
|
||||
(supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) == EXT4_FEATURE_RO_COMPAT_DIR_NLINK ||
|
||||
(supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) == EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE ||
|
||||
@@ -252,17 +252,17 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
new_ext2 |= !ext3 && !ext4;
|
||||
|
||||
if (new_ext2)
|
||||
if(new_ext2)
|
||||
{
|
||||
sb.AppendLine("ext2 filesystem");
|
||||
xmlFSType.Type = "ext2";
|
||||
}
|
||||
if (ext3)
|
||||
if(ext3)
|
||||
{
|
||||
sb.AppendLine("ext3 filesystem");
|
||||
xmlFSType.Type = "ext3";
|
||||
}
|
||||
if (ext4)
|
||||
if(ext4)
|
||||
{
|
||||
sb.AppendLine("ext4 filesystem");
|
||||
xmlFSType.Type = "ext4";
|
||||
@@ -275,7 +275,7 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
|
||||
string ext_os;
|
||||
switch (supblk.creator_os)
|
||||
switch(supblk.creator_os)
|
||||
{
|
||||
case EXT2_OS_FREEBSD:
|
||||
ext_os = "FreeBSD";
|
||||
@@ -297,7 +297,7 @@ namespace DiscImageChef.Plugins
|
||||
break;
|
||||
}
|
||||
|
||||
if (supblk.mkfs_t > 0)
|
||||
if(supblk.mkfs_t > 0)
|
||||
{
|
||||
sb.AppendFormat("Volume was created on {0} for {1}", DateHandlers.UNIXUnsignedToDateTime(supblk.mkfs_t), ext_os).AppendLine();
|
||||
xmlFSType.CreationDate = DateHandlers.UNIXUnsignedToDateTime(supblk.mkfs_t);
|
||||
@@ -310,7 +310,7 @@ namespace DiscImageChef.Plugins
|
||||
byte[] temp_bytes = new byte[8];
|
||||
UInt64 blocks, reserved, free;
|
||||
|
||||
if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT)
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT)
|
||||
{
|
||||
temp_lo = BitConverter.GetBytes(supblk.blocks);
|
||||
temp_hi = BitConverter.GetBytes(supblk.blocks_hi);
|
||||
@@ -355,50 +355,50 @@ namespace DiscImageChef.Plugins
|
||||
free = supblk.free_blocks;
|
||||
}
|
||||
|
||||
if (supblk.block_size == 0) // Then it is 1024 bytes
|
||||
if(supblk.block_size == 0) // Then it is 1024 bytes
|
||||
supblk.block_size = 1024;
|
||||
|
||||
sb.AppendFormat("Volume has {0} blocks of {1} bytes, for a total of {2} bytes", blocks, 1024<<(int)supblk.block_size, blocks * (ulong)(1024<<(int)supblk.block_size)).AppendLine();
|
||||
sb.AppendFormat("Volume has {0} blocks of {1} bytes, for a total of {2} bytes", blocks, 1024 << (int)supblk.block_size, blocks * (ulong)(1024 << (int)supblk.block_size)).AppendLine();
|
||||
xmlFSType.Clusters = (long)blocks;
|
||||
xmlFSType.ClusterSize = 1024 << (int)supblk.block_size;
|
||||
if (supblk.mount_t > 0 || supblk.mount_c > 0)
|
||||
if(supblk.mount_t > 0 || supblk.mount_c > 0)
|
||||
{
|
||||
if (supblk.mount_t > 0)
|
||||
if(supblk.mount_t > 0)
|
||||
sb.AppendFormat("Last mounted on {0}", DateHandlers.UNIXUnsignedToDateTime(supblk.mount_t)).AppendLine();
|
||||
if (supblk.max_mount_c != -1)
|
||||
if(supblk.max_mount_c != -1)
|
||||
sb.AppendFormat("Volume has been mounted {0} times of a maximum of {1} mounts before checking", supblk.mount_c, supblk.max_mount_c).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("Volume has been mounted {0} times with no maximum no. of mounts before checking", supblk.mount_c).AppendLine();
|
||||
if (supblk.last_mount_dir != "")
|
||||
if(supblk.last_mount_dir != "")
|
||||
sb.AppendFormat("Last mounted on: \"{0}\"", supblk.last_mount_dir).AppendLine();
|
||||
if (supblk.mount_options != "")
|
||||
if(supblk.mount_options != "")
|
||||
sb.AppendFormat("Last used mount options were: {0}", supblk.mount_options).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine("Volume has never been mounted");
|
||||
if (supblk.max_mount_c != -1)
|
||||
if(supblk.max_mount_c != -1)
|
||||
sb.AppendFormat("Volume can be mounted {0} times before checking", supblk.max_mount_c).AppendLine();
|
||||
else
|
||||
sb.AppendLine("Volume has no maximum no. of mounts before checking");
|
||||
}
|
||||
|
||||
if (supblk.check_t > 0)
|
||||
if(supblk.check_t > 0)
|
||||
{
|
||||
if (supblk.check_inv > 0)
|
||||
if(supblk.check_inv > 0)
|
||||
sb.AppendFormat("Last checked on {0} (should check every {1} seconds)", DateHandlers.UNIXUnsignedToDateTime(supblk.check_t), supblk.check_inv).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("Last checked on {0}", DateHandlers.UNIXUnsignedToDateTime(supblk.check_t)).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (supblk.check_inv > 0)
|
||||
if(supblk.check_inv > 0)
|
||||
sb.AppendFormat("Volume has never been checked (should check every {0})", supblk.check_inv).AppendLine();
|
||||
else
|
||||
sb.AppendLine("Volume has never been checked");
|
||||
}
|
||||
|
||||
if (supblk.write_t > 0)
|
||||
if(supblk.write_t > 0)
|
||||
{
|
||||
sb.AppendFormat("Last written on {0}", DateHandlers.UNIXUnsignedToDateTime(supblk.write_t)).AppendLine();
|
||||
xmlFSType.ModificationDate = DateHandlers.UNIXUnsignedToDateTime(supblk.write_t);
|
||||
@@ -408,7 +408,7 @@ namespace DiscImageChef.Plugins
|
||||
sb.AppendLine("Volume has never been written");
|
||||
|
||||
xmlFSType.Dirty = true;
|
||||
switch (supblk.state)
|
||||
switch(supblk.state)
|
||||
{
|
||||
case EXT2_VALID_FS:
|
||||
sb.AppendLine("Volume is clean");
|
||||
@@ -425,10 +425,10 @@ namespace DiscImageChef.Plugins
|
||||
break;
|
||||
}
|
||||
|
||||
if (supblk.volume_name != "")
|
||||
if(supblk.volume_name != "")
|
||||
sb.AppendFormat("Volume name: \"{0}\"", supblk.volume_name).AppendLine();
|
||||
|
||||
switch (supblk.err_behaviour)
|
||||
switch(supblk.err_behaviour)
|
||||
{
|
||||
case EXT2_ERRORS_CONTINUE:
|
||||
sb.AppendLine("On errors, filesystem should continue");
|
||||
@@ -444,72 +444,72 @@ namespace DiscImageChef.Plugins
|
||||
break;
|
||||
}
|
||||
|
||||
if (supblk.revision > 0)
|
||||
if(supblk.revision > 0)
|
||||
sb.AppendFormat("Filesystem revision: {0}.{1}", supblk.revision, supblk.minor_revision).AppendLine();
|
||||
|
||||
if (supblk.uuid != Guid.Empty)
|
||||
if(supblk.uuid != Guid.Empty)
|
||||
{
|
||||
sb.AppendFormat("Volume UUID: {0}", supblk.uuid).AppendLine();
|
||||
xmlFSType.VolumeSerial = supblk.uuid.ToString();
|
||||
}
|
||||
|
||||
if (supblk.kbytes_written > 0)
|
||||
if(supblk.kbytes_written > 0)
|
||||
sb.AppendFormat("{0} KiB has been written on volume", supblk.kbytes_written).AppendLine();
|
||||
|
||||
sb.AppendFormat("{0} reserved and {1} free blocks", reserved, free).AppendLine();
|
||||
xmlFSType.FreeClusters = (long)free;
|
||||
xmlFSType.FreeClustersSpecified = true;
|
||||
sb.AppendFormat("{0} inodes with {1} free inodes ({2}%)", supblk.inodes, supblk.free_inodes, supblk.free_inodes * 100 / supblk.inodes).AppendLine();
|
||||
if (supblk.first_inode > 0)
|
||||
if(supblk.first_inode > 0)
|
||||
sb.AppendFormat("First inode is {0}", supblk.first_inode).AppendLine();
|
||||
if (supblk.frag_size > 0)
|
||||
if(supblk.frag_size > 0)
|
||||
sb.AppendFormat("{0} bytes per fragment", supblk.frag_size).AppendLine();
|
||||
if (supblk.blocks_per_grp > 0 && supblk.flags_per_grp > 0 && supblk.inodes_per_grp > 0)
|
||||
if(supblk.blocks_per_grp > 0 && supblk.flags_per_grp > 0 && supblk.inodes_per_grp > 0)
|
||||
sb.AppendFormat("{0} blocks, {1} flags and {2} inodes per group", supblk.blocks_per_grp, supblk.flags_per_grp, supblk.inodes_per_grp).AppendLine();
|
||||
if (supblk.first_block > 0)
|
||||
if(supblk.first_block > 0)
|
||||
sb.AppendFormat("{0} is first data block", supblk.first_block).AppendLine();
|
||||
sb.AppendFormat("Default UID: {0}, GID: {1}", supblk.default_uid, supblk.default_gid).AppendLine();
|
||||
if (supblk.block_group_no > 0)
|
||||
if(supblk.block_group_no > 0)
|
||||
sb.AppendFormat("Block group number is {0}", supblk.block_group_no).AppendLine();
|
||||
if (supblk.desc_grp_size > 0)
|
||||
if(supblk.desc_grp_size > 0)
|
||||
sb.AppendFormat("Group descriptor size is {0} bytes", supblk.desc_grp_size).AppendLine();
|
||||
if (supblk.first_meta_bg > 0)
|
||||
if(supblk.first_meta_bg > 0)
|
||||
sb.AppendFormat("First metablock group is {0}", supblk.first_meta_bg).AppendLine();
|
||||
if (supblk.raid_stride > 0)
|
||||
if(supblk.raid_stride > 0)
|
||||
sb.AppendFormat("RAID stride: {0}", supblk.raid_stride).AppendLine();
|
||||
if (supblk.raid_stripe_width > 0)
|
||||
if(supblk.raid_stripe_width > 0)
|
||||
sb.AppendFormat("{0} blocks on all data disks", supblk.raid_stripe_width).AppendLine();
|
||||
if (supblk.mmp_interval > 0 && supblk.mmp_block > 0)
|
||||
if(supblk.mmp_interval > 0 && supblk.mmp_block > 0)
|
||||
sb.AppendFormat("{0} seconds for multi-mount protection wait, on block {1}", supblk.mmp_interval, supblk.mmp_block).AppendLine();
|
||||
if (supblk.flex_bg_grp_size > 0)
|
||||
if(supblk.flex_bg_grp_size > 0)
|
||||
sb.AppendFormat("{0} Flexible block group size", supblk.flex_bg_grp_size).AppendLine();
|
||||
if (supblk.hash_seed_1 > 0 && supblk.hash_seed_2 > 0 && supblk.hash_seed_3 > 0 && supblk.hash_seed_4 > 0)
|
||||
if(supblk.hash_seed_1 > 0 && supblk.hash_seed_2 > 0 && supblk.hash_seed_3 > 0 && supblk.hash_seed_4 > 0)
|
||||
sb.AppendFormat("Hash seed: {0:X8}{1:X8}{2:X8}{3:X8}, version {4}", supblk.hash_seed_1, supblk.hash_seed_2, supblk.hash_seed_3, supblk.hash_seed_4, supblk.hash_version).AppendLine();
|
||||
|
||||
if ((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL ||
|
||||
if((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL ||
|
||||
(supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
|
||||
{
|
||||
sb.AppendLine("Volume is journaled");
|
||||
if (supblk.journal_uuid != Guid.Empty)
|
||||
if(supblk.journal_uuid != Guid.Empty)
|
||||
sb.AppendFormat("Journal UUID: {0}", supblk.journal_uuid).AppendLine();
|
||||
sb.AppendFormat("Journal has inode {0}", supblk.journal_inode).AppendLine();
|
||||
if ((supblk.ftr_compat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV && supblk.journal_dev > 0)
|
||||
if((supblk.ftr_compat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV && supblk.journal_dev > 0)
|
||||
sb.AppendFormat("Journal is on device {0}", supblk.journal_dev).AppendLine();
|
||||
if (supblk.jnl_backup_type > 0)
|
||||
if(supblk.jnl_backup_type > 0)
|
||||
sb.AppendFormat("Journal backup type: {0}", supblk.jnl_backup_type).AppendLine();
|
||||
if (supblk.last_orphan > 0)
|
||||
if(supblk.last_orphan > 0)
|
||||
sb.AppendFormat("Last orphaned inode is {0}", supblk.last_orphan).AppendLine();
|
||||
else
|
||||
sb.AppendLine("There are no orphaned inodes");
|
||||
}
|
||||
|
||||
if (ext4)
|
||||
if(ext4)
|
||||
{
|
||||
if (supblk.snapshot_id > 0)
|
||||
if(supblk.snapshot_id > 0)
|
||||
sb.AppendFormat("Active snapshot has ID {0}, on inode {1}, with {2} blocks reserved, list starting on block {3}", supblk.snapshot_id,
|
||||
supblk.snapshot_inum, supblk.snapshot_blocks, supblk.snapshot_list).AppendLine();
|
||||
|
||||
if (supblk.error_count > 0)
|
||||
if(supblk.error_count > 0)
|
||||
{
|
||||
sb.AppendFormat("{0} errors registered", supblk.error_count).AppendLine();
|
||||
sb.AppendFormat("First error occurred on {0}, last on {1}", DateHandlers.UNIXUnsignedToDateTime(supblk.first_error_t), DateHandlers.UNIXUnsignedToDateTime(supblk.last_error_t)).AppendLine();
|
||||
@@ -520,101 +520,101 @@ namespace DiscImageChef.Plugins
|
||||
}
|
||||
|
||||
sb.AppendFormat("Flags…:").AppendLine();
|
||||
if ((supblk.flags & EXT2_FLAGS_SIGNED_HASH) == EXT2_FLAGS_SIGNED_HASH)
|
||||
if((supblk.flags & EXT2_FLAGS_SIGNED_HASH) == EXT2_FLAGS_SIGNED_HASH)
|
||||
sb.AppendLine("Signed directory hash is in use");
|
||||
if ((supblk.flags & EXT2_FLAGS_UNSIGNED_HASH) == EXT2_FLAGS_UNSIGNED_HASH)
|
||||
if((supblk.flags & EXT2_FLAGS_UNSIGNED_HASH) == EXT2_FLAGS_UNSIGNED_HASH)
|
||||
sb.AppendLine("Unsigned directory hash is in use");
|
||||
if ((supblk.flags & EXT2_FLAGS_TEST_FILESYS) == EXT2_FLAGS_TEST_FILESYS)
|
||||
if((supblk.flags & EXT2_FLAGS_TEST_FILESYS) == EXT2_FLAGS_TEST_FILESYS)
|
||||
sb.AppendLine("Volume is testing development code");
|
||||
if ((supblk.flags & 0xFFFFFFF8) != 0)
|
||||
if((supblk.flags & 0xFFFFFFF8) != 0)
|
||||
sb.AppendFormat("Unknown set flags: {0:X8}", supblk.flags);
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendFormat("Default mount options…:").AppendLine();
|
||||
if ((supblk.default_mnt_opts & EXT2_DEFM_DEBUG) == EXT2_DEFM_DEBUG)
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_DEBUG) == EXT2_DEFM_DEBUG)
|
||||
sb.AppendLine("(debug): Enable debugging code");
|
||||
if ((supblk.default_mnt_opts & EXT2_DEFM_BSDGROUPS) == EXT2_DEFM_BSDGROUPS)
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_BSDGROUPS) == EXT2_DEFM_BSDGROUPS)
|
||||
sb.AppendLine("(bsdgroups): Emulate BSD behaviour when creating new files");
|
||||
if ((supblk.default_mnt_opts & EXT2_DEFM_XATTR_USER) == EXT2_DEFM_XATTR_USER)
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_XATTR_USER) == EXT2_DEFM_XATTR_USER)
|
||||
sb.AppendLine("(user_xattr): Enable user-specified extended attributes");
|
||||
if ((supblk.default_mnt_opts & EXT2_DEFM_ACL) == EXT2_DEFM_ACL)
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_ACL) == EXT2_DEFM_ACL)
|
||||
sb.AppendLine("(acl): Enable POSIX ACLs");
|
||||
if ((supblk.default_mnt_opts & EXT2_DEFM_UID16) == EXT2_DEFM_UID16)
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_UID16) == EXT2_DEFM_UID16)
|
||||
sb.AppendLine("(uid16): Disable 32bit UIDs and GIDs");
|
||||
if ((supblk.default_mnt_opts & EXT3_DEFM_JMODE_DATA) == EXT3_DEFM_JMODE_DATA)
|
||||
if((supblk.default_mnt_opts & EXT3_DEFM_JMODE_DATA) == EXT3_DEFM_JMODE_DATA)
|
||||
sb.AppendLine("(journal_data): Journal data and metadata");
|
||||
if ((supblk.default_mnt_opts & EXT3_DEFM_JMODE_ORDERED) == EXT3_DEFM_JMODE_ORDERED)
|
||||
if((supblk.default_mnt_opts & EXT3_DEFM_JMODE_ORDERED) == EXT3_DEFM_JMODE_ORDERED)
|
||||
sb.AppendLine("(journal_data_ordered): Write data before journaling metadata");
|
||||
if ((supblk.default_mnt_opts & EXT3_DEFM_JMODE_WBACK) == EXT3_DEFM_JMODE_WBACK)
|
||||
if((supblk.default_mnt_opts & EXT3_DEFM_JMODE_WBACK) == EXT3_DEFM_JMODE_WBACK)
|
||||
sb.AppendLine("(journal_data_writeback): Write journal before data");
|
||||
if ((supblk.default_mnt_opts & 0xFFFFFE20) != 0)
|
||||
if((supblk.default_mnt_opts & 0xFFFFFE20) != 0)
|
||||
sb.AppendFormat("Unknown set default mount options: {0:X8}", supblk.default_mnt_opts);
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendFormat("Compatible features…:").AppendLine();
|
||||
if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_DIR_PREALLOC) == EXT2_FEATURE_COMPAT_DIR_PREALLOC)
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_DIR_PREALLOC) == EXT2_FEATURE_COMPAT_DIR_PREALLOC)
|
||||
sb.AppendLine("Pre-allocate directories");
|
||||
if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES) == EXT2_FEATURE_COMPAT_IMAGIC_INODES)
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES) == EXT2_FEATURE_COMPAT_IMAGIC_INODES)
|
||||
sb.AppendLine("imagic inodes ?");
|
||||
if ((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL)
|
||||
if((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL)
|
||||
sb.AppendLine("Has journal (ext3)");
|
||||
if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) == EXT2_FEATURE_COMPAT_EXT_ATTR)
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) == EXT2_FEATURE_COMPAT_EXT_ATTR)
|
||||
sb.AppendLine("Has extended attribute blocks");
|
||||
if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_RESIZE_INO) == EXT2_FEATURE_COMPAT_RESIZE_INO)
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_RESIZE_INO) == EXT2_FEATURE_COMPAT_RESIZE_INO)
|
||||
sb.AppendLine("Has online filesystem resize reservations");
|
||||
if ((supblk.ftr_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) == EXT2_FEATURE_COMPAT_DIR_INDEX)
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) == EXT2_FEATURE_COMPAT_DIR_INDEX)
|
||||
sb.AppendLine("Can use hashed indexes on directories");
|
||||
if ((supblk.ftr_compat & 0xFFFFFFC0) != 0)
|
||||
if((supblk.ftr_compat & 0xFFFFFFC0) != 0)
|
||||
sb.AppendFormat("Unknown compatible features: {0:X8}", supblk.ftr_compat);
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendFormat("Compatible features if read-only…:").AppendLine();
|
||||
if ((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) == EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
|
||||
if((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) == EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
|
||||
sb.AppendLine("Reduced number of superblocks");
|
||||
if ((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
|
||||
if((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
|
||||
sb.AppendLine("Can have files bigger than 2GiB");
|
||||
if ((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_BTREE_DIR) == EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
|
||||
if((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_BTREE_DIR) == EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
|
||||
sb.AppendLine("Uses B-Tree for directories");
|
||||
if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) == EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) == EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
|
||||
sb.AppendLine("Can have files bigger than 2TiB (ext4)");
|
||||
if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) == EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) == EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
|
||||
sb.AppendLine("Group descriptor checksums and sparse inode table (ext4)");
|
||||
if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) == EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) == EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
|
||||
sb.AppendLine("More than 32000 directory entries (ext4)");
|
||||
if ((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) == EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) == EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
|
||||
sb.AppendLine("Supports nanosecond timestamps and creation time (ext4)");
|
||||
if ((supblk.ftr_ro_compat & 0xFFFFFF80) != 0)
|
||||
if((supblk.ftr_ro_compat & 0xFFFFFF80) != 0)
|
||||
sb.AppendFormat("Unknown read-only compatible features: {0:X8}", supblk.ftr_ro_compat);
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendFormat("Incompatible features…:").AppendLine();
|
||||
if ((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) == EXT2_FEATURE_INCOMPAT_COMPRESSION)
|
||||
if((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) == EXT2_FEATURE_INCOMPAT_COMPRESSION)
|
||||
sb.AppendLine("Uses compression");
|
||||
if ((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE) == EXT2_FEATURE_INCOMPAT_FILETYPE)
|
||||
if((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE) == EXT2_FEATURE_INCOMPAT_FILETYPE)
|
||||
sb.AppendLine("Filetype in directory entries");
|
||||
if ((supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) == EXT3_FEATURE_INCOMPAT_RECOVER)
|
||||
if((supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) == EXT3_FEATURE_INCOMPAT_RECOVER)
|
||||
sb.AppendLine("Journal needs recovery (ext3)");
|
||||
if ((supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
|
||||
if((supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
|
||||
sb.AppendLine("Has journal on another device (ext3)");
|
||||
if ((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_META_BG) == EXT2_FEATURE_INCOMPAT_META_BG)
|
||||
if((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_META_BG) == EXT2_FEATURE_INCOMPAT_META_BG)
|
||||
sb.AppendLine("Reduced block group backups");
|
||||
if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EXTENTS) == EXT4_FEATURE_INCOMPAT_EXTENTS)
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EXTENTS) == EXT4_FEATURE_INCOMPAT_EXTENTS)
|
||||
sb.AppendLine("Volume use extents (ext4)");
|
||||
if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT)
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT)
|
||||
sb.AppendLine("Supports volumes bigger than 2^32 blocks (ext4)");
|
||||
if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP) == EXT4_FEATURE_INCOMPAT_MMP)
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP) == EXT4_FEATURE_INCOMPAT_MMP)
|
||||
sb.AppendLine("Multi-mount protection (ext4)");
|
||||
if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) == EXT4_FEATURE_INCOMPAT_FLEX_BG)
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) == EXT4_FEATURE_INCOMPAT_FLEX_BG)
|
||||
sb.AppendLine("Flexible block group metadata location (ext4)");
|
||||
if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE) == EXT4_FEATURE_INCOMPAT_EA_INODE)
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE) == EXT4_FEATURE_INCOMPAT_EA_INODE)
|
||||
sb.AppendLine("Extended attributes can reside in inode (ext4)");
|
||||
if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA) == EXT4_FEATURE_INCOMPAT_DIRDATA)
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA) == EXT4_FEATURE_INCOMPAT_DIRDATA)
|
||||
sb.AppendLine("Data can reside in directory entry (ext4)");
|
||||
if ((supblk.ftr_incompat & 0xFFFFF020) != 0)
|
||||
if((supblk.ftr_incompat & 0xFFFFF020) != 0)
|
||||
sb.AppendFormat("Unknown incompatible features: {0:X8}", supblk.ftr_incompat);
|
||||
|
||||
information = sb.ToString();
|
||||
|
||||
@@ -53,20 +53,20 @@ namespace DiscImageChef.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||
{
|
||||
if ((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
if((2 + partitionStart) >= imagePlugin.GetSectors())
|
||||
return false;
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector(2 + partitionStart); // Superblock resides at 0x400
|
||||
|
||||
UInt16 magic = BitConverter.ToUInt16(sb_sector, 0x038); // Here should reside magic number
|
||||
|
||||
|
||||
return magic == extFSMagic;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector(2 + partitionStart); // Superblock resides at 0x400
|
||||
|
||||
Reference in New Issue
Block a user