* FileSystemIDandChk/BigEndianBitConverter.cs:

Added BitConverter for BigEndian

	* FileSystemIDandChk/FileSystemIDandChk.csproj:
	  FileSystemIDandChk/BigEndianBitConverter.cs


	* FileSystemIDandChk/ImagePlugins/CDRWin.cs:
	  Corrected parsing
	Implemented all ImagePlugin methods

	* FileSystemIDandChk/ImagePlugins/ImagePlugin.cs:
	  Used document auto formatting

	* FileSystemIDandChk/Main.cs:
	* FileSystemIDandChk/Plugins/FAT.cs:
	* FileSystemIDandChk/Plugins/BFS.cs:
	* FileSystemIDandChk/Plugins/FFS.cs:
	* FileSystemIDandChk/Plugins/ODS.cs:
	* FileSystemIDandChk/Plugins/HPFS.cs:
	* FileSystemIDandChk/Plugins/SysV.cs:
	* FileSystemIDandChk/Plugins/NTFS.cs:
	* FileSystemIDandChk/Plugins/extFS.cs:
	* FileSystemIDandChk/Plugins/Opera.cs:
	* FileSystemIDandChk/Plugins/ext2FS.cs:
	* FileSystemIDandChk/Plugins/Plugin.cs:
	* FileSystemIDandChk/Plugins/UNIXBFS.cs:
	* FileSystemIDandChk/Plugins/SolarFS.cs:
	* FileSystemIDandChk/PartPlugins/MBR.cs:
	* FileSystemIDandChk/Plugins/MinixFS.cs:
	* FileSystemIDandChk/Plugins/ISO9660.cs:
	* FileSystemIDandChk/Plugins/PCEngine.cs:
	* FileSystemIDandChk/Plugins/AppleHFS.cs:
	* FileSystemIDandChk/PartPlugins/NeXT.cs:
	* FileSystemIDandChk/Plugins/AppleMFS.cs:
	* FileSystemIDandChk/PartPlugins/AppleMap.cs:
	* FileSystemIDandChk/Plugins/AppleHFSPlus.cs:
	  Added support for disc image plugins

	* FileSystemIDandChk/PartPlugins/PartPlugin.cs:
	  Added support for disc image plugins
	Added start sector and length in sectors to partitions

	* FileSystemIDandChk/Plugins/Symbian.cs:
	  Commented til code is adapted for disc image plugins

git-svn-id: svn://claunia.com/FileSystemIDandChk@27 17725271-3d32-4980-a8cb-9ff532f270ba
This commit is contained in:
2014-04-14 01:14:20 +00:00
parent 0abc5476b5
commit 32bb28e8c2
30 changed files with 5832 additions and 3656 deletions

View File

