2014-04-17 19:58:14 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2014-06-15 23:39:34 +01:00
The Disc Image Chef
2014-04-17 19:58:14 +00:00
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Filename : SysV . cs
Version : 1.0
Author ( s ) : Natalia Portillo
Component : Filesystem plugins
Revision : $ Revision $
Last change by : $ Author $
Date : $ Date $
- - [ Description ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Identifies UNIX System V filesystems and shows information .
- - [ License ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
This program is free software : you can redistribute it and / or modify
2014-04-19 18:23:00 +01:00
it under the terms of the GNU General Public License as
2014-04-17 19:58:14 +00:00
published by the Free Software Foundation , either version 3 of the
License , or ( at your option ) any later version .
This program 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
2014-04-19 18:23:00 +01:00
GNU General Public License for more details .
2014-04-17 19:58:14 +00:00
2014-04-19 18:23:00 +01:00
You should have received a copy of the GNU General Public License
2014-04-17 19:58:14 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Copyright ( C ) 2011 - 2014 Claunia . com
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
//$Id$
2012-08-07 06:20:13 +00:00
using System ;
using System.Text ;
2014-06-15 23:39:34 +01:00
using DiscImageChef ;
2012-08-07 06:20:13 +00:00
2014-04-17 19:58:14 +00:00
// Information from the Linux kernel
2014-06-15 23:39:34 +01:00
namespace DiscImageChef.Plugins
2012-08-07 06:20:13 +00:00
{
2014-04-14 02:29:13 +00:00
class SysVfs : Plugin
{
const UInt32 XENIX_MAGIC = 0x002B5544 ;
const UInt32 XENIX_CIGAM = 0x44552B00 ;
const UInt32 SYSV_MAGIC = 0xFD187E20 ;
const UInt32 SYSV_CIGAM = 0xFD187E20 ;
// Rest have no magic.
// Per a Linux kernel, Coherent fs has following:
const string COH_FNAME = "nonamexxxxx " ;
const string COH_FPACK = "nopackxxxxx\n" ;
// SCO AFS
const UInt16 SCO_NFREE = 0xFFFF ;
// UNIX 7th Edition has nothing to detect it, so check for a valid filesystem is a must :(
const UInt16 V7_NICINOD = 100 ;
const UInt16 V7_NICFREE = 50 ;
const UInt32 V7_MAXSIZE = 0x00FFFFFF ;
2015-10-05 20:04:05 +01:00
public SysVfs ( )
2012-08-07 06:20:13 +00:00
{
2014-04-14 02:29:13 +00:00
Name = "UNIX System V filesystem" ;
PluginUUID = new Guid ( "9B8D016A-8561-400E-A12A-A198283C211D" ) ;
2012-08-07 06:20:13 +00:00
}
2014-04-14 02:29:13 +00:00
2015-04-20 05:09:46 +01:00
public override bool Identify ( ImagePlugins . ImagePlugin imagePlugin , ulong partitionStart , ulong partitionEnd )
2014-04-14 02:29:13 +00:00
{
2015-04-20 05:09:46 +01:00
if ( ( 2 + partitionStart ) > = imagePlugin . GetSectors ( ) )
2014-07-09 19:49:14 +01:00
return false ;
2014-04-14 02:29:13 +00:00
UInt32 magic ;
string s_fname , s_fpack ;
UInt16 s_nfree , s_ninode ;
UInt32 s_fsize ;
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
/ * for ( int j = 0 ; j < = ( br . BaseStream . Length / 0x200 ) ; j + + )
2012-08-07 06:20:13 +00:00
{
br . BaseStream . Seek ( offset + j * 0x200 + 0x1F8 , SeekOrigin . Begin ) ; // System V magic location
magic = br . ReadUInt32 ( ) ;
if ( magic = = SYSV_MAGIC | | magic = = SYSV_CIGAM )
Console . WriteLine ( "0x{0:X8}: 0x{1:X8} FOUND" , br . BaseStream . Position - 4 , magic ) ;
else
Console . WriteLine ( "0x{0:X8}: 0x{1:X8}" , br . BaseStream . Position - 4 , magic ) ;
} * /
2014-04-14 02:29:13 +00:00
/ * UInt32 number ;
2012-08-07 06:20:13 +00:00
br . BaseStream . Seek ( offset + 0x3A00 , SeekOrigin . Begin ) ;
while ( ( br . BaseStream . Position ) < = ( offset + 0x3C00 ) )
{
number = br . ReadUInt32 ( ) ;
Console . WriteLine ( "@{0:X8}: 0x{1:X8} ({1})" , br . BaseStream . Position - offset - 4 , number ) ;
} * /
2014-04-14 01:14:20 +00:00
byte sb_size_in_sectors ;
if ( imagePlugin . GetSectorSize ( ) < = 0x400 ) // Check if underlying device sector size is smaller than SuperBlock size
sb_size_in_sectors = ( byte ) ( 0x400 / imagePlugin . GetSectorSize ( ) ) ;
else
sb_size_in_sectors = 1 ; // If not a single sector can store it
2015-04-20 05:09:46 +01:00
if ( imagePlugin . GetSectors ( ) < = ( partitionStart + 4 * ( ulong ) sb_size_in_sectors + ( ulong ) sb_size_in_sectors ) ) // Device must be bigger than SB location + SB size + offset
2014-04-14 01:14:20 +00:00
return false ;
// Superblock can start on 0x000, 0x200, 0x600 and 0x800, not aligned, so we assume 16 (128 bytes/sector) sectors as a safe value
2014-04-14 02:29:13 +00:00
for ( int i = 0 ; i < = 16 ; i + + )
{
2015-04-20 05:09:46 +01:00
byte [ ] sb_sector = imagePlugin . ReadSectors ( ( ulong ) i + partitionStart , sb_size_in_sectors ) ;
2012-08-07 06:20:13 +00:00
2014-04-14 01:14:20 +00:00
magic = BitConverter . ToUInt32 ( sb_sector , 0x3F8 ) ; // XENIX magic location
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( magic = = XENIX_MAGIC | | magic = = XENIX_CIGAM )
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
2014-04-14 02:29:13 +00:00
if ( magic = = SYSV_MAGIC | | magic = = SYSV_CIGAM )
return true ;
2012-08-07 06:20:13 +00:00
2014-04-14 01:14:20 +00:00
byte [ ] coherent_string = new byte [ 6 ] ;
Array . Copy ( sb_sector , 0x1E8 , coherent_string , 0 , 6 ) ; // Coherent UNIX s_fname location
s_fname = StringHandlers . CToString ( coherent_string ) ;
Array . Copy ( sb_sector , 0x1EE , coherent_string , 0 , 6 ) ; // Coherent UNIX s_fpack location
s_fpack = StringHandlers . CToString ( coherent_string ) ;
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( s_fname = = COH_FNAME | | s_fpack = = COH_FPACK )
return true ;
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
// Now try to identify 7th edition
2014-04-14 01:14:20 +00:00
s_fsize = BitConverter . ToUInt32 ( sb_sector , 0x002 ) ; // 7th edition's s_fsize
s_nfree = BitConverter . ToUInt16 ( sb_sector , 0x006 ) ; // 7th edition's s_nfree
s_ninode = BitConverter . ToUInt16 ( sb_sector , 0x0D0 ) ; // 7th edition's s_ninode
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( s_fsize > 0 & & s_fsize < 0xFFFFFFFF & & s_nfree > 0 & & s_nfree < 0xFFFF & & s_ninode > 0 & & s_ninode < 0xFFFF )
{
if ( ( s_fsize & 0xFF ) = = 0x00 & & ( s_nfree & 0xFF ) = = 0x00 & & ( s_ninode & 0xFF ) = = 0x00 )
{
// Byteswap
s_fsize = ( ( s_fsize & 0xFF ) < < 24 ) + ( ( s_fsize & 0xFF00 ) < < 8 ) + ( ( s_fsize & 0xFF0000 ) > > 8 ) + ( ( s_fsize & 0xFF000000 ) > > 24 ) ;
s_nfree = ( UInt16 ) ( s_nfree > > 8 ) ;
s_ninode = ( UInt16 ) ( s_ninode > > 8 ) ;
}
if ( ( s_fsize & 0xFF000000 ) = = 0x00 & & ( s_nfree & 0xFF00 ) = = 0x00 & & ( s_ninode & 0xFF00 ) = = 0x00 )
{
if ( s_fsize < V7_MAXSIZE & & s_nfree < V7_NICFREE & & s_ninode < V7_NICINOD )
{
if ( ( s_fsize * 1024 ) < = ( imagePlugin . GetSectors ( ) * imagePlugin . GetSectorSize ( ) ) | | ( s_fsize * 512 ) < = ( imagePlugin . GetSectors ( ) * imagePlugin . GetSectorSize ( ) ) )
return true ;
}
}
}
}
return false ;
}
2015-04-20 05:09:46 +01:00
public override void GetInformation ( ImagePlugins . ImagePlugin imagePlugin , ulong partitionStart , ulong partitionEnd , out string information )
2014-04-14 02:29:13 +00:00
{
information = "" ;
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
StringBuilder sb = new StringBuilder ( ) ;
2014-04-14 01:14:20 +00:00
BigEndianBitConverter . IsLittleEndian = true ; // Start in little endian until we know what are we handling here
2014-04-14 02:29:13 +00:00
int start ;
UInt32 magic ;
string s_fname , s_fpack ;
UInt16 s_nfree , s_ninode ;
UInt32 s_fsize ;
bool xenix = false ;
bool sysv = false ;
bool sysvr4 = false ;
bool sys7th = false ;
bool coherent = false ;
2014-04-14 01:14:20 +00:00
byte [ ] sb_sector ;
byte sb_size_in_sectors ;
if ( imagePlugin . GetSectorSize ( ) < = 0x400 ) // Check if underlying device sector size is smaller than SuperBlock size
sb_size_in_sectors = ( byte ) ( 0x400 / imagePlugin . GetSectorSize ( ) ) ;
else
sb_size_in_sectors = 1 ; // If not a single sector can store it
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
2014-04-14 02:29:13 +00:00
for ( start = 0 ; start < = 16 ; start + + )
{
2015-04-20 05:09:46 +01:00
sb_sector = imagePlugin . ReadSectors ( ( ulong ) start + partitionStart , sb_size_in_sectors ) ;
2014-04-14 01:14:20 +00:00
magic = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x3F8 ) ; // XENIX magic location
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( magic = = XENIX_MAGIC )
{
2014-04-14 01:14:20 +00:00
BigEndianBitConverter . IsLittleEndian = true ; // Little endian
2014-04-14 02:29:13 +00:00
xenix = true ;
break ;
}
if ( magic = = XENIX_CIGAM )
{
2014-04-14 01:14:20 +00:00
BigEndianBitConverter . IsLittleEndian = false ; // Big endian
2014-04-14 02:29:13 +00:00
xenix = true ;
break ;
}
2012-08-07 06:20:13 +00:00
2014-04-14 01:14:20 +00:00
magic = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1F8 ) ; // XENIX magic location
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( magic = = SYSV_MAGIC )
{
2014-04-14 01:14:20 +00:00
BigEndianBitConverter . IsLittleEndian = true ; // Little endian
2014-04-14 02:29:13 +00:00
sysv = true ;
break ;
}
if ( magic = = SYSV_CIGAM )
{
2014-04-14 01:14:20 +00:00
BigEndianBitConverter . IsLittleEndian = false ; // Big endian
2014-04-14 02:29:13 +00:00
sysv = true ;
break ;
}
2012-08-07 06:20:13 +00:00
2014-04-14 01:14:20 +00:00
byte [ ] coherent_string = new byte [ 6 ] ;
Array . Copy ( sb_sector , 0x1E8 , coherent_string , 0 , 6 ) ; // Coherent UNIX s_fname location
s_fname = StringHandlers . CToString ( coherent_string ) ;
Array . Copy ( sb_sector , 0x1EE , coherent_string , 0 , 6 ) ; // Coherent UNIX s_fpack location
s_fpack = StringHandlers . CToString ( coherent_string ) ;
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( s_fname = = COH_FNAME | | s_fpack = = COH_FPACK )
{
2014-04-14 01:14:20 +00:00
BigEndianBitConverter . IsLittleEndian = true ; // Coherent is in PDP endianness, use helper for that
2014-04-14 02:29:13 +00:00
coherent = true ;
break ;
}
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
// Now try to identify 7th edition
2014-04-14 01:14:20 +00:00
s_fsize = BitConverter . ToUInt32 ( sb_sector , 0x002 ) ; // 7th edition's s_fsize
s_nfree = BitConverter . ToUInt16 ( sb_sector , 0x006 ) ; // 7th edition's s_nfree
s_ninode = BitConverter . ToUInt16 ( sb_sector , 0x0D0 ) ; // 7th edition's s_ninode
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( s_fsize > 0 & & s_fsize < 0xFFFFFFFF & & s_nfree > 0 & & s_nfree < 0xFFFF & & s_ninode > 0 & & s_ninode < 0xFFFF )
{
if ( ( s_fsize & 0xFF ) = = 0x00 & & ( s_nfree & 0xFF ) = = 0x00 & & ( s_ninode & 0xFF ) = = 0x00 )
{
// Byteswap
s_fsize = ( ( s_fsize & 0xFF ) < < 24 ) + ( ( s_fsize & 0xFF00 ) < < 8 ) + ( ( s_fsize & 0xFF0000 ) > > 8 ) + ( ( s_fsize & 0xFF000000 ) > > 24 ) ;
s_nfree = ( UInt16 ) ( s_nfree > > 8 ) ;
s_ninode = ( UInt16 ) ( s_ninode > > 8 ) ;
}
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( ( s_fsize & 0xFF000000 ) = = 0x00 & & ( s_nfree & 0xFF00 ) = = 0x00 & & ( s_ninode & 0xFF00 ) = = 0x00 )
{
if ( s_fsize < V7_MAXSIZE & & s_nfree < V7_NICFREE & & s_ninode < V7_NICINOD )
{
if ( ( s_fsize * 1024 ) < = ( imagePlugin . GetSectors ( ) * imagePlugin . GetSectorSize ( ) ) | | ( s_fsize * 512 ) < = ( imagePlugin . GetSectors ( ) * imagePlugin . GetSectorSize ( ) ) )
{
sys7th = true ;
2014-04-14 01:14:20 +00:00
BigEndianBitConverter . IsLittleEndian = true ;
2014-04-14 02:29:13 +00:00
break ;
}
}
}
}
}
if ( ! sys7th & & ! sysv & & ! coherent & & ! xenix )
return ;
2015-12-05 17:10:27 +00:00
xmlFSType = new Schemas . FileSystemType ( ) ;
2014-04-14 02:29:13 +00:00
if ( xenix )
{
2014-04-14 01:14:20 +00:00
byte [ ] xenix_strings = new byte [ 6 ] ;
2014-04-14 02:29:13 +00:00
XenixSuperBlock xnx_sb = new XenixSuperBlock ( ) ;
2015-04-20 05:09:46 +01:00
sb_sector = imagePlugin . ReadSectors ( ( ulong ) start + partitionStart , sb_size_in_sectors ) ;
2014-04-14 01:14:20 +00: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 . ToUInt32 ( sb_sector , 0x266 ) ;
xnx_sb . s_tfree = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x26A ) ;
xnx_sb . s_tinode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x26E ) ;
xnx_sb . s_cylblks = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x270 ) ;
xnx_sb . s_gapblks = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x272 ) ;
xnx_sb . s_dinfo0 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x274 ) ;
xnx_sb . s_dinfo1 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x276 ) ;
Array . Copy ( sb_sector , 0x278 , xenix_strings , 0 , 6 ) ;
xnx_sb . s_fname = StringHandlers . CToString ( xenix_strings ) ;
Array . Copy ( sb_sector , 0x27E , xenix_strings , 0 , 6 ) ;
xnx_sb . s_fpack = StringHandlers . CToString ( xenix_strings ) ;
xnx_sb . s_clean = sb_sector [ 0x284 ] ;
xnx_sb . s_magic = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x3F8 ) ;
xnx_sb . s_type = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x3FC ) ;
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
UInt32 bs = 512 ;
sb . AppendLine ( "XENIX filesystem" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "XENIX fs" ;
2014-04-14 02:29:13 +00:00
switch ( xnx_sb . s_type )
{
case 1 :
sb . AppendLine ( "512 bytes per block" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . ClusterSize = 512 ;
2014-04-14 02:29:13 +00:00
break ;
case 2 :
sb . AppendLine ( "1024 bytes per block" ) ;
bs = 1024 ;
2015-12-05 17:10:27 +00:00
xmlFSType . ClusterSize = 1024 ;
2014-04-14 02:29:13 +00:00
break ;
case 3 :
sb . AppendLine ( "2048 bytes per block" ) ;
bs = 2048 ;
2015-12-05 17:10:27 +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 ;
}
2014-04-14 01:14:20 +00:00
if ( imagePlugin . GetSectorSize ( ) = = 2336 | | imagePlugin . GetSectorSize ( ) = = 2352 | | imagePlugin . GetSectorSize ( ) = = 2448 )
{
if ( bs ! = 2048 )
sb . AppendFormat ( "WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector" , bs , 2048 ) . AppendLine ( ) ;
}
else
{
if ( bs ! = imagePlugin . GetSectorSize ( ) )
sb . AppendFormat ( "WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector" , bs , imagePlugin . GetSectorSize ( ) ) . AppendLine ( ) ;
}
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 ( ) ;
sb . AppendFormat ( "{0} free zones on volume ({1} bytes)" , xnx_sb . s_tfree , xnx_sb . s_tfree * bs ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free blocks on list ({1} bytes)" , xnx_sb . s_nfree , xnx_sb . s_nfree * bs ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} blocks per cylinder ({1} bytes)" , xnx_sb . s_cylblks , xnx_sb . s_cylblks * bs ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} blocks per gap ({1} bytes)" , xnx_sb . s_gapblks , xnx_sb . s_gapblks * bs ) . AppendLine ( ) ;
sb . AppendFormat ( "First data zone: {0}" , xnx_sb . s_isize ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free inodes on volume" , xnx_sb . s_tinode ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free inodes on list" , xnx_sb . s_ninode ) . AppendLine ( ) ;
if ( xnx_sb . s_flock > 0 )
sb . AppendLine ( "Free block list is locked" ) ;
if ( xnx_sb . s_ilock > 0 )
sb . AppendLine ( "inode cache is locked" ) ;
if ( xnx_sb . s_fmod > 0 )
sb . AppendLine ( "Superblock is being modified" ) ;
if ( xnx_sb . s_ronly > 0 )
sb . AppendLine ( "Volume is mounted read-only" ) ;
sb . AppendFormat ( "Superblock last updated on {0}" , DateHandlers . UNIXUnsignedToDateTime ( xnx_sb . s_time ) ) . AppendLine ( ) ;
2015-12-06 05:09:31 +00:00
if ( xnx_sb . s_time ! = 0 )
{
xmlFSType . ModificationDate = DateHandlers . UNIXUnsignedToDateTime ( xnx_sb . s_time ) ;
xmlFSType . ModificationDateSpecified = true ;
}
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume name: {0}" , xnx_sb . s_fname ) . AppendLine ( ) ;
2015-12-05 17:10:27 +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 ( ) ;
if ( xnx_sb . s_clean = = 0x46 )
sb . AppendLine ( "Volume is clean" ) ;
else
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Volume is dirty" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Dirty = true ;
}
2014-04-14 02:29:13 +00:00
}
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( sysv )
{
2015-04-20 05:09:46 +01:00
sb_sector = imagePlugin . ReadSectors ( ( ulong ) start + partitionStart , sb_size_in_sectors ) ;
2014-04-14 02:29:13 +00:00
UInt16 pad0 , pad1 , pad2 ;
2014-04-14 01:14:20 +00:00
byte [ ] sysv_strings = new byte [ 6 ] ;
2012-08-07 06:20:13 +00:00
2014-04-14 01:14:20 +00:00
pad0 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x002 ) ; // First padding
pad1 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x00A ) ; // Second padding
pad2 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x0D6 ) ; // Third padding
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
// This detection is not working as expected
sysvr4 | = pad0 = = 0 & & pad1 = = 0 & & pad2 = = 0 ;
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
SystemVRelease4SuperBlock sysv_sb = new SystemVRelease4SuperBlock ( ) ;
2014-04-14 01:14:20 +00:00
// Common offsets
sysv_sb . s_isize = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x000 ) ;
sysv_sb . s_state = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1F4 ) ;
sysv_sb . s_magic = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1F8 ) ;
sysv_sb . s_type = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1FC ) ;
if ( sysvr4 )
{
sysv_sb . s_fsize = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x004 ) ;
sysv_sb . s_nfree = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x008 ) ;
sysv_sb . s_ninode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x0D4 ) ;
sysv_sb . s_flock = sb_sector [ 0x1A0 ] ;
sysv_sb . s_ilock = sb_sector [ 0x1A1 ] ;
sysv_sb . s_fmod = sb_sector [ 0x1A2 ] ;
sysv_sb . s_ronly = sb_sector [ 0x1A3 ] ;
sysv_sb . s_time = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1A4 ) ;
sysv_sb . s_cylblks = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1A8 ) ;
sysv_sb . s_gapblks = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1AA ) ;
sysv_sb . s_dinfo0 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1AC ) ;
sysv_sb . s_dinfo1 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1AE ) ;
sysv_sb . s_tfree = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1B0 ) ;
sysv_sb . s_tinode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1B4 ) ;
Array . Copy ( sb_sector , 0x1B8 , sysv_strings , 0 , 6 ) ;
sysv_sb . s_fname = StringHandlers . CToString ( sysv_strings ) ;
Array . Copy ( sb_sector , 0x1BE , sysv_strings , 0 , 6 ) ;
sysv_sb . s_fpack = StringHandlers . CToString ( sysv_strings ) ;
}
else
{
sysv_sb . s_fsize = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x002 ) ;
sysv_sb . s_nfree = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x006 ) ;
sysv_sb . s_ninode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x0D0 ) ;
sysv_sb . s_flock = sb_sector [ 0x19A ] ;
sysv_sb . s_ilock = sb_sector [ 0x19B ] ;
sysv_sb . s_fmod = sb_sector [ 0x19C ] ;
sysv_sb . s_ronly = sb_sector [ 0x19D ] ;
sysv_sb . s_time = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x19E ) ;
sysv_sb . s_cylblks = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1A2 ) ;
sysv_sb . s_gapblks = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1A4 ) ;
sysv_sb . s_dinfo0 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1A6 ) ;
sysv_sb . s_dinfo1 = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1A8 ) ;
sysv_sb . s_tfree = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1AA ) ;
sysv_sb . s_tinode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1AE ) ;
Array . Copy ( sb_sector , 0x1B0 , sysv_strings , 0 , 6 ) ;
sysv_sb . s_fname = StringHandlers . CToString ( sysv_strings ) ;
Array . Copy ( sb_sector , 0x1B6 , sysv_strings , 0 , 6 ) ;
sysv_sb . s_fpack = StringHandlers . CToString ( sysv_strings ) ;
}
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
UInt32 bs = 512 ;
if ( sysvr4 )
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "System V Release 4 filesystem" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "SVR4 fs" ;
}
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 ( "System V Release 2 filesystem" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "SVR2 fs" ;
}
2014-04-14 02:29:13 +00:00
switch ( sysv_sb . s_type )
{
case 1 :
sb . AppendLine ( "512 bytes per block" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . ClusterSize = 512 ;
2014-04-14 02:29:13 +00:00
break ;
case 2 :
sb . AppendLine ( "1024 bytes per block" ) ;
bs = 1024 ;
2015-12-05 17:10:27 +00:00
xmlFSType . ClusterSize = 1024 ;
2014-04-14 02:29:13 +00:00
break ;
case 3 :
sb . AppendLine ( "2048 bytes per block" ) ;
bs = 2048 ;
2015-12-05 17:10:27 +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 ;
}
2014-04-14 01:14:20 +00:00
if ( imagePlugin . GetSectorSize ( ) = = 2336 | | imagePlugin . GetSectorSize ( ) = = 2352 | | imagePlugin . GetSectorSize ( ) = = 2448 )
{
if ( bs ! = 2048 )
sb . AppendFormat ( "WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector" , bs , 2048 ) . AppendLine ( ) ;
}
else
{
if ( bs ! = imagePlugin . GetSectorSize ( ) )
sb . AppendFormat ( "WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/sector" , bs , imagePlugin . GetSectorSize ( ) ) . AppendLine ( ) ;
}
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 ( ) ;
sb . AppendFormat ( "{0} free zones on volume ({1} bytes)" , sysv_sb . s_tfree , sysv_sb . s_tfree * bs ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free blocks on list ({1} bytes)" , sysv_sb . s_nfree , sysv_sb . s_nfree * bs ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} blocks per cylinder ({1} bytes)" , sysv_sb . s_cylblks , sysv_sb . s_cylblks * bs ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} blocks per gap ({1} bytes)" , sysv_sb . s_gapblks , sysv_sb . s_gapblks * bs ) . AppendLine ( ) ;
sb . AppendFormat ( "First data zone: {0}" , sysv_sb . s_isize ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free inodes on volume" , sysv_sb . s_tinode ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free inodes on list" , sysv_sb . s_ninode ) . AppendLine ( ) ;
if ( sysv_sb . s_flock > 0 )
sb . AppendLine ( "Free block list is locked" ) ;
if ( sysv_sb . s_ilock > 0 )
sb . AppendLine ( "inode cache is locked" ) ;
if ( sysv_sb . s_fmod > 0 )
sb . AppendLine ( "Superblock is being modified" ) ;
if ( sysv_sb . s_ronly > 0 )
sb . AppendLine ( "Volume is mounted read-only" ) ;
sb . AppendFormat ( "Superblock last updated on {0}" , DateHandlers . UNIXUnsignedToDateTime ( sysv_sb . s_time ) ) . AppendLine ( ) ;
2015-12-06 05:09:31 +00:00
if ( sysv_sb . s_time ! = 0 )
{
xmlFSType . ModificationDate = DateHandlers . UNIXUnsignedToDateTime ( sysv_sb . s_time ) ;
xmlFSType . ModificationDateSpecified = true ;
}
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume name: {0}" , sysv_sb . s_fname ) . AppendLine ( ) ;
2015-12-05 17:10:27 +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 ( ) ;
if ( sysv_sb . s_state = = ( 0x7C269D38 - sysv_sb . s_time ) )
sb . AppendLine ( "Volume is clean" ) ;
else
2015-12-05 17:10:27 +00:00
{
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Volume is dirty" ) ;
2015-12-05 17:10:27 +00:00
xmlFSType . Dirty = true ;
}
2014-04-14 02:29:13 +00:00
}
2012-08-07 06:20:13 +00:00
2014-04-14 02:29:13 +00:00
if ( coherent )
{
2015-04-20 05:09:46 +01:00
sb_sector = imagePlugin . ReadSectors ( ( ulong ) start + partitionStart , sb_size_in_sectors ) ;
2014-04-14 02:29:13 +00:00
CoherentSuperBlock coh_sb = new CoherentSuperBlock ( ) ;
2014-04-14 01:14:20 +00:00
byte [ ] coh_strings = new byte [ 6 ] ;
coh_sb . s_isize = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x000 ) ;
coh_sb . s_fsize = Swapping . PDPFromLittleEndian ( BigEndianBitConverter . ToUInt32 ( sb_sector , 0x002 ) ) ;
coh_sb . s_nfree = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x006 ) ;
coh_sb . s_ninode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x108 ) ;
coh_sb . s_flock = sb_sector [ 0x1D2 ] ;
coh_sb . s_ilock = sb_sector [ 0x1D3 ] ;
coh_sb . s_fmod = sb_sector [ 0x1D4 ] ;
coh_sb . s_ronly = sb_sector [ 0x1D5 ] ;
coh_sb . s_time = Swapping . PDPFromLittleEndian ( BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1D6 ) ) ;
coh_sb . s_tfree = Swapping . PDPFromLittleEndian ( BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1DE ) ) ;
coh_sb . s_tinode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1E2 ) ;
coh_sb . s_int_m = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1E4 ) ;
coh_sb . s_int_n = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1E6 ) ;
Array . Copy ( sb_sector , 0x1E8 , coh_strings , 0 , 6 ) ;
coh_sb . s_fname = StringHandlers . CToString ( coh_strings ) ;
Array . Copy ( sb_sector , 0x1EE , coh_strings , 0 , 6 ) ;
coh_sb . s_fpack = StringHandlers . CToString ( coh_strings ) ;
2012-08-07 06:20:13 +00:00
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "Coherent fs" ;
xmlFSType . ClusterSize = 512 ;
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "Coherent UNIX filesystem" ) ;
2014-04-14 01:14:20 +00:00
if ( imagePlugin . GetSectorSize ( ) ! = 512 )
sb . 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 ( ) ;
sb . AppendFormat ( "{0} free zones on volume ({1} bytes)" , coh_sb . s_tfree , coh_sb . s_tfree * 512 ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free blocks on list ({1} bytes)" , coh_sb . s_nfree , coh_sb . s_nfree * 512 ) . AppendLine ( ) ;
sb . AppendFormat ( "First data zone: {0}" , coh_sb . s_isize ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free inodes on volume" , coh_sb . s_tinode ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free inodes on list" , coh_sb . s_ninode ) . AppendLine ( ) ;
if ( coh_sb . s_flock > 0 )
sb . AppendLine ( "Free block list is locked" ) ;
if ( coh_sb . s_ilock > 0 )
sb . AppendLine ( "inode cache is locked" ) ;
if ( coh_sb . s_fmod > 0 )
sb . AppendLine ( "Superblock is being modified" ) ;
if ( coh_sb . s_ronly > 0 )
sb . AppendLine ( "Volume is mounted read-only" ) ;
sb . AppendFormat ( "Superblock last updated on {0}" , DateHandlers . UNIXUnsignedToDateTime ( coh_sb . s_time ) ) . AppendLine ( ) ;
2015-12-06 05:09:31 +00:00
if ( coh_sb . s_time ! = 0 )
{
xmlFSType . ModificationDate = DateHandlers . UNIXUnsignedToDateTime ( coh_sb . s_time ) ;
xmlFSType . ModificationDateSpecified = true ;
}
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume name: {0}" , coh_sb . s_fname ) . AppendLine ( ) ;
2015-12-05 17:10:27 +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 ( ) ;
}
if ( sys7th )
{
2015-04-20 05:09:46 +01:00
sb_sector = imagePlugin . ReadSectors ( ( ulong ) start + partitionStart , sb_size_in_sectors ) ;
2014-04-14 01:14:20 +00:00
UNIX7thEditionSuperBlock v7_sb = new UNIX7thEditionSuperBlock ( ) ;
byte [ ] sys7_strings = new byte [ 6 ] ;
v7_sb . s_isize = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x000 ) ;
v7_sb . s_fsize = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x002 ) ;
v7_sb . s_nfree = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x006 ) ;
v7_sb . s_ninode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x0D0 ) ;
v7_sb . s_flock = sb_sector [ 0x19A ] ;
v7_sb . s_ilock = sb_sector [ 0x19B ] ;
v7_sb . s_fmod = sb_sector [ 0x19C ] ;
v7_sb . s_ronly = sb_sector [ 0x19D ] ;
v7_sb . s_time = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x19E ) ;
v7_sb . s_tfree = BigEndianBitConverter . ToUInt32 ( sb_sector , 0x1A2 ) ;
v7_sb . s_tinode = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1A6 ) ;
v7_sb . s_int_m = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1A8 ) ;
v7_sb . s_int_n = BigEndianBitConverter . ToUInt16 ( sb_sector , 0x1AA ) ;
Array . Copy ( sb_sector , 0x1AC , sys7_strings , 0 , 6 ) ;
v7_sb . s_fname = StringHandlers . CToString ( sys7_strings ) ;
Array . Copy ( sb_sector , 0x1B2 , sys7_strings , 0 , 6 ) ;
v7_sb . s_fpack = StringHandlers . CToString ( sys7_strings ) ;
2012-08-07 06:20:13 +00:00
2015-12-05 17:10:27 +00:00
xmlFSType . Type = "UNIX 7th Edition fs" ;
xmlFSType . ClusterSize = 512 ;
2014-04-14 02:29:13 +00:00
sb . AppendLine ( "UNIX 7th Edition filesystem" ) ;
2014-04-14 01:14:20 +00:00
if ( imagePlugin . GetSectorSize ( ) ! = 512 )
sb . 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 ( ) ;
sb . AppendFormat ( "{0} free zones on volume ({1} bytes)" , v7_sb . s_tfree , v7_sb . s_tfree * 512 ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free blocks on list ({1} bytes)" , v7_sb . s_nfree , v7_sb . s_nfree * 512 ) . AppendLine ( ) ;
sb . AppendFormat ( "First data zone: {0}" , v7_sb . s_isize ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free inodes on volume" , v7_sb . s_tinode ) . AppendLine ( ) ;
sb . AppendFormat ( "{0} free inodes on list" , v7_sb . s_ninode ) . AppendLine ( ) ;
if ( v7_sb . s_flock > 0 )
sb . AppendLine ( "Free block list is locked" ) ;
if ( v7_sb . s_ilock > 0 )
sb . AppendLine ( "inode cache is locked" ) ;
if ( v7_sb . s_fmod > 0 )
sb . AppendLine ( "Superblock is being modified" ) ;
if ( v7_sb . s_ronly > 0 )
sb . AppendLine ( "Volume is mounted read-only" ) ;
sb . AppendFormat ( "Superblock last updated on {0}" , DateHandlers . UNIXUnsignedToDateTime ( v7_sb . s_time ) ) . AppendLine ( ) ;
2015-12-06 05:09:31 +00:00
if ( v7_sb . s_time ! = 0 )
{
xmlFSType . ModificationDate = DateHandlers . UNIXUnsignedToDateTime ( v7_sb . s_time ) ;
xmlFSType . ModificationDateSpecified = true ;
}
2014-04-14 02:29:13 +00:00
sb . AppendFormat ( "Volume name: {0}" , v7_sb . s_fname ) . AppendLine ( ) ;
2015-12-05 17:10:27 +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
}
struct XenixSuperBlock
{
public UInt16 s_isize ;
// 0x000, index of first data zone
public UInt32 s_fsize ;
// 0x002, total number of zones of this volume
// the start of the free block list:
public UInt16 s_nfree ;
// 0x006, blocks in s_free, <=100
public UInt32 [ ] s_free ;
// 0x008, 100 entries, first free block list chunk
// the cache of free inodes:
public UInt16 s_ninode ;
// 0x198, number of inodes in s_inode, <= 100
public UInt16 [ ] s_inode ;
// 0x19A, 100 entries, some free inodes
public byte s_flock ;
// 0x262, free block list manipulation lock
public byte s_ilock ;
// 0x263, inode cache manipulation lock
public byte s_fmod ;
// 0x264, superblock modification flag
public byte s_ronly ;
// 0x265, read-only mounted flag
public UInt32 s_time ;
// 0x266, time of last superblock update
public UInt32 s_tfree ;
// 0x26A, total number of free zones
public UInt16 s_tinode ;
// 0x26E, total number of free inodes
public UInt16 s_cylblks ;
// 0x270, blocks per cylinder
public UInt16 s_gapblks ;
// 0x272, blocks per gap
public UInt16 s_dinfo0 ;
// 0x274, device information ??
public UInt16 s_dinfo1 ;
// 0x276, device information ??
public string s_fname ;
// 0x278, 6 bytes, volume name
public string s_fpack ;
// 0x27E, 6 bytes, pack name
public byte s_clean ;
// 0x284, 0x46 if volume is clean
public byte [ ] s_fill ;
// 0x285, 371 bytes
public UInt32 s_magic ;
// 0x3F8, magic
public UInt32 s_type ;
// 0x3FC, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk, 3 = 2048 bytes/blk)
}
struct SystemVRelease4SuperBlock
{
public UInt16 s_isize ;
// 0x000, index of first data zone
public UInt16 s_pad0 ;
// 0x002, padding
public UInt32 s_fsize ;
// 0x004, total number of zones of this volume
// the start of the free block list:
public UInt16 s_nfree ;
// 0x008, blocks in s_free, <=100
public UInt16 s_pad1 ;
// 0x00A, padding
public UInt32 [ ] s_free ;
// 0x00C, 50 entries, first free block list chunk
// the cache of free inodes:
public UInt16 s_ninode ;
// 0x0D4, number of inodes in s_inode, <= 100
public UInt16 s_pad2 ;
// 0x0D6, padding
public UInt16 [ ] s_inode ;
// 0x0D8, 100 entries, some free inodes
public byte s_flock ;
// 0x1A0, free block list manipulation lock
public byte s_ilock ;
// 0x1A1, inode cache manipulation lock
public byte s_fmod ;
// 0x1A2, superblock modification flag
public byte s_ronly ;
// 0x1A3, read-only mounted flag
public UInt32 s_time ;
// 0x1A4, time of last superblock update
public UInt16 s_cylblks ;
// 0x1A8, blocks per cylinder
public UInt16 s_gapblks ;
// 0x1AA, blocks per gap
public UInt16 s_dinfo0 ;
// 0x1AC, device information ??
public UInt16 s_dinfo1 ;
// 0x1AE, device information ??
public UInt32 s_tfree ;
// 0x1B0, total number of free zones
public UInt16 s_tinode ;
// 0x1B4, total number of free inodes
public UInt16 s_pad3 ;
// 0x1B6, padding
public string s_fname ;
// 0x1B8, 6 bytes, volume name
public string s_fpack ;
// 0x1BE, 6 bytes, pack name
public byte [ ] s_fill ;
// 0x1C4, 48 bytes
public UInt32 s_state ;
// 0x1F4, if s_state == (0x7C269D38 - s_time) then filesystem is clean
public UInt32 s_magic ;
// 0x1F8, magic
public UInt32 s_type ;
// 0x1FC, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk)
}
struct SystemVRelease2SuperBlock
{
public UInt16 s_isize ;
// 0x000, index of first data zone
public UInt32 s_fsize ;
// 0x002, total number of zones of this volume
// the start of the free block list:
public UInt16 s_nfree ;
// 0x006, blocks in s_free, <=100
public UInt32 [ ] s_free ;
// 0x008, 50 entries, first free block list chunk
// the cache of free inodes:
public UInt16 s_ninode ;
// 0x0D0, number of inodes in s_inode, <= 100
public UInt16 [ ] s_inode ;
// 0x0D2, 100 entries, some free inodes
public byte s_flock ;
// 0x19A, free block list manipulation lock
public byte s_ilock ;
// 0x19B, inode cache manipulation lock
public byte s_fmod ;
// 0x19C, superblock modification flag
public byte s_ronly ;
// 0x19D, read-only mounted flag
public UInt32 s_time ;
// 0x19E, time of last superblock update
public UInt16 s_cylblks ;
// 0x1A2, blocks per cylinder
public UInt16 s_gapblks ;
// 0x1A4, blocks per gap
public UInt16 s_dinfo0 ;
// 0x1A6, device information ??
public UInt16 s_dinfo1 ;
// 0x1A8, device information ??
public UInt32 s_tfree ;
// 0x1AA, total number of free zones
public UInt16 s_tinode ;
// 0x1AE, total number of free inodes
public string s_fname ;
// 0x1B0, 6 bytes, volume name
public string s_fpack ;
// 0x1B6, 6 bytes, pack name
public byte [ ] s_fill ;
// 0x1BC, 56 bytes
public UInt32 s_state ;
// 0x1F4, if s_state == (0x7C269D38 - s_time) then filesystem is clean
public UInt32 s_magic ;
// 0x1F8, magic
public UInt32 s_type ;
// 0x1FC, filesystem type (1 = 512 bytes/blk, 2 = 1024 bytes/blk)
}
struct UNIX7thEditionSuperBlock
{
public UInt16 s_isize ;
// 0x000, index of first data zone
public UInt32 s_fsize ;
// 0x002, total number of zones of this volume
// the start of the free block list:
public UInt16 s_nfree ;
// 0x006, blocks in s_free, <=100
public UInt32 [ ] s_free ;
// 0x008, 50 entries, first free block list chunk
// the cache of free inodes:
public UInt16 s_ninode ;
// 0x0D0, number of inodes in s_inode, <= 100
public UInt16 [ ] s_inode ;
// 0x0D2, 100 entries, some free inodes
public byte s_flock ;
// 0x19A, free block list manipulation lock
public byte s_ilock ;
// 0x19B, inode cache manipulation lock
public byte s_fmod ;
// 0x19C, superblock modification flag
public byte s_ronly ;
// 0x19D, read-only mounted flag
public UInt32 s_time ;
// 0x19E, time of last superblock update
public UInt32 s_tfree ;
// 0x1A2, total number of free zones
public UInt16 s_tinode ;
// 0x1A6, total number of free inodes
public UInt16 s_int_m ;
// 0x1A8, interleave factor
public UInt16 s_int_n ;
// 0x1AA, interleave factor
public string s_fname ;
// 0x1AC, 6 bytes, volume name
public string s_fpack ;
// 0x1B2, 6 bytes, pack name
}
struct CoherentSuperBlock
{
public UInt16 s_isize ;
// 0x000, index of first data zone
public UInt32 s_fsize ;
// 0x002, total number of zones of this volume
// the start of the free block list:
public UInt16 s_nfree ;
// 0x006, blocks in s_free, <=100
public UInt32 [ ] s_free ;
// 0x008, 64 entries, first free block list chunk
// the cache of free inodes:
public UInt16 s_ninode ;
// 0x108, number of inodes in s_inode, <= 100
public UInt16 [ ] s_inode ;
// 0x10A, 100 entries, some free inodes
public byte s_flock ;
// 0x1D2, free block list manipulation lock
public byte s_ilock ;
// 0x1D3, inode cache manipulation lock
public byte s_fmod ;
// 0x1D4, superblock modification flag
public byte s_ronly ;
// 0x1D5, read-only mounted flag
public UInt32 s_time ;
// 0x1D6, time of last superblock update
public UInt32 s_tfree ;
// 0x1DE, total number of free zones
public UInt16 s_tinode ;
// 0x1E2, total number of free inodes
public UInt16 s_int_m ;
// 0x1E4, interleave factor
public UInt16 s_int_n ;
// 0x1E6, interleave factor
public string s_fname ;
// 0x1E8, 6 bytes, volume name
public string s_fpack ;
// 0x1EE, 6 bytes, pack name
public UInt32 s_unique ;
// 0x1F4, zero-filled
}
}
2014-04-14 01:14:20 +00:00
}