2017-07-19 16:31:08 +01:00
|
|
|
|
// /***************************************************************************
|
2016-07-28 18:13:49 +01:00
|
|
|
|
// The Disc Image Chef
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// Filename : SysV.cs
|
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
|
//
|
|
|
|
|
|
// Component : UNIX System V filesystem plugin.
|
|
|
|
|
|
//
|
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// Identifies the UNIX System V filesystem and shows information.
|
|
|
|
|
|
//
|
|
|
|
|
|
// --[ 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
//
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2017-12-19 03:50:57 +00:00
|
|
|
|
// Copyright © 2011-2018 Natalia Portillo
|
2016-07-28 18:13:49 +01:00
|
|
|
|
// ****************************************************************************/
|
2014-04-17 19:58:14 +00:00
|
|
|
|
|
2012-08-07 06:20:13 +00:00
|
|
|
|
using System;
|
2017-12-22 08:43:22 +00:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2017-12-21 07:08:26 +00:00
|
|
|
|
using System.Linq;
|
2017-07-19 16:31:08 +01:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
using DiscImageChef.CommonTypes;
|
2018-06-25 19:08:16 +01:00
|
|
|
|
using DiscImageChef.CommonTypes.Interfaces;
|
2017-12-21 14:30:38 +00:00
|
|
|
|
using Schemas;
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2016-07-21 16:15:39 +01:00
|
|
|
|
namespace DiscImageChef.Filesystems
|
2012-08-07 06:20:13 +00:00
|
|
|
|
{
|
2016-07-28 22:25:26 +01:00
|
|
|
|
// Information from the Linux kernel
|
2017-12-22 08:43:22 +00:00
|
|
|
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
2017-12-26 06:05:12 +00:00
|
|
|
|
public class SysVfs : IFilesystem
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2016-07-28 22:25:26 +01:00
|
|
|
|
const uint XENIX_MAGIC = 0x002B5544;
|
|
|
|
|
|
const uint XENIX_CIGAM = 0x44552B00;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
const uint SYSV_MAGIC = 0xFD187E20;
|
|
|
|
|
|
const uint SYSV_CIGAM = 0x207E18FD;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// Rest have no magic.
|
|
|
|
|
|
// Per a Linux kernel, Coherent fs has following:
|
2017-09-17 05:49:22 +01:00
|
|
|
|
const string COH_FNAME = "noname";
|
|
|
|
|
|
const string COH_FPACK = "nopack";
|
2017-09-17 07:39:48 +01:00
|
|
|
|
const string COH_XXXXX = "xxxxx";
|
|
|
|
|
|
const string COH_XXXXS = "xxxxx ";
|
|
|
|
|
|
const string COH_XXXXN = "xxxxx\n";
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// SCO AFS
|
2016-07-28 22:25:26 +01:00
|
|
|
|
const ushort SCO_NFREE = 0xFFFF;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// UNIX 7th Edition has nothing to detect it, so check for a valid filesystem is a must :(
|
2016-07-28 22:25:26 +01:00
|
|
|
|
const ushort V7_NICINOD = 100;
|
2017-09-17 23:02:31 +01:00
|
|
|
|
const ushort V7_NICFREE = 100;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
const uint V7_MAXSIZE = 0x00FFFFFF;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
|
2017-12-26 08:01:40 +00:00
|
|
|
|
public FileSystemType XmlFsType { get; private set; }
|
2018-06-22 08:08:38 +01:00
|
|
|
|
public Encoding Encoding { get; private set; }
|
|
|
|
|
|
public string Name => "UNIX System V filesystem";
|
|
|
|
|
|
public Guid Id => new Guid("9B8D016A-8561-400E-A12A-A198283C211D");
|
2017-10-12 23:54:02 +01:00
|
|
|
|
|
2017-12-26 07:28:40 +00:00
|
|
|
|
public bool Identify(IMediaImage imagePlugin, Partition partition)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2017-12-20 17:26:28 +00:00
|
|
|
|
if(2 + partition.Start >= partition.End) return false;
|
2014-07-09 19:49:14 +01:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
byte sb_size_in_sectors;
|
|
|
|
|
|
|
2017-12-26 06:05:12 +00:00
|
|
|
|
if(imagePlugin.Info.SectorSize <= 0x400
|
2017-12-19 20:33:03 +00:00
|
|
|
|
) // Check if underlying device sector size is smaller than SuperBlock size
|
2018-06-22 08:08:38 +01:00
|
|
|
|
sb_size_in_sectors = (byte)(0x400 / imagePlugin.Info.SectorSize);
|
2017-12-19 20:33:03 +00:00
|
|
|
|
else sb_size_in_sectors = 1; // If not a single sector can store it
|
2014-04-14 01:14:20 +00:00
|
|
|
|
|
2017-12-20 17:26:28 +00:00
|
|
|
|
if(partition.End <= partition.Start + 4 * (ulong)sb_size_in_sectors + sb_size_in_sectors
|
2017-12-19 20:33:03 +00:00
|
|
|
|
) // Device must be bigger than SB location + SB size + offset
|
2014-04-14 01:14:20 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2017-11-08 22:42:29 +00:00
|
|
|
|
// Sectors in a cylinder
|
2017-12-26 06:05:12 +00:00
|
|
|
|
int spc = (int)(imagePlugin.Info.Heads * imagePlugin.Info.SectorsPerTrack);
|
2017-11-08 22:42:29 +00:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
// Superblock can start on 0x000, 0x200, 0x600 and 0x800, not aligned, so we assume 16 (128 bytes/sector) sectors as a safe value
|
2017-12-19 20:33:03 +00:00
|
|
|
|
int[] locations =
|
|
|
|
|
|
{
|
|
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
2017-11-08 22:42:29 +00:00
|
|
|
|
// Superblock can also skip one cylinder (for boot)
|
2017-12-19 20:33:03 +00:00
|
|
|
|
spc
|
|
|
|
|
|
};
|
2017-11-08 22:42:29 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
foreach(byte[] sb_sector in locations
|
|
|
|
|
|
.TakeWhile(i => (ulong)i + partition.Start + sb_size_in_sectors <
|
|
|
|
|
|
imagePlugin.Info.Sectors)
|
|
|
|
|
|
.Select(i => imagePlugin.ReadSectors((ulong)i + partition.Start,
|
|
|
|
|
|
sb_size_in_sectors)))
|
2017-12-24 02:37:41 +00:00
|
|
|
|
{
|
2017-12-22 08:43:22 +00:00
|
|
|
|
uint magic = BitConverter.ToUInt32(sb_sector, 0x3F8);
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2017-11-08 17:04:15 +00:00
|
|
|
|
if(magic == XENIX_MAGIC || magic == XENIX_CIGAM || magic == SYSV_MAGIC || magic == SYSV_CIGAM)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
return true;
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
magic = BitConverter.ToUInt32(sb_sector, 0x1F8); // System V magic location
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(magic == SYSV_MAGIC || magic == SYSV_CIGAM) return true;
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2016-08-03 02:57:08 +01:00
|
|
|
|
magic = BitConverter.ToUInt32(sb_sector, 0x1F0); // XENIX 3 magic location
|
2016-08-01 00:02:14 +01:00
|
|
|
|
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(magic == XENIX_MAGIC || magic == XENIX_CIGAM) return true;
|
2016-08-01 00:02:14 +01:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
byte[] coherent_string = new byte[6];
|
2017-09-17 05:49:22 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x1E4, coherent_string, 0, 6); // Coherent UNIX s_fname location
|
2017-12-26 06:36:15 +00:00
|
|
|
|
string s_fname = StringHandlers.CToString(coherent_string);
|
2017-09-17 05:49:22 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x1EA, coherent_string, 0, 6); // Coherent UNIX s_fpack location
|
2017-12-26 06:36:15 +00:00
|
|
|
|
string s_fpack = StringHandlers.CToString(coherent_string);
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2017-12-20 17:26:28 +00:00
|
|
|
|
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) return true;
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// Now try to identify 7th edition
|
2018-06-22 08:08:38 +01:00
|
|
|
|
uint s_fsize = BitConverter.ToUInt32(sb_sector, 0x002);
|
|
|
|
|
|
ushort s_nfree = BitConverter.ToUInt16(sb_sector, 0x006);
|
2017-12-22 08:43:22 +00:00
|
|
|
|
ushort s_ninode = BitConverter.ToUInt16(sb_sector, 0x0D0);
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if(s_fsize <= 0 || s_fsize >= 0xFFFFFFFF || s_nfree <= 0 || s_nfree >= 0xFFFF || s_ninode <= 0 ||
|
2017-12-21 06:06:19 +00:00
|
|
|
|
s_ninode >= 0xFFFF) continue;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if((s_fsize & 0xFF) == 0x00 && (s_nfree & 0xFF) == 0x00 && (s_ninode & 0xFF) == 0x00)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Byteswap
|
2018-06-22 08:08:38 +01:00
|
|
|
|
s_fsize = ((s_fsize & 0xFF) << 24) + ((s_fsize & 0xFF00) << 8) + ((s_fsize & 0xFF0000) >> 8) +
|
2017-12-21 06:06:19 +00:00
|
|
|
|
((s_fsize & 0xFF000000) >> 24);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
s_nfree = (ushort)(s_nfree >> 8);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
s_ninode = (ushort)(s_ninode >> 8);
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if((s_fsize & 0xFF000000) != 0x00 || (s_nfree & 0xFF00) != 0x00 ||
|
|
|
|
|
|
(s_ninode & 0xFF00) != 0x00) continue;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
|
|
|
|
|
|
if(s_fsize >= V7_MAXSIZE || s_nfree >= V7_NICFREE || s_ninode >= V7_NICINOD) continue;
|
|
|
|
|
|
|
2017-12-26 06:05:12 +00:00
|
|
|
|
if(s_fsize * 1024 == (partition.End - partition.Start) * imagePlugin.Info.SectorSize ||
|
2018-06-22 08:08:38 +01:00
|
|
|
|
s_fsize * 512 == (partition.End - partition.Start) * imagePlugin.Info.SectorSize) return true;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
|
|
|
|
|
|
Encoding encoding)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
|
2014-04-14 02:29:13 +00:00
|
|
|
|
information = "";
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
StringBuilder sb = new StringBuilder();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
BigEndianBitConverter.IsLittleEndian =
|
|
|
|
|
|
true; // Start in little endian until we know what are we handling here
|
2018-06-22 08:08:38 +01:00
|
|
|
|
int start = 0;
|
|
|
|
|
|
bool xenix = false;
|
|
|
|
|
|
bool sysv = false;
|
|
|
|
|
|
bool sys7th = false;
|
|
|
|
|
|
bool coherent = false;
|
|
|
|
|
|
bool xenix3 = false;
|
2014-04-14 01:14:20 +00:00
|
|
|
|
byte[] sb_sector;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
byte sb_size_in_sectors;
|
|
|
|
|
|
int offset = 0;
|
2014-04-14 01:14:20 +00:00
|
|
|
|
|
2017-12-26 06:05:12 +00:00
|
|
|
|
if(imagePlugin.Info.SectorSize <= 0x400
|
2017-12-19 20:33:03 +00:00
|
|
|
|
) // Check if underlying device sector size is smaller than SuperBlock size
|
2018-06-22 08:08:38 +01:00
|
|
|
|
sb_size_in_sectors = (byte)(0x400 / imagePlugin.Info.SectorSize);
|
2017-12-19 20:33:03 +00:00
|
|
|
|
else sb_size_in_sectors = 1; // If not a single sector can store it
|
2017-11-08 22:42:29 +00:00
|
|
|
|
// Sectors in a cylinder
|
2017-12-26 06:05:12 +00:00
|
|
|
|
int spc = (int)(imagePlugin.Info.Heads * imagePlugin.Info.SectorsPerTrack);
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
// Superblock can start on 0x000, 0x200, 0x600 and 0x800, not aligned, so we assume 16 (128 bytes/sector) sectors as a safe value
|
2017-12-19 20:33:03 +00:00
|
|
|
|
int[] locations =
|
|
|
|
|
|
{
|
|
|
|
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
2017-11-08 22:42:29 +00:00
|
|
|
|
// Superblock can also skip one cylinder (for boot)
|
2017-12-19 20:33:03 +00:00
|
|
|
|
spc
|
|
|
|
|
|
};
|
2017-11-08 22:42:29 +00:00
|
|
|
|
|
|
|
|
|
|
foreach(int i in locations)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2017-11-08 22:42:29 +00:00
|
|
|
|
sb_sector = imagePlugin.ReadSectors((ulong)i + partition.Start, sb_size_in_sectors);
|
2017-12-22 08:43:22 +00:00
|
|
|
|
uint magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x3F8);
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2017-11-08 17:04:15 +00:00
|
|
|
|
if(magic == XENIX_MAGIC || magic == SYSV_MAGIC)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2014-04-14 01:14:20 +00:00
|
|
|
|
BigEndianBitConverter.IsLittleEndian = true; // Little endian
|
2017-11-08 17:04:15 +00:00
|
|
|
|
if(magic == SYSV_MAGIC)
|
|
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
sysv = true;
|
2017-11-08 17:04:15 +00:00
|
|
|
|
offset = 0x200;
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
else xenix = true;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
|
2017-11-08 22:42:29 +00:00
|
|
|
|
start = i;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2017-11-08 17:04:15 +00:00
|
|
|
|
if(magic == XENIX_CIGAM || magic == SYSV_CIGAM)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2014-04-14 01:14:20 +00:00
|
|
|
|
BigEndianBitConverter.IsLittleEndian = false; // Big endian
|
2017-11-08 17:04:15 +00:00
|
|
|
|
if(magic == SYSV_CIGAM)
|
|
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
sysv = true;
|
2017-11-08 17:04:15 +00:00
|
|
|
|
offset = 0x200;
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
else xenix = true;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
|
2017-11-08 22:42:29 +00:00
|
|
|
|
start = i;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2016-08-03 02:57:08 +01:00
|
|
|
|
magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F0); // XENIX 3 magic location
|
2016-08-01 00:02:14 +01:00
|
|
|
|
|
|
|
|
|
|
if(magic == XENIX_MAGIC)
|
|
|
|
|
|
{
|
|
|
|
|
|
BigEndianBitConverter.IsLittleEndian = true; // Little endian
|
2018-06-22 08:08:38 +01:00
|
|
|
|
xenix3 = true;
|
|
|
|
|
|
start = i;
|
2016-08-01 00:02:14 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2016-08-01 00:02:14 +01:00
|
|
|
|
if(magic == XENIX_CIGAM)
|
|
|
|
|
|
{
|
|
|
|
|
|
BigEndianBitConverter.IsLittleEndian = false; // Big endian
|
2018-06-22 08:08:38 +01:00
|
|
|
|
xenix3 = true;
|
|
|
|
|
|
start = i;
|
2016-08-01 00:02:14 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F8); // XENIX magic location
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
|
|
|
|
|
if(magic == SYSV_MAGIC)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2014-04-14 01:14:20 +00:00
|
|
|
|
BigEndianBitConverter.IsLittleEndian = true; // Little endian
|
2018-06-22 08:08:38 +01:00
|
|
|
|
sysv = true;
|
|
|
|
|
|
start = i;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(magic == SYSV_CIGAM)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2014-04-14 01:14:20 +00:00
|
|
|
|
BigEndianBitConverter.IsLittleEndian = false; // Big endian
|
2018-06-22 08:08:38 +01:00
|
|
|
|
sysv = true;
|
|
|
|
|
|
start = i;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
byte[] coherent_string = new byte[6];
|
2017-09-17 05:49:22 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x1E4, coherent_string, 0, 6); // Coherent UNIX s_fname location
|
2017-12-26 08:01:40 +00:00
|
|
|
|
string s_fname = StringHandlers.CToString(coherent_string, Encoding);
|
2017-09-17 05:49:22 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x1EA, coherent_string, 0, 6); // Coherent UNIX s_fpack location
|
2017-12-26 08:01:40 +00:00
|
|
|
|
string s_fpack = StringHandlers.CToString(coherent_string, Encoding);
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2017-12-20 17:26:28 +00:00
|
|
|
|
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)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2014-04-14 01:14:20 +00:00
|
|
|
|
BigEndianBitConverter.IsLittleEndian = true; // Coherent is in PDP endianness, use helper for that
|
2018-06-22 08:08:38 +01:00
|
|
|
|
coherent = true;
|
|
|
|
|
|
start = i;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// Now try to identify 7th edition
|
2018-06-22 08:08:38 +01:00
|
|
|
|
uint s_fsize = BitConverter.ToUInt32(sb_sector, 0x002);
|
|
|
|
|
|
ushort s_nfree = BitConverter.ToUInt16(sb_sector, 0x006);
|
2017-12-22 08:43:22 +00:00
|
|
|
|
ushort s_ninode = BitConverter.ToUInt16(sb_sector, 0x0D0);
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if(s_fsize <= 0 || s_fsize >= 0xFFFFFFFF || s_nfree <= 0 || s_nfree >= 0xFFFF || s_ninode <= 0 ||
|
2017-12-21 06:06:19 +00:00
|
|
|
|
s_ninode >= 0xFFFF) continue;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2017-12-21 06:06:19 +00:00
|
|
|
|
if((s_fsize & 0xFF) == 0x00 && (s_nfree & 0xFF) == 0x00 && (s_ninode & 0xFF) == 0x00)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Byteswap
|
2018-06-22 08:08:38 +01:00
|
|
|
|
s_fsize = ((s_fsize & 0xFF) << 24) + ((s_fsize & 0xFF00) << 8) + ((s_fsize & 0xFF0000) >> 8) +
|
2017-12-21 06:06:19 +00:00
|
|
|
|
((s_fsize & 0xFF000000) >> 24);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
s_nfree = (ushort)(s_nfree >> 8);
|
2017-12-21 06:06:19 +00:00
|
|
|
|
s_ninode = (ushort)(s_ninode >> 8);
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
2017-12-21 06:06:19 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if((s_fsize & 0xFF000000) != 0x00 || (s_nfree & 0xFF00) != 0x00 ||
|
|
|
|
|
|
(s_ninode & 0xFF00) != 0x00) continue;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
|
|
|
|
|
|
if(s_fsize >= V7_MAXSIZE || s_nfree >= V7_NICFREE || s_ninode >= V7_NICINOD) continue;
|
|
|
|
|
|
|
2017-12-26 06:05:12 +00:00
|
|
|
|
if(s_fsize * 1024 != (partition.End - partition.Start) * imagePlugin.Info.SectorSize &&
|
2018-06-22 08:08:38 +01:00
|
|
|
|
s_fsize * 512 != (partition.End - partition.Start) * imagePlugin.Info.SectorSize) continue;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
sys7th = true;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
BigEndianBitConverter.IsLittleEndian = true;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
start = i;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
break;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
|
|
|
|
|
if(!sys7th && !sysv && !coherent && !xenix && !xenix3) return;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType = new FileSystemType();
|
2015-12-05 17:10:27 +00:00
|
|
|
|
|
2016-08-03 02:57:08 +01:00
|
|
|
|
if(xenix || xenix3)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
byte[] xenix_strings = new byte[6];
|
|
|
|
|
|
XenixSuperBlock xnx_sb = new XenixSuperBlock();
|
2017-07-19 16:37:11 +01:00
|
|
|
|
sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors);
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2016-08-03 02:57:08 +01:00
|
|
|
|
if(xenix3)
|
2016-08-01 00:02:14 +01:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
xnx_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8);
|
|
|
|
|
|
xnx_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
xnx_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AC);
|
|
|
|
|
|
xnx_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AE);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x1B0, xenix_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
xnx_sb.s_fname = StringHandlers.CToString(xenix_strings, Encoding);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x1B6, xenix_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
xnx_sb.s_fpack = StringHandlers.CToString(xenix_strings, Encoding);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
xnx_sb.s_clean = sb_sector[0x1BC];
|
|
|
|
|
|
xnx_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F0);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
xnx_sb.s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x1F4);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
xnx_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x270);
|
|
|
|
|
|
xnx_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x272);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
xnx_sb.s_dinfo0 = BigEndianBitConverter.ToUInt16(sb_sector, 0x274);
|
|
|
|
|
|
xnx_sb.s_dinfo1 = BigEndianBitConverter.ToUInt16(sb_sector, 0x276);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x278, xenix_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
xnx_sb.s_fname = StringHandlers.CToString(xenix_strings, Encoding);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x27E, xenix_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
xnx_sb.s_fpack = StringHandlers.CToString(xenix_strings, Encoding);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
xnx_sb.s_clean = sb_sector[0x284];
|
|
|
|
|
|
xnx_sb.s_magic = BigEndianBitConverter.ToUInt32(sb_sector, 0x3F8);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
xnx_sb.s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x3FC);
|
2016-08-01 00:02:14 +01:00
|
|
|
|
}
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2016-07-28 22:25:26 +01:00
|
|
|
|
uint bs = 512;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendLine("XENIX filesystem");
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.Type = "XENIX fs";
|
2016-04-19 02:11:47 +01:00
|
|
|
|
switch(xnx_sb.s_type)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
sb.AppendLine("512 bytes per block");
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ClusterSize = 512;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
sb.AppendLine("1024 bytes per block");
|
2018-06-22 08:08:38 +01:00
|
|
|
|
bs = 1024;
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ClusterSize = 1024;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
sb.AppendLine("2048 bytes per block");
|
2018-06-22 08:08:38 +01:00
|
|
|
|
bs = 2048;
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ClusterSize = 2048;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
sb.AppendFormat("Unknown s_type value: 0x{0:X8}", xnx_sb.s_type).AppendLine();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2017-12-26 06:05:12 +00:00
|
|
|
|
if(imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 ||
|
|
|
|
|
|
imagePlugin.Info.SectorSize == 2448)
|
2014-04-14 01:14:20 +00:00
|
|
|
|
{
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(bs != 2048)
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sb
|
2018-06-22 08:08:38 +01:00
|
|
|
|
.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector",
|
|
|
|
|
|
bs, 2048).AppendLine();
|
2014-04-14 01:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2017-12-26 06:05:12 +00:00
|
|
|
|
if(bs != imagePlugin.Info.SectorSize)
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sb
|
2018-06-22 08:08:38 +01:00
|
|
|
|
.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector",
|
|
|
|
|
|
bs, imagePlugin.Info.SectorSize).AppendLine();
|
2014-04-14 01:14:20 +00:00
|
|
|
|
}
|
2018-06-22 08:08:38 +01:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("{0} zones on volume ({1} bytes)", xnx_sb.s_fsize, xnx_sb.s_fsize * bs).AppendLine();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
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();
|
2014-04-14 02:29:13 +00:00
|
|
|
|
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();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
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");
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if(xnx_sb.s_fmod > 0) sb.AppendLine("Superblock is being modified");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(xnx_sb.s_ronly > 0) sb.AppendLine("Volume is mounted read-only");
|
2017-12-23 03:59:48 +00:00
|
|
|
|
sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixToDateTime(xnx_sb.s_time))
|
2017-12-19 20:33:03 +00:00
|
|
|
|
.AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(xnx_sb.s_time != 0)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(xnx_sb.s_time);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ModificationDateSpecified = true;
|
2015-12-06 05:09:31 +00:00
|
|
|
|
}
|
2018-06-22 08:08:38 +01:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("Volume name: {0}", xnx_sb.s_fname).AppendLine();
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.VolumeName = xnx_sb.s_fname;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("Pack name: {0}", xnx_sb.s_fpack).AppendLine();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(xnx_sb.s_clean == 0x46) sb.AppendLine("Volume is clean");
|
2014-04-14 02:29:13 +00:00
|
|
|
|
else
|
2015-12-05 17:10:27 +00:00
|
|
|
|
{
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendLine("Volume is dirty");
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.Dirty = true;
|
2015-12-05 17:10:27 +00:00
|
|
|
|
}
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(sysv)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2017-07-19 16:37:11 +01:00
|
|
|
|
sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors);
|
2014-04-14 01:14:20 +00:00
|
|
|
|
byte[] sysv_strings = new byte[6];
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2017-12-22 08:43:22 +00:00
|
|
|
|
SystemVRelease4SuperBlock sysv_sb = new SystemVRelease4SuperBlock
|
|
|
|
|
|
{
|
|
|
|
|
|
s_type = BigEndianBitConverter.ToUInt32(sb_sector, 0x1FC + offset)
|
|
|
|
|
|
};
|
2016-07-28 22:25:26 +01:00
|
|
|
|
uint bs = 512;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
switch(sysv_sb.s_type)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
|
|
|
|
|
case 1:
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ClusterSize = 512;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
2018-06-22 08:08:38 +01:00
|
|
|
|
bs = 1024;
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ClusterSize = 1024;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
2018-06-22 08:08:38 +01:00
|
|
|
|
bs = 2048;
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ClusterSize = 2048;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
sb.AppendFormat("Unknown s_type value: 0x{0:X8}", sysv_sb.s_type).AppendLine();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2017-11-08 17:04:15 +00:00
|
|
|
|
sysv_sb.s_fsize = BigEndianBitConverter.ToUInt32(sb_sector, 0x002 + offset);
|
|
|
|
|
|
|
2017-12-22 08:43:22 +00:00
|
|
|
|
bool sysvr4 = sysv_sb.s_fsize * bs <= 0 || sysv_sb.s_fsize * bs != partition.Size;
|
2017-11-08 17:04:15 +00:00
|
|
|
|
|
|
|
|
|
|
if(sysvr4)
|
2014-04-14 01:14:20 +00:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2017-11-08 17:04:15 +00:00
|
|
|
|
sysv_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8 + offset);
|
|
|
|
|
|
sysv_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA + offset);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2017-11-08 17:04:15 +00:00
|
|
|
|
Array.Copy(sb_sector, 0x1B6 + offset, sysv_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
sysv_sb.s_fname = StringHandlers.CToString(sysv_strings, Encoding);
|
2017-11-08 17:04:15 +00:00
|
|
|
|
Array.Copy(sb_sector, 0x1BC + offset, sysv_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
sysv_sb.s_fpack = StringHandlers.CToString(sysv_strings, Encoding);
|
2017-11-08 17:04:15 +00:00
|
|
|
|
sb.AppendLine("System V Release 4 filesystem");
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.Type = "SVR4 fs";
|
2014-04-14 01:14:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2017-11-08 17:04:15 +00:00
|
|
|
|
sysv_sb.s_cylblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A2 + offset);
|
|
|
|
|
|
sysv_sb.s_gapblks = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A4 + offset);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2017-11-08 17:04:15 +00:00
|
|
|
|
Array.Copy(sb_sector, 0x1B0 + offset, sysv_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
sysv_sb.s_fname = StringHandlers.CToString(sysv_strings, Encoding);
|
2017-11-08 17:04:15 +00:00
|
|
|
|
Array.Copy(sb_sector, 0x1B6 + offset, sysv_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
sysv_sb.s_fpack = StringHandlers.CToString(sysv_strings, Encoding);
|
2017-11-08 17:04:15 +00:00
|
|
|
|
sb.AppendLine("System V Release 2 filesystem");
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.Type = "SVR2 fs";
|
2014-04-14 01:14:20 +00:00
|
|
|
|
}
|
2018-06-22 08:08:38 +01:00
|
|
|
|
|
2017-11-08 17:04:15 +00:00
|
|
|
|
sb.AppendFormat("{0} bytes per block", bs).AppendLine();
|
|
|
|
|
|
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.Clusters = sysv_sb.s_fsize;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("{0} zones on volume ({1} bytes)", sysv_sb.s_fsize, sysv_sb.s_fsize * bs).AppendLine();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
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();
|
2014-04-14 02:29:13 +00:00
|
|
|
|
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();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
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");
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if(sysv_sb.s_fmod > 0) sb.AppendLine("Superblock is being modified");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(sysv_sb.s_ronly > 0) sb.AppendLine("Volume is mounted read-only");
|
2017-12-23 03:59:48 +00:00
|
|
|
|
sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixUnsignedToDateTime(sysv_sb.s_time))
|
2017-12-19 20:33:03 +00:00
|
|
|
|
.AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(sysv_sb.s_time != 0)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(sysv_sb.s_time);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ModificationDateSpecified = true;
|
2015-12-06 05:09:31 +00:00
|
|
|
|
}
|
2018-06-22 08:08:38 +01:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("Volume name: {0}", sysv_sb.s_fname).AppendLine();
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.VolumeName = sysv_sb.s_fname;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("Pack name: {0}", sysv_sb.s_fpack).AppendLine();
|
2017-12-20 17:26:28 +00:00
|
|
|
|
if(sysv_sb.s_state == 0x7C269D38 - sysv_sb.s_time) sb.AppendLine("Volume is clean");
|
2014-04-14 02:29:13 +00:00
|
|
|
|
else
|
2015-12-05 17:10:27 +00:00
|
|
|
|
{
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendLine("Volume is dirty");
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.Dirty = true;
|
2015-12-05 17:10:27 +00:00
|
|
|
|
}
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(coherent)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2017-07-19 16:37:11 +01:00
|
|
|
|
sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
CoherentSuperBlock coh_sb = new CoherentSuperBlock();
|
|
|
|
|
|
byte[] coh_strings = new byte[6];
|
2014-04-14 01:14:20 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2017-09-17 05:49:22 +01:00
|
|
|
|
coh_sb.s_ninode = BitConverter.ToUInt16(sb_sector, 0x108);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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));
|
2017-09-17 05:49:22 +01:00
|
|
|
|
coh_sb.s_tinode = BitConverter.ToUInt16(sb_sector, 0x1DE);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
coh_sb.s_int_m = BitConverter.ToUInt16(sb_sector, 0x1E0);
|
|
|
|
|
|
coh_sb.s_int_n = BitConverter.ToUInt16(sb_sector, 0x1E2);
|
2017-09-17 05:49:22 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x1E4, coh_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
coh_sb.s_fname = StringHandlers.CToString(coh_strings, Encoding);
|
2017-09-17 05:49:22 +01:00
|
|
|
|
Array.Copy(sb_sector, 0x1EA, coh_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
coh_sb.s_fpack = StringHandlers.CToString(coh_strings, Encoding);
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
XmlFsType.Type = "Coherent fs";
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ClusterSize = 512;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
XmlFsType.Clusters = coh_sb.s_fsize;
|
2015-12-05 17:10:27 +00:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendLine("Coherent UNIX filesystem");
|
2017-12-26 06:05:12 +00:00
|
|
|
|
if(imagePlugin.Info.SectorSize != 512)
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sb
|
2018-06-22 08:08:38 +01:00
|
|
|
|
.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector",
|
|
|
|
|
|
512, 2048).AppendLine();
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("{0} zones on volume ({1} bytes)", coh_sb.s_fsize, coh_sb.s_fsize * 512).AppendLine();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
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();
|
2014-04-14 02:29:13 +00:00
|
|
|
|
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();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
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");
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if(coh_sb.s_fmod > 0) sb.AppendLine("Superblock is being modified");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(coh_sb.s_ronly > 0) sb.AppendLine("Volume is mounted read-only");
|
2017-12-23 03:59:48 +00:00
|
|
|
|
sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixUnsignedToDateTime(coh_sb.s_time))
|
2017-12-19 20:33:03 +00:00
|
|
|
|
.AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(coh_sb.s_time != 0)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(coh_sb.s_time);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ModificationDateSpecified = true;
|
2015-12-06 05:09:31 +00:00
|
|
|
|
}
|
2018-06-22 08:08:38 +01:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("Volume name: {0}", coh_sb.s_fname).AppendLine();
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.VolumeName = coh_sb.s_fname;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("Pack name: {0}", coh_sb.s_fpack).AppendLine();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(sys7th)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
{
|
2017-07-19 16:37:11 +01:00
|
|
|
|
sb_sector = imagePlugin.ReadSectors((ulong)start + partition.Start, sb_size_in_sectors);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
UNIX7thEditionSuperBlock v7_sb = new UNIX7thEditionSuperBlock();
|
|
|
|
|
|
byte[] sys7_strings = new byte[6];
|
2014-04-14 01:14:20 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2014-04-14 01:14:20 +00:00
|
|
|
|
v7_sb.s_ninode = BigEndianBitConverter.ToUInt16(sb_sector, 0x0D0);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
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);
|
2014-04-14 01:14:20 +00:00
|
|
|
|
v7_sb.s_tinode = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A6);
|
2018-06-22 08:08:38 +01:00
|
|
|
|
v7_sb.s_int_m = BigEndianBitConverter.ToUInt16(sb_sector, 0x1A8);
|
|
|
|
|
|
v7_sb.s_int_n = BigEndianBitConverter.ToUInt16(sb_sector, 0x1AA);
|
2014-04-14 01:14:20 +00:00
|
|
|
|
Array.Copy(sb_sector, 0x1AC, sys7_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
v7_sb.s_fname = StringHandlers.CToString(sys7_strings, Encoding);
|
2014-04-14 01:14:20 +00:00
|
|
|
|
Array.Copy(sb_sector, 0x1B2, sys7_strings, 0, 6);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
v7_sb.s_fpack = StringHandlers.CToString(sys7_strings, Encoding);
|
2012-08-07 06:20:13 +00:00
|
|
|
|
|
2018-06-22 08:08:38 +01:00
|
|
|
|
XmlFsType.Type = "UNIX 7th Edition fs";
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ClusterSize = 512;
|
2018-06-22 08:08:38 +01:00
|
|
|
|
XmlFsType.Clusters = v7_sb.s_fsize;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendLine("UNIX 7th Edition filesystem");
|
2017-12-26 06:05:12 +00:00
|
|
|
|
if(imagePlugin.Info.SectorSize != 512)
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sb
|
2018-06-22 08:08:38 +01:00
|
|
|
|
.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector",
|
|
|
|
|
|
512, 2048).AppendLine();
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("{0} zones on volume ({1} bytes)", v7_sb.s_fsize, v7_sb.s_fsize * 512).AppendLine();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
sb.AppendFormat("{0} free zones on volume ({1} bytes)", v7_sb.s_tfree, v7_sb.s_tfree * 512)
|
|
|
|
|
|
.AppendLine();
|
2014-04-14 02:29:13 +00:00
|
|
|
|
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();
|
2017-12-19 20:33:03 +00:00
|
|
|
|
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");
|
2018-06-22 08:08:38 +01:00
|
|
|
|
if(v7_sb.s_fmod > 0) sb.AppendLine("Superblock is being modified");
|
2017-12-19 20:33:03 +00:00
|
|
|
|
if(v7_sb.s_ronly > 0) sb.AppendLine("Volume is mounted read-only");
|
2017-12-23 03:59:48 +00:00
|
|
|
|
sb.AppendFormat("Superblock last updated on {0}", DateHandlers.UnixUnsignedToDateTime(v7_sb.s_time))
|
2017-12-19 20:33:03 +00:00
|
|
|
|
.AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(v7_sb.s_time != 0)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
2018-06-22 08:08:38 +01:00
|
|
|
|
XmlFsType.ModificationDate = DateHandlers.UnixUnsignedToDateTime(v7_sb.s_time);
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.ModificationDateSpecified = true;
|
2015-12-06 05:09:31 +00:00
|
|
|
|
}
|
2018-06-22 08:08:38 +01:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("Volume name: {0}", v7_sb.s_fname).AppendLine();
|
2017-12-26 08:01:40 +00:00
|
|
|
|
XmlFsType.VolumeName = v7_sb.s_fname;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
sb.AppendFormat("Pack name: {0}", v7_sb.s_fpack).AppendLine();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
information = sb.ToString();
|
2014-04-14 01:14:20 +00:00
|
|
|
|
|
|
|
|
|
|
BigEndianBitConverter.IsLittleEndian = false; // Return to default (bigendian)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-08-01 00:02:14 +01:00
|
|
|
|
// Old XENIX use different offsets
|
2014-04-14 02:29:13 +00:00
|
|
|
|
struct XenixSuperBlock
|
|
|
|
|
|
{
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x000, index of first data zone</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_isize;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x002, total number of zones of this volume</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_fsize;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the start of the free block list:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x006, blocks in s_free, <=100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_nfree;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x008, 100 entries, 50 entries for Xenix 3, first free block list chunk</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint[] s_free;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the cache of free inodes:
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x198 (0xD0), number of inodes in s_inode, <= 100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_ninode;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x19A (0xD2), 100 entries, some free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort[] s_inode;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x262 (0x19A), free block list manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_flock;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x263 (0x19B), inode cache manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ilock;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x264 (0x19C), superblock modification flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_fmod;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x265 (0x19D), read-only mounted flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ronly;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x266 (0x19E), time of last superblock update</summary>
|
|
|
|
|
|
public int s_time;
|
|
|
|
|
|
/// <summary>0x26A (0x1A2), total number of free zones</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_tfree;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x26E (0x1A6), total number of free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_tinode;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x270 (0x1A8), blocks per cylinder</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_cylblks;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x272 (0x1AA), blocks per gap</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_gapblks;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x274 (0x1AC), device information ??</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_dinfo0;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x276 (0x1AE), device information ??</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_dinfo1;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x278 (0x1B0), 6 bytes, volume name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fname;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x27E (0x1B6), 6 bytes, pack name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fpack;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x284 (0x1BC), 0x46 if volume is clean</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_clean;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x285 (0x1BD), 371 bytes, 51 bytes for Xenix 3</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte[] s_fill;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x3F8 (0x1F0), magic</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_magic;
|
2016-08-03 02:57:08 +01:00
|
|
|
|
/// <summary>0x3FC (0x1F4), filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk, 3 = 2048 bytes/blk)</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_type;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct SystemVRelease4SuperBlock
|
|
|
|
|
|
{
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x000, index of first data zone</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_isize;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x002, padding</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_pad0;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x004, total number of zones of this volume</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_fsize;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the start of the free block list:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x008, blocks in s_free, <=100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_nfree;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x00A, padding</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_pad1;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x00C, 50 entries, first free block list chunk</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint[] s_free;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the cache of free inodes:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x0D4, number of inodes in s_inode, <= 100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_ninode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x0D6, padding</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_pad2;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x0D8, 100 entries, some free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort[] s_inode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A0, free block list manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_flock;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A1, inode cache manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ilock;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A2, superblock modification flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_fmod;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A3, read-only mounted flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ronly;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A4, time of last superblock update</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_time;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A8, blocks per cylinder</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_cylblks;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1AA, blocks per gap</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_gapblks;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1AC, device information ??</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_dinfo0;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1AE, device information ??</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_dinfo1;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1B0, total number of free zones</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_tfree;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1B4, total number of free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_tinode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1B6, padding</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_pad3;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1B8, 6 bytes, volume name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fname;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1BE, 6 bytes, pack name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fpack;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1C4, 48 bytes</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte[] s_fill;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1F4, if s_state == (0x7C269D38 - s_time) then filesystem is clean</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_state;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1F8, magic</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_magic;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1FC, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk)</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_type;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct SystemVRelease2SuperBlock
|
|
|
|
|
|
{
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x000, index of first data zone</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_isize;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x002, total number of zones of this volume</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_fsize;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the start of the free block list:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x006, blocks in s_free, <=100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_nfree;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x008, 50 entries, first free block list chunk</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint[] s_free;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the cache of free inodes:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x0D0, number of inodes in s_inode, <= 100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_ninode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x0D2, 100 entries, some free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort[] s_inode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19A, free block list manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_flock;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19B, inode cache manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ilock;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19C, superblock modification flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_fmod;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19D, read-only mounted flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ronly;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19E, time of last superblock update</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_time;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A2, blocks per cylinder</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_cylblks;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A4, blocks per gap</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_gapblks;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A6, device information ??</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_dinfo0;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A8, device information ??</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_dinfo1;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1AA, total number of free zones</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_tfree;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1AE, total number of free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_tinode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1B0, 6 bytes, volume name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fname;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1B6, 6 bytes, pack name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fpack;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1BC, 56 bytes</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte[] s_fill;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1F4, if s_state == (0x7C269D38 - s_time) then filesystem is clean</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_state;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1F8, magic</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_magic;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1FC, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk)</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_type;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct UNIX7thEditionSuperBlock
|
|
|
|
|
|
{
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x000, index of first data zone</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_isize;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x002, total number of zones of this volume</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_fsize;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the start of the free block list:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x006, blocks in s_free, <=100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_nfree;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x008, 50 entries, first free block list chunk</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint[] s_free;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the cache of free inodes:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x0D0, number of inodes in s_inode, <= 100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_ninode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x0D2, 100 entries, some free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort[] s_inode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19A, free block list manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_flock;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19B, inode cache manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ilock;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19C, superblock modification flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_fmod;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19D, read-only mounted flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ronly;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x19E, time of last superblock update</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_time;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A2, total number of free zones</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_tfree;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A6, total number of free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_tinode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1A8, interleave factor</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_int_m;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1AA, interleave factor</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_int_n;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1AC, 6 bytes, volume name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fname;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1B2, 6 bytes, pack name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fpack;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct CoherentSuperBlock
|
|
|
|
|
|
{
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x000, index of first data zone</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_isize;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x002, total number of zones of this volume</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_fsize;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the start of the free block list:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x006, blocks in s_free, <=100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_nfree;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x008, 64 entries, first free block list chunk</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint[] s_free;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// the cache of free inodes:
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x108, number of inodes in s_inode, <= 100</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_ninode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x10A, 100 entries, some free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort[] s_inode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1D2, free block list manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_flock;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1D3, inode cache manipulation lock</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ilock;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1D4, superblock modification flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_fmod;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1D5, read-only mounted flag</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public byte s_ronly;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1D6, time of last superblock update</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_time;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1DE, total number of free zones</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_tfree;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1E2, total number of free inodes</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_tinode;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1E4, interleave factor</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_int_m;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1E6, interleave factor</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public ushort s_int_n;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1E8, 6 bytes, volume name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fname;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1EE, 6 bytes, pack name</summary>
|
2014-04-14 02:29:13 +00:00
|
|
|
|
public string s_fpack;
|
2015-12-06 07:18:36 +00:00
|
|
|
|
/// <summary>0x1F4, zero-filled</summary>
|
2016-07-28 22:25:26 +01:00
|
|
|
|
public uint s_unique;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-04-14 01:14:20 +00:00
|
|
|
|
}
|