@@ -4,7 +4,6 @@ using System.Text;
using FileSystemIDandChk;
// Using information from Linux kernel headers
namespace FileSystemIDandChk.Plugins
{
public class FFSPlugin : Plugin
@@ -15,42 +14,48 @@ namespace FileSystemIDandChk.Plugins
base.PluginUUID = new Guid("CC90D342-05DB-48A8-988C-C1FE000034A3");
}
public override bool Identify(FileStream fileStream, long offset)
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
{
UInt32 magic;
BinaryReader br = new BinaryReader(fileStream);
uint sb_size_in_sectors;
byte[] ufs_sb_sectors;
if(fileStream.Length > (offset + sb_start_floppy + 0x055C))
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 ||imagePlugin.GetSectorSize() == 2448)
sb_size_in_sectors = block_size / 2048;
else
sb_size_in_sectors = block_size / imagePlugin.GetSectorSize();
if(imagePlugin.GetSectors() > (partitionOffset + sb_start_floppy*sb_size_in_sectors + sb_size_in_sectors))
{
br.BaseStream.Seek(offset + sb_start_floppy + 0x055C, SeekOrigin.Begin);
magic = br.ReadUInt32();
ufs_sb_sectors = imagePlugin.ReadSectors(partitionOffset + sb_start_floppy * sb_size_in_sectors, sb_size_in_sectors);
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
return true;
}
if(fileStream.Length > (offset + sb_start_ufs1 + 0x055C))
if(imagePlugin.GetSectors() > (partitionOffset + sb_start_ufs1*sb_size_in_sectors + sb_size_in_sectors))
{
br.BaseStream.Seek(offset + sb_start_ufs1 + 0x055C, SeekOrigin.Begin);
magic = br.ReadUInt32();
ufs_sb_sectors = imagePlugin.ReadSectors(partitionOffset + sb_start_ufs1 * sb_size_in_sectors, sb_size_in_sectors);
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
return true;
}
if(fileStream.Length > (offset + sb_start_ufs2 + 0x055C))
if(imagePlugin.GetSectors() > (partitionOffset + sb_start_ufs2*sb_size_in_sectors + sb_size_in_sectors))
{
br.BaseStream.Seek(offset + sb_start_ufs2 + 0x055C, SeekOrigin.Begin);
magic = br.ReadUInt32();
ufs_sb_sectors = imagePlugin.ReadSectors(partitionOffset + sb_start_ufs2 * sb_size_in_sectors, sb_size_in_sectors);
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
return true;
}
if(fileStream.Length > (offset + sb_start_piggy + 0x055C))
if(imagePlugin.GetSectors() > (partitionOffset + sb_start_piggy*sb_size_in_sectors + sb_size_in_sectors))
{
br.BaseStream.Seek(offset + sb_start_piggy + 0x055C, SeekOrigin.Begin);
magic = br.ReadUInt32();
ufs_sb_sectors = imagePlugin.ReadSectors(partitionOffset + sb_start_piggy * sb_size_in_sectors, sb_size_in_sectors);
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
return true;
@@ -59,14 +64,15 @@ namespace FileSystemIDandChk.Plugins
return false;
}
public override void GetInformation (FileStream fileStream, long offset, out string information)
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
{
information = "";
StringBuilder sbInformation = new StringBuilder();
UInt32 magic = 0;
BinaryReader br = new BinaryReader(fileStream);
long sb_offset = offset;
uint sb_size_in_sectors;
byte[] ufs_sb_sectors;
ulong sb_offset = partitionOffset;
bool fs_type_42bsd = false;
bool fs_type_43bsd = false;
bool fs_type_44bsd = false;
@@ -74,47 +80,52 @@ namespace FileSystemIDandChk.Plugins
bool fs_type_ufs2 = false;
bool fs_type_sun = false;
bool fs_type_sun86 = false;
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 ||imagePlugin.GetSectorSize() == 2448)
sb_size_in_sectors = block_size / 2048;
else
sb_size_in_sectors = block_size / imagePlugin.GetSectorSize();
if(fileStream.Length > (offset + sb_start_floppy + 0x055C) && magic == 0)
if(imagePlugin.GetSectors() > (partitionOffset + sb_start_floppy*sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
{
br.BaseStream.Seek(offset + sb_start_floppy + 0x055C, SeekOrigin.Begin);
magic = br.ReadUInt32();
ufs_sb_sectors = imagePlugin.ReadSectors(partitionOffset + sb_start_floppy * sb_size_in_sectors, sb_size_in_sectors);
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
sb_offset = offset + sb_start_floppy;
sb_offset = partitionOffset + sb_start_floppy * sb_size_in_sectors;
else
magic = 0;
}
if(fileStream.Length > (offset + sb_start_ufs1 + 0x055C) && magic == 0)
if(imagePlugin.GetSectors() > (partitionOffset + sb_start_ufs1*sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
{
br.BaseStream.Seek(offset + sb_start_ufs1 + 0x055C, SeekOrigin.Begin);
magic = br.ReadUInt32();
ufs_sb_sectors = imagePlugin.ReadSectors(partitionOffset + sb_start_ufs1 * sb_size_in_sectors, sb_size_in_sectors);
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
sb_offset = offset + sb_start_ufs1;
sb_offset = partitionOffset + sb_start_ufs1 * sb_size_in_sectors;
else
magic = 0;
}
if(fileStream.Length > (offset + sb_start_ufs2 + 0x055C) && magic == 0)
if(imagePlugin.GetSectors() > (partitionOffset + sb_start_ufs2*sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
{
br.BaseStream.Seek(offset + sb_start_ufs2 + 0x055C, SeekOrigin.Begin);
magic = br.ReadUInt32();
ufs_sb_sectors = imagePlugin.ReadSectors(partitionOffset + sb_start_ufs2 * sb_size_in_sectors, sb_size_in_sectors);
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
sb_offset = offset + sb_start_ufs2;
sb_offset = partitionOffset + sb_start_ufs2 * sb_size_in_sectors;
else
magic = 0;
}
if(fileStream.Length > (offset + sb_start_piggy + 0x055C) && magic == 0)
if(imagePlugin.GetSectors() > (partitionOffset + sb_start_piggy*sb_size_in_sectors + sb_size_in_sectors) && magic == 0)
{
br.BaseStream.Seek(offset + sb_start_piggy + 0x055C, SeekOrigin.Begin);
magic = br.ReadUInt32();
ufs_sb_sectors = imagePlugin.ReadSectors(partitionOffset + sb_start_piggy * sb_size_in_sectors, sb_size_in_sectors);
magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if (magic == UFS_MAGIC || magic == UFS_MAGIC_BW || magic == UFS2_MAGIC || magic == UFS_CIGAM || magic == UFS_BAD_MAGIC)
sb_offset = offset + sb_start_piggy;
sb_offset = partitionOffset + sb_start_piggy * sb_size_in_sectors;
else
magic = 0;
}
@@ -147,196 +158,191 @@ namespace FileSystemIDandChk.Plugins
break;
}
EndianAwareBinaryReader eabr;
if(magic == UFS_CIGAM)
eabr = new EndianAwareBinaryReader(fileStream, false); // Big-endian UFS
if (magic == UFS_CIGAM)
BigEndianBitConverter.IsLittleEndian = false; // Big-endian UFS
else
eabr = new EndianAwareBinaryReader(fileStream, true); // Little-endian UFS
BigEndianBitConverter.IsLittleEndian = true; // Little-endian UFS
// Are there any other cases to detect big-endian UFS?
// Fun with seeking follows on superblock reading!
UFSSuperBlock ufs_sb = new UFSSuperBlock();
byte[] strings_b;
eabr.BaseStream.Seek(sb_offset, SeekOrigin.Begin);
ufs_sb_sectors = imagePlugin.ReadSectors(sb_offset, sb_size_in_sectors);
ufs_sb.fs_link_42bsd = eabr.ReadUInt32();
ufs_sb.fs_link_42bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0000); // 0x0000
ufs_sb.fs_state_sun = ufs_sb.fs_link_42bsd;
ufs_sb.fs_rlink = eabr.ReadUInt32(); // 0x0004 UNUSED
ufs_sb.fs_sblkno = eabr.ReadUInt32(); // 0x0008 addr of super-block in filesys
ufs_sb.fs_cblkno = eabr.ReadUInt32(); // 0x000C offset of cyl-block in filesys
ufs_sb.fs_iblkno = eabr.ReadUInt32(); // 0x0010 offset of inode-blocks in filesys
ufs_sb.fs_dblkno = eabr.ReadUInt32(); // 0x0014 offset of first data after cg
ufs_sb.fs_cgoffset = eabr.ReadUInt32(); // 0x0018 cylinder group offset in cylinder
ufs_sb.fs_cgmask = eabr.ReadUInt32(); // 0x001C used to calc mod fs_ntrak
ufs_sb.fs_time_t = eabr.ReadUInt32(); // 0x0020 last time written -- time_t
ufs_sb.fs_size = eabr.ReadUInt32(); // 0x0024 number of blocks in fs
ufs_sb.fs_dsize = eabr.ReadUInt32(); // 0x0028 number of data blocks in fs
ufs_sb.fs_ncg = eabr.ReadUInt32(); // 0x002C number of cylinder groups
ufs_sb.fs_bsize = eabr.ReadUInt32(); // 0x0030 size of basic blocks in fs
ufs_sb.fs_fsize = eabr.ReadUInt32(); // 0x0034 size of frag blocks in fs
ufs_sb.fs_frag = eabr.ReadUInt32(); // 0x0038 number of frags in a block in fs
ufs_sb.fs_rlink = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0004); // 0x0004 UNUSED
ufs_sb.fs_sblkno = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0008); // 0x0008 addr of super-block in filesys
ufs_sb.fs_cblkno = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x000C); // 0x000C offset of cyl-block in filesys
ufs_sb.fs_iblkno = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0010); // 0x0010 offset of inode-blocks in filesys
ufs_sb.fs_dblkno = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0014); // 0x0014 offset of first data after cg
ufs_sb.fs_cgoffset = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0018); // 0x0018 cylinder group offset in cylinder
ufs_sb.fs_cgmask = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x001C); // 0x001C used to calc mod fs_ntrak
ufs_sb.fs_time_t = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0020); // 0x0020 last time written -- time_t
ufs_sb.fs_size = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0024); // 0x0024 number of blocks in fs
ufs_sb.fs_dsize = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0028); // 0x0028 number of data blocks in fs
ufs_sb.fs_ncg = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x002C); // 0x002C number of cylinder groups
ufs_sb.fs_bsize = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0030); // 0x0030 size of basic blocks in fs
ufs_sb.fs_fsize = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0034); // 0x0034 size of frag blocks in fs
ufs_sb.fs_frag = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0038); // 0x0038 number of frags in a block in fs
// these are configuration parameters
ufs_sb.fs_minfree = eabr.ReadUInt32(); // 0x003C minimum percentage of free blocks
ufs_sb.fs_rotdelay = eabr.ReadUInt32(); // 0x0040 num of ms for optimal next block
ufs_sb.fs_rps = eabr.ReadUInt32(); // 0x0044 disk revolutions per second
ufs_sb.fs_minfree = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x003C); // 0x003C minimum percentage of free blocks
ufs_sb.fs_rotdelay = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0040); // 0x0040 num of ms for optimal next block
ufs_sb.fs_rps = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0044); // 0x0044 disk revolutions per second
// these fields can be computed from the others
ufs_sb.fs_bmask = eabr.ReadUInt32(); // 0x0048 ``blkoff'' calc of blk offsets
ufs_sb.fs_fmask = eabr.ReadUInt32(); // 0x004C ``fragoff'' calc of frag offsets
ufs_sb.fs_bshift = eabr.ReadUInt32(); // 0x0050 ``lblkno'' calc of logical blkno
ufs_sb.fs_fshift = eabr.ReadUInt32(); // 0x0054 ``numfrags'' calc number of frags
ufs_sb.fs_bmask = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0048); // 0x0048 ``blkoff'' calc of blk offsets
ufs_sb.fs_fmask = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x004C); // 0x004C ``fragoff'' calc of frag offsets
ufs_sb.fs_bshift = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0050); // 0x0050 ``lblkno'' calc of logical blkno
ufs_sb.fs_fshift = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0054); // 0x0054 ``numfrags'' calc number of frags
// these are configuration parameters
ufs_sb.fs_maxcontig = eabr.ReadUInt32(); // 0x0058 max number of contiguous blks
ufs_sb.fs_maxbpg = eabr.ReadUInt32(); // 0x005C max number of blks per cyl group
ufs_sb.fs_maxcontig = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0058); // 0x0058 max number of contiguous blks
ufs_sb.fs_maxbpg = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x005C); // 0x005C max number of blks per cyl group
// these fields can be computed from the others
ufs_sb.fs_fragshift = eabr.ReadUInt32(); // 0x0060 block to frag shift
ufs_sb.fs_fsbtodb = eabr.ReadUInt32(); // 0x0064 fsbtodb and dbtofsb shift constant
ufs_sb.fs_sbsize = eabr.ReadUInt32(); // 0x0068 actual size of super block
ufs_sb.fs_csmask = eabr.ReadUInt32(); // 0x006C csum block offset
ufs_sb.fs_csshift = eabr.ReadUInt32(); // 0x0070 csum block number
ufs_sb.fs_nindir = eabr.ReadUInt32(); // 0x0074 value of NINDIR
ufs_sb.fs_inopb = eabr.ReadUInt32(); // 0x0078 value of INOPB
ufs_sb.fs_nspf = eabr.ReadUInt32(); // 0x007C value of NSPF
ufs_sb.fs_fragshift = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0060); // 0x0060 block to frag shift
ufs_sb.fs_fsbtodb = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0064); // 0x0064 fsbtodb and dbtofsb shift constant
ufs_sb.fs_sbsize = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0068); // 0x0068 actual size of super block
ufs_sb.fs_csmask = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x006C); // 0x006C csum block offset
ufs_sb.fs_csshift = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0070); // 0x0070 csum block number
ufs_sb.fs_nindir = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0074); // 0x0074 value of NINDIR
ufs_sb.fs_inopb = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0078); // 0x0078 value of INOPB
ufs_sb.fs_nspf = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x007C); // 0x007C value of NSPF
// yet another configuration parameter
ufs_sb.fs_optim = eabr.ReadUInt32(); // 0x0080 optimization preference, see below
ufs_sb.fs_optim = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0080); // 0x0080 optimization preference, see below
// these fields are derived from the hardware
#region Sun
ufs_sb.fs_npsect_sun = eabr.ReadUInt32(); // 0x0084 # sectors/track including spares
ufs_sb.fs_npsect_sun = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0084); // 0x0084 # sectors/track including spares
#endregion Sun
#region Sunx86
eabr.BaseStream.Seek(sb_offset + 0x0084, SeekOrigin.Begin);
ufs_sb.fs_state_t_sun86 = eabr.ReadUInt32(); // 0x0084 file system state time stamp
ufs_sb.fs_state_t_sun86 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0084); // 0x0084 file system state time stamp
#endregion Sunx86
#region COMMON
ufs_sb.fs_interleave = eabr.ReadUInt32(); // 0x0088 hardware sector interleave
ufs_sb.fs_trackskew = eabr.ReadUInt32(); // 0x008C sector 0 skew, per track
ufs_sb.fs_interleave = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0088); // 0x0088 hardware sector interleave
ufs_sb.fs_trackskew = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x008C); // 0x008C sector 0 skew, per track
#endregion COMMON
// a unique id for this filesystem (currently unused and unmaintained)
// In 4.3 Tahoe this space is used by fs_headswitch and fs_trkseek
// Neither of those fields is used in the Tahoe code right now but
// there could be problems if they are.
#region COMMON
ufs_sb.fs_id_1 = eabr.ReadUInt32(); // 0x0090
ufs_sb.fs_id_2 = eabr.ReadUInt32(); // 0x0094
ufs_sb.fs_id_1 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0090); // 0x0090
ufs_sb.fs_id_2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0094); // 0x0094
#endregion COMMON
#region 43BSD
eabr.BaseStream.Seek(sb_offset + 0x0090, SeekOrigin.Begin);
ufs_sb.fs_headswitch_43bsd = eabr.ReadUInt32(); // 0x0090
ufs_sb.fs_trkseek_43bsd = eabr.ReadUInt32(); // 0x0094
ufs_sb.fs_headswitch_43bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0090); // 0x0090
ufs_sb.fs_trkseek_43bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0094); // 0x0094
#endregion 43BSD
#region COMMON
// sizes determined by number of cylinder groups and their sizes
ufs_sb.fs_csaddr = eabr.ReadUInt32(); // 0x0098 blk addr of cyl grp summary area
ufs_sb.fs_cssize = eabr.ReadUInt32(); // 0x009C size of cyl grp summary area
ufs_sb.fs_cgsize = eabr.ReadUInt32(); // 0x00A0 cylinder group size
ufs_sb.fs_csaddr = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0098); // 0x0098 blk addr of cyl grp summary area
ufs_sb.fs_cssize = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x009C); // 0x009C size of cyl grp summary area
ufs_sb.fs_cgsize = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00A0); // 0x00A0 cylinder group size
// these fields are derived from the hardware
ufs_sb.fs_ntrak = eabr.ReadUInt32(); // 0x00A4 tracks per cylinder
ufs_sb.fs_nsect = eabr.ReadUInt32(); // 0x00A8 sectors per track
ufs_sb.fs_spc = eabr.ReadUInt32(); // 0x00AC sectors per cylinder
ufs_sb.fs_ntrak = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00A4); // 0x00A4 tracks per cylinder
ufs_sb.fs_nsect = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00A8); // 0x00A8 sectors per track
ufs_sb.fs_spc = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00AC); // 0x00AC sectors per cylinder
// this comes from the disk driver partitioning
ufs_sb.fs_ncyl = eabr.ReadUInt32(); // 0x00B0 cylinders in file system
ufs_sb.fs_ncyl = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00B0); // 0x00B0 cylinders in file system
// these fields can be computed from the others
ufs_sb.fs_cpg = eabr.ReadUInt32(); // 0x00B4 cylinders per group
ufs_sb.fs_ipg = eabr.ReadUInt32(); // 0x00B8 inodes per cylinder group
ufs_sb.fs_fpg = eabr.ReadUInt32(); // 0x00BC blocks per group * fs_frag
ufs_sb.fs_cpg = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00B4); // 0x00B4 cylinders per group
ufs_sb.fs_ipg = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00B8); // 0x00B8 inodes per cylinder group
ufs_sb.fs_fpg = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00BC); // 0x00BC blocks per group * fs_frag
// this data must be re-computed after crashes
// struct ufs_csum fs_cstotal = eabr.ReadUInt32(); // cylinder summary information
ufs_sb.fs_cstotal_ndir = eabr.ReadUInt32(); // 0x00C0 number of directories
ufs_sb.fs_cstotal_nbfree = eabr.ReadUInt32(); // 0x00C4 number of free blocks
ufs_sb.fs_cstotal_nifree = eabr.ReadUInt32(); // 0x00C8 number of free inodes
ufs_sb.fs_cstotal_nffree = eabr.ReadUInt32(); // 0x00CC number of free frags
// struct ufs_csum fs_cstotal = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0000); // cylinder summary information
ufs_sb.fs_cstotal_ndir = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00C0); // 0x00C0 number of directories
ufs_sb.fs_cstotal_nbfree = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00C4); // 0x00C4 number of free blocks
ufs_sb.fs_cstotal_nifree = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00C8); // 0x00C8 number of free inodes
ufs_sb.fs_cstotal_nffree = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x00CC); // 0x00CC number of free frags
// these fields are cleared at mount time
ufs_sb.fs_fmod = eabr.ReadByte(); // 0x00D0 super block modified flag
ufs_sb.fs_clean = eabr.ReadByte(); // 0x00D1 file system is clean flag
ufs_sb.fs_ronly = eabr.ReadByte(); // 0x00D2 mounted read-only flag
ufs_sb.fs_flags = eabr.ReadByte(); // 0x00D3
ufs_sb.fs_fmod = ufs_sb_sectors[0x00D0]; // 0x00D0 super block modified flag
ufs_sb.fs_clean = ufs_sb_sectors[0x00D1]; // 0x00D1 file system is clean flag
ufs_sb.fs_ronly = ufs_sb_sectors[0x00D2]; // 0x00D2 mounted read-only flag
ufs_sb.fs_flags = ufs_sb_sectors[0x00D3]; // 0x00D3
#endregion COMMON
#region UFS1
strings_b = eabr.ReadBytes(512);
strings_b = new byte[512];
Array.Copy(ufs_sb_sectors, 0x00D4, strings_b, 0, 512);
ufs_sb.fs_fsmnt_ufs1 = StringHandlers.CToString(strings_b); // 0x00D4, 512 bytes, name mounted on
ufs_sb.fs_cgrotor_ufs1 = eabr.ReadUInt32(); // 0x02D4 last cg searched
ufs_sb.fs_cs_ufs1 = eabr.ReadBytes(124); // 0x02D8, 124 bytes, UInt32s, list of fs_cs info buffers
ufs_sb.fs_maxcluster_ufs1 = eabr.ReadUInt32(); // 0x0354
ufs_sb.fs_cpc_ufs1 = eabr.ReadUInt32(); // 0x0358 cyl per cycle in postbl
ufs_sb.fs_opostbl_ufs1 = eabr.ReadBytes(256); // 0x035C, 256 bytes, [16][8] matrix of UInt16s, old rotation block list head
ufs_sb.fs_cgrotor_ufs1 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0000); // 0x02D4 last cg searched
Array.Copy(ufs_sb_sectors, 0x02D8, ufs_sb.fs_cs_ufs1, 0, 124); // 0x02D8, 124 bytes, UInt32s, list of fs_cs info buffers
ufs_sb.fs_maxcluster_ufs1 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0354); // 0x0354
ufs_sb.fs_cpc_ufs1 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0358); // 0x0358 cyl per cycle in postbl
Array.Copy(ufs_sb_sectors, 0x035C, ufs_sb.fs_opostbl_ufs1, 0, 256); // 0x035C, 256 bytes, [16][8] matrix of UInt16s, old rotation block list head
#endregion UFS1
#region UFS2
eabr.BaseStream.Seek(sb_offset + 0x00D4, SeekOrigin.Begin);
strings_b = eabr.ReadBytes(468);
strings_b = new byte[468];
Array.Copy(ufs_sb_sectors, 0x00D4, strings_b, 0, 468);
ufs_sb.fs_fsmnt_ufs2 = StringHandlers.CToString(strings_b); // 0x00D4, 468 bytes, name mounted on
strings_b = eabr.ReadBytes(32);
strings_b = new byte[32];
Array.Copy(ufs_sb_sectors, 0x02A8, strings_b, 0, 32);
ufs_sb.fs_volname_ufs2 = StringHandlers.CToString(strings_b); // 0x02A8, 32 bytes, volume name
ufs_sb.fs_swuid_ufs2 = eabr.ReadUInt32(); // 0x02C8 system-wide uid
ufs_sb.fs_pad_ufs2 = eabr.ReadUInt32(); // 0x02D0 due to alignment of fs_swuid
ufs_sb.fs_cgrotor_ufs2 = eabr.ReadUInt32(); // 0x02D4 last cg searched
ufs_sb.fs_ocsp_ufs2 = eabr.ReadBytes(112); // 0x02D8, 112 bytes, UInt32s, list of fs_cs info buffers
ufs_sb.fs_contigdirs_ufs2 = eabr.ReadUInt32(); // 0x0348 # of contiguously allocated dirs
ufs_sb.fs_csp_ufs2 = eabr.ReadUInt32(); // 0x034C cg summary info buffer for fs_cs
ufs_sb.fs_maxcluster_ufs2 = eabr.ReadUInt32(); // 0x0350
ufs_sb.fs_active_ufs2 = eabr.ReadUInt32(); // 0x0354 used by snapshots to track fs
ufs_sb.fs_old_cpc_ufs2 = eabr.ReadUInt32(); // 0x0358 cyl per cycle in postbl
ufs_sb.fs_maxbsize_ufs2 = eabr.ReadUInt32(); // 0x035C maximum blocking factor permitted
ufs_sb.fs_sparecon64_ufs2 = eabr.ReadBytes(136); // 0x0360, 136 bytes, UInt64s, old rotation block list head
ufs_sb.fs_sblockloc_ufs2 = eabr.ReadUInt64(); // 0x03E8 byte offset of standard superblock
ufs_sb.fs_swuid_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x02C8); // 0x02C8 system-wide uid
ufs_sb.fs_pad_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x02D0); // 0x02D0 due to alignment of fs_swuid
ufs_sb.fs_cgrotor_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x02D4); // 0x02D4 last cg searched
Array.Copy(ufs_sb_sectors, 0x02D8, ufs_sb.fs_ocsp_ufs2, 0, 112); // 0x02D8, 112 bytes, UInt32s, list of fs_cs info buffers
ufs_sb.fs_contigdirs_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0348); // 0x0348 # of contiguously allocated dirs
ufs_sb.fs_csp_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x034C); // 0x034C cg summary info buffer for fs_cs
ufs_sb.fs_maxcluster_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0350); // 0x0350
ufs_sb.fs_active_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0354); // 0x0354 used by snapshots to track fs
ufs_sb.fs_old_cpc_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0358); // 0x0358 cyl per cycle in postbl
ufs_sb.fs_maxbsize_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x035C); // 0x035C maximum blocking factor permitted
Array.Copy(ufs_sb_sectors, 0x0360, ufs_sb.fs_sparecon64_ufs2, 0, 136); // 0x0360, 136 bytes, UInt64s, old rotation block list head
ufs_sb.fs_sblockloc_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x03E8); // 0x03E8 byte offset of standard superblock
//cylinder summary information*/
ufs_sb.fs_cstotal_ndir_ufs2 = eabr.ReadUInt64(); // 0x03F0 number of directories
ufs_sb.fs_cstotal_nbfree_ufs2 = eabr.ReadUInt64(); // 0x03F8 number of free blocks
ufs_sb.fs_cstotal_nifree_ufs2 = eabr.ReadUInt64(); // 0x0400 number of free inodes
ufs_sb.fs_cstotal_nffree_ufs2 = eabr.ReadUInt64(); // 0x0408 number of free frags
ufs_sb.fs_cstotal_numclusters_ufs2 = eabr.ReadUInt64(); // 0x0410 number of free clusters
ufs_sb.fs_cstotal_spare0_ufs2 = eabr.ReadUInt64(); // 0x0418 future expansion
ufs_sb.fs_cstotal_spare1_ufs2 = eabr.ReadUInt64(); // 0x0420 future expansion
ufs_sb.fs_cstotal_spare2_ufs2 = eabr.ReadUInt64(); // 0x0428 future expansion
ufs_sb.fs_time_sec_ufs2 = eabr.ReadUInt32(); // 0x0430 last time written
ufs_sb.fs_time_usec_ufs2 = eabr.ReadUInt32(); // 0x0434 last time written
ufs_sb.fs_size_ufs2 = eabr.ReadUInt64(); // 0x0438 number of blocks in fs
ufs_sb.fs_dsize_ufs2 = eabr.ReadUInt64(); // 0x0440 number of data blocks in fs
ufs_sb.fs_csaddr_ufs2 = eabr.ReadUInt64(); // 0x0448 blk addr of cyl grp summary area
ufs_sb.fs_pendingblocks_ufs2 = eabr.ReadUInt64(); // 0x0450 blocks in process of being freed
ufs_sb.fs_pendinginodes_ufs2 = eabr.ReadUInt32(); // 0x0458 inodes in process of being freed
ufs_sb.fs_cstotal_ndir_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x03F0); // 0x03F0 number of directories
ufs_sb.fs_cstotal_nbfree_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x03F8); // 0x03F8 number of free blocks
ufs_sb.fs_cstotal_nifree_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0400); // 0x0400 number of free inodes
ufs_sb.fs_cstotal_nffree_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0408); // 0x0408 number of free frags
ufs_sb.fs_cstotal_numclusters_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0410); // 0x0410 number of free clusters
ufs_sb.fs_cstotal_spare0_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0418); // 0x0418 future expansion
ufs_sb.fs_cstotal_spare1_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0420); // 0x0420 future expansion
ufs_sb.fs_cstotal_spare2_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0428); // 0x0428 future expansion
ufs_sb.fs_time_sec_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0430); // 0x0430 last time written
ufs_sb.fs_time_usec_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0434); // 0x0434 last time written
ufs_sb.fs_size_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0438); // 0x0438 number of blocks in fs
ufs_sb.fs_dsize_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0440); // 0x0440 number of data blocks in fs
ufs_sb.fs_csaddr_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0448); // 0x0448 blk addr of cyl grp summary area
ufs_sb.fs_pendingblocks_ufs2 = BigEndianBitConverter.ToUInt64(ufs_sb_sectors, 0x0450); // 0x0450 blocks in process of being freed
ufs_sb.fs_pendinginodes_ufs2 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0458); // 0x0458 inodes in process of being freed
#endregion UFS2
#region Sun
ufs_sb.fs_sparecon_sun = eabr.ReadBytes(212); // 0x045C, 212 bytes, reserved for future constants
ufs_sb.fs_reclaim_sun = eabr.ReadUInt32(); // 0x0530
ufs_sb.fs_sparecon2_sun = eabr.ReadUInt32(); // 0x0534
ufs_sb.fs_state_t_sun = eabr.ReadUInt32(); // 0x0538 file system state time stamp
ufs_sb.fs_qbmask0_sun = eabr.ReadUInt32(); // 0x053C ~usb_bmask
ufs_sb.fs_qbmask1_sun = eabr.ReadUInt32(); // 0x0540 ~usb_bmask
ufs_sb.fs_qfmask0_sun = eabr.ReadUInt32(); // 0x0544 ~usb_fmask
ufs_sb.fs_qfmask1_sun = eabr.ReadUInt32(); // 0x0548 ~usb_fmask
Array.Copy(ufs_sb_sectors, 0x045C, ufs_sb.fs_sparecon_sun, 0, 212); // 0x045C, 212 bytes, reserved for future constants
ufs_sb.fs_reclaim_sun = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0530); // 0x0530
ufs_sb.fs_sparecon2_sun = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0534); // 0x0534
ufs_sb.fs_state_t_sun = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0538); // 0x0538 file system state time stamp
ufs_sb.fs_qbmask0_sun = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x053C); // 0x053C ~usb_bmask
ufs_sb.fs_qbmask1_sun = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0540); // 0x0540 ~usb_bmask
ufs_sb.fs_qfmask0_sun = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0544); // 0x0544 ~usb_fmask
ufs_sb.fs_qfmask1_sun = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0548); // 0x0548 ~usb_fmask
#endregion Sun
#region Sunx86
eabr.BaseStream.Seek(sb_offset + 0x045C, SeekOrigin.Begin);
ufs_sb.fs_sparecon_sun86 = eabr.ReadBytes(212); // 0x045C, 212 bytes, reserved for future constants
ufs_sb.fs_reclaim_sun86 = eabr.ReadUInt32(); // 0x0530
ufs_sb.fs_sparecon2_sun86 = eabr.ReadUInt32(); // 0x0534
ufs_sb.fs_npsect_sun86 = eabr.ReadUInt32(); // 0x0538 # sectors/track including spares
ufs_sb.fs_qbmask0_sun86 = eabr.ReadUInt32(); // 0x053C ~usb_bmask
ufs_sb.fs_qbmask1_sun86 = eabr.ReadUInt32(); // 0x0540 ~usb_bmask
ufs_sb.fs_qfmask0_sun86 = eabr.ReadUInt32(); // 0x0544 ~usb_fmask
ufs_sb.fs_qfmask1_sun86 = eabr.ReadUInt32(); // 0x0548 ~usb_fmask
Array.Copy(ufs_sb_sectors, 0x045C, ufs_sb.fs_sparecon_sun86, 0, 212); // 0x045C, 212 bytes, reserved for future constants
ufs_sb.fs_reclaim_sun86 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0530); // 0x0530
ufs_sb.fs_sparecon2_sun86 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0534); // 0x0534
ufs_sb.fs_npsect_sun86 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0538); // 0x0538 # sectors/track including spares
ufs_sb.fs_qbmask0_sun86 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x053C); // 0x053C ~usb_bmask
ufs_sb.fs_qbmask1_sun86 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0540); // 0x0540 ~usb_bmask
ufs_sb.fs_qfmask0_sun86 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0544); // 0x0544 ~usb_fmask
ufs_sb.fs_qfmask1_sun86 = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0548); // 0x0548 ~usb_fmask
#endregion Sunx86
#region 44BSD
eabr.BaseStream.Seek(sb_offset + 0x045C, SeekOrigin.Begin);
ufs_sb.fs_sparecon_44bsd = eabr.ReadBytes(200); // 0x045C, 200 bytes
ufs_sb.fs_contigsumsize_44bsd = eabr.ReadUInt32(); // 0x0524 size of cluster summary array
ufs_sb.fs_maxsymlinklen_44bsd = eabr.ReadUInt32(); // 0x0528 max length of an internal symlink
ufs_sb.fs_inodefmt_44bsd = eabr.ReadUInt32(); // 0x052C format of on-disk inodes
ufs_sb.fs_maxfilesize0_44bsd = eabr.ReadUInt32(); // 0x0530 max representable file size
ufs_sb.fs_maxfilesize1_44bsd = eabr.ReadUInt32(); // 0x0534 max representable file size
ufs_sb.fs_qbmask0_44bsd = eabr.ReadUInt32(); // 0x0538 ~usb_bmask
ufs_sb.fs_qbmask1_44bsd = eabr.ReadUInt32(); // 0x053C ~usb_bmask
ufs_sb.fs_qfmask0_44bsd = eabr.ReadUInt32(); // 0x0540 ~usb_fmask
ufs_sb.fs_qfmask1_44bsd = eabr.ReadUInt32(); // 0x0544 ~usb_fmask
ufs_sb.fs_state_t_44bsd = eabr.ReadUInt32(); // 0x0548 file system state time stamp
Array.Copy(ufs_sb_sectors, 0x045C, ufs_sb.fs_sparecon_44bsd, 0, 200); // 0x045C, 200 bytes
ufs_sb.fs_contigsumsize_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0524); // 0x0524 size of cluster summary array
ufs_sb.fs_maxsymlinklen_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0528); // 0x0528 max length of an internal symlink
ufs_sb.fs_inodefmt_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x052C); // 0x052C format of on-disk inodes
ufs_sb.fs_maxfilesize0_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0530); // 0x0530 max representable file size
ufs_sb.fs_maxfilesize1_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0534); // 0x0534 max representable file size
ufs_sb.fs_qbmask0_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0538); // 0x0538 ~usb_bmask
ufs_sb.fs_qbmask1_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x053C); // 0x053C ~usb_bmask
ufs_sb.fs_qfmask0_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0540); // 0x0540 ~usb_fmask
ufs_sb.fs_qfmask1_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0544); // 0x0544 ~usb_fmask
ufs_sb.fs_state_t_44bsd = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0548); // 0x0548 file system state time stamp
#endregion 44BSD
ufs_sb.fs_postblformat = eabr.ReadUInt32(); // 0x054C format of positional layout tables
ufs_sb.fs_nrpos = eabr.ReadUInt32(); // 0x0550 number of rotational positions
ufs_sb.fs_postbloff = eabr.ReadUInt32(); // 0x0554 (__s16) rotation block list head
ufs_sb.fs_rotbloff = eabr.ReadUInt32(); // 0x0558 (__u8) blocks for each rotation
ufs_sb.fs_magic = eabr.ReadUInt32(); // 0x055C magic number
ufs_sb.fs_space = eabr.ReadByte(); // 0x0560 list of blocks for each rotation
if(eabr.BaseStream.Position != (sb_offset + 0x0561) && MainClass.isDebug)
Console.WriteLine("Error reading superblock, out of alignment 0x{0:X8}, expected 0x{1:X8}", eabr.BaseStream.Position, (sb_offset + 0x0561));
ufs_sb.fs_postblformat = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x054C); // 0x054C format of positional layout tables
ufs_sb.fs_nrpos = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0550); // 0x0550 number of rotational positions
ufs_sb.fs_postbloff = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0554); // 0x0554 (__s16) rotation block list head
ufs_sb.fs_rotbloff = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x0558); // 0x0558 (__u8) blocks for each rotation
ufs_sb.fs_magic = BigEndianBitConverter.ToUInt32(ufs_sb_sectors, 0x055C); // 0x055C magic number
ufs_sb.fs_space = ufs_sb_sectors[0x0560]; // 0x0560 list of blocks for each rotation
if(MainClass.isDebug)
{
@@ -655,13 +661,13 @@ namespace FileSystemIDandChk.Plugins
information = sbInformation.ToString();
}
private const int block_size = 8192;
private const uint block_size = 8192;
// As specified in FreeBSD source code, FFS/UFS can start in any of four places
private const long sb_start_floppy = 0; // For floppies, start at offset 0
private const long sb_start_ufs1 = block_size; // For normal devices, start at offset 8192
private const long sb_start_ufs2 = block_size*8; // For UFS2, start at offset 65536
private const long sb_start_piggy = block_size*32; // For piggy devices (?), start at offset 262144
private const ulong sb_start_floppy = 0; // For floppies, start at offset 0
private const ulong sb_start_ufs1 = 1; // For normal devices, start at offset 8192
private const ulong sb_start_ufs2 = 8; // For UFS2, start at offset 65536
private const ulong sb_start_piggy = 32; // For piggy devices (?), start at offset 262144
// MAGICs
private const UInt32 UFS_MAGIC = 0x00011954; // UFS magic
@@ -674,6 +680,7 @@ namespace FileSystemIDandChk.Plugins
// There is no clear way to detect which one is correct
// And as C# does not support unions this struct will clearly appear quite dirty :p
// To clean up things a little, comment starts with relative superblock offset of field
// Biggest sized supleblock would be 1377 bytes
public struct UFSSuperBlock
{
#region 42BSD