diff --git a/Aaru.Filesystems/SysV/Consts.cs b/Aaru.Filesystems/SysV/Consts.cs index 2aa999329..60f7124f8 100644 --- a/Aaru.Filesystems/SysV/Consts.cs +++ b/Aaru.Filesystems/SysV/Consts.cs @@ -40,10 +40,14 @@ namespace Aaru.Filesystems; [SuppressMessage("ReSharper", "UnusedType.Local")] public sealed partial class SysVfs { + /// Magic number for XENIX const uint XENIX_MAGIC = 0x002B5544; + /// Byte swapped magic number for XENIX const uint XENIX_CIGAM = 0x44552B00; - const uint SYSV_MAGIC = 0xFD187E20; - const uint SYSV_CIGAM = 0x207E18FD; + /// Magic number for System V + const uint SYSV_MAGIC = 0xFD187E20; + /// Byte swapped magic number for System V + const uint SYSV_CIGAM = 0x207E18FD; // Rest have no magic. // Per a Linux kernel, Coherent fs has following: @@ -66,4 +70,33 @@ public sealed partial class SysVfs const string FS_TYPE_SVR2 = "sysv_r2"; const string FS_TYPE_COHERENT = "coherent"; const string FS_TYPE_UNIX7 = "unix7fs"; + + /// Number of superblock inodes + const int NICINOD = 100; + /// Number of superblock free inodes (Coherent) + const int COH_NICFREE = 64; + /// Number of superblock free inodes (XENIX 3) + const int XNX_NICFREE = 100; + /// Number of superblock free inodes + const int NICFREE = 50; + /// Number of superblock free inodes in archaic filesystems when block size is 1024 bytes + const int NICFREE_CL2 = 178; + /// Number of superblock free inodes in archaic filesystems when block size is 2048 bytes + const int NICFREE_CL4 = 434; + /// Filler for XENIX superblock + const int NSBFILL = 371; + /// Filler for XENIX 3 superblock + const int XNX3_NSBFILL = 51; + + /// Clean filesystem + const uint FS_OKAY = 0x7c269d38; + /// Active filesystem + const uint FS_ACTIVE = 0x5e72d81a; + /// Bad root + const uint FS_BAD = 0xcb096f43; + /// Filesystem corrupted by a bad block + const uint FS_BADBLK = 0xbadbc14b; + + /// Maximum size of a filename + const int DIRSIZE = 14; } \ No newline at end of file diff --git a/Aaru.Filesystems/SysV/Enums.cs b/Aaru.Filesystems/SysV/Enums.cs new file mode 100644 index 000000000..bda72e2d3 --- /dev/null +++ b/Aaru.Filesystems/SysV/Enums.cs @@ -0,0 +1,54 @@ +// /*************************************************************************** +// Aaru Data Preservation Suite +// ---------------------------------------------------------------------------- +// +// Filename : Consts.cs +// Author(s) : Natalia Portillo +// +// Component : UNIX System V filesystem plugin. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2026 Natalia Portillo +// ****************************************************************************/ + +// ReSharper disable NotAccessedField.Local + +using System.Diagnostics.CodeAnalysis; + +namespace Aaru.Filesystems; + +/// +[SuppressMessage("ReSharper", "InconsistentNaming")] +[SuppressMessage("ReSharper", "UnusedMember.Local")] +[SuppressMessage("ReSharper", "UnusedType.Local")] +public sealed partial class SysVfs +{ + enum FsType + { + /// 512 bytes per block + Fs_512 = 1, + /// 1024 bytes per block + Fs_1024 = 2, + /// 2048 bytes per block + Fs_2048 = 3, + /// 4096 bytes per block + Fs_4096 = 4, + /// 8192 bytes per block + Fs_8192 = 5 + } +} \ No newline at end of file diff --git a/Aaru.Filesystems/SysV/Info.cs b/Aaru.Filesystems/SysV/Info.cs index bdb17b9a7..dc2e47f8d 100644 --- a/Aaru.Filesystems/SysV/Info.cs +++ b/Aaru.Filesystems/SysV/Info.cs @@ -339,52 +339,48 @@ public sealed partial class SysVfs if(xenix3) { xnx_sb.s_isize = BitConverter.ToUInt16(sb_sector, 0x000); - xnx_sb.s_fsize = BitConverter.ToUInt32(sb_sector, 0x002); - xnx_sb.s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); - xnx_sb.s_ninode = BitConverter.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_fsize = BitConverter.ToInt32(sb_sector, 0x002); + xnx_sb.s_nfree = BitConverter.ToInt16(sb_sector, 0x006); + xnx_sb.s_ninode = BitConverter.ToInt16(sb_sector, 0x0D0); + xnx_sb.s_flock = (sbyte)sb_sector[0x19A]; + xnx_sb.s_ilock = (sbyte)sb_sector[0x19B]; + xnx_sb.s_fmod = (sbyte)sb_sector[0x19C]; + xnx_sb.s_ronly = (sbyte)sb_sector[0x19D]; xnx_sb.s_time = BitConverter.ToInt32(sb_sector, 0x19E); - xnx_sb.s_tfree = BitConverter.ToUInt32(sb_sector, 0x1A2); + xnx_sb.s_tfree = BitConverter.ToInt32(sb_sector, 0x1A2); xnx_sb.s_tinode = BitConverter.ToUInt16(sb_sector, 0x1A6); - xnx_sb.s_cylblks = BitConverter.ToUInt16(sb_sector, 0x1A8); - xnx_sb.s_gapblks = BitConverter.ToUInt16(sb_sector, 0x1AA); - xnx_sb.s_dinfo0 = BitConverter.ToUInt16(sb_sector, 0x1AC); - xnx_sb.s_dinfo1 = BitConverter.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_cylblks = BitConverter.ToInt16(sb_sector, 0x1A8); + xnx_sb.s_gapblks = BitConverter.ToInt16(sb_sector, 0x1AA); + xnx_sb.s_dinfo0 = BitConverter.ToInt16(sb_sector, 0x1AC); + xnx_sb.s_dinfo1 = BitConverter.ToInt16(sb_sector, 0x1AE); + Array.Copy(sb_sector, 0x1B0, xnx_sb.s_fname, 0, 6); + Array.Copy(sb_sector, 0x1B6, xnx_sb.s_fpack, 0, 6); xnx_sb.s_clean = sb_sector[0x1BC]; xnx_sb.s_magic = BitConverter.ToUInt32(sb_sector, 0x1F0); - xnx_sb.s_type = BitConverter.ToUInt32(sb_sector, 0x1F4); + xnx_sb.s_type = (FsType)BitConverter.ToInt32(sb_sector, 0x1F4); } else { xnx_sb.s_isize = BitConverter.ToUInt16(sb_sector, 0x000); - xnx_sb.s_fsize = BitConverter.ToUInt32(sb_sector, 0x002); - xnx_sb.s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); - xnx_sb.s_ninode = BitConverter.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_fsize = BitConverter.ToInt32(sb_sector, 0x002); + xnx_sb.s_nfree = BitConverter.ToInt16(sb_sector, 0x006); + xnx_sb.s_ninode = BitConverter.ToInt16(sb_sector, 0x198); + xnx_sb.s_flock = (sbyte)sb_sector[0x262]; + xnx_sb.s_ilock = (sbyte)sb_sector[0x263]; + xnx_sb.s_fmod = (sbyte)sb_sector[0x264]; + xnx_sb.s_ronly = (sbyte)sb_sector[0x265]; xnx_sb.s_time = BitConverter.ToInt32(sb_sector, 0x266); - xnx_sb.s_tfree = BitConverter.ToUInt32(sb_sector, 0x26A); + xnx_sb.s_tfree = BitConverter.ToInt32(sb_sector, 0x26A); xnx_sb.s_tinode = BitConverter.ToUInt16(sb_sector, 0x26E); - xnx_sb.s_cylblks = BitConverter.ToUInt16(sb_sector, 0x270); - xnx_sb.s_gapblks = BitConverter.ToUInt16(sb_sector, 0x272); - xnx_sb.s_dinfo0 = BitConverter.ToUInt16(sb_sector, 0x274); - xnx_sb.s_dinfo1 = BitConverter.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_cylblks = BitConverter.ToInt16(sb_sector, 0x270); + xnx_sb.s_gapblks = BitConverter.ToInt16(sb_sector, 0x272); + xnx_sb.s_dinfo0 = BitConverter.ToInt16(sb_sector, 0x274); + xnx_sb.s_dinfo1 = BitConverter.ToInt16(sb_sector, 0x276); + Array.Copy(sb_sector, 0x278, xnx_sb.s_fname, 0, 6); + Array.Copy(sb_sector, 0x27E, xnx_sb.s_fpack, 0, 6); xnx_sb.s_clean = sb_sector[0x284]; xnx_sb.s_magic = BitConverter.ToUInt32(sb_sector, 0x3F8); - xnx_sb.s_type = BitConverter.ToUInt32(sb_sector, 0x3FC); + xnx_sb.s_type = (FsType)BitConverter.ToInt32(sb_sector, 0x3FC); } if(bigEndian) @@ -401,7 +397,7 @@ public sealed partial class SysVfs xnx_sb.s_dinfo0 = Swapping.Swap(xnx_sb.s_dinfo0); xnx_sb.s_dinfo1 = Swapping.Swap(xnx_sb.s_dinfo1); xnx_sb.s_magic = Swapping.Swap(xnx_sb.s_magic); - xnx_sb.s_type = Swapping.Swap(xnx_sb.s_type); + xnx_sb.s_type = (FsType)Swapping.Swap((uint)xnx_sb.s_type); } uint bs = 512; @@ -410,18 +406,18 @@ public sealed partial class SysVfs switch(xnx_sb.s_type) { - case 1: + case FsType.Fs_512: sb.AppendLine(Localization._512_bytes_per_block); metadata.ClusterSize = 512; break; - case 2: + case FsType.Fs_1024: sb.AppendLine(Localization._1024_bytes_per_block); bs = 1024; metadata.ClusterSize = 1024; break; - case 3: + case FsType.Fs_2048: sb.AppendLine(Localization._2048_bytes_per_block); bs = 2048; metadata.ClusterSize = 2048; @@ -487,9 +483,9 @@ public sealed partial class SysVfs if(xnx_sb.s_time != 0) metadata.ModificationDate = DateHandlers.UnixToDateTime(xnx_sb.s_time); - sb.AppendFormat(Localization.Volume_name_0, xnx_sb.s_fname).AppendLine(); - metadata.VolumeName = xnx_sb.s_fname; - sb.AppendFormat(Localization.Pack_name_0, xnx_sb.s_fpack).AppendLine(); + sb.AppendFormat(Localization.Volume_name_0, StringHandlers.CToString(xnx_sb.s_fname)).AppendLine(); + metadata.VolumeName = StringHandlers.CToString(xnx_sb.s_fname); + sb.AppendFormat(Localization.Pack_name_0, StringHandlers.CToString(xnx_sb.s_fpack)).AppendLine(); if(xnx_sb.s_clean == 0x46) sb.AppendLine(Localization.Volume_is_clean); @@ -514,28 +510,38 @@ public sealed partial class SysVfs var sysv_sb = new SystemVRelease4SuperBlock { - s_type = BitConverter.ToUInt32(sb_sector, 0x1FC + offset) + s_type = (FsType)BitConverter.ToUInt32(sb_sector, 0x1FC + offset) }; - if(bigEndian) sysv_sb.s_type = Swapping.Swap(sysv_sb.s_type); + if(bigEndian) sysv_sb.s_type = (FsType)Swapping.Swap((uint)sysv_sb.s_type); uint bs = 512; switch(sysv_sb.s_type) { - case 1: + case FsType.Fs_512: metadata.ClusterSize = 512; break; - case 2: + case FsType.Fs_1024: bs = 1024; metadata.ClusterSize = 1024; break; - case 3: + case FsType.Fs_2048: bs = 2048; metadata.ClusterSize = 2048; + break; + case FsType.Fs_4096: + bs = 4096; + metadata.ClusterSize = 4096; + + break; + case FsType.Fs_8192: + bs = 8192; + metadata.ClusterSize = 8192; + break; default: sb.AppendFormat(Localization.Unknown_s_type_value_0, sysv_sb.s_type).AppendLine(); @@ -543,61 +549,57 @@ public sealed partial class SysVfs break; } - sysv_sb.s_fsize = BitConverter.ToUInt32(sb_sector, 0x002 + offset); + sysv_sb.s_fsize = BitConverter.ToInt32(sb_sector, 0x002 + offset); if(bigEndian) sysv_sb.s_fsize = Swapping.Swap(sysv_sb.s_fsize); - bool sysvr4 = sysv_sb.s_fsize * bs <= 0 || sysv_sb.s_fsize * bs != partition.Size; + bool sysvr4 = sysv_sb.s_fsize * bs <= 0 || sysv_sb.s_fsize * bs != (long)partition.Size; if(sysvr4) { sysv_sb.s_isize = BitConverter.ToUInt16(sb_sector, 0x000 + offset); - sysv_sb.s_state = BitConverter.ToUInt32(sb_sector, 0x1F4 + offset); + sysv_sb.s_state = BitConverter.ToInt32(sb_sector, 0x1F4 + offset); sysv_sb.s_magic = BitConverter.ToUInt32(sb_sector, 0x1F8 + offset); - sysv_sb.s_fsize = BitConverter.ToUInt32(sb_sector, 0x004 + offset); - sysv_sb.s_nfree = BitConverter.ToUInt16(sb_sector, 0x008 + offset); - sysv_sb.s_ninode = BitConverter.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 = BitConverter.ToUInt32(sb_sector, 0x1A4 + offset); - sysv_sb.s_cylblks = BitConverter.ToUInt16(sb_sector, 0x1A8 + offset); - sysv_sb.s_gapblks = BitConverter.ToUInt16(sb_sector, 0x1AA + offset); - sysv_sb.s_dinfo0 = BitConverter.ToUInt16(sb_sector, 0x1AC + offset); - sysv_sb.s_dinfo1 = BitConverter.ToUInt16(sb_sector, 0x1AE + offset); - sysv_sb.s_tfree = BitConverter.ToUInt32(sb_sector, 0x1B0 + offset); - sysv_sb.s_tinode = BitConverter.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); + sysv_sb.s_fsize = BitConverter.ToInt32(sb_sector, 0x004 + offset); + sysv_sb.s_nfree = BitConverter.ToInt16(sb_sector, 0x008 + offset); + sysv_sb.s_ninode = BitConverter.ToInt16(sb_sector, 0x0D4 + offset); + sysv_sb.s_flock = (sbyte)sb_sector[0x1A0 + offset]; + sysv_sb.s_ilock = (sbyte)sb_sector[0x1A1 + offset]; + sysv_sb.s_fmod = (sbyte)sb_sector[0x1A2 + offset]; + sysv_sb.s_ronly = (sbyte)sb_sector[0x1A3 + offset]; + sysv_sb.s_time = BitConverter.ToInt32(sb_sector, 0x1A4 + offset); + sysv_sb.s_cylblks = BitConverter.ToInt16(sb_sector, 0x1A8 + offset); + sysv_sb.s_gapblks = BitConverter.ToInt16(sb_sector, 0x1AA + offset); + sysv_sb.s_dinfo0 = BitConverter.ToInt16(sb_sector, 0x1AC + offset); + sysv_sb.s_dinfo1 = BitConverter.ToInt16(sb_sector, 0x1AE + offset); + sysv_sb.s_tfree = BitConverter.ToInt32(sb_sector, 0x1B0 + offset); + sysv_sb.s_tinode = BitConverter.ToInt16(sb_sector, 0x1B4 + offset); + Array.Copy(sb_sector, 0x1B6 + offset, sysv_sb.s_fname, 0, 6); + Array.Copy(sb_sector, 0x1BC + offset, sysv_sb.s_fpack, 0, 6); sb.AppendLine(Localization.System_V_Release_4_filesystem); metadata.Type = FS_TYPE_SVR4; } else { sysv_sb.s_isize = BitConverter.ToUInt16(sb_sector, 0x000 + offset); - sysv_sb.s_state = BitConverter.ToUInt32(sb_sector, 0x1F4 + offset); + sysv_sb.s_state = BitConverter.ToInt32(sb_sector, 0x1F4 + offset); sysv_sb.s_magic = BitConverter.ToUInt32(sb_sector, 0x1F8 + offset); - sysv_sb.s_fsize = BitConverter.ToUInt32(sb_sector, 0x002 + offset); - sysv_sb.s_nfree = BitConverter.ToUInt16(sb_sector, 0x006 + offset); - sysv_sb.s_ninode = BitConverter.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 = BitConverter.ToUInt32(sb_sector, 0x19E + offset); - sysv_sb.s_cylblks = BitConverter.ToUInt16(sb_sector, 0x1A2 + offset); - sysv_sb.s_gapblks = BitConverter.ToUInt16(sb_sector, 0x1A4 + offset); - sysv_sb.s_dinfo0 = BitConverter.ToUInt16(sb_sector, 0x1A6 + offset); - sysv_sb.s_dinfo1 = BitConverter.ToUInt16(sb_sector, 0x1A8 + offset); - sysv_sb.s_tfree = BitConverter.ToUInt32(sb_sector, 0x1AA + offset); - sysv_sb.s_tinode = BitConverter.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); + sysv_sb.s_fsize = BitConverter.ToInt32(sb_sector, 0x002 + offset); + sysv_sb.s_nfree = BitConverter.ToInt16(sb_sector, 0x006 + offset); + sysv_sb.s_ninode = BitConverter.ToInt16(sb_sector, 0x0D0 + offset); + sysv_sb.s_flock = (sbyte)sb_sector[0x19A + offset]; + sysv_sb.s_ilock = (sbyte)sb_sector[0x19B + offset]; + sysv_sb.s_fmod = (sbyte)sb_sector[0x19C + offset]; + sysv_sb.s_ronly = (sbyte)sb_sector[0x19D + offset]; + sysv_sb.s_time = BitConverter.ToInt32(sb_sector, 0x19E + offset); + sysv_sb.s_cylblks = BitConverter.ToInt16(sb_sector, 0x1A2 + offset); + sysv_sb.s_gapblks = BitConverter.ToInt16(sb_sector, 0x1A4 + offset); + sysv_sb.s_dinfo0 = BitConverter.ToInt16(sb_sector, 0x1A6 + offset); + sysv_sb.s_dinfo1 = BitConverter.ToInt16(sb_sector, 0x1A8 + offset); + sysv_sb.s_tfree = BitConverter.ToInt32(sb_sector, 0x1AA + offset); + sysv_sb.s_tinode = BitConverter.ToInt16(sb_sector, 0x1AE + offset); + Array.Copy(sb_sector, 0x1B0 + offset, sysv_sb.s_fname, 0, 6); + Array.Copy(sb_sector, 0x1B6 + offset, sysv_sb.s_fpack, 0, 6); sb.AppendLine(Localization.System_V_Release_2_filesystem); metadata.Type = FS_TYPE_SVR2; } @@ -621,7 +623,7 @@ public sealed partial class SysVfs sb.AppendFormat(Localization._0_bytes_per_block, bs).AppendLine(); - metadata.Clusters = sysv_sb.s_fsize; + metadata.Clusters = (ulong)sysv_sb.s_fsize; sb.AppendFormat(Localization._0_zones_in_volume_1_bytes, sysv_sb.s_fsize, sysv_sb.s_fsize * bs) .AppendLine(); @@ -650,15 +652,14 @@ public sealed partial class SysVfs if(sysv_sb.s_ronly > 0) sb.AppendLine(Localization.Volume_is_mounted_read_only); - sb.AppendFormat(Localization.Superblock_last_updated_on_0, - DateHandlers.UnixUnsignedToDateTime(sysv_sb.s_time)) + sb.AppendFormat(Localization.Superblock_last_updated_on_0, DateHandlers.UnixToDateTime(sysv_sb.s_time)) .AppendLine(); - if(sysv_sb.s_time != 0) metadata.ModificationDate = DateHandlers.UnixUnsignedToDateTime(sysv_sb.s_time); + if(sysv_sb.s_time != 0) metadata.ModificationDate = DateHandlers.UnixToDateTime(sysv_sb.s_time); - sb.AppendFormat(Localization.Volume_name_0, sysv_sb.s_fname).AppendLine(); - metadata.VolumeName = sysv_sb.s_fname; - sb.AppendFormat(Localization.Pack_name_0, sysv_sb.s_fpack).AppendLine(); + sb.AppendFormat(Localization.Volume_name_0, StringHandlers.CToString(sysv_sb.s_fname)).AppendLine(); + metadata.VolumeName = StringHandlers.CToString(sysv_sb.s_fname); + sb.AppendFormat(Localization.Pack_name_0, StringHandlers.CToString(sysv_sb.s_fpack)).AppendLine(); if(sysv_sb.s_state == 0x7C269D38 - sysv_sb.s_time) sb.AppendLine(Localization.Volume_is_clean); @@ -683,26 +684,24 @@ public sealed partial class SysVfs var 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_fsize = (int)Swapping.PDPFromLittleEndian(BitConverter.ToUInt32(sb_sector, 0x002)); + coh_sb.s_nfree = BitConverter.ToInt16(sb_sector, 0x006); + coh_sb.s_ninode = BitConverter.ToInt16(sb_sector, 0x108); + coh_sb.s_flock = (sbyte)sb_sector[0x1D2]; + coh_sb.s_ilock = (sbyte)sb_sector[0x1D3]; + coh_sb.s_fmod = (sbyte)sb_sector[0x1D4]; + coh_sb.s_ronly = (sbyte)sb_sector[0x1D5]; + coh_sb.s_time = (int)Swapping.PDPFromLittleEndian(BitConverter.ToUInt32(sb_sector, 0x1D6)); + coh_sb.s_tfree = (int)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); + coh_sb.s_m = BitConverter.ToInt16(sb_sector, 0x1E0); + coh_sb.s_n = BitConverter.ToInt16(sb_sector, 0x1E2); + Array.Copy(sb_sector, 0x1E4, coh_sb.s_fname, 0, 6); + Array.Copy(sb_sector, 0x1EA, coh_sb.s_fpack, 0, 6); metadata.Type = FS_TYPE_COHERENT; metadata.ClusterSize = 512; - metadata.Clusters = coh_sb.s_fsize; + metadata.Clusters = (ulong)coh_sb.s_fsize; sb.AppendLine(Localization.Coherent_UNIX_filesystem); @@ -735,15 +734,14 @@ public sealed partial class SysVfs if(coh_sb.s_ronly > 0) sb.AppendLine(Localization.Volume_is_mounted_read_only); - sb.AppendFormat(Localization.Superblock_last_updated_on_0, - DateHandlers.UnixUnsignedToDateTime(coh_sb.s_time)) + sb.AppendFormat(Localization.Superblock_last_updated_on_0, DateHandlers.UnixToDateTime(coh_sb.s_time)) .AppendLine(); - if(coh_sb.s_time != 0) metadata.ModificationDate = DateHandlers.UnixUnsignedToDateTime(coh_sb.s_time); + if(coh_sb.s_time != 0) metadata.ModificationDate = DateHandlers.UnixToDateTime(coh_sb.s_time); - sb.AppendFormat(Localization.Volume_name_0, coh_sb.s_fname).AppendLine(); - metadata.VolumeName = coh_sb.s_fname; - sb.AppendFormat(Localization.Pack_name_0, coh_sb.s_fpack).AppendLine(); + sb.AppendFormat(Localization.Volume_name_0, StringHandlers.CToString(coh_sb.s_fname)).AppendLine(); + metadata.VolumeName = StringHandlers.CToString(coh_sb.s_fname); + sb.AppendFormat(Localization.Pack_name_0, StringHandlers.CToString(coh_sb.s_fpack)).AppendLine(); } if(sys7th) @@ -761,21 +759,19 @@ public sealed partial class SysVfs v7_sb.s_isize = BitConverter.ToUInt16(sb_sector, 0x000); v7_sb.s_fsize = BitConverter.ToUInt32(sb_sector, 0x002); - v7_sb.s_nfree = BitConverter.ToUInt16(sb_sector, 0x006); - v7_sb.s_ninode = BitConverter.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 = BitConverter.ToUInt32(sb_sector, 0x19E); - v7_sb.s_tfree = BitConverter.ToUInt32(sb_sector, 0x1A2); + v7_sb.s_nfree = BitConverter.ToInt16(sb_sector, 0x006); + v7_sb.s_ninode = BitConverter.ToInt16(sb_sector, 0x0D0); + v7_sb.s_flock = (sbyte)sb_sector[0x19A]; + v7_sb.s_ilock = (sbyte)sb_sector[0x19B]; + v7_sb.s_fmod = (sbyte)sb_sector[0x19C]; + v7_sb.s_ronly = (sbyte)sb_sector[0x19D]; + v7_sb.s_time = BitConverter.ToInt32(sb_sector, 0x19E); + v7_sb.s_tfree = BitConverter.ToInt32(sb_sector, 0x1A2); v7_sb.s_tinode = BitConverter.ToUInt16(sb_sector, 0x1A6); - v7_sb.s_int_m = BitConverter.ToUInt16(sb_sector, 0x1A8); - v7_sb.s_int_n = BitConverter.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); + v7_sb.s_m = BitConverter.ToInt16(sb_sector, 0x1A8); + v7_sb.s_n = BitConverter.ToInt16(sb_sector, 0x1AA); + Array.Copy(sb_sector, 0x1AC, v7_sb.s_fname, 0, 6); + Array.Copy(sb_sector, 0x1B2, v7_sb.s_fpack, 0, 6); metadata.Type = FS_TYPE_UNIX7; metadata.ClusterSize = 512; @@ -811,15 +807,14 @@ public sealed partial class SysVfs if(v7_sb.s_ronly > 0) sb.AppendLine(Localization.Volume_is_mounted_read_only); - sb.AppendFormat(Localization.Superblock_last_updated_on_0, - DateHandlers.UnixUnsignedToDateTime(v7_sb.s_time)) + sb.AppendFormat(Localization.Superblock_last_updated_on_0, DateHandlers.UnixToDateTime(v7_sb.s_time)) .AppendLine(); - if(v7_sb.s_time != 0) metadata.ModificationDate = DateHandlers.UnixUnsignedToDateTime(v7_sb.s_time); + if(v7_sb.s_time != 0) metadata.ModificationDate = DateHandlers.UnixToDateTime(v7_sb.s_time); - sb.AppendFormat(Localization.Volume_name_0, v7_sb.s_fname).AppendLine(); - metadata.VolumeName = v7_sb.s_fname; - sb.AppendFormat(Localization.Pack_name_0, v7_sb.s_fpack).AppendLine(); + sb.AppendFormat(Localization.Volume_name_0, StringHandlers.CToString(v7_sb.s_fname)).AppendLine(); + metadata.VolumeName = StringHandlers.CToString(v7_sb.s_fname); + sb.AppendFormat(Localization.Pack_name_0, StringHandlers.CToString(v7_sb.s_fpack)).AppendLine(); } information = sb.ToString(); diff --git a/Aaru.Filesystems/SysV/Structs.cs b/Aaru.Filesystems/SysV/Structs.cs index 320a3ccfc..89d132f45 100644 --- a/Aaru.Filesystems/SysV/Structs.cs +++ b/Aaru.Filesystems/SysV/Structs.cs @@ -29,6 +29,10 @@ // ReSharper disable NotAccessedField.Local using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using Aaru.CommonTypes.Attributes; + +// ReSharper disable InheritdocConsiderUsage namespace Aaru.Filesystems; @@ -42,186 +46,213 @@ public sealed partial class SysVfs { #region Nested type: CoherentSuperBlock -#pragma warning disable CS0649 - struct CoherentSuperBlock + /// + /// Superblock for COHERENT UNIX filesystem + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapPdpEndian] + partial struct CoherentSuperBlock { /// 0x000, index of first data zone public ushort s_isize; /// 0x002, total number of zones of this volume - public uint s_fsize; + public int s_fsize; // the start of the free block list: /// 0x006, blocks in s_free, <=100 - public ushort s_nfree; + public short s_nfree; /// 0x008, 64 entries, first free block list chunk - public uint[] s_free; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = COH_NICFREE)] + public int[] s_free; // the cache of free inodes: /// 0x108, number of inodes in s_inode, <= 100 - public ushort s_ninode; + public short s_ninode; /// 0x10A, 100 entries, some free inodes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] public ushort[] s_inode; /// 0x1D2, free block list manipulation lock - public byte s_flock; + public sbyte s_flock; /// 0x1D3, inode cache manipulation lock - public byte s_ilock; + public sbyte s_ilock; /// 0x1D4, superblock modification flag - public byte s_fmod; + public sbyte s_fmod; /// 0x1D5, read-only mounted flag - public byte s_ronly; + public sbyte s_ronly; /// 0x1D6, time of last superblock update - public uint s_time; + public int s_time; /// 0x1DE, total number of free zones - public uint s_tfree; + public int s_tfree; /// 0x1E2, total number of free inodes public ushort s_tinode; /// 0x1E4, interleave factor - public ushort s_int_m; + public short s_m; /// 0x1E6, interleave factor - public ushort s_int_n; + public short s_n; /// 0x1E8, 6 bytes, volume name - public string s_fname; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fname; /// 0x1EE, 6 bytes, pack name - public string s_fpack; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fpack; /// 0x1F4, zero-filled - public uint s_unique; + public int s_unique; } -#pragma warning restore CS0649 #endregion #region Nested type: SystemVRelease2SuperBlock -#pragma warning disable CS0649 - struct SystemVRelease2SuperBlock + /// + /// Superblock for System V Release 2 and derivates + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct SystemVRelease2SuperBlock { - /// 0x000, index of first data zone + /// 0x000, size in blocks of i-list public ushort s_isize; /// 0x002, total number of zones of this volume - public uint s_fsize; + public int s_fsize; // the start of the free block list: /// 0x006, blocks in s_free, <=100 - public ushort s_nfree; + public short s_nfree; /// 0x008, 50 entries, first free block list chunk - public uint[] s_free; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICFREE)] + public int[] s_free; // the cache of free inodes: /// 0x0D0, number of inodes in s_inode, <= 100 - public ushort s_ninode; + public short s_ninode; /// 0x0D2, 100 entries, some free inodes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] public ushort[] s_inode; /// 0x19A, free block list manipulation lock - public byte s_flock; + public sbyte s_flock; /// 0x19B, inode cache manipulation lock - public byte s_ilock; + public sbyte s_ilock; /// 0x19C, superblock modification flag - public byte s_fmod; + public sbyte s_fmod; /// 0x19D, read-only mounted flag - public byte s_ronly; + public sbyte s_ronly; /// 0x19E, time of last superblock update - public uint s_time; + public int s_time; /// 0x1A2, blocks per cylinder - public ushort s_cylblks; + public short s_cylblks; /// 0x1A4, blocks per gap - public ushort s_gapblks; + public short s_gapblks; /// 0x1A6, device information ?? - public ushort s_dinfo0; + public short s_dinfo0; /// 0x1A8, device information ?? - public ushort s_dinfo1; + public short s_dinfo1; /// 0x1AA, total number of free zones - public uint s_tfree; + public int s_tfree; /// 0x1AE, total number of free inodes public ushort s_tinode; /// 0x1B0, 6 bytes, volume name - public string s_fname; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fname; /// 0x1B6, 6 bytes, pack name - public string s_fpack; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fpack; /// 0x1BC, 56 bytes - public byte[] s_fill; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] + public int[] s_fill; /// 0x1F4, if s_state == (0x7C269D38 - s_time) then filesystem is clean - public uint s_state; + public int s_state; /// 0x1F8, magic public uint s_magic; /// 0x1FC, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk) - public uint s_type; + public FsType s_type; } -#pragma warning restore CS0649 #endregion #region Nested type: SystemVRelease4SuperBlock -#pragma warning disable CS0649 - struct SystemVRelease4SuperBlock + /// + /// Superblock for System V Release 4 and derivates + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct SystemVRelease4SuperBlock { - /// 0x000, index of first data zone + /// 0x000, size in blocks of i-list public ushort s_isize; /// 0x002, padding - public ushort s_pad0; + public short s_pad0; /// 0x004, total number of zones of this volume - public uint s_fsize; + public int s_fsize; // the start of the free block list: /// 0x008, blocks in s_free, <=100 - public ushort s_nfree; + public short s_nfree; /// 0x00A, padding - public ushort s_pad1; + public short s_pad1; /// 0x00C, 50 entries, first free block list chunk + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICFREE)] public uint[] s_free; // the cache of free inodes: /// 0x0D4, number of inodes in s_inode, <= 100 - public ushort s_ninode; + public short s_ninode; /// 0x0D6, padding - public ushort s_pad2; + public short s_pad2; /// 0x0D8, 100 entries, some free inodes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] public ushort[] s_inode; /// 0x1A0, free block list manipulation lock - public byte s_flock; + public sbyte s_flock; /// 0x1A1, inode cache manipulation lock - public byte s_ilock; + public sbyte s_ilock; /// 0x1A2, superblock modification flag - public byte s_fmod; + public sbyte s_fmod; /// 0x1A3, read-only mounted flag - public byte s_ronly; + public sbyte s_ronly; /// 0x1A4, time of last superblock update - public uint s_time; + public int s_time; /// 0x1A8, blocks per cylinder - public ushort s_cylblks; + public short s_cylblks; /// 0x1AA, blocks per gap - public ushort s_gapblks; + public short s_gapblks; /// 0x1AC, device information ?? - public ushort s_dinfo0; + public short s_dinfo0; /// 0x1AE, device information ?? - public ushort s_dinfo1; + public short s_dinfo1; /// 0x1B0, total number of free zones - public uint s_tfree; + public int s_tfree; /// 0x1B4, total number of free inodes - public ushort s_tinode; + public short s_tinode; /// 0x1B6, padding - public ushort s_pad3; + public short s_pad3; /// 0x1B8, 6 bytes, volume name - public string s_fname; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fname; /// 0x1BE, 6 bytes, pack name - public string s_fpack; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fpack; /// 0x1C4, 48 bytes - public byte[] s_fill; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] + public int[] s_fill; /// 0x1F4, if s_state == (0x7C269D38 - s_time) then filesystem is clean - public uint s_state; + public int s_state; /// 0x1F8, magic public uint s_magic; /// 0x1FC, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk) - public uint s_type; + public FsType s_type; } -#pragma warning restore CS0649 #endregion #region Nested type: UNIX7thEditionSuperBlock -#pragma warning disable CS0649 - struct UNIX7thEditionSuperBlock + /// + /// Superblock for 512 bytes per block UNIX 7th Edition filesystem + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct UNIX7thEditionSuperBlock { /// 0x000, index of first data zone public ushort s_isize; @@ -230,100 +261,339 @@ public sealed partial class SysVfs // the start of the free block list: /// 0x006, blocks in s_free, <=100 - public ushort s_nfree; + public short s_nfree; /// 0x008, 50 entries, first free block list chunk - public uint[] s_free; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICFREE)] + public int[] s_free; // the cache of free inodes: /// 0x0D0, number of inodes in s_inode, <= 100 - public ushort s_ninode; + public short s_ninode; /// 0x0D2, 100 entries, some free inodes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] public ushort[] s_inode; /// 0x19A, free block list manipulation lock - public byte s_flock; + public sbyte s_flock; /// 0x19B, inode cache manipulation lock - public byte s_ilock; + public sbyte s_ilock; /// 0x19C, superblock modification flag - public byte s_fmod; + public sbyte s_fmod; /// 0x19D, read-only mounted flag - public byte s_ronly; + public sbyte s_ronly; /// 0x19E, time of last superblock update - public uint s_time; + public int s_time; /// 0x1A2, total number of free zones - public uint s_tfree; + public int s_tfree; /// 0x1A6, total number of free inodes public ushort s_tinode; /// 0x1A8, interleave factor - public ushort s_int_m; + public short s_m; /// 0x1AA, interleave factor - public ushort s_int_n; + public short s_n; /// 0x1AC, 6 bytes, volume name - public string s_fname; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fname; /// 0x1B2, 6 bytes, pack name - public string s_fpack; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fpack; + /// 0x1B8, start place for circular search + public ushort s_lasti; + /// 0x1BE, est # free inodes before s_lasti + public ushort s_nbehind; + } + +#endregion + +#region Nested type: UNIX7thEditionSuperBlock_CL2 + + /// + /// Superblock for 1024 bytes per block UNIX 7th Edition filesystem + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct UNIX7thEditionSuperBlock_CL2 + { + /// 0x000, index of first data zone + public ushort s_isize; + /// 0x002, total number of zones of this volume + public uint s_fsize; + + // the start of the free block list: + /// 0x006, blocks in s_free, <=100 + public short s_nfree; + /// 0x008, 178 entries, first free block list chunk + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICFREE_CL2)] + public int[] s_free; + + // the cache of free inodes: + /// 0x2D0, number of inodes in s_inode, <= 100 + public short s_ninode; + /// 0x2D2, 100 entries, some free inodes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] + public ushort[] s_inode; + /// 0x39A, free block list manipulation lock + public sbyte s_flock; + /// 0x39B, inode cache manipulation lock + public sbyte s_ilock; + /// 0x39C, superblock modification flag + public sbyte s_fmod; + /// 0x39D, read-only mounted flag + public sbyte s_ronly; + /// 0x39E, time of last superblock update + public int s_time; + /// 0x3A2, total number of free zones + public int s_tfree; + /// 0x3A6, total number of free inodes + public ushort s_tinode; + /// 0x3A8, interleave factor + public short s_m; + /// 0x3AA, interleave factor + public short s_n; + /// 0x3AC, 6 bytes, volume name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fname; + /// 0x3B2, 6 bytes, pack name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fpack; + /// 0x3B8, start place for circular search + public ushort s_lasti; + /// 0x3BE, est # free inodes before s_lasti + public ushort s_nbehind; + } + +#endregion + +#region Nested type: UNIX7thEditionSuperBlock_CL4 + + /// + /// Superblock for 2048 bytes per block UNIX 7th Edition filesystem + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct UNIX7thEditionSuperBlock_CL4 + { + /// 0x000, index of first data zone + public ushort s_isize; + /// 0x002, total number of zones of this volume + public uint s_fsize; + + // the start of the free block list: + /// 0x006, blocks in s_free, <=100 + public short s_nfree; + /// 0x008, 434 entries, first free block list chunk + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICFREE_CL4)] + public int[] s_free; + + // the cache of free inodes: + /// 0x6D0, number of inodes in s_inode, <= 100 + public short s_ninode; + /// 0x6D2, 100 entries, some free inodes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] + public ushort[] s_inode; + /// 0x79A, free block list manipulation lock + public sbyte s_flock; + /// 0x79B, inode cache manipulation lock + public sbyte s_ilock; + /// 0x79C, superblock modification flag + public sbyte s_fmod; + /// 0x79D, read-only mounted flag + public sbyte s_ronly; + /// 0x79E, time of last superblock update + public int s_time; + /// 0x7A2, total number of free zones + public int s_tfree; + /// 0x7A6, total number of free inodes + public ushort s_tinode; + /// 0x7A8, interleave factor + public short s_m; + /// 0x7AA, interleave factor + public short s_n; + /// 0x7AC, 6 bytes, volume name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fname; + /// 0x7B2, 6 bytes, pack name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fpack; + /// 0x7B8, start place for circular search + public ushort s_lasti; + /// 0x7BE, est # free inodes before s_lasti + public ushort s_nbehind; } -#pragma warning restore CS0649 #endregion #region Nested type: XenixSuperBlock - // Old XENIX use different offsets -#pragma warning disable CS0649 - struct XenixSuperBlock + /// + /// Superblock for XENIX and UNIX System III + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct XenixSuperBlock { - /// 0x000, index of first data zone + /// 0x000, size in blocks of i-list public ushort s_isize; /// 0x002, total number of zones of this volume - public uint s_fsize; + public int s_fsize; // the start of the free block list: /// 0x006, blocks in s_free, <=100 - public ushort s_nfree; - /// 0x008, 100 entries, 50 entries for Xenix 3, first free block list chunk - public uint[] s_free; + public short s_nfree; + /// 0x008, 100 entries, first free block list chunk + [MarshalAs(UnmanagedType.ByValArray, SizeConst = XNX_NICFREE)] + public int[] s_free; // the cache of free inodes: - /// 0x198 (0xD0), number of inodes in s_inode, <= 100 - public ushort s_ninode; - /// 0x19A (0xD2), 100 entries, some free inodes + /// 0x198, number of inodes in s_inode, <= 100 + public short s_ninode; + /// 0x19A, 100 entries, some free inodes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] public ushort[] s_inode; - /// 0x262 (0x19A), free block list manipulation lock - public byte s_flock; - /// 0x263 (0x19B), inode cache manipulation lock - public byte s_ilock; - /// 0x264 (0x19C), superblock modification flag - public byte s_fmod; - /// 0x265 (0x19D), read-only mounted flag - public byte s_ronly; - /// 0x266 (0x19E), time of last superblock update + /// 0x262, free block list manipulation lock + public sbyte s_flock; + /// 0x263, inode cache manipulation lock + public sbyte s_ilock; + /// 0x264, superblock modification flag + public sbyte s_fmod; + /// 0x265, read-only mounted flag + public sbyte s_ronly; + /// 0x266, time of last superblock update public int s_time; - /// 0x26A (0x1A2), total number of free zones - public uint s_tfree; - /// 0x26E (0x1A6), total number of free inodes + /// 0x26A, total number of free zones + public int s_tfree; + /// 0x26E, total number of free inodes public ushort s_tinode; - /// 0x270 (0x1A8), blocks per cylinder - public ushort s_cylblks; - /// 0x272 (0x1AA), blocks per gap - public ushort s_gapblks; - /// 0x274 (0x1AC), device information ?? - public ushort s_dinfo0; - /// 0x276 (0x1AE), device information ?? - public ushort s_dinfo1; - /// 0x278 (0x1B0), 6 bytes, volume name - public string s_fname; - /// 0x27E (0x1B6), 6 bytes, pack name - public string s_fpack; - /// 0x284 (0x1BC), 0x46 if volume is clean + /// 0x270, blocks per cylinder + public short s_cylblks; + /// 0x272, blocks per gap + public short s_gapblks; + /// 0x274, device information ?? + public short s_dinfo0; + /// 0x276, device information ?? + public short s_dinfo1; + /// 0x278, 6 bytes, volume name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fname; + /// 0x27E, 6 bytes, pack name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fpack; + /// 0x284, 0x46 if volume is clean public byte s_clean; - /// 0x285 (0x1BD), 371 bytes, 51 bytes for Xenix 3 + /// 0x285, 371 bytes, 51 bytes for Xenix 3 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NSBFILL)] public byte[] s_fill; - /// 0x3F8 (0x1F0), magic + /// 0x3F8, magic public uint s_magic; - /// 0x3FC (0x1F4), filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk, 3 = 2048 bytes/blk) - public uint s_type; + /// 0x3FC, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk, 3 = 2048 bytes/blk) + public FsType s_type; } -#pragma warning restore CS0649 #endregion + +#region Nested type: Xenix3SuperBlock + + /// + /// Superblock for XENIX 3 + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct Xenix3SuperBlock + { + /// 0x000, size in blocks of i-list + public ushort s_isize; + /// 0x002, total number of zones of this volume + public int s_fsize; + + // the start of the free block list: + /// 0x006, blocks in s_free, <=100 + public short s_nfree; + /// 0x008, 50 entries, first free block list chunk + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICFREE)] + public int[] s_free; + + // the cache of free inodes: + /// 0xD0, number of inodes in s_inode, <= 100 + public short s_ninode; + /// 0xD2, 100 entries, some free inodes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] + public ushort[] s_inode; + /// 0x19A, free block list manipulation lock + public sbyte s_flock; + /// 0x19B, inode cache manipulation lock + public sbyte s_ilock; + /// 0x19C, superblock modification flag + public sbyte s_fmod; + /// 0x19D, read-only mounted flag + public sbyte s_ronly; + /// 0x19E, time of last superblock update + public int s_time; + /// 0x1A2, total number of free zones + public int s_tfree; + /// 0x1A6, total number of free inodes + public short s_tinode; + /// 0x1A8, blocks per cylinder + public short s_cylblks; + /// 0x1AA, blocks per gap + public short s_gapblks; + /// 0x1AC, device information ?? + public short s_dinfo0; + /// 0x1AE, device information ?? + public short s_dinfo1; + /// 0x1B0, 6 bytes, volume name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fname; + /// 0x1B6, 6 bytes, pack name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] s_fpack; + /// 0x1BC, 0x46 if volume is clean + public sbyte s_clean; + /// 0x1BD, 371 bytes, 51 bytes for Xenix 3 + [MarshalAs(UnmanagedType.ByValArray, SizeConst = XNX3_NSBFILL)] + public byte[] s_fill; + /// 0x1F0, magic + public uint s_magic; + /// 0x1F4, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk, 3 = 2048 bytes/blk) + public FsType s_type; + } + +#endregion + + /// Directory entry + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct DirectoryEntry + { + /// Inode number + public ushort d_ino; + /// File name + [MarshalAs(UnmanagedType.ByValArray, SizeConst = DIRSIZE)] + public byte[] d_name; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + [SwapEndian] + partial struct Inode + { + ///mode and type of file + public ushort di_mode; + ///number of links to file + public short di_nlink; + ///owner's user id + public short di_uid; + ///owner's group id + public short di_gid; + ///number of bytes in file + public int di_size; + ///disk block addresses + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 39)] + public byte[] di_addr; + ///file generation number + public sbyte di_gen; + ///time last accessed + public int di_atime; + ///time last modified + public int di_mtime; + ///time created + public int di_ctime; + } } \ No newline at end of file diff --git a/Aaru.sln.DotSettings b/Aaru.sln.DotSettings index 3336dd61f..b9d8f0a53 100644 --- a/Aaru.sln.DotSettings +++ b/Aaru.sln.DotSettings @@ -1,4 +1,7 @@ - + Null ExplicitlyExcluded @@ -1043,7 +1046,7 @@ True True True - True + True True True True @@ -1185,6 +1188,7 @@ True True True + True True True True