mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Corrected detection and reading of misaligned partitions on
optical media (e.g. map says sector 17 on 512 byte units, that would fall on sector 4.25 on 2048 units).
This commit is contained in:
@@ -81,25 +81,17 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
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 + partition.Start);
|
mdb_sector = imagePlugin.ReadSectors(partition.Start, 2);
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
|
||||||
|
|
||||||
|
foreach(int offset in new[] { 0, 0x200, 0x400, 0x600, 0x800, 0xA00 })
|
||||||
|
{
|
||||||
|
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, offset);
|
||||||
if(drSigWord == HFS_MAGIC)
|
if(drSigWord == HFS_MAGIC)
|
||||||
{
|
{
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x7C); // Seek to embedded HFS+ signature
|
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, offset + 0x7C); // Seek to embedded HFS+ signature
|
||||||
|
|
||||||
return drSigWord != HFSP_MAGIC;
|
return drSigWord != HFSP_MAGIC;
|
||||||
}
|
}
|
||||||
mdb_sector = Read2048SectorAs512(imagePlugin, 2 + partition.Start * 4);
|
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
|
||||||
|
|
||||||
if(drSigWord == HFS_MAGIC)
|
|
||||||
{
|
|
||||||
DicConsole.DebugWriteLine("HFS plugin", "HFS sector size is 512 bytes, but device's 2048");
|
|
||||||
|
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x7C); // Seek to embedded HFS+ signature
|
|
||||||
|
|
||||||
return drSigWord != HFSP_MAGIC;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -126,37 +118,35 @@ namespace DiscImageChef.Filesystems
|
|||||||
HFS_MasterDirectoryBlock MDB = new HFS_MasterDirectoryBlock();
|
HFS_MasterDirectoryBlock MDB = new HFS_MasterDirectoryBlock();
|
||||||
HFS_BootBlock BB = new HFS_BootBlock();
|
HFS_BootBlock BB = new HFS_BootBlock();
|
||||||
|
|
||||||
byte[] pString;
|
byte[] bb_sector = null;
|
||||||
|
byte[] mdb_sector = null;
|
||||||
byte[] bb_sector;
|
|
||||||
byte[] mdb_sector;
|
|
||||||
ushort drSigWord;
|
ushort drSigWord;
|
||||||
|
|
||||||
bool APMFromHDDOnCD = false;
|
bool APMFromHDDOnCD = false;
|
||||||
|
|
||||||
|
// TODO: I don't like this, I can do better
|
||||||
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 + partition.Start);
|
byte[] tmp_sector = imagePlugin.ReadSectors(partition.Start, 2);
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
|
||||||
|
|
||||||
|
foreach(int offset in new[] { 0, 0x200, 0x400, 0x600, 0x800, 0xA00 })
|
||||||
|
{
|
||||||
|
drSigWord = BigEndianBitConverter.ToUInt16(tmp_sector, offset);
|
||||||
if(drSigWord == HFS_MAGIC)
|
if(drSigWord == HFS_MAGIC)
|
||||||
{
|
{
|
||||||
bb_sector = imagePlugin.ReadSector(partition.Start);
|
bb_sector = new byte[1024];
|
||||||
}
|
mdb_sector = new byte[512];
|
||||||
else
|
if(offset >= 0x400)
|
||||||
{
|
Array.Copy(tmp_sector, offset - 0x400, bb_sector, 0, 1024);
|
||||||
mdb_sector = Read2048SectorAs512(imagePlugin, 2 + partition.Start * 4);
|
Array.Copy(tmp_sector, offset, mdb_sector, 0, 512);
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
|
||||||
|
|
||||||
if(drSigWord == HFS_MAGIC)
|
|
||||||
{
|
|
||||||
bb_sector = Read2048SectorAs512(imagePlugin, partition.Start * 4);
|
|
||||||
APMFromHDDOnCD = true;
|
APMFromHDDOnCD = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if(!APMFromHDDOnCD)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mdb_sector = imagePlugin.ReadSector(2 + partition.Start);
|
mdb_sector = imagePlugin.ReadSector(2 + partition.Start);
|
||||||
@@ -174,7 +164,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
sb.AppendLine("Apple Hierarchical File System");
|
sb.AppendLine("Apple Hierarchical File System");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
if(APMFromHDDOnCD)
|
if(APMFromHDDOnCD)
|
||||||
sb.AppendLine("HFS uses 512 bytes/sector while devices uses 2048 bytes/sector.").AppendLine();
|
sb.AppendLine("HFS uses 512 bytes/sector while device uses 2048 bytes/sector.").AppendLine();
|
||||||
sb.AppendLine("Master Directory Block:");
|
sb.AppendLine("Master Directory Block:");
|
||||||
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(MDB.drCrDate)).AppendLine();
|
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(MDB.drCrDate)).AppendLine();
|
||||||
sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(MDB.drLsMod)).AppendLine();
|
sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(MDB.drLsMod)).AppendLine();
|
||||||
@@ -235,6 +225,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
sb.AppendFormat("CNID of previously opened directory: {0}", MDB.drFndrInfo2).AppendLine();
|
sb.AppendFormat("CNID of previously opened directory: {0}", MDB.drFndrInfo2).AppendLine();
|
||||||
sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", MDB.drFndrInfo3).AppendLine();
|
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("CNID of bootable Mac OS X directory: {0}", MDB.drFndrInfo5).AppendLine();
|
||||||
|
if(MDB.drFndrInfo6 != 0 && MDB.drFndrInfo7 != 0)
|
||||||
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", MDB.drFndrInfo6, MDB.drFndrInfo7).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)
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ using System.Collections.Generic;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
|
using DiscImageChef.Console;
|
||||||
|
|
||||||
namespace DiscImageChef.Filesystems
|
namespace DiscImageChef.Filesystems
|
||||||
{
|
{
|
||||||
@@ -82,23 +83,27 @@ namespace DiscImageChef.Filesystems
|
|||||||
byte[] vh_sector;
|
byte[] vh_sector;
|
||||||
ulong hfsp_offset;
|
ulong hfsp_offset;
|
||||||
|
|
||||||
vh_sector = imagePlugin.ReadSector(2 + partition.Start); // Read volume header, of HFS Wrapper MDB
|
uint sectorsToRead = 0x800 / imagePlugin.ImageInfo.sectorSize;
|
||||||
|
if(0x800 % imagePlugin.ImageInfo.sectorSize > 0)
|
||||||
|
sectorsToRead++;
|
||||||
|
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0); // Check for HFS Wrapper MDB
|
vh_sector = imagePlugin.ReadSectors(partition.Start, sectorsToRead); // Read volume header, of HFS Wrapper MDB
|
||||||
|
|
||||||
|
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x400); // 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
|
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x47C); // 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
|
xdrStABNt = BigEndianBitConverter.ToUInt16(vh_sector, 0x47E); // Starting block number of embedded HFS+ volume
|
||||||
|
|
||||||
drAlBlkSiz = BigEndianBitConverter.ToUInt32(vh_sector, 0x014); // Block size
|
drAlBlkSiz = BigEndianBitConverter.ToUInt32(vh_sector, 0x414); // Block size
|
||||||
|
|
||||||
drAlBlSt = BigEndianBitConverter.ToUInt16(vh_sector, 0x01C); // Start of allocated blocks (in 512-byte/block)
|
drAlBlSt = BigEndianBitConverter.ToUInt16(vh_sector, 0x41C); // Start of allocated blocks (in 512-byte/block)
|
||||||
|
|
||||||
hfsp_offset = (drAlBlSt + xdrStABNt * (drAlBlkSiz / 512)) * (imagePlugin.GetSectorSize() / 512);
|
hfsp_offset = (ulong)(((drAlBlSt * 512) + (xdrStABNt * drAlBlkSiz)) / imagePlugin.GetSectorSize());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -110,9 +115,9 @@ namespace DiscImageChef.Filesystems
|
|||||||
hfsp_offset = 0;
|
hfsp_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vh_sector = imagePlugin.ReadSector(2 + partition.Start + hfsp_offset); // Read volume header
|
vh_sector = imagePlugin.ReadSectors(partition.Start + hfsp_offset, sectorsToRead); // Read volume header
|
||||||
|
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0);
|
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x400);
|
||||||
if(drSigWord == HFSP_MAGIC || drSigWord == HFSX_MAGIC)
|
if(drSigWord == HFSP_MAGIC || drSigWord == HFSX_MAGIC)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
@@ -132,23 +137,27 @@ namespace DiscImageChef.Filesystems
|
|||||||
bool wrapped;
|
bool wrapped;
|
||||||
byte[] vh_sector;
|
byte[] vh_sector;
|
||||||
|
|
||||||
vh_sector = imagePlugin.ReadSector(2 + partition.Start); // Read volume header, of HFS Wrapper MDB
|
uint sectorsToRead = 0x800 / imagePlugin.ImageInfo.sectorSize;
|
||||||
|
if(0x800 % imagePlugin.ImageInfo.sectorSize > 0)
|
||||||
|
sectorsToRead++;
|
||||||
|
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0); // Check for HFS Wrapper MDB
|
vh_sector = imagePlugin.ReadSectors(partition.Start, sectorsToRead); // Read volume header, of HFS Wrapper MDB
|
||||||
|
|
||||||
|
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x400); // 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
|
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x47C); // 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
|
xdrStABNt = BigEndianBitConverter.ToUInt16(vh_sector, 0x47E); // Starting block number of embedded HFS+ volume
|
||||||
|
|
||||||
drAlBlkSiz = BigEndianBitConverter.ToUInt32(vh_sector, 0x014); // Block size
|
drAlBlkSiz = BigEndianBitConverter.ToUInt32(vh_sector, 0x414); // Block size
|
||||||
|
|
||||||
drAlBlSt = BigEndianBitConverter.ToUInt16(vh_sector, 0x01C); // Start of allocated blocks (in 512-byte/block)
|
drAlBlSt = BigEndianBitConverter.ToUInt16(vh_sector, 0x41C); // Start of allocated blocks (in 512-byte/block)
|
||||||
|
|
||||||
hfsp_offset = (drAlBlSt + xdrStABNt * (drAlBlkSiz / 512)) * (imagePlugin.GetSectorSize() / 512);
|
hfsp_offset = (ulong)(((drAlBlSt * 512) + (xdrStABNt * drAlBlkSiz)) / imagePlugin.GetSectorSize());
|
||||||
wrapped = true;
|
wrapped = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -163,9 +172,9 @@ namespace DiscImageChef.Filesystems
|
|||||||
wrapped = false;
|
wrapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vh_sector = imagePlugin.ReadSector(2 + partition.Start + hfsp_offset); // Read volume header
|
vh_sector = imagePlugin.ReadSectors(partition.Start + hfsp_offset, sectorsToRead); // Read volume header
|
||||||
|
|
||||||
HPVH.signature = BigEndianBitConverter.ToUInt16(vh_sector, 0x000);
|
HPVH.signature = BigEndianBitConverter.ToUInt16(vh_sector, 0x400);
|
||||||
if(HPVH.signature == HFSP_MAGIC || HPVH.signature == HFSX_MAGIC)
|
if(HPVH.signature == HFSP_MAGIC || HPVH.signature == HFSX_MAGIC)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@@ -177,6 +186,10 @@ namespace DiscImageChef.Filesystems
|
|||||||
if(wrapped)
|
if(wrapped)
|
||||||
sb.AppendLine("Volume is wrapped inside an HFS volume.");
|
sb.AppendLine("Volume is wrapped inside an HFS volume.");
|
||||||
|
|
||||||
|
byte[] tmp = new byte[0x400];
|
||||||
|
Array.Copy(vh_sector, 0x400, tmp, 0, 0x400);
|
||||||
|
vh_sector = tmp;
|
||||||
|
|
||||||
HPVH = BigEndianMarshal.ByteArrayToStructureBigEndian<HFSPlusVolumeHeader>(vh_sector);
|
HPVH = BigEndianMarshal.ByteArrayToStructureBigEndian<HFSPlusVolumeHeader>(vh_sector);
|
||||||
|
|
||||||
if(HPVH.version == 4 || HPVH.version == 5)
|
if(HPVH.version == 4 || HPVH.version == 5)
|
||||||
|
|||||||
@@ -101,6 +101,25 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
// Blocks 0 and 1 are boot code
|
// Blocks 0 and 1 are boot code
|
||||||
byte[] rootDirectoryKeyBlock = imagePlugin.ReadSector(2 + partition.Start);
|
byte[] rootDirectoryKeyBlock = imagePlugin.ReadSector(2 + partition.Start);
|
||||||
|
bool APMFromHDDOnCD = false;
|
||||||
|
|
||||||
|
if(imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448 || imagePlugin.GetSectorSize() == 2048)
|
||||||
|
{
|
||||||
|
byte[] tmp = imagePlugin.ReadSectors(partition.Start, 2);
|
||||||
|
|
||||||
|
foreach(int offset in new[] { 0, 0x200, 0x400, 0x600, 0x800, 0xA00 })
|
||||||
|
{
|
||||||
|
if(BitConverter.ToUInt16(tmp, offset) == 0 &&
|
||||||
|
(byte)((tmp[offset + 0x04] & ProDOSStorageTypeMask) >> 4) == RootDirectoryType &&
|
||||||
|
tmp[offset + 0x23] == ProDOSEntryLength &&
|
||||||
|
tmp[offset + 0x24] == ProDOSEntriesPerBlock)
|
||||||
|
{
|
||||||
|
Array.Copy(tmp, offset, rootDirectoryKeyBlock, 0, 0x200);
|
||||||
|
APMFromHDDOnCD = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ushort prePointer = BitConverter.ToUInt16(rootDirectoryKeyBlock, 0);
|
ushort prePointer = BitConverter.ToUInt16(rootDirectoryKeyBlock, 0);
|
||||||
DicConsole.DebugWriteLine("ProDOS plugin", "prePointer = {0}", prePointer);
|
DicConsole.DebugWriteLine("ProDOS plugin", "prePointer = {0}", prePointer);
|
||||||
@@ -128,6 +147,9 @@ namespace DiscImageChef.Filesystems
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
ushort total_blocks = BitConverter.ToUInt16(rootDirectoryKeyBlock, 0x29);
|
ushort total_blocks = BitConverter.ToUInt16(rootDirectoryKeyBlock, 0x29);
|
||||||
|
if(APMFromHDDOnCD)
|
||||||
|
total_blocks /= 4;
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("ProDOS plugin", "{0} <= ({1} - {2} + 1)? {3}", total_blocks, partition.End, partition.Start, total_blocks <= (partition.End - partition.Start + 1));
|
DicConsole.DebugWriteLine("ProDOS plugin", "{0} <= ({1} - {2} + 1)? {3}", total_blocks, partition.End, partition.Start, total_blocks <= (partition.End - partition.Start + 1));
|
||||||
return total_blocks <= (partition.End - partition.Start + 1);
|
return total_blocks <= (partition.End - partition.Start + 1);
|
||||||
}
|
}
|
||||||
@@ -139,6 +161,26 @@ namespace DiscImageChef.Filesystems
|
|||||||
// Blocks 0 and 1 are boot code
|
// Blocks 0 and 1 are boot code
|
||||||
byte[] rootDirectoryKeyBlockBytes = imagePlugin.ReadSector(2 + partition.Start);
|
byte[] rootDirectoryKeyBlockBytes = imagePlugin.ReadSector(2 + partition.Start);
|
||||||
|
|
||||||
|
bool APMFromHDDOnCD = false;
|
||||||
|
|
||||||
|
if(imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448 || imagePlugin.GetSectorSize() == 2048)
|
||||||
|
{
|
||||||
|
byte[] tmp = imagePlugin.ReadSectors(partition.Start, 2);
|
||||||
|
|
||||||
|
foreach(int offset in new[] { 0, 0x200, 0x400, 0x600, 0x800, 0xA00 })
|
||||||
|
{
|
||||||
|
if(BitConverter.ToUInt16(tmp, offset) == 0 &&
|
||||||
|
(byte)((tmp[offset + 0x04] & ProDOSStorageTypeMask) >> 4) == RootDirectoryType &&
|
||||||
|
tmp[offset + 0x23] == ProDOSEntryLength &&
|
||||||
|
tmp[offset + 0x24] == ProDOSEntriesPerBlock)
|
||||||
|
{
|
||||||
|
Array.Copy(tmp, offset, rootDirectoryKeyBlockBytes, 0, 0x200);
|
||||||
|
APMFromHDDOnCD = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ProDOSRootDirectoryKeyBlock rootDirectoryKeyBlock = new ProDOSRootDirectoryKeyBlock();
|
ProDOSRootDirectoryKeyBlock rootDirectoryKeyBlock = new ProDOSRootDirectoryKeyBlock();
|
||||||
rootDirectoryKeyBlock.header = new ProDOSRootDirectoryHeader();
|
rootDirectoryKeyBlock.header = new ProDOSRootDirectoryHeader();
|
||||||
|
|
||||||
@@ -158,6 +200,10 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
temp_timestamp_left = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x1C);
|
temp_timestamp_left = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x1C);
|
||||||
temp_timestamp_right = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x1E);
|
temp_timestamp_right = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x1E);
|
||||||
|
|
||||||
|
bool dateCorrect;
|
||||||
|
try
|
||||||
|
{
|
||||||
temp_timestamp = (uint)((temp_timestamp_left << 16) + temp_timestamp_right);
|
temp_timestamp = (uint)((temp_timestamp_left << 16) + temp_timestamp_right);
|
||||||
year = (int)((temp_timestamp & ProDOSYearMask) >> 25);
|
year = (int)((temp_timestamp & ProDOSYearMask) >> 25);
|
||||||
month = (int)((temp_timestamp & ProDOSMonthMask) >> 21);
|
month = (int)((temp_timestamp & ProDOSMonthMask) >> 21);
|
||||||
@@ -174,6 +220,12 @@ namespace DiscImageChef.Filesystems
|
|||||||
DicConsole.DebugWriteLine("ProDOS plugin", "Datetime field year {0}, month {1}, day {2}, hour {3}, minute {4}.", year, month, day, hour, minute);
|
DicConsole.DebugWriteLine("ProDOS plugin", "Datetime field year {0}, month {1}, day {2}, hour {3}, minute {4}.", year, month, day, hour, minute);
|
||||||
|
|
||||||
rootDirectoryKeyBlock.header.creation_time = new DateTime(year, month, day, hour, minute, 0);
|
rootDirectoryKeyBlock.header.creation_time = new DateTime(year, month, day, hour, minute, 0);
|
||||||
|
dateCorrect = true;
|
||||||
|
}
|
||||||
|
catch(ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
dateCorrect = false;
|
||||||
|
}
|
||||||
|
|
||||||
rootDirectoryKeyBlock.header.version = rootDirectoryKeyBlockBytes[0x20];
|
rootDirectoryKeyBlock.header.version = rootDirectoryKeyBlockBytes[0x20];
|
||||||
rootDirectoryKeyBlock.header.min_version = rootDirectoryKeyBlockBytes[0x21];
|
rootDirectoryKeyBlock.header.min_version = rootDirectoryKeyBlockBytes[0x21];
|
||||||
@@ -185,6 +237,9 @@ namespace DiscImageChef.Filesystems
|
|||||||
rootDirectoryKeyBlock.header.bit_map_pointer = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x27);
|
rootDirectoryKeyBlock.header.bit_map_pointer = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x27);
|
||||||
rootDirectoryKeyBlock.header.total_blocks = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x29);
|
rootDirectoryKeyBlock.header.total_blocks = BitConverter.ToUInt16(rootDirectoryKeyBlockBytes, 0x29);
|
||||||
|
|
||||||
|
if(APMFromHDDOnCD)
|
||||||
|
sbInformation.AppendLine("ProDOS uses 512 bytes/sector while devices uses 2048 bytes/sector.").AppendLine();
|
||||||
|
|
||||||
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("Warning! Detected unknown ProDOS version ProDOS filesystem.");
|
||||||
@@ -202,6 +257,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
sbInformation.AppendFormat("Unknown ProDOS version with field {0} is at least required for reading this volume.", rootDirectoryKeyBlock.header.min_version).AppendLine();
|
sbInformation.AppendFormat("Unknown ProDOS version with field {0} is at least required for reading this volume.", rootDirectoryKeyBlock.header.min_version).AppendLine();
|
||||||
|
|
||||||
sbInformation.AppendFormat("Volume name is {0}", rootDirectoryKeyBlock.header.volume_name).AppendLine();
|
sbInformation.AppendFormat("Volume name is {0}", rootDirectoryKeyBlock.header.volume_name).AppendLine();
|
||||||
|
if(dateCorrect)
|
||||||
sbInformation.AppendFormat("Volume created on {0}", rootDirectoryKeyBlock.header.creation_time).AppendLine();
|
sbInformation.AppendFormat("Volume created on {0}", rootDirectoryKeyBlock.header.creation_time).AppendLine();
|
||||||
sbInformation.AppendFormat("{0} bytes per directory entry", rootDirectoryKeyBlock.header.entry_length).AppendLine();
|
sbInformation.AppendFormat("{0} bytes per directory entry", rootDirectoryKeyBlock.header.entry_length).AppendLine();
|
||||||
sbInformation.AppendFormat("{0} entries per directory block", rootDirectoryKeyBlock.header.entries_per_block).AppendLine();
|
sbInformation.AppendFormat("{0} entries per directory block", rootDirectoryKeyBlock.header.entries_per_block).AppendLine();
|
||||||
@@ -227,7 +283,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
xmlFSType = new Schemas.FileSystemType();
|
xmlFSType = new Schemas.FileSystemType();
|
||||||
xmlFSType.VolumeName = rootDirectoryKeyBlock.header.volume_name;
|
xmlFSType.VolumeName = rootDirectoryKeyBlock.header.volume_name;
|
||||||
if(year != 0 || month != 0 || day != 0 || hour != 0 || minute != 0)
|
if(dateCorrect)
|
||||||
{
|
{
|
||||||
xmlFSType.CreationDate = rootDirectoryKeyBlock.header.creation_time;
|
xmlFSType.CreationDate = rootDirectoryKeyBlock.header.creation_time;
|
||||||
xmlFSType.CreationDateSpecified = true;
|
xmlFSType.CreationDateSpecified = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user