public void Open(Stream stream) { byte[] mtimeB = new byte[4]; byte[] isizeB = new byte[4]; _dataStream = stream; _basePath = null; _dataStream.Seek(4, SeekOrigin.Begin); _dataStream.Read(mtimeB, 0, 4); _dataStream.Seek(-4, SeekOrigin.End); _dataStream.Read(isizeB, 0, 4); _dataStream.Seek(0, SeekOrigin.Begin); uint mtime = BitConverter.ToUInt32(mtimeB, 0); uint isize = BitConverter.ToUInt32(isizeB, 0); _decompressedSize = isize; _creationTime = DateHandlers.UnixUnsignedToDateTime(mtime); _lastWriteTime = _creationTime; _zStream = new ForcedSeekStream <GZipStream>(_decompressedSize, _dataStream, CompressionMode.Decompress); _opened = true; }
public void Open(byte[] buffer) { byte[] mtime_b = new byte[4]; byte[] isize_b = new byte[4]; dataStream = new MemoryStream(buffer); basePath = null; dataStream.Seek(4, SeekOrigin.Begin); dataStream.Read(mtime_b, 0, 4); dataStream.Seek(-4, SeekOrigin.End); dataStream.Read(isize_b, 0, 4); dataStream.Seek(0, SeekOrigin.Begin); uint mtime = BitConverter.ToUInt32(mtime_b, 0); uint isize = BitConverter.ToUInt32(isize_b, 0); decompressedSize = isize; creationTime = DateHandlers.UnixUnsignedToDateTime(mtime); lastWriteTime = creationTime; zStream = new ForcedSeekStream <GZipStream>(decompressedSize, dataStream, CompressionMode.Decompress); opened = true; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1"); byte[] rootBlockSector = imagePlugin.ReadSector(partition.Start); RootBlock rootBlock = Marshal.ByteArrayToStructureBigEndian <RootBlock>(rootBlockSector); var sbInformation = new StringBuilder(); sbInformation.AppendLine("SmartFileSystem"); sbInformation.AppendFormat("Volume version {0}", rootBlock.version).AppendLine(); sbInformation.AppendFormat("Volume starts on device byte {0} and ends on byte {1}", rootBlock.firstbyte, rootBlock.lastbyte).AppendLine(); sbInformation. AppendFormat("Volume has {0} blocks of {1} bytes each", rootBlock.totalblocks, rootBlock.blocksize). AppendLine(); sbInformation.AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(rootBlock.datecreated).AddYears(8)). AppendLine(); sbInformation.AppendFormat("Bitmap starts in block {0}", rootBlock.bitmapbase).AppendLine(); sbInformation.AppendFormat("Admin space container starts in block {0}", rootBlock.adminspacecontainer). AppendLine(); sbInformation.AppendFormat("Root object container starts in block {0}", rootBlock.rootobjectcontainer). AppendLine(); sbInformation. AppendFormat("Root node of the extent B-tree resides in block {0}", rootBlock.extentbnoderoot). AppendLine(); sbInformation.AppendFormat("Root node of the object B-tree resides in block {0}", rootBlock.objectnoderoot). AppendLine(); if (rootBlock.bits.HasFlag(Flags.CaseSensitive)) { sbInformation.AppendLine("Volume is case sensitive"); } if (rootBlock.bits.HasFlag(Flags.RecycledFolder)) { sbInformation.AppendLine("Volume moves deleted files to a recycled folder"); } information = sbInformation.ToString(); XmlFsType = new FileSystemType { CreationDate = DateHandlers.UnixUnsignedToDateTime(rootBlock.datecreated).AddYears(8), CreationDateSpecified = true, Clusters = rootBlock.totalblocks, ClusterSize = rootBlock.blocksize, Type = "SmartFileSystem" }; }
public void Open(string path) { byte[] mtimeB = new byte[4]; byte[] isizeB = new byte[4]; _dataStream = new FileStream(path, FileMode.Open, FileAccess.Read); _basePath = Path.GetFullPath(path); _dataStream.Seek(4, SeekOrigin.Begin); _dataStream.Read(mtimeB, 0, 4); _dataStream.Seek(-4, SeekOrigin.End); _dataStream.Read(isizeB, 0, 4); _dataStream.Seek(0, SeekOrigin.Begin); uint mtime = BitConverter.ToUInt32(mtimeB, 0); uint isize = BitConverter.ToUInt32(isizeB, 0); _decompressedSize = isize; var fi = new FileInfo(path); _creationTime = fi.CreationTimeUtc; _lastWriteTime = DateHandlers.UnixUnsignedToDateTime(mtime); _zStream = new ForcedSeekStream <GZipStream>(_decompressedSize, _dataStream, CompressionMode.Decompress); _opened = true; }
public static string PrettifyHPModePage_3C(HP_ModePage_3C?modePage) { if (!modePage.HasValue) { return(null); } HP_ModePage_3C page = modePage.Value; var sb = new StringBuilder(); sb.AppendLine("HP Device Time Mode Page:"); if (page.PS) { sb.AppendLine("\tParameters can be saved"); } if (page.PT) { sb.AppendFormat("\tDrive has been powered up {0} times", page.CurrentPowerOn); sb.AppendFormat("\tDrive has been powered up since {0} this time", TimeSpan.FromSeconds(page.PowerOnTime)).AppendLine(); sb.AppendFormat("\tDrive has been powered up a total of {0}", TimeSpan.FromSeconds(page.CumulativePowerOn)).AppendLine(); } if (page.WT) { sb.AppendFormat("\tDrive's date/time is: {0}", DateHandlers.UnixUnsignedToDateTime(page.WorldTime)). AppendLine(); if (page.UTC) { sb.AppendLine("\tDrive's time is UTC"); } if (page.NTP) { sb.AppendLine("\tDrive's time is synchronized with a NTP source"); } } if (page.LT) { sb.AppendFormat("\tLibrary time is {0}", new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, page.LibraryHours, page.LibraryMinutes, page.LibrarySeconds)).AppendLine(); } return(sb.ToString()); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.UTF8; ulong vmfsSuperOff = VXFS_BASE / imagePlugin.Info.SectorSize; byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); SuperBlock vxSb = Marshal.ByteArrayToStructureLittleEndian <SuperBlock>(sector); var sbInformation = new StringBuilder(); sbInformation.AppendLine("Veritas file system"); sbInformation.AppendFormat("Volume version {0}", vxSb.vs_version).AppendLine(); sbInformation.AppendFormat("Volume name {0}", StringHandlers.CToString(vxSb.vs_fname, Encoding)). AppendLine(); sbInformation.AppendFormat("Volume has {0} blocks of {1} bytes each", vxSb.vs_bsize, vxSb.vs_size). AppendLine(); sbInformation.AppendFormat("Volume has {0} inodes per block", vxSb.vs_inopb).AppendLine(); sbInformation.AppendFormat("Volume has {0} free inodes", vxSb.vs_ifree).AppendLine(); sbInformation.AppendFormat("Volume has {0} free blocks", vxSb.vs_free).AppendLine(); sbInformation.AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(vxSb.vs_ctime, vxSb.vs_cutime)).AppendLine(); sbInformation.AppendFormat("Volume last modified on {0}", DateHandlers.UnixUnsignedToDateTime(vxSb.vs_wtime, vxSb.vs_wutime)).AppendLine(); if (vxSb.vs_clean != 0) { sbInformation.AppendLine("Volume is dirty"); } information = sbInformation.ToString(); XmlFsType = new FileSystemType { Type = "Veritas file system", CreationDate = DateHandlers.UnixUnsignedToDateTime(vxSb.vs_ctime, vxSb.vs_cutime), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(vxSb.vs_wtime, vxSb.vs_wutime), ModificationDateSpecified = true, Clusters = (ulong)vxSb.vs_size, ClusterSize = (uint)vxSb.vs_bsize, Dirty = vxSb.vs_clean != 0, FreeClusters = (ulong)vxSb.vs_free, FreeClustersSpecified = true }; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.UTF8; ulong vmfsSuperOff = VMFS_BASE / imagePlugin.Info.SectorSize; byte[] sector = imagePlugin.ReadSector(partition.Start + vmfsSuperOff); VolumeInfo volInfo = new VolumeInfo(); IntPtr volInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(volInfo)); Marshal.Copy(sector, 0, volInfoPtr, Marshal.SizeOf(volInfo)); volInfo = (VolumeInfo)Marshal.PtrToStructure(volInfoPtr, typeof(VolumeInfo)); Marshal.FreeHGlobal(volInfoPtr); StringBuilder sbInformation = new StringBuilder(); sbInformation.AppendLine("VMware file system"); uint ctimeSecs = (uint)(volInfo.ctime / 1000000); uint ctimeNanoSecs = (uint)(volInfo.ctime % 1000000); uint mtimeSecs = (uint)(volInfo.mtime / 1000000); uint mtimeNanoSecs = (uint)(volInfo.mtime % 1000000); sbInformation.AppendFormat("Volume version {0}", volInfo.version).AppendLine(); sbInformation.AppendFormat("Volume name {0}", StringHandlers.CToString(volInfo.name, Encoding)) .AppendLine(); sbInformation.AppendFormat("Volume size {0} bytes", volInfo.size * 256).AppendLine(); sbInformation.AppendFormat("Volume UUID {0}", volInfo.uuid).AppendLine(); sbInformation .AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(ctimeSecs, ctimeNanoSecs)) .AppendLine(); sbInformation.AppendFormat("Volume last modified on {0}", DateHandlers.UnixUnsignedToDateTime(mtimeSecs, mtimeNanoSecs)).AppendLine(); information = sbInformation.ToString(); XmlFsType = new FileSystemType { Type = "VMware file system", CreationDate = DateHandlers.UnixUnsignedToDateTime(ctimeSecs, ctimeNanoSecs), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(mtimeSecs, mtimeNanoSecs), ModificationDateSpecified = true, Clusters = volInfo.size * 256 / imagePlugin.Info.SectorSize, ClusterSize = (int)imagePlugin.Info.SectorSize, VolumeSerial = volInfo.uuid.ToString() }; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize; if (sbAddr == 0) { sbAddr = 1; } uint sbSize = (uint)(Marshal.SizeOf <Reiser_Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <Reiser_Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); if (sector.Length < Marshal.SizeOf <Reiser_Superblock>()) { return; } Reiser_Superblock reiserSb = Marshal.ByteArrayToStructureLittleEndian <Reiser_Superblock>(sector); if (!reiser35_magic.SequenceEqual(reiserSb.magic) && !reiser36_magic.SequenceEqual(reiserSb.magic) && !reiserJr_magic.SequenceEqual(reiserSb.magic)) { return; } var sb = new StringBuilder(); if (reiser35_magic.SequenceEqual(reiserSb.magic)) { sb.AppendLine("Reiser 3.5 filesystem"); } else if (reiser36_magic.SequenceEqual(reiserSb.magic)) { sb.AppendLine("Reiser 3.6 filesystem"); } else if (reiserJr_magic.SequenceEqual(reiserSb.magic)) { sb.AppendLine("Reiser Jr. filesystem"); } sb.AppendFormat("Volume has {0} blocks with {1} blocks free", reiserSb.block_count, reiserSb.free_blocks). AppendLine(); sb.AppendFormat("{0} bytes per block", reiserSb.blocksize).AppendLine(); sb.AppendFormat("Root directory resides on block {0}", reiserSb.root_block).AppendLine(); if (reiserSb.umount_state == 2) { sb.AppendLine("Volume has not been cleanly umounted"); } sb.AppendFormat("Volume last checked on {0}", DateHandlers.UnixUnsignedToDateTime(reiserSb.last_check)). AppendLine(); if (reiserSb.version >= 2) { sb.AppendFormat("Volume UUID: {0}", reiserSb.uuid).AppendLine(); sb.AppendFormat("Volume name: {0}", Encoding.GetString(reiserSb.label)).AppendLine(); } information = sb.ToString(); XmlFsType = new FileSystemType(); if (reiser35_magic.SequenceEqual(reiserSb.magic)) { XmlFsType.Type = "Reiser 3.5 filesystem"; } else if (reiser36_magic.SequenceEqual(reiserSb.magic)) { XmlFsType.Type = "Reiser 3.6 filesystem"; } else if (reiserJr_magic.SequenceEqual(reiserSb.magic)) { XmlFsType.Type = "Reiser Jr. filesystem"; } XmlFsType.ClusterSize = reiserSb.blocksize; XmlFsType.Clusters = reiserSb.block_count; XmlFsType.FreeClusters = reiserSb.free_blocks; XmlFsType.FreeClustersSpecified = true; XmlFsType.Dirty = reiserSb.umount_state == 2; if (reiserSb.version < 2) { return; } XmlFsType.VolumeName = Encoding.GetString(reiserSb.label); XmlFsType.VolumeSerial = reiserSb.uuid.ToString(); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; StringBuilder sb = new StringBuilder(); bool newExt2 = false; bool ext3 = false; bool ext4 = false; int sbSizeInBytes = Marshal.SizeOf(typeof(ext2FSSuperBlock)); uint sbSizeInSectors = (uint)(sbSizeInBytes / imagePlugin.Info.SectorSize); if (sbSizeInBytes % imagePlugin.Info.SectorSize > 0) { sbSizeInSectors++; } ulong sbSectorOff = SB_POS / imagePlugin.Info.SectorSize; uint sbOff = SB_POS % imagePlugin.Info.SectorSize; byte[] sbSector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSizeInSectors); byte[] sblock = new byte[sbSizeInBytes]; Array.Copy(sbSector, sbOff, sblock, 0, sbSizeInBytes); IntPtr sbPtr = Marshal.AllocHGlobal(sbSizeInBytes); Marshal.Copy(sblock, 0, sbPtr, sbSizeInBytes); ext2FSSuperBlock supblk = (ext2FSSuperBlock)Marshal.PtrToStructure(sbPtr, typeof(ext2FSSuperBlock)); Marshal.FreeHGlobal(sbPtr); XmlFsType = new FileSystemType(); switch (supblk.magic) { case EXT2_MAGIC_OLD: sb.AppendLine("ext2 (old) filesystem"); XmlFsType.Type = "ext2"; break; case EXT2_MAGIC: 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 || (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 || (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT || (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP) == EXT4_FEATURE_INCOMPAT_MMP || (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) == EXT4_FEATURE_INCOMPAT_FLEX_BG || (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE) == EXT4_FEATURE_INCOMPAT_EA_INODE || (supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA) == EXT4_FEATURE_INCOMPAT_DIRDATA) { ext3 = false; ext4 = true; } newExt2 |= !ext3 && !ext4; if (newExt2) { sb.AppendLine("ext2 filesystem"); XmlFsType.Type = "ext2"; } if (ext3) { sb.AppendLine("ext3 filesystem"); XmlFsType.Type = "ext3"; } if (ext4) { sb.AppendLine("ext4 filesystem"); XmlFsType.Type = "ext4"; } break; default: information = "Not a ext2/3/4 filesystem" + Environment.NewLine; return; } string extOs; switch (supblk.creator_os) { case EXT2_OS_FREEBSD: extOs = "FreeBSD"; break; case EXT2_OS_HURD: extOs = "Hurd"; break; case EXT2_OS_LINUX: extOs = "Linux"; break; case EXT2_OS_LITES: extOs = "Lites"; break; case EXT2_OS_MASIX: extOs = "MasIX"; break; default: extOs = $"Unknown OS ({supblk.creator_os})"; break; } XmlFsType.SystemIdentifier = extOs; if (supblk.mkfs_t > 0) { sb.AppendFormat("Volume was created on {0} for {1}", DateHandlers.UnixUnsignedToDateTime(supblk.mkfs_t), extOs).AppendLine(); XmlFsType.CreationDate = DateHandlers.UnixUnsignedToDateTime(supblk.mkfs_t); XmlFsType.CreationDateSpecified = true; } else { sb.AppendFormat("Volume was created for {0}", extOs).AppendLine(); } byte[] tempBytes = new byte[8]; ulong blocks, reserved, free; if ((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT) { byte[] tempLo = BitConverter.GetBytes(supblk.blocks); byte[] tempHi = BitConverter.GetBytes(supblk.blocks_hi); tempBytes[0] = tempLo[0]; tempBytes[1] = tempLo[1]; tempBytes[2] = tempLo[2]; tempBytes[3] = tempLo[3]; tempBytes[4] = tempHi[0]; tempBytes[5] = tempHi[1]; tempBytes[6] = tempHi[2]; tempBytes[7] = tempHi[3]; blocks = BitConverter.ToUInt64(tempBytes, 0); tempLo = BitConverter.GetBytes(supblk.reserved_blocks); tempHi = BitConverter.GetBytes(supblk.reserved_blocks_hi); tempBytes[0] = tempLo[0]; tempBytes[1] = tempLo[1]; tempBytes[2] = tempLo[2]; tempBytes[3] = tempLo[3]; tempBytes[4] = tempHi[0]; tempBytes[5] = tempHi[1]; tempBytes[6] = tempHi[2]; tempBytes[7] = tempHi[3]; reserved = BitConverter.ToUInt64(tempBytes, 0); tempLo = BitConverter.GetBytes(supblk.free_blocks); tempHi = BitConverter.GetBytes(supblk.free_blocks_hi); tempBytes[0] = tempLo[0]; tempBytes[1] = tempLo[1]; tempBytes[2] = tempLo[2]; tempBytes[3] = tempLo[3]; tempBytes[4] = tempHi[0]; tempBytes[5] = tempHi[1]; tempBytes[6] = tempHi[2]; tempBytes[7] = tempHi[3]; free = BitConverter.ToUInt64(tempBytes, 0); } else { blocks = supblk.blocks; reserved = supblk.reserved_blocks; free = supblk.free_blocks; } 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(); 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) { sb.AppendFormat("Last mounted on {0}", DateHandlers.UnixUnsignedToDateTime(supblk.mount_t)) .AppendLine(); } 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 (!string.IsNullOrEmpty(StringHandlers.CToString(supblk.last_mount_dir, Encoding))) { sb.AppendFormat("Last mounted on: \"{0}\"", StringHandlers.CToString(supblk.last_mount_dir, Encoding)).AppendLine(); } if (!string.IsNullOrEmpty(StringHandlers.CToString(supblk.mount_options, Encoding))) { sb.AppendFormat("Last used mount options were: {0}", StringHandlers.CToString(supblk.mount_options, Encoding)).AppendLine(); } } else { sb.AppendLine("Volume has never been mounted"); 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_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) { 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) { sb.AppendFormat("Last written on {0}", DateHandlers.UnixUnsignedToDateTime(supblk.write_t)) .AppendLine(); XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(supblk.write_t); XmlFsType.ModificationDateSpecified = true; } else { sb.AppendLine("Volume has never been written"); } XmlFsType.Dirty = true; switch (supblk.state) { case EXT2_VALID_FS: sb.AppendLine("Volume is clean"); XmlFsType.Dirty = false; break; case EXT2_ERROR_FS: sb.AppendLine("Volume is dirty"); break; case EXT3_ORPHAN_FS: sb.AppendLine("Volume is recovering orphan files"); break; default: sb.AppendFormat("Volume is in an unknown state ({0})", supblk.state).AppendLine(); break; } if (!string.IsNullOrEmpty(StringHandlers.CToString(supblk.volume_name, Encoding))) { sb.AppendFormat("Volume name: \"{0}\"", StringHandlers.CToString(supblk.volume_name, Encoding)) .AppendLine(); XmlFsType.VolumeName = StringHandlers.CToString(supblk.volume_name, Encoding); } switch (supblk.err_behaviour) { case EXT2_ERRORS_CONTINUE: sb.AppendLine("On errors, filesystem should continue"); break; case EXT2_ERRORS_RO: sb.AppendLine("On errors, filesystem should remount read-only"); break; case EXT2_ERRORS_PANIC: sb.AppendLine("On errors, filesystem should panic"); break; default: sb.AppendFormat("On errors filesystem will do an unknown thing ({0})", supblk.err_behaviour) .AppendLine(); break; } if (supblk.revision > 0) { sb.AppendFormat("Filesystem revision: {0}.{1}", supblk.revision, supblk.minor_revision).AppendLine(); } if (supblk.uuid != Guid.Empty) { sb.AppendFormat("Volume UUID: {0}", supblk.uuid).AppendLine(); XmlFsType.VolumeSerial = supblk.uuid.ToString(); } 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) { sb.AppendFormat("First inode is {0}", supblk.first_inode).AppendLine(); } 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) { 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) { 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) { sb.AppendFormat("Block group number is {0}", supblk.block_group_no).AppendLine(); } 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) { sb.AppendFormat("First metablock group is {0}", supblk.first_meta_bg).AppendLine(); } if (supblk.raid_stride > 0) { sb.AppendFormat("RAID stride: {0}", supblk.raid_stride).AppendLine(); } 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) { 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) { 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) { 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 || (supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { sb.AppendLine("Volume is journaled"); 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) { sb.AppendFormat("Journal is on device {0}", supblk.journal_dev).AppendLine(); } if (supblk.jnl_backup_type > 0) { sb.AppendFormat("Journal backup type: {0}", supblk.jnl_backup_type).AppendLine(); } 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 (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) { 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(); sb.AppendFormat("First error inode is {0}, last is {1}", supblk.first_error_inode, supblk.last_error_inode).AppendLine(); sb.AppendFormat("First error block is {0}, last is {1}", supblk.first_error_block, supblk.last_error_block).AppendLine(); sb.AppendFormat("First error function is \"{0}\", last is \"{1}\"", supblk.first_error_func, supblk.last_error_func).AppendLine(); } } sb.AppendFormat("Flags…:").AppendLine(); 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) { sb.AppendLine("Unsigned directory hash is in use"); } if ((supblk.flags & EXT2_FLAGS_TEST_FILESYS) == EXT2_FLAGS_TEST_FILESYS) { sb.AppendLine("Volume is testing development code"); } 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) { sb.AppendLine("(debug): Enable debugging code"); } 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) { sb.AppendLine("(user_xattr): Enable user-specified extended attributes"); } 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) { sb.AppendLine("(uid16): Disable 32bit UIDs and GIDs"); } 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) { sb.AppendLine("(journal_data_ordered): Write data before journaling metadata"); } 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) { 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) { sb.AppendLine("Pre-allocate directories"); } 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) { sb.AppendLine("Has journal (ext3)"); } 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) { sb.AppendLine("Has online filesystem resize reservations"); } 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) { 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) { sb.AppendLine("Reduced number of superblocks"); } 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) { sb.AppendLine("Uses B-Tree for directories"); } 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) { 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) { 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) { sb.AppendLine("Supports nanosecond timestamps and creation time (ext4)"); } 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) { sb.AppendLine("Uses compression"); } 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) { sb.AppendLine("Journal needs recovery (ext3)"); } 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) { sb.AppendLine("Reduced block group backups"); } 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) { sb.AppendLine("Supports volumes bigger than 2^32 blocks (ext4)"); } 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) { sb.AppendLine("Flexible block group metadata location (ext4)"); } 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) { sb.AppendLine("Data can reside in directory entry (ext4)"); } if ((supblk.ftr_incompat & 0xFFFFF020) != 0) { sb.AppendFormat("Unknown incompatible features: {0:X8}", supblk.ftr_incompat); } information = sb.ToString(); }
public void Open(string path) { FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read); fs.Seek(0, SeekOrigin.Begin); byte[] hdr_b = new byte[26]; fs.Read(hdr_b, 0, 26); header = Marshal.ByteArrayToStructureBigEndian <AppleSingleHeader>(hdr_b); AppleSingleEntry[] entries = new AppleSingleEntry[header.entries]; for (int i = 0; i < header.entries; i++) { byte[] entry = new byte[12]; fs.Read(entry, 0, 12); entries[i] = Marshal.ByteArrayToStructureBigEndian <AppleSingleEntry>(entry); } creationTime = DateTime.UtcNow; lastWriteTime = creationTime; foreach (AppleSingleEntry entry in entries) { switch ((AppleSingleEntryID)entry.id) { case AppleSingleEntryID.DataFork: dataFork = entry; break; case AppleSingleEntryID.FileDates: fs.Seek(entry.offset, SeekOrigin.Begin); byte[] dates_b = new byte[16]; fs.Read(dates_b, 0, 16); AppleSingleFileDates dates = Marshal.ByteArrayToStructureBigEndian <AppleSingleFileDates>(dates_b); creationTime = DateHandlers.MacToDateTime(dates.creationDate); lastWriteTime = DateHandlers.MacToDateTime(dates.modificationDate); break; case AppleSingleEntryID.FileInfo: fs.Seek(entry.offset, SeekOrigin.Begin); byte[] finfo = new byte[entry.length]; fs.Read(finfo, 0, finfo.Length); if (MacintoshHome.SequenceEqual(header.homeFilesystem)) { AppleSingleMacFileInfo macinfo = Marshal.ByteArrayToStructureBigEndian <AppleSingleMacFileInfo>(finfo); creationTime = DateHandlers.MacToDateTime(macinfo.creationDate); lastWriteTime = DateHandlers.MacToDateTime(macinfo.modificationDate); } else if (ProDOSHome.SequenceEqual(header.homeFilesystem)) { AppleSingleProDOSFileInfo prodosinfo = Marshal.ByteArrayToStructureBigEndian <AppleSingleProDOSFileInfo>(finfo); creationTime = DateHandlers.MacToDateTime(prodosinfo.creationDate); lastWriteTime = DateHandlers.MacToDateTime(prodosinfo.modificationDate); } else if (UNIXHome.SequenceEqual(header.homeFilesystem)) { AppleSingleUNIXFileInfo unixinfo = Marshal.ByteArrayToStructureBigEndian <AppleSingleUNIXFileInfo>(finfo); creationTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.creationDate); lastWriteTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.modificationDate); } else if (DOSHome.SequenceEqual(header.homeFilesystem)) { AppleSingleDOSFileInfo dosinfo = Marshal.ByteArrayToStructureBigEndian <AppleSingleDOSFileInfo>(finfo); lastWriteTime = DateHandlers.DosToDateTime(dosinfo.modificationDate, dosinfo.modificationTime); } break; case AppleSingleEntryID.ResourceFork: rsrcFork = entry; break; } } fs.Close(); opened = true; isPath = true; basePath = path; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; var sb = new StringBuilder(); uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize; byte[] sector = imagePlugin.ReadSector(partition.Start + bootSectors); if (sector.Length < 512) { return; } JfsSuperBlock jfsSb = Marshal.ByteArrayToStructureLittleEndian <JfsSuperBlock>(sector); sb.AppendLine("JFS filesystem"); sb.AppendFormat("Version {0}", jfsSb.s_version).AppendLine(); sb.AppendFormat("{0} blocks of {1} bytes", jfsSb.s_size, jfsSb.s_bsize).AppendLine(); sb.AppendFormat("{0} blocks per allocation group", jfsSb.s_agsize).AppendLine(); if (jfsSb.s_flags.HasFlag(JfsFlags.Unicode)) { sb.AppendLine("Volume uses Unicode for directory entries"); } if (jfsSb.s_flags.HasFlag(JfsFlags.RemountRO)) { sb.AppendLine("Volume remounts read-only on error"); } if (jfsSb.s_flags.HasFlag(JfsFlags.Continue)) { sb.AppendLine("Volume continues on error"); } if (jfsSb.s_flags.HasFlag(JfsFlags.Panic)) { sb.AppendLine("Volume panics on error"); } if (jfsSb.s_flags.HasFlag(JfsFlags.UserQuota)) { sb.AppendLine("Volume has user quotas enabled"); } if (jfsSb.s_flags.HasFlag(JfsFlags.GroupQuota)) { sb.AppendLine("Volume has group quotas enabled"); } if (jfsSb.s_flags.HasFlag(JfsFlags.NoJournal)) { sb.AppendLine("Volume is not using any journal"); } if (jfsSb.s_flags.HasFlag(JfsFlags.Discard)) { sb.AppendLine("Volume sends TRIM/UNMAP commands to underlying device"); } if (jfsSb.s_flags.HasFlag(JfsFlags.GroupCommit)) { sb.AppendLine("Volume commits in groups of 1"); } if (jfsSb.s_flags.HasFlag(JfsFlags.LazyCommit)) { sb.AppendLine("Volume commits lazy"); } if (jfsSb.s_flags.HasFlag(JfsFlags.Temporary)) { sb.AppendLine("Volume does not commit to log"); } if (jfsSb.s_flags.HasFlag(JfsFlags.InlineLog)) { sb.AppendLine("Volume has log withing itself"); } if (jfsSb.s_flags.HasFlag(JfsFlags.InlineMoving)) { sb.AppendLine("Volume has log withing itself and is moving it out"); } if (jfsSb.s_flags.HasFlag(JfsFlags.BadSAIT)) { sb.AppendLine("Volume has bad current secondary ait"); } if (jfsSb.s_flags.HasFlag(JfsFlags.Sparse)) { sb.AppendLine("Volume supports sparse files"); } if (jfsSb.s_flags.HasFlag(JfsFlags.DASDEnabled)) { sb.AppendLine("Volume has DASD limits enabled"); } if (jfsSb.s_flags.HasFlag(JfsFlags.DASDPrime)) { sb.AppendLine("Volume primes DASD on boot"); } if (jfsSb.s_flags.HasFlag(JfsFlags.SwapBytes)) { sb.AppendLine("Volume is in a big-endian system"); } if (jfsSb.s_flags.HasFlag(JfsFlags.DirIndex)) { sb.AppendLine("Volume has presistent indexes"); } if (jfsSb.s_flags.HasFlag(JfsFlags.Linux)) { sb.AppendLine("Volume supports Linux"); } if (jfsSb.s_flags.HasFlag(JfsFlags.DFS)) { sb.AppendLine("Volume supports DCE DFS LFS"); } if (jfsSb.s_flags.HasFlag(JfsFlags.OS2)) { sb.AppendLine("Volume supports OS/2, and is case insensitive"); } if (jfsSb.s_flags.HasFlag(JfsFlags.AIX)) { sb.AppendLine("Volume supports AIX"); } if (jfsSb.s_state != 0) { sb.AppendLine("Volume is dirty"); } sb.AppendFormat("Volume was last updated on {0}", DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec)). AppendLine(); if (jfsSb.s_version == 1) { sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(jfsSb.s_fpack, Encoding)).AppendLine(); } else { sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(jfsSb.s_label, Encoding)).AppendLine(); } sb.AppendFormat("Volume UUID: {0}", jfsSb.s_uuid).AppendLine(); XmlFsType = new FileSystemType { Type = "JFS filesystem", Clusters = jfsSb.s_size, ClusterSize = jfsSb.s_bsize, Bootable = true, VolumeName = StringHandlers.CToString(jfsSb.s_version == 1 ? jfsSb.s_fpack : jfsSb.s_label, Encoding), VolumeSerial = $"{jfsSb.s_uuid}", ModificationDate = DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec), ModificationDateSpecified = true }; if (jfsSb.s_state != 0) { XmlFsType.Dirty = true; } information = sb.ToString(); }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if (stream.Length < 512) { return(false); } byte[] qHdrB = new byte[48]; stream.Read(qHdrB, 0, 48); qHdr = Marshal.SpanToStructureBigEndian <QCowHeader>(qHdrB); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.magic = 0x{0:X8}", qHdr.magic); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.version = {0}", qHdr.version); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.backing_file_offset = {0}", qHdr.backing_file_offset); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.backing_file_size = {0}", qHdr.backing_file_size); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.mtime = {0}", qHdr.mtime); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.size = {0}", qHdr.size); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.cluster_bits = {0}", qHdr.cluster_bits); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.l2_bits = {0}", qHdr.l2_bits); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.padding = {0}", qHdr.padding); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.crypt_method = {0}", qHdr.crypt_method); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.l1_table_offset = {0}", qHdr.l1_table_offset); if (qHdr.size <= 1) { throw new ArgumentOutOfRangeException(nameof(qHdr.size), "Image size is too small"); } if (qHdr.cluster_bits < 9 || qHdr.cluster_bits > 16) { throw new ArgumentOutOfRangeException(nameof(qHdr.cluster_bits), "Cluster size must be between 512 bytes and 64 Kbytes"); } if (qHdr.l2_bits < 9 - 3 || qHdr.l2_bits > 16 - 3) { throw new ArgumentOutOfRangeException(nameof(qHdr.l2_bits), "L2 size must be between 512 bytes and 64 Kbytes"); } if (qHdr.crypt_method > QCOW_ENCRYPTION_AES) { throw new ArgumentOutOfRangeException(nameof(qHdr.crypt_method), "Invalid encryption method"); } if (qHdr.crypt_method > QCOW_ENCRYPTION_NONE) { throw new NotImplementedException("AES encrypted images not yet supported"); } if (qHdr.backing_file_offset != 0) { throw new NotImplementedException("Differencing images not yet supported"); } int shift = qHdr.cluster_bits + qHdr.l2_bits; if (qHdr.size > ulong.MaxValue - (ulong)(1 << shift)) { throw new ArgumentOutOfRangeException(nameof(qHdr.size), "Image is too large"); } clusterSize = 1 << qHdr.cluster_bits; clusterSectors = 1 << (qHdr.cluster_bits - 9); l1Size = (uint)(((qHdr.size + (ulong)(1 << shift)) - 1) >> shift); l2Size = 1 << qHdr.l2_bits; AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.clusterSize = {0}", clusterSize); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.clusterSectors = {0}", clusterSectors); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.l1Size = {0}", l1Size); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.l2Size = {0}", l2Size); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.sectors = {0}", imageInfo.Sectors); byte[] l1TableB = new byte[l1Size * 8]; stream.Seek((long)qHdr.l1_table_offset, SeekOrigin.Begin); stream.Read(l1TableB, 0, (int)l1Size * 8); l1Table = MemoryMarshal.Cast <byte, ulong>(l1TableB).ToArray(); AaruConsole.DebugWriteLine("QCOW plugin", "Reading L1 table"); for (long i = 0; i < l1Table.LongLength; i++) { l1Table[i] = Swapping.Swap(l1Table[i]); } l1Mask = 0; int c = 0; l1Shift = qHdr.l2_bits + qHdr.cluster_bits; for (int i = 0; i < 64; i++) { l1Mask <<= 1; if (c >= 64 - l1Shift) { continue; } l1Mask += 1; c++; } l2Mask = 0; for (int i = 0; i < qHdr.l2_bits; i++) { l2Mask = (l2Mask << 1) + 1; } l2Mask <<= qHdr.cluster_bits; sectorMask = 0; for (int i = 0; i < qHdr.cluster_bits; i++) { sectorMask = (sectorMask << 1) + 1; } AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.l1Mask = {0:X}", l1Mask); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.l1Shift = {0}", l1Shift); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.l2Mask = {0:X}", l2Mask); AaruConsole.DebugWriteLine("QCOW plugin", "qHdr.sectorMask = {0:X}", sectorMask); maxL2TableCache = MAX_CACHE_SIZE / (l2Size * 8); maxClusterCache = MAX_CACHE_SIZE / clusterSize; imageStream = stream; sectorCache = new Dictionary <ulong, byte[]>(); l2TableCache = new Dictionary <ulong, ulong[]>(); clusterCache = new Dictionary <ulong, byte[]>(); imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = qHdr.mtime > 0 ? DateHandlers.UnixUnsignedToDateTime(qHdr.mtime) : imageFilter.GetLastWriteTime(); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.Sectors = qHdr.size / 512; imageInfo.SectorSize = 512; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.MediaType = MediaType.GENERIC_HDD; imageInfo.ImageSize = qHdr.size; imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); imageInfo.Heads = 16; imageInfo.SectorsPerTrack = 63; return(true); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.UTF8; byte[] sector = imagePlugin.ReadSector(partition.Start); uint magic = BitConverter.ToUInt32(sector, 0x00); var sqSb = new SquashSuperBlock(); bool littleEndian = true; switch (magic) { case SQUASH_MAGIC: sqSb = Marshal.ByteArrayToStructureLittleEndian <SquashSuperBlock>(sector); break; case SQUASH_CIGAM: sqSb = Marshal.ByteArrayToStructureBigEndian <SquashSuperBlock>(sector); littleEndian = false; break; } var sbInformation = new StringBuilder(); sbInformation.AppendLine("Squash file system"); sbInformation.AppendLine(littleEndian ? "Little-endian" : "Big-endian"); sbInformation.AppendFormat("Volume version {0}.{1}", sqSb.s_major, sqSb.s_minor).AppendLine(); sbInformation.AppendFormat("Volume has {0} bytes", sqSb.bytes_used).AppendLine(); sbInformation.AppendFormat("Volume has {0} bytes per block", sqSb.block_size).AppendLine(); sbInformation.AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time)). AppendLine(); sbInformation.AppendFormat("Volume has {0} inodes", sqSb.inodes).AppendLine(); switch (sqSb.compression) { case (ushort)SquashCompression.Lz4: sbInformation.AppendLine("Volume is compressed using LZ4"); break; case (ushort)SquashCompression.Lzo: sbInformation.AppendLine("Volume is compressed using LZO"); break; case (ushort)SquashCompression.Lzma: sbInformation.AppendLine("Volume is compressed using LZMA"); break; case (ushort)SquashCompression.Xz: sbInformation.AppendLine("Volume is compressed using XZ"); break; case (ushort)SquashCompression.Zlib: sbInformation.AppendLine("Volume is compressed using GZIP"); break; case (ushort)SquashCompression.Zstd: sbInformation.AppendLine("Volume is compressed using Zstandard"); break; default: sbInformation.AppendFormat("Volume is compressed using unknown algorithm {0}", sqSb.compression). AppendLine(); break; } information = sbInformation.ToString(); XmlFsType = new FileSystemType { Type = "Squash file system", CreationDate = DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time), CreationDateSpecified = true, Clusters = (((partition.End - partition.Start) + 1) * imagePlugin.Info.SectorSize) / sqSb.block_size, ClusterSize = sqSb.block_size, Files = sqSb.inodes, FilesSpecified = true, FreeClusters = 0, FreeClustersSpecified = true }; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.UTF8; information = ""; if (imagePlugin.Info.SectorSize < 512) { return; } uint sbAddr = NILFS2_SUPER_OFFSET / imagePlugin.Info.SectorSize; if (sbAddr == 0) { sbAddr = 1; } uint sbSize = (uint)(Marshal.SizeOf <NILFS2_Superblock>() / imagePlugin.Info.SectorSize); if (Marshal.SizeOf <NILFS2_Superblock>() % imagePlugin.Info.SectorSize != 0) { sbSize++; } byte[] sector = imagePlugin.ReadSectors(partition.Start + sbAddr, sbSize); if (sector.Length < Marshal.SizeOf <NILFS2_Superblock>()) { return; } NILFS2_Superblock nilfsSb = Marshal.ByteArrayToStructureLittleEndian <NILFS2_Superblock>(sector); if (nilfsSb.magic != NILFS2_MAGIC) { return; } StringBuilder sb = new StringBuilder(); sb.AppendLine("NILFS2 filesystem"); sb.AppendFormat("Version {0}.{1}", nilfsSb.rev_level, nilfsSb.minor_rev_level).AppendLine(); sb.AppendFormat("{0} bytes per block", 1 << (int)(nilfsSb.log_block_size + 10)).AppendLine(); sb.AppendFormat("{0} bytes in volume", nilfsSb.dev_size).AppendLine(); sb.AppendFormat("{0} blocks per segment", nilfsSb.blocks_per_segment).AppendLine(); sb.AppendFormat("{0} segments", nilfsSb.nsegments).AppendLine(); if (nilfsSb.creator_os == 0) { sb.AppendLine("Filesystem created on Linux"); } else { sb.AppendFormat("Creator OS code: {0}", nilfsSb.creator_os).AppendLine(); } sb.AppendFormat("{0} bytes per inode", nilfsSb.inode_size).AppendLine(); sb.AppendFormat("Volume UUID: {0}", nilfsSb.uuid).AppendLine(); sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(nilfsSb.volume_name, Encoding)).AppendLine(); sb.AppendFormat("Volume created on {0}", DateHandlers.UnixUnsignedToDateTime(nilfsSb.ctime)).AppendLine(); sb.AppendFormat("Volume last mounted on {0}", DateHandlers.UnixUnsignedToDateTime(nilfsSb.mtime)) .AppendLine(); sb.AppendFormat("Volume last written on {0}", DateHandlers.UnixUnsignedToDateTime(nilfsSb.wtime)) .AppendLine(); information = sb.ToString(); XmlFsType = new FileSystemType { Type = "NILFS2 filesystem", ClusterSize = (uint)(1 << (int)(nilfsSb.log_block_size + 10)), VolumeName = StringHandlers.CToString(nilfsSb.volume_name, Encoding), VolumeSerial = nilfsSb.uuid.ToString(), CreationDate = DateHandlers.UnixUnsignedToDateTime(nilfsSb.ctime), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(nilfsSb.wtime), ModificationDateSpecified = true }; if (nilfsSb.creator_os == 0) { XmlFsType.SystemIdentifier = "Linux"; } XmlFsType.Clusters = nilfsSb.dev_size / XmlFsType.ClusterSize; }
public void Open(string path) { string filename = Path.GetFileName(path); string filenameNoExt = Path.GetFileNameWithoutExtension(path); string parentFolder = Path.GetDirectoryName(path); // Prepend data fork name with "R." string ProDosAppleDouble = Path.Combine(parentFolder ?? throw new InvalidOperationException(), "R." + filename); // Prepend data fork name with '%' string UNIXAppleDouble = Path.Combine(parentFolder, "%" + filename); // Change file extension to ADF string DOSAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF"); // Change file extension to adf string DOSAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf"); // Store AppleDouble header file in ".AppleDouble" folder with same name string NetatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", filename ?? throw new InvalidOperationException()); // Store AppleDouble header file in "resource.frk" folder with same name string DAVEAppleDouble = Path.Combine(parentFolder, "resource.frk", filename); // Prepend data fork name with "._" string OSXAppleDouble = Path.Combine(parentFolder, "._" + filename); // Adds ".rsrc" extension string UnArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc"); // Check AppleDouble created by A/UX in ProDOS filesystem if (File.Exists(ProDosAppleDouble)) { FileStream prodosStream = new FileStream(ProDosAppleDouble, FileMode.Open, FileAccess.Read); if (prodosStream.Length > 26) { byte[] prodos_b = new byte[26]; prodosStream.Read(prodos_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(prodos_b); prodosStream.Close(); if (header.magic == AppleDoubleMagic && (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2)) { headerPath = ProDosAppleDouble; } } } // Check AppleDouble created by A/UX in UFS filesystem if (File.Exists(UNIXAppleDouble)) { FileStream unixStream = new FileStream(UNIXAppleDouble, FileMode.Open, FileAccess.Read); if (unixStream.Length > 26) { byte[] unix_b = new byte[26]; unixStream.Read(unix_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(unix_b); unixStream.Close(); if (header.magic == AppleDoubleMagic && (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2)) { headerPath = UNIXAppleDouble; } } } // Check AppleDouble created by A/UX in FAT filesystem if (File.Exists(DOSAppleDouble)) { FileStream dosStream = new FileStream(DOSAppleDouble, FileMode.Open, FileAccess.Read); if (dosStream.Length > 26) { byte[] dos_b = new byte[26]; dosStream.Read(dos_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dos_b); dosStream.Close(); if (header.magic == AppleDoubleMagic && (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2)) { headerPath = DOSAppleDouble; } } } // Check AppleDouble created by A/UX in case preserving FAT filesystem if (File.Exists(DOSAppleDoubleLower)) { FileStream doslStream = new FileStream(DOSAppleDoubleLower, FileMode.Open, FileAccess.Read); if (doslStream.Length > 26) { byte[] dosl_b = new byte[26]; doslStream.Read(dosl_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dosl_b); doslStream.Close(); if (header.magic == AppleDoubleMagic && (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2)) { headerPath = DOSAppleDoubleLower; } } } // Check AppleDouble created by Netatalk if (File.Exists(NetatalkAppleDouble)) { FileStream netatalkStream = new FileStream(NetatalkAppleDouble, FileMode.Open, FileAccess.Read); if (netatalkStream.Length > 26) { byte[] netatalk_b = new byte[26]; netatalkStream.Read(netatalk_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(netatalk_b); netatalkStream.Close(); if (header.magic == AppleDoubleMagic && (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2)) { headerPath = NetatalkAppleDouble; } } } // Check AppleDouble created by DAVE if (File.Exists(DAVEAppleDouble)) { FileStream daveStream = new FileStream(DAVEAppleDouble, FileMode.Open, FileAccess.Read); if (daveStream.Length > 26) { byte[] dave_b = new byte[26]; daveStream.Read(dave_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dave_b); daveStream.Close(); if (header.magic == AppleDoubleMagic && (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2)) { headerPath = DAVEAppleDouble; } } } // Check AppleDouble created by Mac OS X if (File.Exists(OSXAppleDouble)) { FileStream osxStream = new FileStream(OSXAppleDouble, FileMode.Open, FileAccess.Read); if (osxStream.Length > 26) { byte[] osx_b = new byte[26]; osxStream.Read(osx_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(osx_b); osxStream.Close(); if (header.magic == AppleDoubleMagic && (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2)) { headerPath = OSXAppleDouble; } } } // Check AppleDouble created by UnAr (from The Unarchiver) if (File.Exists(UnArAppleDouble)) { FileStream unarStream = new FileStream(UnArAppleDouble, FileMode.Open, FileAccess.Read); if (unarStream.Length > 26) { byte[] unar_b = new byte[26]; unarStream.Read(unar_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(unar_b); unarStream.Close(); if (header.magic == AppleDoubleMagic && (header.version == AppleDoubleVersion || header.version == AppleDoubleVersion2)) { headerPath = UnArAppleDouble; } } } FileStream fs = new FileStream(headerPath, FileMode.Open, FileAccess.Read); fs.Seek(0, SeekOrigin.Begin); byte[] hdr_b = new byte[26]; fs.Read(hdr_b, 0, 26); header = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(hdr_b); AppleDoubleEntry[] entries = new AppleDoubleEntry[header.entries]; for (int i = 0; i < header.entries; i++) { byte[] entry = new byte[12]; fs.Read(entry, 0, 12); entries[i] = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleEntry>(entry); } creationTime = DateTime.UtcNow; lastWriteTime = creationTime; foreach (AppleDoubleEntry entry in entries) { switch ((AppleDoubleEntryID)entry.id) { case AppleDoubleEntryID.DataFork: // AppleDouble have datafork in separated file break; case AppleDoubleEntryID.FileDates: fs.Seek(entry.offset, SeekOrigin.Begin); byte[] dates_b = new byte[16]; fs.Read(dates_b, 0, 16); AppleDoubleFileDates dates = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleFileDates>(dates_b); creationTime = DateHandlers.UnixUnsignedToDateTime(dates.creationDate); lastWriteTime = DateHandlers.UnixUnsignedToDateTime(dates.modificationDate); break; case AppleDoubleEntryID.FileInfo: fs.Seek(entry.offset, SeekOrigin.Begin); byte[] finfo = new byte[entry.length]; fs.Read(finfo, 0, finfo.Length); if (MacintoshHome.SequenceEqual(header.homeFilesystem)) { AppleDoubleMacFileInfo macinfo = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleMacFileInfo>(finfo); creationTime = DateHandlers.MacToDateTime(macinfo.creationDate); lastWriteTime = DateHandlers.MacToDateTime(macinfo.modificationDate); } else if (ProDOSHome.SequenceEqual(header.homeFilesystem)) { AppleDoubleProDOSFileInfo prodosinfo = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleProDOSFileInfo>(finfo); creationTime = DateHandlers.MacToDateTime(prodosinfo.creationDate); lastWriteTime = DateHandlers.MacToDateTime(prodosinfo.modificationDate); } else if (UNIXHome.SequenceEqual(header.homeFilesystem)) { AppleDoubleUNIXFileInfo unixinfo = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleUNIXFileInfo>(finfo); creationTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.creationDate); lastWriteTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.modificationDate); } else if (DOSHome.SequenceEqual(header.homeFilesystem)) { AppleDoubleDOSFileInfo dosinfo = BigEndianMarshal.ByteArrayToStructureBigEndian <AppleDoubleDOSFileInfo>(finfo); lastWriteTime = DateHandlers.DosToDateTime(dosinfo.modificationDate, dosinfo.modificationTime); } break; case AppleDoubleEntryID.ResourceFork: rsrcFork = entry; break; } } dataFork = new AppleDoubleEntry { id = (uint)AppleDoubleEntryID.DataFork }; if (File.Exists(path)) { FileStream dataFs = new FileStream(path, FileMode.Open, FileAccess.Read); dataFork.length = (uint)dataFs.Length; dataFs.Close(); } fs.Close(); opened = true; basePath = path; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; StringBuilder sb = new StringBuilder(); uint sectors = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize; uint bootSectors = QNX6_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize; byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors); byte[] sector = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors); if (sector.Length < QNX6_SUPER_BLOCK_SIZE) { return; } QNX6_AudiSuperBlock audiSb = new QNX6_AudiSuperBlock(); IntPtr audiPtr = Marshal.AllocHGlobal(Marshal.SizeOf(audiSb)); Marshal.Copy(audiSector, 0, audiPtr, Marshal.SizeOf(audiSb)); audiSb = (QNX6_AudiSuperBlock)Marshal.PtrToStructure(audiPtr, typeof(QNX6_AudiSuperBlock)); Marshal.FreeHGlobal(audiPtr); QNX6_SuperBlock qnxSb = new QNX6_SuperBlock(); IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(qnxSb)); Marshal.Copy(sector, 0, sbPtr, Marshal.SizeOf(qnxSb)); qnxSb = (QNX6_SuperBlock)Marshal.PtrToStructure(sbPtr, typeof(QNX6_SuperBlock)); Marshal.FreeHGlobal(sbPtr); bool audi = audiSb.magic == QNX6_MAGIC; if (audi) { sb.AppendLine("QNX6 (Audi) filesystem"); sb.AppendFormat("Checksum: 0x{0:X8}", audiSb.checksum).AppendLine(); sb.AppendFormat("Serial: 0x{0:X16}", audiSb.checksum).AppendLine(); sb.AppendFormat("{0} bytes per block", audiSb.blockSize).AppendLine(); sb.AppendFormat("{0} inodes free of {1}", audiSb.freeInodes, audiSb.numInodes).AppendLine(); sb.AppendFormat("{0} blocks ({1} bytes) free of {2} ({3} bytes)", audiSb.freeBlocks, audiSb.freeBlocks * audiSb.blockSize, audiSb.numBlocks, audiSb.numBlocks * audiSb.blockSize).AppendLine(); XmlFsType = new FileSystemType { Type = "QNX6 (Audi) filesystem", Clusters = audiSb.numBlocks, ClusterSize = (int)audiSb.blockSize, Bootable = true, Files = audiSb.numInodes - audiSb.freeInodes, FilesSpecified = true, FreeClusters = audiSb.freeBlocks, FreeClustersSpecified = true, VolumeSerial = $"{audiSb.serial:X16}" }; //xmlFSType.VolumeName = CurrentEncoding.GetString(audiSb.id); information = sb.ToString(); return; } sb.AppendLine("QNX6 filesystem"); sb.AppendFormat("Checksum: 0x{0:X8}", qnxSb.checksum).AppendLine(); sb.AppendFormat("Serial: 0x{0:X16}", qnxSb.checksum).AppendLine(); sb.AppendFormat("Created on {0}", DateHandlers.UnixUnsignedToDateTime(qnxSb.ctime)).AppendLine(); sb.AppendFormat("Last mounted on {0}", DateHandlers.UnixUnsignedToDateTime(qnxSb.atime)).AppendLine(); sb.AppendFormat("Flags: 0x{0:X8}", qnxSb.flags).AppendLine(); sb.AppendFormat("Version1: 0x{0:X4}", qnxSb.version1).AppendLine(); sb.AppendFormat("Version2: 0x{0:X4}", qnxSb.version2).AppendLine(); //sb.AppendFormat("Volume ID: \"{0}\"", CurrentEncoding.GetString(qnxSb.volumeid)).AppendLine(); sb.AppendFormat("{0} bytes per block", qnxSb.blockSize).AppendLine(); sb.AppendFormat("{0} inodes free of {1}", qnxSb.freeInodes, qnxSb.numInodes).AppendLine(); sb.AppendFormat("{0} blocks ({1} bytes) free of {2} ({3} bytes)", qnxSb.freeBlocks, qnxSb.freeBlocks * qnxSb.blockSize, qnxSb.numBlocks, qnxSb.numBlocks * qnxSb.blockSize) .AppendLine(); XmlFsType = new FileSystemType { Type = "QNX6 filesystem", Clusters = qnxSb.numBlocks, ClusterSize = (int)qnxSb.blockSize, Bootable = true, Files = qnxSb.numInodes - qnxSb.freeInodes, FilesSpecified = true, FreeClusters = qnxSb.freeBlocks, FreeClustersSpecified = true, VolumeSerial = $"{qnxSb.serial:X16}", CreationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.ctime), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.atime), ModificationDateSpecified = true }; //xmlFSType.VolumeName = CurrentEncoding.GetString(qnxSb.volumeid); information = sb.ToString(); }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; StringBuilder sbInformation = new StringBuilder(); uint magic = 0; uint sb_size_in_sectors; byte[] ufs_sb_sectors; ulong sb_offset = partition.Start; bool fs_type_42bsd = false; bool fs_type_43bsd = false; bool fs_type_44bsd = false; bool fs_type_ufs = false; bool fs_type_ufs2 = false; bool fs_type_sun = false; bool fs_type_sun86 = false; if (imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 || imagePlugin.Info.SectorSize == 2448) { sb_size_in_sectors = block_size / 2048; } else { sb_size_in_sectors = block_size / imagePlugin.Info.SectorSize; } ulong[] locations = { sb_start_floppy, sb_start_boot, sb_start_long_boot, sb_start_piggy, sb_start_att_dsdd, 8192 / imagePlugin.Info.SectorSize, 65536 / imagePlugin.Info.SectorSize, 262144 / imagePlugin.Info.SectorSize }; foreach (ulong loc in locations.Where(loc => partition.End > partition.Start + loc + sb_size_in_sectors)) { ufs_sb_sectors = imagePlugin.ReadSectors(partition.Start + loc, sb_size_in_sectors); magic = BitConverter.ToUInt32(ufs_sb_sectors, 0x055C); if (magic == UFS_MAGIC || magic == UFS_CIGAM || magic == UFS_MAGIC_BW || magic == UFS_CIGAM_BW || magic == UFS2_MAGIC || magic == UFS2_CIGAM || magic == UFS_BAD_MAGIC || magic == UFS_BAD_CIGAM) { sb_offset = partition.Start + loc; break; } magic = 0; } if (magic == 0) { information = "Not a UFS filesystem, I shouldn't have arrived here!"; return; } XmlFsType = new FileSystemType(); switch (magic) { case UFS_MAGIC: sbInformation.AppendLine("UFS filesystem"); XmlFsType.Type = "UFS"; break; case UFS_CIGAM: sbInformation.AppendLine("Big-endian UFS filesystem"); XmlFsType.Type = "UFS"; break; case UFS_MAGIC_BW: sbInformation.AppendLine("BorderWare UFS filesystem"); XmlFsType.Type = "UFS"; break; case UFS_CIGAM_BW: sbInformation.AppendLine("Big-endian BorderWare UFS filesystem"); XmlFsType.Type = "UFS"; break; case UFS2_MAGIC: sbInformation.AppendLine("UFS2 filesystem"); XmlFsType.Type = "UFS2"; break; case UFS2_CIGAM: sbInformation.AppendLine("Big-endian UFS2 filesystem"); XmlFsType.Type = "UFS2"; break; case UFS_BAD_MAGIC: sbInformation.AppendLine("Incompletely initialized UFS filesystem"); sbInformation.AppendLine("BEWARE!!! Following information may be completely wrong!"); XmlFsType.Type = "UFS"; break; case UFS_BAD_CIGAM: sbInformation.AppendLine("Incompletely initialized big-endian UFS filesystem"); sbInformation.AppendLine("BEWARE!!! Following information may be completely wrong!"); XmlFsType.Type = "UFS"; break; } // Fun with seeking follows on superblock reading! ufs_sb_sectors = imagePlugin.ReadSectors(sb_offset, sb_size_in_sectors); IntPtr sbPtr = Marshal.AllocHGlobal(ufs_sb_sectors.Length); Marshal.Copy(ufs_sb_sectors, 0, sbPtr, ufs_sb_sectors.Length); UFSSuperBlock ufs_sb = (UFSSuperBlock)Marshal.PtrToStructure(sbPtr, typeof(UFSSuperBlock)); Marshal.FreeHGlobal(sbPtr); UFSSuperBlock bs_sfu = BigEndianMarshal.ByteArrayToStructureBigEndian <UFSSuperBlock>(ufs_sb_sectors); if (bs_sfu.fs_magic == UFS_MAGIC && ufs_sb.fs_magic == UFS_CIGAM || bs_sfu.fs_magic == UFS_MAGIC_BW && ufs_sb.fs_magic == UFS_CIGAM_BW || bs_sfu.fs_magic == UFS2_MAGIC && ufs_sb.fs_magic == UFS2_CIGAM || bs_sfu.fs_magic == UFS_BAD_MAGIC && ufs_sb.fs_magic == UFS_BAD_CIGAM) { ufs_sb = bs_sfu; ufs_sb.fs_old_cstotal.cs_nbfree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nbfree); ufs_sb.fs_old_cstotal.cs_ndir = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_ndir); ufs_sb.fs_old_cstotal.cs_nffree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nffree); ufs_sb.fs_old_cstotal.cs_nifree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nifree); ufs_sb.fs_cstotal.cs_numclusters = Swapping.Swap(ufs_sb.fs_cstotal.cs_numclusters); ufs_sb.fs_cstotal.cs_nbfree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nbfree); ufs_sb.fs_cstotal.cs_ndir = Swapping.Swap(ufs_sb.fs_cstotal.cs_ndir); ufs_sb.fs_cstotal.cs_nffree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nffree); ufs_sb.fs_cstotal.cs_nifree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nifree); ufs_sb.fs_cstotal.cs_spare[0] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[0]); ufs_sb.fs_cstotal.cs_spare[1] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[1]); ufs_sb.fs_cstotal.cs_spare[2] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[2]); } DicConsole.DebugWriteLine("FFS plugin", "ufs_sb offset: 0x{0:X8}", sb_offset); DicConsole.DebugWriteLine("FFS plugin", "fs_rlink: 0x{0:X8}", ufs_sb.fs_rlink); DicConsole.DebugWriteLine("FFS plugin", "fs_sblkno: 0x{0:X8}", ufs_sb.fs_sblkno); DicConsole.DebugWriteLine("FFS plugin", "fs_cblkno: 0x{0:X8}", ufs_sb.fs_cblkno); DicConsole.DebugWriteLine("FFS plugin", "fs_iblkno: 0x{0:X8}", ufs_sb.fs_iblkno); DicConsole.DebugWriteLine("FFS plugin", "fs_dblkno: 0x{0:X8}", ufs_sb.fs_dblkno); DicConsole.DebugWriteLine("FFS plugin", "fs_size: 0x{0:X8}", ufs_sb.fs_size); DicConsole.DebugWriteLine("FFS plugin", "fs_dsize: 0x{0:X8}", ufs_sb.fs_dsize); DicConsole.DebugWriteLine("FFS plugin", "fs_ncg: 0x{0:X8}", ufs_sb.fs_ncg); DicConsole.DebugWriteLine("FFS plugin", "fs_bsize: 0x{0:X8}", ufs_sb.fs_bsize); DicConsole.DebugWriteLine("FFS plugin", "fs_fsize: 0x{0:X8}", ufs_sb.fs_fsize); DicConsole.DebugWriteLine("FFS plugin", "fs_frag: 0x{0:X8}", ufs_sb.fs_frag); DicConsole.DebugWriteLine("FFS plugin", "fs_minfree: 0x{0:X8}", ufs_sb.fs_minfree); DicConsole.DebugWriteLine("FFS plugin", "fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask); DicConsole.DebugWriteLine("FFS plugin", "fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask); DicConsole.DebugWriteLine("FFS plugin", "fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift); DicConsole.DebugWriteLine("FFS plugin", "fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift); DicConsole.DebugWriteLine("FFS plugin", "fs_maxcontig: 0x{0:X8}", ufs_sb.fs_maxcontig); DicConsole.DebugWriteLine("FFS plugin", "fs_maxbpg: 0x{0:X8}", ufs_sb.fs_maxbpg); DicConsole.DebugWriteLine("FFS plugin", "fs_fragshift: 0x{0:X8}", ufs_sb.fs_fragshift); DicConsole.DebugWriteLine("FFS plugin", "fs_fsbtodb: 0x{0:X8}", ufs_sb.fs_fsbtodb); DicConsole.DebugWriteLine("FFS plugin", "fs_sbsize: 0x{0:X8}", ufs_sb.fs_sbsize); DicConsole.DebugWriteLine("FFS plugin", "fs_csmask: 0x{0:X8}", ufs_sb.fs_csmask); DicConsole.DebugWriteLine("FFS plugin", "fs_csshift: 0x{0:X8}", ufs_sb.fs_csshift); DicConsole.DebugWriteLine("FFS plugin", "fs_nindir: 0x{0:X8}", ufs_sb.fs_nindir); DicConsole.DebugWriteLine("FFS plugin", "fs_inopb: 0x{0:X8}", ufs_sb.fs_inopb); DicConsole.DebugWriteLine("FFS plugin", "fs_optim: 0x{0:X8}", ufs_sb.fs_optim); DicConsole.DebugWriteLine("FFS plugin", "fs_id_1: 0x{0:X8}", ufs_sb.fs_id_1); DicConsole.DebugWriteLine("FFS plugin", "fs_id_2: 0x{0:X8}", ufs_sb.fs_id_2); DicConsole.DebugWriteLine("FFS plugin", "fs_csaddr: 0x{0:X8}", ufs_sb.fs_csaddr); DicConsole.DebugWriteLine("FFS plugin", "fs_cssize: 0x{0:X8}", ufs_sb.fs_cssize); DicConsole.DebugWriteLine("FFS plugin", "fs_cgsize: 0x{0:X8}", ufs_sb.fs_cgsize); DicConsole.DebugWriteLine("FFS plugin", "fs_ipg: 0x{0:X8}", ufs_sb.fs_ipg); DicConsole.DebugWriteLine("FFS plugin", "fs_fpg: 0x{0:X8}", ufs_sb.fs_fpg); DicConsole.DebugWriteLine("FFS plugin", "fs_fmod: 0x{0:X2}", ufs_sb.fs_fmod); DicConsole.DebugWriteLine("FFS plugin", "fs_clean: 0x{0:X2}", ufs_sb.fs_clean); DicConsole.DebugWriteLine("FFS plugin", "fs_ronly: 0x{0:X2}", ufs_sb.fs_ronly); DicConsole.DebugWriteLine("FFS plugin", "fs_flags: 0x{0:X2}", ufs_sb.fs_flags); DicConsole.DebugWriteLine("FFS plugin", "fs_magic: 0x{0:X8}", ufs_sb.fs_magic); if (ufs_sb.fs_magic == UFS2_MAGIC) { fs_type_ufs2 = true; } else { const uint SunOSEpoch = 0x1A54C580; // We are supposing there cannot be a Sun's fs created before 1/1/1982 00:00:00 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 > 0) { fs_type_42bsd = true; // It was used in 4.2BSD fs_type_43bsd = false; } if ((ufs_sb.fs_maxfilesize & 0xFFFFFFFF) > SunOSEpoch && DateHandlers.UnixUnsignedToDateTime(ufs_sb.fs_maxfilesize & 0xFFFFFFFF) < DateTime.Now) { fs_type_42bsd = false; fs_type_sun = true; fs_type_43bsd = false; } // 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_old_npsect > SunOSEpoch && DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect) < DateTime.Now ) { fs_type_42bsd = false; fs_type_sun86 = true; fs_type_sun = false; fs_type_43bsd = false; } if (ufs_sb.fs_cgrotor > 0x00000000 && (uint)ufs_sb.fs_cgrotor < 0xFFFFFFFF) { fs_type_42bsd = false; fs_type_sun = false; fs_type_sun86 = false; fs_type_ufs = true; fs_type_43bsd = false; } // 4.3BSD code does not use these fields, they are always set up to 0 fs_type_43bsd &= ufs_sb.fs_id_2 == 0 && ufs_sb.fs_id_1 == 0; // This is the only 4.4BSD inode format fs_type_44bsd |= ufs_sb.fs_old_inodefmt == 2; } if (!fs_type_ufs2) { 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 (fs_type_42bsd) { sbInformation.AppendLine("Guessed as 42BSD FFS"); } if (fs_type_43bsd) { sbInformation.AppendLine("Guessed as 43BSD FFS"); } if (fs_type_44bsd) { sbInformation.AppendLine("Guessed as 44BSD FFS"); } if (fs_type_sun) { sbInformation.AppendLine("Guessed as SunOS FFS"); } if (fs_type_sun86) { sbInformation.AppendLine("Guessed as SunOS/x86 FFS"); } if (fs_type_ufs) { sbInformation.AppendLine("Guessed as UFS"); } if (fs_type_42bsd) { sbInformation.AppendFormat("Linked list of filesystems: 0x{0:X8}", ufs_sb.fs_link).AppendLine(); } sbInformation.AppendFormat("Superblock LBA: {0}", ufs_sb.fs_sblkno).AppendLine(); sbInformation.AppendFormat("Cylinder-block LBA: {0}", ufs_sb.fs_cblkno).AppendLine(); sbInformation.AppendFormat("inode-block LBA: {0}", ufs_sb.fs_iblkno).AppendLine(); sbInformation.AppendFormat("First data block LBA: {0}", ufs_sb.fs_dblkno).AppendLine(); sbInformation.AppendFormat("Cylinder group offset in cylinder: {0}", ufs_sb.fs_old_cgoffset).AppendLine(); sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_time)) .AppendLine(); XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(ufs_sb.fs_old_time); XmlFsType.ModificationDateSpecified = true; sbInformation.AppendFormat("{0} blocks in volume ({1} bytes)", ufs_sb.fs_old_size, (long)ufs_sb.fs_old_size * ufs_sb.fs_fsize).AppendLine(); XmlFsType.Clusters = ufs_sb.fs_old_size; XmlFsType.ClusterSize = ufs_sb.fs_fsize; sbInformation.AppendFormat("{0} data blocks in volume ({1} bytes)", ufs_sb.fs_old_dsize, (long)ufs_sb.fs_old_dsize * ufs_sb.fs_fsize).AppendLine(); sbInformation.AppendFormat("{0} cylinder groups in volume", ufs_sb.fs_ncg).AppendLine(); sbInformation.AppendFormat("{0} bytes in a basic block", ufs_sb.fs_bsize).AppendLine(); sbInformation.AppendFormat("{0} bytes in a frag block", ufs_sb.fs_fsize).AppendLine(); sbInformation.AppendFormat("{0} frags in a block", ufs_sb.fs_frag).AppendLine(); sbInformation.AppendFormat("{0}% of blocks must be free", ufs_sb.fs_minfree).AppendLine(); sbInformation.AppendFormat("{0}ms for optimal next block", ufs_sb.fs_old_rotdelay).AppendLine(); sbInformation.AppendFormat("disk rotates {0} times per second ({1}rpm)", ufs_sb.fs_old_rps, ufs_sb.fs_old_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("{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_old_nspf).AppendLine(); switch (ufs_sb.fs_optim) { case 0: sbInformation.AppendLine("Filesystem will minimize allocation time"); break; case 1: sbInformation.AppendLine("Filesystem will minimize volume fragmentation"); break; default: sbInformation.AppendFormat("Unknown optimization value: 0x{0:X8}", ufs_sb.fs_optim).AppendLine(); break; } if (fs_type_sun) { sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_old_npsect).AppendLine(); } else if (fs_type_sun86) { sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect)) .AppendLine(); } sbInformation.AppendFormat("Hardware sector interleave: {0}", ufs_sb.fs_old_interleave).AppendLine(); sbInformation.AppendFormat("Sector 0 skew: {0}/track", ufs_sb.fs_old_trackskew).AppendLine(); 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(); } else if (fs_type_43bsd && ufs_sb.fs_id_1 > 0 && ufs_sb.fs_id_2 > 0) { sbInformation.AppendFormat("{0} µsec for head switch", ufs_sb.fs_id_1).AppendLine(); sbInformation.AppendFormat("{0} µsec for track-to-track seek", ufs_sb.fs_id_2).AppendLine(); } sbInformation.AppendFormat("Cylinder group summary LBA: {0}", ufs_sb.fs_old_csaddr).AppendLine(); sbInformation.AppendFormat("{0} bytes in cylinder group summary", ufs_sb.fs_cssize).AppendLine(); sbInformation.AppendFormat("{0} bytes in cylinder group", ufs_sb.fs_cgsize).AppendLine(); sbInformation.AppendFormat("{0} tracks/cylinder", ufs_sb.fs_old_ntrak).AppendLine(); sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_old_nsect).AppendLine(); sbInformation.AppendFormat("{0} sectors/cylinder", ufs_sb.fs_old_spc).AppendLine(); sbInformation.AppendFormat("{0} cylinder in volume", ufs_sb.fs_old_ncyl).AppendLine(); sbInformation.AppendFormat("{0} cylinders/group", ufs_sb.fs_old_cpg).AppendLine(); sbInformation.AppendFormat("{0} inodes per cylinder group", ufs_sb.fs_ipg).AppendLine(); sbInformation.AppendFormat("{0} blocks per group", ufs_sb.fs_fpg / ufs_sb.fs_frag).AppendLine(); sbInformation.AppendFormat("{0} directories", ufs_sb.fs_old_cstotal.cs_ndir).AppendLine(); sbInformation.AppendFormat("{0} free blocks ({1} bytes)", ufs_sb.fs_old_cstotal.cs_nbfree, (long)ufs_sb.fs_old_cstotal.cs_nbfree * ufs_sb.fs_fsize).AppendLine(); XmlFsType.FreeClusters = ufs_sb.fs_old_cstotal.cs_nbfree; XmlFsType.FreeClustersSpecified = true; sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_old_cstotal.cs_nifree).AppendLine(); sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_old_cstotal.cs_nffree).AppendLine(); if (ufs_sb.fs_fmod == 1) { sbInformation.AppendLine("Superblock is under modification"); XmlFsType.Dirty = true; } if (ufs_sb.fs_clean == 1) { sbInformation.AppendLine("Volume is clean"); } 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) { sbInformation.AppendFormat("Volume last mounted on \"{0}\"", StringHandlers.CToString(ufs_sb.fs_fsmnt)) .AppendLine(); } else if (fs_type_ufs2) { sbInformation.AppendFormat("Volume last mounted on \"{0}\"", StringHandlers.CToString(ufs_sb.fs_fsmnt)) .AppendLine(); sbInformation.AppendFormat("Volume name: \"{0}\"", StringHandlers.CToString(ufs_sb.fs_volname)) .AppendLine(); XmlFsType.VolumeName = StringHandlers.CToString(ufs_sb.fs_volname); sbInformation.AppendFormat("Volume ID: 0x{0:X16}", ufs_sb.fs_swuid).AppendLine(); //xmlFSType.VolumeSerial = string.Format("{0:X16}", ufs_sb.fs_swuid); sbInformation.AppendFormat("Last searched cylinder group: {0}", ufs_sb.fs_cgrotor).AppendLine(); sbInformation.AppendFormat("{0} contiguously allocated directories", ufs_sb.fs_contigdirs).AppendLine(); sbInformation.AppendFormat("Standard superblock LBA: {0}", ufs_sb.fs_sblkno).AppendLine(); sbInformation.AppendFormat("{0} directories", ufs_sb.fs_cstotal.cs_ndir).AppendLine(); sbInformation.AppendFormat("{0} free blocks ({1} bytes)", ufs_sb.fs_cstotal.cs_nbfree, ufs_sb.fs_cstotal.cs_nbfree * ufs_sb.fs_fsize).AppendLine(); XmlFsType.FreeClusters = ufs_sb.fs_cstotal.cs_nbfree; XmlFsType.FreeClustersSpecified = true; sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_cstotal.cs_nifree).AppendLine(); sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_cstotal.cs_nffree).AppendLine(); sbInformation.AppendFormat("{0} free clusters", ufs_sb.fs_cstotal.cs_numclusters).AppendLine(); sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_time)) .AppendLine(); XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(ufs_sb.fs_time); XmlFsType.ModificationDateSpecified = true; sbInformation.AppendFormat("{0} blocks ({1} bytes)", ufs_sb.fs_size, ufs_sb.fs_size * ufs_sb.fs_fsize) .AppendLine(); XmlFsType.Clusters = ufs_sb.fs_size; sbInformation .AppendFormat("{0} data blocks ({1} bytes)", ufs_sb.fs_dsize, ufs_sb.fs_dsize * ufs_sb.fs_fsize) .AppendLine(); sbInformation.AppendFormat("Cylinder group summary area LBA: {0}", ufs_sb.fs_csaddr).AppendLine(); sbInformation.AppendFormat("{0} blocks pending of being freed", ufs_sb.fs_pendingblocks).AppendLine(); sbInformation.AppendFormat("{0} inodes pending of being freed", ufs_sb.fs_pendinginodes).AppendLine(); } if (fs_type_sun) { sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect)) .AppendLine(); } else if (fs_type_sun86) { sbInformation.AppendFormat("{0} sectors/track", ufs_sb.fs_state).AppendLine(); } else if (fs_type_44bsd) { sbInformation.AppendFormat("{0} blocks on cluster summary array", ufs_sb.fs_contigsumsize).AppendLine(); sbInformation.AppendFormat("Maximum length of a symbolic link: {0}", ufs_sb.fs_maxsymlinklen) .AppendLine(); sbInformation.AppendFormat("A file can be {0} bytes at max", ufs_sb.fs_maxfilesize).AppendLine(); sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_state)) .AppendLine(); } if (ufs_sb.fs_old_nrpos > 0) { sbInformation.AppendFormat("{0} rotational positions", ufs_sb.fs_old_nrpos).AppendLine(); } if (ufs_sb.fs_old_rotbloff > 0) { sbInformation.AppendFormat("{0} blocks per rotation", ufs_sb.fs_old_rotbloff).AppendLine(); } information = sbInformation.ToString(); }
public void Open(string path) { string filename = Path.GetFileName(path); string filenameNoExt = Path.GetFileNameWithoutExtension(path); string parentFolder = Path.GetDirectoryName(path); parentFolder ??= ""; if (filename is null || filenameNoExt is null) { throw new ArgumentNullException(nameof(path)); } // Prepend data fork name with "R." string proDosAppleDouble = Path.Combine(parentFolder, "R." + filename); // Prepend data fork name with '%' string unixAppleDouble = Path.Combine(parentFolder, "%" + filename); // Change file extension to ADF string dosAppleDouble = Path.Combine(parentFolder, filenameNoExt + ".ADF"); // Change file extension to adf string dosAppleDoubleLower = Path.Combine(parentFolder, filenameNoExt + ".adf"); // Store AppleDouble header file in ".AppleDouble" folder with same name string netatalkAppleDouble = Path.Combine(parentFolder, ".AppleDouble", filename); // Store AppleDouble header file in "resource.frk" folder with same name string daveAppleDouble = Path.Combine(parentFolder, "resource.frk", filename); // Prepend data fork name with "._" string osxAppleDouble = Path.Combine(parentFolder, "._" + filename); // Adds ".rsrc" extension string unArAppleDouble = Path.Combine(parentFolder, filename + ".rsrc"); // Check AppleDouble created by A/UX in ProDOS filesystem if (File.Exists(proDosAppleDouble)) { var prodosStream = new FileStream(proDosAppleDouble, FileMode.Open, FileAccess.Read); if (prodosStream.Length > 26) { byte[] prodosB = new byte[26]; prodosStream.Read(prodosB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(prodosB); prodosStream.Close(); if (_header.magic == MAGIC && (_header.version == VERSION || _header.version == VERSION2)) { _headerPath = proDosAppleDouble; } } } // Check AppleDouble created by A/UX in UFS filesystem if (File.Exists(unixAppleDouble)) { var unixStream = new FileStream(unixAppleDouble, FileMode.Open, FileAccess.Read); if (unixStream.Length > 26) { byte[] unixB = new byte[26]; unixStream.Read(unixB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(unixB); unixStream.Close(); if (_header.magic == MAGIC && (_header.version == VERSION || _header.version == VERSION2)) { _headerPath = unixAppleDouble; } } } // Check AppleDouble created by A/UX in FAT filesystem if (File.Exists(dosAppleDouble)) { var dosStream = new FileStream(dosAppleDouble, FileMode.Open, FileAccess.Read); if (dosStream.Length > 26) { byte[] dosB = new byte[26]; dosStream.Read(dosB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(dosB); dosStream.Close(); if (_header.magic == MAGIC && (_header.version == VERSION || _header.version == VERSION2)) { _headerPath = dosAppleDouble; } } } // Check AppleDouble created by A/UX in case preserving FAT filesystem if (File.Exists(dosAppleDoubleLower)) { var doslStream = new FileStream(dosAppleDoubleLower, FileMode.Open, FileAccess.Read); if (doslStream.Length > 26) { byte[] doslB = new byte[26]; doslStream.Read(doslB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(doslB); doslStream.Close(); if (_header.magic == MAGIC && (_header.version == VERSION || _header.version == VERSION2)) { _headerPath = dosAppleDoubleLower; } } } // Check AppleDouble created by Netatalk if (File.Exists(netatalkAppleDouble)) { var netatalkStream = new FileStream(netatalkAppleDouble, FileMode.Open, FileAccess.Read); if (netatalkStream.Length > 26) { byte[] netatalkB = new byte[26]; netatalkStream.Read(netatalkB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(netatalkB); netatalkStream.Close(); if (_header.magic == MAGIC && (_header.version == VERSION || _header.version == VERSION2)) { _headerPath = netatalkAppleDouble; } } } // Check AppleDouble created by DAVE if (File.Exists(daveAppleDouble)) { var daveStream = new FileStream(daveAppleDouble, FileMode.Open, FileAccess.Read); if (daveStream.Length > 26) { byte[] daveB = new byte[26]; daveStream.Read(daveB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(daveB); daveStream.Close(); if (_header.magic == MAGIC && (_header.version == VERSION || _header.version == VERSION2)) { _headerPath = daveAppleDouble; } } } // Check AppleDouble created by Mac OS X if (File.Exists(osxAppleDouble)) { var osxStream = new FileStream(osxAppleDouble, FileMode.Open, FileAccess.Read); if (osxStream.Length > 26) { byte[] osxB = new byte[26]; osxStream.Read(osxB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(osxB); osxStream.Close(); if (_header.magic == MAGIC && (_header.version == VERSION || _header.version == VERSION2)) { _headerPath = osxAppleDouble; } } } // Check AppleDouble created by UnAr (from The Unarchiver) if (File.Exists(unArAppleDouble)) { var unarStream = new FileStream(unArAppleDouble, FileMode.Open, FileAccess.Read); if (unarStream.Length > 26) { byte[] unarB = new byte[26]; unarStream.Read(unarB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(unarB); unarStream.Close(); if (_header.magic == MAGIC && (_header.version == VERSION || _header.version == VERSION2)) { _headerPath = unArAppleDouble; } } } var fs = new FileStream(_headerPath, FileMode.Open, FileAccess.Read); fs.Seek(0, SeekOrigin.Begin); byte[] hdrB = new byte[26]; fs.Read(hdrB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleDoubleHeader>(hdrB); AppleDoubleEntry[] entries = new AppleDoubleEntry[_header.entries]; for (int i = 0; i < _header.entries; i++) { byte[] entry = new byte[12]; fs.Read(entry, 0, 12); entries[i] = Marshal.ByteArrayToStructureBigEndian <AppleDoubleEntry>(entry); } _creationTime = DateTime.UtcNow; _lastWriteTime = _creationTime; foreach (AppleDoubleEntry entry in entries) { switch ((AppleDoubleEntryID)entry.id) { case AppleDoubleEntryID.DataFork: // AppleDouble have datafork in separated file break; case AppleDoubleEntryID.FileDates: fs.Seek(entry.offset, SeekOrigin.Begin); byte[] datesB = new byte[16]; fs.Read(datesB, 0, 16); AppleDoubleFileDates dates = Marshal.ByteArrayToStructureBigEndian <AppleDoubleFileDates>(datesB); _creationTime = DateHandlers.UnixUnsignedToDateTime(dates.creationDate); _lastWriteTime = DateHandlers.UnixUnsignedToDateTime(dates.modificationDate); break; case AppleDoubleEntryID.FileInfo: fs.Seek(entry.offset, SeekOrigin.Begin); byte[] finfo = new byte[entry.length]; fs.Read(finfo, 0, finfo.Length); if (_macintoshHome.SequenceEqual(_header.homeFilesystem)) { AppleDoubleMacFileInfo macinfo = Marshal.ByteArrayToStructureBigEndian <AppleDoubleMacFileInfo>(finfo); _creationTime = DateHandlers.MacToDateTime(macinfo.creationDate); _lastWriteTime = DateHandlers.MacToDateTime(macinfo.modificationDate); } else if (_proDosHome.SequenceEqual(_header.homeFilesystem)) { AppleDoubleProDOSFileInfo prodosinfo = Marshal.ByteArrayToStructureBigEndian <AppleDoubleProDOSFileInfo>(finfo); _creationTime = DateHandlers.MacToDateTime(prodosinfo.creationDate); _lastWriteTime = DateHandlers.MacToDateTime(prodosinfo.modificationDate); } else if (_unixHome.SequenceEqual(_header.homeFilesystem)) { AppleDoubleUnixFileInfo unixinfo = Marshal.ByteArrayToStructureBigEndian <AppleDoubleUnixFileInfo>(finfo); _creationTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.creationDate); _lastWriteTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.modificationDate); } else if (_dosHome.SequenceEqual(_header.homeFilesystem)) { AppleDoubleDOSFileInfo dosinfo = Marshal.ByteArrayToStructureBigEndian <AppleDoubleDOSFileInfo>(finfo); _lastWriteTime = DateHandlers.DosToDateTime(dosinfo.modificationDate, dosinfo.modificationTime); } break; case AppleDoubleEntryID.ResourceFork: _rsrcFork = entry; break; } } _dataFork = new AppleDoubleEntry { id = (uint)AppleDoubleEntryID.DataFork }; if (File.Exists(path)) { var dataFs = new FileStream(path, FileMode.Open, FileAccess.Read); _dataFork.length = (uint)dataFs.Length; dataFs.Close(); } fs.Close(); _opened = true; _basePath = path; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; StringBuilder sb = new StringBuilder(); BigEndianBitConverter.IsLittleEndian = true; // Start in little endian until we know what are we handling here int start = 0; bool xenix = false; bool sysv = false; bool sys7th = false; bool coherent = false; bool xenix3 = false; byte[] sb_sector; byte sb_size_in_sectors; int offset = 0; if (imagePlugin.Info.SectorSize <= 0x400 ) // Check if underlying device sector size is smaller than SuperBlock size { sb_size_in_sectors = (byte)(0x400 / imagePlugin.Info.SectorSize); } else { sb_size_in_sectors = 1; // If not a single sector can store it } // Sectors in a cylinder int spc = (int)(imagePlugin.Info.Heads * imagePlugin.Info.SectorsPerTrack); // Superblock can start on 0x000, 0x200, 0x600 and 0x800, not aligned, so we assume 16 (128 bytes/sector) sectors as a safe value int[] locations = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // Superblock can also skip one cylinder (for boot) spc }; foreach (int i in locations) { sb_sector = imagePlugin.ReadSectors((ulong)i + partition.Start, sb_size_in_sectors); uint magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x3F8); if (magic == XENIX_MAGIC || magic == SYSV_MAGIC) { BigEndianBitConverter.IsLittleEndian = true; // Little endian if (magic == SYSV_MAGIC) { sysv = true; offset = 0x200; } else { xenix = true; } start = i; break; } if (magic == XENIX_CIGAM || magic == SYSV_CIGAM) { BigEndianBitConverter.IsLittleEndian = false; // Big endian if (magic == SYSV_CIGAM) { sysv = true; offset = 0x200; } else { xenix = true; } start = i; break; } magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F0); // XENIX 3 magic location if (magic == XENIX_MAGIC) { BigEndianBitConverter.IsLittleEndian = true; // Little endian xenix3 = true; start = i; break; } if (magic == XENIX_CIGAM) { BigEndianBitConverter.IsLittleEndian = false; // Big endian xenix3 = true; start = i; break; } magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8); // XENIX magic location if (magic == SYSV_MAGIC) { BigEndianBitConverter.IsLittleEndian = true; // Little endian sysv = true; start = i; break; } if (magic == SYSV_CIGAM) { BigEndianBitConverter.IsLittleEndian = false; // Big endian sysv = true; start = i; break; } byte[] coherent_string = new byte[6]; Array.Copy(sb_sector, 0x1E4, coherent_string, 0, 6); // Coherent UNIX s_fname location string s_fname = StringHandlers.CToString(coherent_string, Encoding); Array.Copy(sb_sector, 0x1EA, coherent_string, 0, 6); // Coherent UNIX s_fpack location string s_fpack = StringHandlers.CToString(coherent_string, Encoding); if (s_fname == COH_FNAME && s_fpack == COH_FPACK || s_fname == COH_XXXXX && s_fpack == COH_XXXXX || s_fname == COH_XXXXS && s_fpack == COH_XXXXN) { BigEndianBitConverter.IsLittleEndian = true; // Coherent is in PDP endianness, use helper for that coherent = true; start = i; break; } // Now try to identify 7th edition uint s_fsize = BitConverter.ToUInt32(sb_sector, 0x002); ushort s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); ushort s_ninode = BitConverter.ToUInt16(sb_sector, 0x0D0); if (s_fsize <= 0 || s_fsize >= 0xFFFFFFFF || s_nfree <= 0 || s_nfree >= 0xFFFF || s_ninode <= 0 || s_ninode >= 0xFFFF) { continue; } 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 = (ushort)(s_nfree >> 8); s_ninode = (ushort)(s_ninode >> 8); } if ((s_fsize & 0xFF000000) != 0x00 || (s_nfree & 0xFF00) != 0x00 || (s_ninode & 0xFF00) != 0x00) { continue; } if (s_fsize >= V7_MAXSIZE || s_nfree >= V7_NICFREE || s_ninode >= V7_NICINOD) { continue; } if (s_fsize * 1024 != (partition.End - partition.Start) * imagePlugin.Info.SectorSize && s_fsize * 512 != (partition.End - partition.Start) * imagePlugin.Info.SectorSize) { continue; } sys7th = true; BigEndianBitConverter.IsLittleEndian = true; start = i; break; } if (!sys7th && !sysv && !coherent && !xenix && !xenix3) { return; } XmlFsType = new FileSystemType(); if (xenix || xenix3) { byte[] xenix_strings = new byte[6]; XenixSuperBlock xnx_sb = new XenixSuperBlock(); sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); if (xenix3) { 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); xnx_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D0); xnx_sb.s_flock = sb_sector[0x19A]; xnx_sb.s_ilock = sb_sector[0x19B]; xnx_sb.s_fmod = sb_sector[0x19C]; xnx_sb.s_ronly = sb_sector[0x19D]; xnx_sb.s_time = BigEndianBitConverter.ToInt32(sb_sector, 0x19E); xnx_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x1A2); xnx_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A6); xnx_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8); xnx_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA); xnx_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AC); xnx_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AE); Array.Copy(sb_sector, 0x1B0, xenix_strings, 0, 6); xnx_sb.s_fname = StringHandlers.CToString(xenix_strings, Encoding); Array.Copy(sb_sector, 0x1B6, xenix_strings, 0, 6); xnx_sb.s_fpack = StringHandlers.CToString(xenix_strings, Encoding); xnx_sb.s_clean = sb_sector[0x1BC]; xnx_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F0); xnx_sb.s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F4); } else { 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); xnx_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x198); xnx_sb.s_flock = sb_sector[0x262]; xnx_sb.s_ilock = sb_sector[0x263]; xnx_sb.s_fmod = sb_sector[0x264]; xnx_sb.s_ronly = sb_sector[0x265]; xnx_sb.s_time = BigEndianBitConverter.ToInt32(sb_sector, 0x266); xnx_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x26A); xnx_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x26E); xnx_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x270); xnx_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x272); xnx_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x274); xnx_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x276); Array.Copy(sb_sector, 0x278, xenix_strings, 0, 6); xnx_sb.s_fname = StringHandlers.CToString(xenix_strings, Encoding); Array.Copy(sb_sector, 0x27E, xenix_strings, 0, 6); xnx_sb.s_fpack = StringHandlers.CToString(xenix_strings, Encoding); xnx_sb.s_clean = sb_sector[0x284]; xnx_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x3F8); xnx_sb.s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x3FC); } uint bs = 512; sb.AppendLine("XENIX filesystem"); XmlFsType.Type = "XENIX fs"; switch (xnx_sb.s_type) { case 1: sb.AppendLine("512 bytes per block"); XmlFsType.ClusterSize = 512; break; case 2: sb.AppendLine("1024 bytes per block"); bs = 1024; XmlFsType.ClusterSize = 1024; break; case 3: sb.AppendLine("2048 bytes per block"); bs = 2048; XmlFsType.ClusterSize = 2048; break; default: sb.AppendFormat("Unknown s_type value: 0x{0:X8}", xnx_sb.s_type).AppendLine(); break; } if (imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 || imagePlugin.Info.SectorSize == 2448) { if (bs != 2048) { sb .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", bs, 2048).AppendLine(); } } else { if (bs != imagePlugin.Info.SectorSize) { sb .AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector", bs, imagePlugin.Info.SectorSize).AppendLine(); } } sb.AppendFormat("{0} zones on volume ({1} bytes)", xnx_sb.s_fsize, xnx_sb.s_fsize * bs).AppendLine(); sb.AppendFormat("{0} free zones on volume ({1} bytes)", xnx_sb.s_tfree, xnx_sb.s_tfree * bs) .AppendLine(); sb.AppendFormat("{0} free blocks on list ({1} bytes)", xnx_sb.s_nfree, xnx_sb.s_nfree * bs) .AppendLine(); sb.AppendFormat("{0} blocks per cylinder ({1} bytes)", xnx_sb.s_cylblks, xnx_sb.s_cylblks * bs) .AppendLine(); sb.AppendFormat("{0} blocks per gap ({1} bytes)", xnx_sb.s_gapblks, xnx_sb.s_gapblks * bs).AppendLine(); 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) { sb.AppendLine("Free block list is locked"); } if (xnx_sb.s_ilock > 0) { sb.AppendLine("inode cache is locked"); } if (xnx_sb.s_fmod > 0) { sb.AppendLine("Superblock is being modified"); } if (xnx_sb.s_ronly > 0) { sb.AppendLine("Volume is mounted read-only"); } sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixToDateTime(xnx_sb.s_time)) .AppendLine(); if (xnx_sb.s_time != 0) { XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(xnx_sb.s_time); XmlFsType.ModificationDateSpecified = true; } 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) { sb.AppendLine("Volume is clean"); } else { sb.AppendLine("Volume is dirty"); XmlFsType.Dirty = true; } } if (sysv) { sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); byte[] sysv_strings = new byte[6]; SystemVRelease4SuperBlock sysv_sb = new SystemVRelease4SuperBlock { s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x1FC + offset) }; uint bs = 512; switch (sysv_sb.s_type) { case 1: XmlFsType.ClusterSize = 512; break; case 2: bs = 1024; XmlFsType.ClusterSize = 1024; break; case 3: bs = 2048; XmlFsType.ClusterSize = 2048; break; default: sb.AppendFormat("Unknown s_type value: 0x{0:X8}", sysv_sb.s_type).AppendLine(); break; } sysv_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002 + offset); bool sysvr4 = sysv_sb.s_fsize * bs <= 0 || sysv_sb.s_fsize * bs != partition.Size; if (sysvr4) { sysv_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000 + offset); sysv_sb.s_state = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F4 + offset); sysv_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8 + offset); sysv_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x004 + offset); sysv_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x008 + offset); sysv_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D4 + offset); sysv_sb.s_flock = sb_sector[0x1A0 + offset]; sysv_sb.s_ilock = sb_sector[0x1A1 + offset]; sysv_sb.s_fmod = sb_sector[0x1A2 + offset]; sysv_sb.s_ronly = sb_sector[0x1A3 + offset]; sysv_sb.s_time = BigEndianBitConverter.ToUInt32(sb_sector, 0x1A4 + offset); sysv_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8 + offset); sysv_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA + offset); sysv_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AC + offset); sysv_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AE + offset); sysv_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x1B0 + offset); sysv_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1B4 + offset); Array.Copy(sb_sector, 0x1B6 + offset, sysv_strings, 0, 6); sysv_sb.s_fname = StringHandlers.CToString(sysv_strings, Encoding); Array.Copy(sb_sector, 0x1BC + offset, sysv_strings, 0, 6); sysv_sb.s_fpack = StringHandlers.CToString(sysv_strings, Encoding); sb.AppendLine("System V Release 4 filesystem"); XmlFsType.Type = "SVR4 fs"; } else { sysv_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000 + offset); sysv_sb.s_state = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F4 + offset); sysv_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8 + offset); sysv_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002 + offset); sysv_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x006 + offset); sysv_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D0 + offset); sysv_sb.s_flock = sb_sector[0x19A + offset]; sysv_sb.s_ilock = sb_sector[0x19B + offset]; sysv_sb.s_fmod = sb_sector[0x19C + offset]; sysv_sb.s_ronly = sb_sector[0x19D + offset]; sysv_sb.s_time = BigEndianBitConverter.ToUInt32(sb_sector, 0x19E + offset); sysv_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A2 + offset); sysv_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A4 + offset); sysv_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A6 + offset); sysv_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8 + offset); sysv_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x1AA + offset); sysv_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AE + offset); Array.Copy(sb_sector, 0x1B0 + offset, sysv_strings, 0, 6); sysv_sb.s_fname = StringHandlers.CToString(sysv_strings, Encoding); Array.Copy(sb_sector, 0x1B6 + offset, sysv_strings, 0, 6); sysv_sb.s_fpack = StringHandlers.CToString(sysv_strings, Encoding); sb.AppendLine("System V Release 2 filesystem"); XmlFsType.Type = "SVR2 fs"; } sb.AppendFormat("{0} bytes per block", bs).AppendLine(); XmlFsType.Clusters = sysv_sb.s_fsize; sb.AppendFormat("{0} zones on volume ({1} bytes)", sysv_sb.s_fsize, sysv_sb.s_fsize * bs).AppendLine(); sb.AppendFormat("{0} free zones on volume ({1} bytes)", sysv_sb.s_tfree, sysv_sb.s_tfree * bs) .AppendLine(); sb.AppendFormat("{0} free blocks on list ({1} bytes)", sysv_sb.s_nfree, sysv_sb.s_nfree * bs) .AppendLine(); sb.AppendFormat("{0} blocks per cylinder ({1} bytes)", sysv_sb.s_cylblks, sysv_sb.s_cylblks * bs) .AppendLine(); sb.AppendFormat("{0} blocks per gap ({1} bytes)", sysv_sb.s_gapblks, sysv_sb.s_gapblks * bs) .AppendLine(); 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) { sb.AppendLine("Free block list is locked"); } if (sysv_sb.s_ilock > 0) { sb.AppendLine("inode cache is locked"); } if (sysv_sb.s_fmod > 0) { sb.AppendLine("Superblock is being modified"); } 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) { XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(sysv_sb.s_time); XmlFsType.ModificationDateSpecified = true; } 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) { sb.AppendLine("Volume is clean"); } else { sb.AppendLine("Volume is dirty"); XmlFsType.Dirty = true; } } if (coherent) { sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); CoherentSuperBlock coh_sb = new CoherentSuperBlock(); byte[] coh_strings = new byte[6]; coh_sb.s_isize = BitConverter.ToUInt16(sb_sector, 0x000); coh_sb.s_fsize = Swapping.PDPFromLittleEndian(BitConverter.ToUInt32(sb_sector, 0x002)); coh_sb.s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); coh_sb.s_ninode = BitConverter.ToUInt16(sb_sector, 0x108); coh_sb.s_flock = sb_sector[0x1D2]; coh_sb.s_ilock = sb_sector[0x1D3]; coh_sb.s_fmod = sb_sector[0x1D4]; coh_sb.s_ronly = sb_sector[0x1D5]; coh_sb.s_time = Swapping.PDPFromLittleEndian(BitConverter.ToUInt32(sb_sector, 0x1D6)); coh_sb.s_tfree = Swapping.PDPFromLittleEndian(BitConverter.ToUInt32(sb_sector, 0x1DA)); coh_sb.s_tinode = BitConverter.ToUInt16(sb_sector, 0x1DE); coh_sb.s_int_m = BitConverter.ToUInt16(sb_sector, 0x1E0); coh_sb.s_int_n = BitConverter.ToUInt16(sb_sector, 0x1E2); Array.Copy(sb_sector, 0x1E4, coh_strings, 0, 6); coh_sb.s_fname = StringHandlers.CToString(coh_strings, Encoding); Array.Copy(sb_sector, 0x1EA, coh_strings, 0, 6); coh_sb.s_fpack = StringHandlers.CToString(coh_strings, Encoding); XmlFsType.Type = "Coherent fs"; XmlFsType.ClusterSize = 512; XmlFsType.Clusters = coh_sb.s_fsize; sb.AppendLine("Coherent UNIX filesystem"); if (imagePlugin.Info.SectorSize != 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(); sb.AppendFormat("{0} free blocks on list ({1} bytes)", coh_sb.s_nfree, coh_sb.s_nfree * 512) .AppendLine(); 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) { sb.AppendLine("Free block list is locked"); } if (coh_sb.s_ilock > 0) { sb.AppendLine("inode cache is locked"); } if (coh_sb.s_fmod > 0) { sb.AppendLine("Superblock is being modified"); } 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) { XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(coh_sb.s_time); XmlFsType.ModificationDateSpecified = true; } sb.AppendFormat("Volume name: {0}", coh_sb.s_fname).AppendLine(); XmlFsType.VolumeName = coh_sb.s_fname; sb.AppendFormat("Pack name: {0}", coh_sb.s_fpack).AppendLine(); } if (sys7th) { sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors); UNIX7thEditionSuperBlock v7_sb = new UNIX7thEditionSuperBlock(); byte[] sys7_strings = new byte[6]; v7_sb.s_isize = BigEndianBitConverter.ToUInt16(sb_sector, 0x000); v7_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002); v7_sb.s_nfree = BigEndianBitConverter.ToUInt16(sb_sector, 0x006); v7_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D0); v7_sb.s_flock = sb_sector[0x19A]; v7_sb.s_ilock = sb_sector[0x19B]; v7_sb.s_fmod = sb_sector[0x19C]; v7_sb.s_ronly = sb_sector[0x19D]; v7_sb.s_time = BigEndianBitConverter.ToUInt32(sb_sector, 0x19E); v7_sb.s_tfree = BigEndianBitConverter.ToUInt32(sb_sector, 0x1A2); v7_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A6); v7_sb.s_int_m = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8); v7_sb.s_int_n = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA); Array.Copy(sb_sector, 0x1AC, sys7_strings, 0, 6); v7_sb.s_fname = StringHandlers.CToString(sys7_strings, Encoding); Array.Copy(sb_sector, 0x1B2, sys7_strings, 0, 6); v7_sb.s_fpack = StringHandlers.CToString(sys7_strings, Encoding); XmlFsType.Type = "UNIX 7th Edition fs"; XmlFsType.ClusterSize = 512; XmlFsType.Clusters = v7_sb.s_fsize; sb.AppendLine("UNIX 7th Edition filesystem"); if (imagePlugin.Info.SectorSize != 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(); sb.AppendFormat("{0} free blocks on list ({1} bytes)", v7_sb.s_nfree, v7_sb.s_nfree * 512).AppendLine(); 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) { sb.AppendLine("Free block list is locked"); } if (v7_sb.s_ilock > 0) { sb.AppendLine("inode cache is locked"); } if (v7_sb.s_fmod > 0) { sb.AppendLine("Superblock is being modified"); } 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) { XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(v7_sb.s_time); XmlFsType.ModificationDateSpecified = true; } sb.AppendFormat("Volume name: {0}", v7_sb.s_fname).AppendLine(); XmlFsType.VolumeName = v7_sb.s_fname; sb.AppendFormat("Pack name: {0}", v7_sb.s_fpack).AppendLine(); } information = sb.ToString(); BigEndianBitConverter.IsLittleEndian = false; // Return to default (bigendian) }
public void Open(string path) { var fs = new FileStream(path, FileMode.Open, FileAccess.Read); fs.Seek(0, SeekOrigin.Begin); byte[] hdrB = new byte[26]; fs.Read(hdrB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <Header>(hdrB); Entry[] entries = new Entry[_header.entries]; for (int i = 0; i < _header.entries; i++) { byte[] entry = new byte[12]; fs.Read(entry, 0, 12); entries[i] = Marshal.ByteArrayToStructureBigEndian <Entry>(entry); } _creationTime = DateTime.UtcNow; _lastWriteTime = _creationTime; foreach (Entry entry in entries) { switch ((AppleSingleEntryID)entry.id) { case AppleSingleEntryID.DataFork: _dataFork = entry; break; case AppleSingleEntryID.FileDates: fs.Seek(entry.offset, SeekOrigin.Begin); byte[] datesB = new byte[16]; fs.Read(datesB, 0, 16); FileDates dates = Marshal.ByteArrayToStructureBigEndian <FileDates>(datesB); _creationTime = DateHandlers.MacToDateTime(dates.creationDate); _lastWriteTime = DateHandlers.MacToDateTime(dates.modificationDate); break; case AppleSingleEntryID.FileInfo: fs.Seek(entry.offset, SeekOrigin.Begin); byte[] finfo = new byte[entry.length]; fs.Read(finfo, 0, finfo.Length); if (_macintoshHome.SequenceEqual(_header.homeFilesystem)) { MacFileInfo macinfo = Marshal.ByteArrayToStructureBigEndian <MacFileInfo>(finfo); _creationTime = DateHandlers.MacToDateTime(macinfo.creationDate); _lastWriteTime = DateHandlers.MacToDateTime(macinfo.modificationDate); } else if (_proDosHome.SequenceEqual(_header.homeFilesystem)) { ProDOSFileInfo prodosinfo = Marshal.ByteArrayToStructureBigEndian <ProDOSFileInfo>(finfo); _creationTime = DateHandlers.MacToDateTime(prodosinfo.creationDate); _lastWriteTime = DateHandlers.MacToDateTime(prodosinfo.modificationDate); } else if (_unixHome.SequenceEqual(_header.homeFilesystem)) { UnixFileInfo unixinfo = Marshal.ByteArrayToStructureBigEndian <UnixFileInfo>(finfo); _creationTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.creationDate); _lastWriteTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.modificationDate); } else if (_dosHome.SequenceEqual(_header.homeFilesystem)) { DOSFileInfo dosinfo = Marshal.ByteArrayToStructureBigEndian <DOSFileInfo>(finfo); _lastWriteTime = DateHandlers.DosToDateTime(dosinfo.modificationDate, dosinfo.modificationTime); } break; case AppleSingleEntryID.ResourceFork: _rsrcFork = entry; break; } } fs.Close(); _opened = true; _isPath = true; _basePath = path; }
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information, Encoding encoding) { Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15"); information = ""; byte[] sector = imagePlugin.ReadSector(partition.Start + 1); if (sector.Length < 512) { return; } Superblock qnxSb = Marshal.ByteArrayToStructureLittleEndian <Superblock>(sector); // Too much useless information /* * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_fname = {0}", CurrentEncoding.GetString(qnxSb.rootDir.di_fname)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_size = {0}", qnxSb.rootDir.di_size); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_first_xtnt.block = {0}", qnxSb.rootDir.di_first_xtnt.block); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_first_xtnt.length = {0}", qnxSb.rootDir.di_first_xtnt.length); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_xblk = {0}", qnxSb.rootDir.di_xblk); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_ftime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_mtime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_atime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.rootDir.di_ctime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_num_xtnts = {0}", qnxSb.rootDir.di_num_xtnts); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_mode = {0}", Convert.ToString(qnxSb.rootDir.di_mode, 8)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_uid = {0}", qnxSb.rootDir.di_uid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_gid = {0}", qnxSb.rootDir.di_gid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_nlink = {0}", qnxSb.rootDir.di_nlink); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_zero = {0}", qnxSb.rootDir.di_zero); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_type = {0}", qnxSb.rootDir.di_type); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.rootDir.di_status = {0}", qnxSb.rootDir.di_status); * * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_fname = {0}", CurrentEncoding.GetString(qnxSb.inode.di_fname)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_size = {0}", qnxSb.inode.di_size); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_first_xtnt.block = {0}", qnxSb.inode.di_first_xtnt.block); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_first_xtnt.length = {0}", qnxSb.inode.di_first_xtnt.length); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_xblk = {0}", qnxSb.inode.di_xblk); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_ftime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_mtime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_atime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.inode.di_ctime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_num_xtnts = {0}", qnxSb.inode.di_num_xtnts); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_mode = {0}", Convert.ToString(qnxSb.inode.di_mode, 8)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_uid = {0}", qnxSb.inode.di_uid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_gid = {0}", qnxSb.inode.di_gid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_nlink = {0}", qnxSb.inode.di_nlink); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_zero = {0}", qnxSb.inode.di_zero); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_type = {0}", qnxSb.inode.di_type); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.inode.di_status = {0}", qnxSb.inode.di_status); * * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_fname = {0}", CurrentEncoding.GetString(qnxSb.boot.di_fname)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_size = {0}", qnxSb.boot.di_size); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_first_xtnt.block = {0}", qnxSb.boot.di_first_xtnt.block); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_first_xtnt.length = {0}", qnxSb.boot.di_first_xtnt.length); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_xblk = {0}", qnxSb.boot.di_xblk); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_ftime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_mtime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_atime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.boot.di_ctime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_num_xtnts = {0}", qnxSb.boot.di_num_xtnts); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_mode = {0}", Convert.ToString(qnxSb.boot.di_mode, 8)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_uid = {0}", qnxSb.boot.di_uid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_gid = {0}", qnxSb.boot.di_gid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_nlink = {0}", qnxSb.boot.di_nlink); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_zero = {0}", qnxSb.boot.di_zero); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_type = {0}", qnxSb.boot.di_type); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.boot.di_status = {0}", qnxSb.boot.di_status); * * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_fname = {0}", CurrentEncoding.GetString(qnxSb.altBoot.di_fname)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_size = {0}", qnxSb.altBoot.di_size); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_first_xtnt.block = {0}", qnxSb.altBoot.di_first_xtnt.block); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_first_xtnt.length = {0}", qnxSb.altBoot.di_first_xtnt.length); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_xblk = {0}", qnxSb.altBoot.di_xblk); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_ftime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_ftime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_mtime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_mtime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_atime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_atime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_ctime = {0}", DateHandlers.UNIXUnsignedToDateTime(qnxSb.altBoot.di_ctime)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_num_xtnts = {0}", qnxSb.altBoot.di_num_xtnts); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_mode = {0}", Convert.ToString(qnxSb.altBoot.di_mode, 8)); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_uid = {0}", qnxSb.altBoot.di_uid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_gid = {0}", qnxSb.altBoot.di_gid); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_nlink = {0}", qnxSb.altBoot.di_nlink); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_zero = {0}", qnxSb.altBoot.di_zero); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_type = {0}", qnxSb.altBoot.di_type); * AaruConsole.DebugWriteLine("QNX4 plugin", "qnxSb.altBoot.di_status = {0}", qnxSb.altBoot.di_status); */ information = $"QNX4 filesystem\nCreated on {DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_ftime)}\n"; XmlFsType = new FileSystemType { Type = "QNX4 filesystem", Clusters = partition.Length, ClusterSize = 512, CreationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_ftime), CreationDateSpecified = true, ModificationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_mtime), ModificationDateSpecified = true }; XmlFsType.Bootable |= qnxSb.boot.di_size != 0 || qnxSb.altBoot.di_size != 0; }
public void Open(Stream stream) { stream.Seek(0, SeekOrigin.Begin); byte[] hdrB = new byte[26]; stream.Read(hdrB, 0, 26); _header = Marshal.ByteArrayToStructureBigEndian <AppleSingleHeader>(hdrB); AppleSingleEntry[] entries = new AppleSingleEntry[_header.entries]; for (int i = 0; i < _header.entries; i++) { byte[] entry = new byte[12]; stream.Read(entry, 0, 12); entries[i] = Marshal.ByteArrayToStructureBigEndian <AppleSingleEntry>(entry); } _creationTime = DateTime.UtcNow; _lastWriteTime = _creationTime; foreach (AppleSingleEntry entry in entries) { switch ((AppleSingleEntryID)entry.id) { case AppleSingleEntryID.DataFork: _dataFork = entry; break; case AppleSingleEntryID.FileDates: stream.Seek(entry.offset, SeekOrigin.Begin); byte[] datesB = new byte[16]; stream.Read(datesB, 0, 16); AppleSingleFileDates dates = Marshal.ByteArrayToStructureBigEndian <AppleSingleFileDates>(datesB); _creationTime = DateHandlers.MacToDateTime(dates.creationDate); _lastWriteTime = DateHandlers.MacToDateTime(dates.modificationDate); break; case AppleSingleEntryID.FileInfo: stream.Seek(entry.offset, SeekOrigin.Begin); byte[] finfo = new byte[entry.length]; stream.Read(finfo, 0, finfo.Length); if (_macintoshHome.SequenceEqual(_header.homeFilesystem)) { AppleSingleMacFileInfo macinfo = Marshal.ByteArrayToStructureBigEndian <AppleSingleMacFileInfo>(finfo); _creationTime = DateHandlers.MacToDateTime(macinfo.creationDate); _lastWriteTime = DateHandlers.MacToDateTime(macinfo.modificationDate); } else if (_proDosHome.SequenceEqual(_header.homeFilesystem)) { AppleSingleProDOSFileInfo prodosinfo = Marshal.ByteArrayToStructureBigEndian <AppleSingleProDOSFileInfo>(finfo); _creationTime = DateHandlers.MacToDateTime(prodosinfo.creationDate); _lastWriteTime = DateHandlers.MacToDateTime(prodosinfo.modificationDate); } else if (_unixHome.SequenceEqual(_header.homeFilesystem)) { AppleSingleUnixFileInfo unixinfo = Marshal.ByteArrayToStructureBigEndian <AppleSingleUnixFileInfo>(finfo); _creationTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.creationDate); _lastWriteTime = DateHandlers.UnixUnsignedToDateTime(unixinfo.modificationDate); } else if (_dosHome.SequenceEqual(_header.homeFilesystem)) { AppleSingleDOSFileInfo dosinfo = Marshal.ByteArrayToStructureBigEndian <AppleSingleDOSFileInfo>(finfo); _lastWriteTime = DateHandlers.DosToDateTime(dosinfo.modificationDate, dosinfo.modificationTime); } break; case AppleSingleEntryID.ResourceFork: _rsrcFork = entry; break; } } stream.Seek(0, SeekOrigin.Begin); _opened = true; _isStream = true; _stream = stream; }