diff --git a/DiscImageChef.Filesystems/AppleHFSPlus.cs b/DiscImageChef.Filesystems/AppleHFSPlus.cs index 646dad6b3..6b2e0df6c 100644 --- a/DiscImageChef.Filesystems/AppleHFSPlus.cs +++ b/DiscImageChef.Filesystems/AppleHFSPlus.cs @@ -33,6 +33,7 @@ using System; using System.Text; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace DiscImageChef.Filesystems { @@ -175,48 +176,10 @@ namespace DiscImageChef.Filesystems if(wrapped) sb.AppendLine("Volume is wrapped inside an HFS volume."); - HPVH.version = BigEndianBitConverter.ToUInt16(vh_sector, 0x002); + HPVH = BigEndianMarshal.ByteArrayToStructureBigEndian(vh_sector); 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.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.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.writeCount = BigEndianBitConverter.ToUInt32(vh_sector, 0x054); - - HPVH.drFndrInfo0 = BigEndianBitConverter.ToUInt32(vh_sector, 0x060); - HPVH.drFndrInfo1 = BigEndianBitConverter.ToUInt32(vh_sector, 0x064); - HPVH.drFndrInfo2 = BigEndianBitConverter.ToUInt32(vh_sector, 0x068); - HPVH.drFndrInfo3 = BigEndianBitConverter.ToUInt32(vh_sector, 0x06C); - 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(); @@ -237,13 +200,19 @@ namespace DiscImageChef.Filesystems if((HPVH.attributes & 0x8000) == 0x8000) sb.AppendLine("Volume is locked on software."); - sb.AppendFormat("Implementation that last mounted the volume: \"{0}\".", HPVH.lastMountedVersion).AppendLine(); + sb.AppendFormat("Implementation that last mounted the volume: \"{0}\".", Encoding.ASCII.GetString(HPVH.lastMountedVersion)).AppendLine(); 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(); - sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(HPVH.backupDate)).AppendLine(); - sb.AppendFormat("Last check date: {0}", DateHandlers.MacToDateTime(HPVH.checkedDate)).AppendLine(); + if(HPVH.backupDate > 0) + sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(HPVH.backupDate)).AppendLine(); + else + sb.AppendLine("Volume has never been backed up"); + if(HPVH.backupDate > 0) + sb.AppendFormat("Last check date: {0}", DateHandlers.MacToDateTime(HPVH.checkedDate)).AppendLine(); + else + sb.AppendLine("Volume has never been checked up"); sb.AppendFormat("{0} files on volume.", HPVH.fileCount).AppendLine(); sb.AppendFormat("{0} folders on volume.", HPVH.folderCount).AppendLine(); sb.AppendFormat("{0} bytes per allocation block.", HPVH.blockSize).AppendLine(); @@ -265,7 +234,8 @@ namespace DiscImageChef.Filesystems sb.AppendFormat("CNID of previously opened directory: {0}", HPVH.drFndrInfo2).AppendLine(); sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", HPVH.drFndrInfo3).AppendLine(); sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", HPVH.drFndrInfo5).AppendLine(); - sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", HPVH.drFndrInfo6, HPVH.drFndrInfo7).AppendLine(); + if(HPVH.drFndrInfo6 != 0 && HPVH.drFndrInfo7 != 0) + sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", HPVH.drFndrInfo6, HPVH.drFndrInfo7).AppendLine(); xmlFSType = new Schemas.FileSystemType(); if(HPVH.backupDate > 0) @@ -296,8 +266,8 @@ namespace DiscImageChef.Filesystems if(HPVH.signature == 0x4858) xmlFSType.Type = "HFSX"; if(HPVH.drFndrInfo6 != 0 && HPVH.drFndrInfo7 != 0) - xmlFSType.VolumeSerial = string.Format("{0:X8}{1:x8}", HPVH.drFndrInfo6, HPVH.drFndrInfo7); - xmlFSType.SystemIdentifier = HPVH.lastMountedVersion; + xmlFSType.VolumeSerial = string.Format("{0:X8}{1:X8}", HPVH.drFndrInfo6, HPVH.drFndrInfo7); + xmlFSType.SystemIdentifier = Encoding.ASCII.GetString(HPVH.lastMountedVersion); } else { @@ -314,6 +284,7 @@ namespace DiscImageChef.Filesystems /// /// HFS+ Volume Header, should be at offset 0x0400 bytes in volume with a size of 532 bytes /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] struct HFSPlusVolumeHeader { /// 0x000, "H+" for HFS+, "HX" for HFSX @@ -328,249 +299,250 @@ namespace DiscImageChef.Filesystems /// "10.0" Mac OS X /// "HFSJ" Journaled implementation /// "fsck" /sbin/fsck - public string lastMountedVersion; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] lastMountedVersion; /// 0x00C, Allocation block number containing the journal public uint journalInfoBlock; /// 0x010, Date of volume creation - public ulong createDate; - /// 0x018, Date of last volume modification - public ulong modifyDate; - /// 0x020, Date of last backup - public ulong backupDate; - /// 0x028, Date of last consistency check - public ulong checkedDate; - /// 0x030, File on the volume + public uint createDate; + /// 0x014, Date of last volume modification + public uint modifyDate; + /// 0x018, Date of last backup + public uint backupDate; + /// 0x01C, Date of last consistency check + public uint checkedDate; + /// 0x020, File on the volume public uint fileCount; - /// 0x034, Folders on the volume + /// 0x024, Folders on the volume public uint folderCount; - /// 0x038, Bytes per allocation block + /// 0x028, Bytes per allocation block public uint blockSize; - /// 0x03C, Allocation blocks on the volume + /// 0x02C, Allocation blocks on the volume public uint totalBlocks; - /// 0x040, Free allocation blocks + /// 0x030, Free allocation blocks public uint freeBlocks; - /// 0x044, Hint for next allocation block + /// 0x034, Hint for next allocation block public uint nextAllocation; - /// 0x048, Resource fork clump size + /// 0x038, Resource fork clump size public uint rsrcClumpSize; - /// 0x04C, Data fork clump size + /// 0x03C, Data fork clump size public uint dataClumpSize; - /// 0x050, Next unused CNID + /// 0x040, Next unused CNID public uint nextCatalogID; - /// 0x054, Times that the volume has been mounted writable + /// 0x044, Times that the volume has been mounted writable public uint writeCount; - /// 0x058, Used text encoding hints + /// 0x048, Used text encoding hints public ulong encodingsBitmap; - /// 0x060, finderInfo[0], CNID for bootable system's directory + /// 0x050, finderInfo[0], CNID for bootable system's directory public uint drFndrInfo0; - /// 0x064, finderInfo[1], CNID of the directory containing the boot application + /// 0x054, finderInfo[1], CNID of the directory containing the boot application public uint drFndrInfo1; - /// 0x068, finderInfo[2], CNID of the directory that should be opened on boot + /// 0x058, finderInfo[2], CNID of the directory that should be opened on boot public uint drFndrInfo2; - /// 0x06C, finderInfo[3], CNID for Mac OS 8 or 9 directory + /// 0x05C, finderInfo[3], CNID for Mac OS 8 or 9 directory public uint drFndrInfo3; - /// 0x070, finderInfo[4], Reserved + /// 0x060, finderInfo[4], Reserved public uint drFndrInfo4; - /// 0x074, finderInfo[5], CNID for Mac OS X directory + /// 0x064, finderInfo[5], CNID for Mac OS X directory public uint drFndrInfo5; - /// 0x078, finderInfo[6], first part of Mac OS X volume ID + /// 0x068, finderInfo[6], first part of Mac OS X volume ID public uint drFndrInfo6; - /// 0x07C, finderInfo[7], second part of Mac OS X volume ID + /// 0x06C, finderInfo[7], second part of Mac OS X volume ID public uint drFndrInfo7; // HFSPlusForkData allocationFile; - /// 0x080 + /// 0x070 public ulong allocationFile_logicalSize; - /// 0x088 + /// 0x078 public uint allocationFile_clumpSize; - /// 0x08C + /// 0x07C public uint allocationFile_totalBlocks; - /// 0x090 + /// 0x080 public uint allocationFile_extents_startBlock0; - /// 0x094 + /// 0x084 public uint allocationFile_extents_blockCount0; - /// 0x098 + /// 0x088 public uint allocationFile_extents_startBlock1; - /// 0x09C + /// 0x08C public uint allocationFile_extents_blockCount1; - /// 0x0A0 + /// 0x090 public uint allocationFile_extents_startBlock2; - /// 0x0A4 + /// 0x094 public uint allocationFile_extents_blockCount2; - /// 0x0A8 + /// 0x098 public uint allocationFile_extents_startBlock3; - /// 0x0AC + /// 0x09C public uint allocationFile_extents_blockCount3; - /// 0x0B0 + /// 0x0A0 public uint allocationFile_extents_startBlock4; - /// 0x0B4 + /// 0x0A4 public uint allocationFile_extents_blockCount4; - /// 0x0B8 + /// 0x0A8 public uint allocationFile_extents_startBlock5; - /// 0x0BC + /// 0x0AC public uint allocationFile_extents_blockCount5; - /// 0x0C0 + /// 0x0B0 public uint allocationFile_extents_startBlock6; - /// 0x0C4 + /// 0x0B4 public uint allocationFile_extents_blockCount6; - /// 0x0C8 + /// 0x0B8 public uint allocationFile_extents_startBlock7; - /// 0x0CC + /// 0x0BC public uint allocationFile_extents_blockCount7; // HFSPlusForkData extentsFile; - /// 0x0D0 + /// 0x0C0 public ulong extentsFile_logicalSize; - /// 0x0D8 + /// 0x0C8 public uint extentsFile_clumpSize; - /// 0x0DC + /// 0x0CC public uint extentsFile_totalBlocks; - /// 0x0E0 + /// 0x0D0 public uint extentsFile_extents_startBlock0; - /// 0x0E4 + /// 0x0D4 public uint extentsFile_extents_blockCount0; - /// 0x0E8 + /// 0x0D8 public uint extentsFile_extents_startBlock1; - /// 0x0EC + /// 0x0DC public uint extentsFile_extents_blockCount1; - /// 0x0F0 + /// 0x0E0 public uint extentsFile_extents_startBlock2; - /// 0x0F4 + /// 0x0E4 public uint extentsFile_extents_blockCount2; - /// 0x0F8 + /// 0x0E8 public uint extentsFile_extents_startBlock3; - /// 0x0FC + /// 0x0EC public uint extentsFile_extents_blockCount3; - /// 0x100 + /// 0x0F0 public uint extentsFile_extents_startBlock4; - /// 0x104 + /// 0x0F4 public uint extentsFile_extents_blockCount4; - /// 0x108 + /// 0x0F8 public uint extentsFile_extents_startBlock5; - /// 0x10C + /// 0x0FC public uint extentsFile_extents_blockCount5; - /// 0x110 + /// 0x100 public uint extentsFile_extents_startBlock6; - /// 0x114 + /// 0x104 public uint extentsFile_extents_blockCount6; - /// 0x118 + /// 0x108 public uint extentsFile_extents_startBlock7; - /// 0x11C + /// 0x10C public uint extentsFile_extents_blockCount7; // HFSPlusForkData catalogFile; - /// 0x120 + /// 0x110 public ulong catalogFile_logicalSize; - /// 0x128 + /// 0x118 public uint catalogFile_clumpSize; - /// 0x12C + /// 0x11C public uint catalogFile_totalBlocks; - /// 0x130 + /// 0x120 public uint catalogFile_extents_startBlock0; - /// 0x134 + /// 0x124 public uint catalogFile_extents_blockCount0; - /// 0x138 + /// 0x128 public uint catalogFile_extents_startBlock1; - /// 0x13C + /// 0x12C public uint catalogFile_extents_blockCount1; - /// 0x140 + /// 0x130 public uint catalogFile_extents_startBlock2; - /// 0x144 + /// 0x134 public uint catalogFile_extents_blockCount2; - /// 0x148 + /// 0x138 public uint catalogFile_extents_startBlock3; - /// 0x14C + /// 0x13C public uint catalogFile_extents_blockCount3; - /// 0x150 + /// 0x140 public uint catalogFile_extents_startBlock4; - /// 0x154 + /// 0x144 public uint catalogFile_extents_blockCount4; - /// 0x158 + /// 0x148 public uint catalogFile_extents_startBlock5; - /// 0x15C + /// 0x14C public uint catalogFile_extents_blockCount5; - /// 0x160 + /// 0x150 public uint catalogFile_extents_startBlock6; - /// 0x164 + /// 0x154 public uint catalogFile_extents_blockCount6; - /// 0x168 + /// 0x158 public uint catalogFile_extents_startBlock7; - /// 0x16C + /// 0x15C public uint catalogFile_extents_blockCount7; // HFSPlusForkData attributesFile; - /// 0x170 + /// 0x160 public ulong attributesFile_logicalSize; - /// 0x178 + /// 0x168 public uint attributesFile_clumpSize; - /// 0x17C + /// 0x16C public uint attributesFile_totalBlocks; - /// 0x180 + /// 0x170 public uint attributesFile_extents_startBlock0; - /// 0x184 + /// 0x174 public uint attributesFile_extents_blockCount0; - /// 0x188 + /// 0x178 public uint attributesFile_extents_startBlock1; - /// 0x18C + /// 0x17C public uint attributesFile_extents_blockCount1; - /// 0x190 + /// 0x180 public uint attributesFile_extents_startBlock2; - /// 0x194 + /// 0x184 public uint attributesFile_extents_blockCount2; - /// 0x198 + /// 0x188 public uint attributesFile_extents_startBlock3; - /// 0x19C + /// 0x18C public uint attributesFile_extents_blockCount3; - /// 0x1A0 + /// 0x190 public uint attributesFile_extents_startBlock4; - /// 0x1A4 + /// 0x194 public uint attributesFile_extents_blockCount4; - /// 0x1A8 + /// 0x198 public uint attributesFile_extents_startBlock5; - /// 0x1AC + /// 0x19C public uint attributesFile_extents_blockCount5; - /// 0x1B0 + /// 0x1A0 public uint attributesFile_extents_startBlock6; - /// 0x1B4 + /// 0x1A4 public uint attributesFile_extents_blockCount6; - /// 0x1B8 + /// 0x1A8 public uint attributesFile_extents_startBlock7; - /// 0x1BC + /// 0x1AC public uint attributesFile_extents_blockCount7; // HFSPlusForkData startupFile; - /// 0x1C0 + /// 0x1B0 public ulong startupFile_logicalSize; - /// 0x1C8 + /// 0x1B8 public uint startupFile_clumpSize; - /// 0x1CC + /// 0x1BC public uint startupFile_totalBlocks; - /// 0x1D0 + /// 0x1C0 public uint startupFile_extents_startBlock0; - /// 0x1D4 + /// 0x1C4 public uint startupFile_extents_blockCount0; - /// 0x1D8 + /// 0x1C8 public uint startupFile_extents_startBlock1; - /// 0x1E0 + /// 0x1D0 public uint startupFile_extents_blockCount1; - /// 0x1E4 + /// 0x1D4 public uint startupFile_extents_startBlock2; - /// 0x1E8 + /// 0x1D8 public uint startupFile_extents_blockCount2; - /// 0x1EC + /// 0x1DC public uint startupFile_extents_startBlock3; - /// 0x1F0 + /// 0x1E0 public uint startupFile_extents_blockCount3; - /// 0x1F4 + /// 0x1E4 public uint startupFile_extents_startBlock4; - /// 0x1F8 + /// 0x1E8 public uint startupFile_extents_blockCount4; - /// 0x1FC + /// 0x1EC public uint startupFile_extents_startBlock5; - /// 0x200 + /// 0x1F0 public uint startupFile_extents_blockCount5; - /// 0x204 + /// 0x1F4 public uint startupFile_extents_startBlock6; - /// 0x208 + /// 0x1F8 public uint startupFile_extents_blockCount6; - /// 0x20C + /// 0x1FC public uint startupFile_extents_startBlock7; - /// 0x210 + /// 0x200 public uint startupFile_extents_blockCount7; }