mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
* ODS.cs:
* HPFS.cs: * ISO9660.cs: * AppleMFS.cs: * AppleHFS.cs: * AppleHFSPlus.cs: Moved datetime conversion to DateHandlers class. * Symbian.cs: Identifies .SIS files. Yes I know it's not a filesystem but I needed it so. * Main.cs: Corrected typo * FileSystemIDandChk.csproj: Added datetime conversion handling class, Symbian .SIS installers, ext filesystem and ext2/3/4 filesystems. * ext2FS.cs: Detects ext2, ext3 and ext4 filesystems up to Linux 3.1 kernel. * extFS.cs: Detects ext filesystems. Untested as no Linux 2.0 was available at time :p * DateHandlers.cs: Moved all datetime convertions from plugins to central class. git-svn-id: svn://claunia.com/FileSystemIDandChk@11 17725271-3d32-4980-a8cb-9ff532f270ba
This commit is contained in:
33
FileSystemIDandChk/ChangeLog
Normal file
33
FileSystemIDandChk/ChangeLog
Normal file
@@ -0,0 +1,33 @@
|
||||
2012-08-03 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* Plugins/ODS.cs:
|
||||
* Plugins/HPFS.cs:
|
||||
* Plugins/ISO9660.cs:
|
||||
* Plugins/AppleMFS.cs:
|
||||
* Plugins/AppleHFS.cs:
|
||||
* Plugins/AppleHFSPlus.cs:
|
||||
Moved datetime conversion to DateHandlers class.
|
||||
|
||||
* Plugins/Symbian.cs:
|
||||
Identifies .SIS files. Yes I know it's not a filesystem but
|
||||
I needed it so.
|
||||
|
||||
* Main.cs:
|
||||
Corrected typo
|
||||
|
||||
* FileSystemIDandChk.csproj:
|
||||
Added datetime conversion handling class, Symbian .SIS
|
||||
installers, ext filesystem and ext2/3/4 filesystems.
|
||||
|
||||
* Plugins/ext2FS.cs:
|
||||
Detects ext2, ext3 and ext4 filesystems up to Linux 3.1
|
||||
kernel.
|
||||
|
||||
* Plugins/extFS.cs:
|
||||
Detects ext filesystems. Untested as no Linux 2.0 was
|
||||
available at time :p
|
||||
|
||||
* DateHandlers.cs:
|
||||
Moved all datetime convertions from plugins to central
|
||||
class.
|
||||
|
||||
75
FileSystemIDandChk/DateHandlers.cs
Normal file
75
FileSystemIDandChk/DateHandlers.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
|
||||
namespace FileSystemIDandChk
|
||||
{
|
||||
public static class DateHandlers
|
||||
{
|
||||
private static DateTime MacEpoch = new DateTime(1904, 1, 1, 0, 0, 0);
|
||||
private static DateTime UNIXEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||
private static DateTime JulianEpoch = new DateTime(1858, 11, 17, 0, 0, 0); // Day 0 of Julian Date system
|
||||
|
||||
public static DateTime MacToDateTime(ulong MacTimeStamp)
|
||||
{
|
||||
return MacEpoch.AddTicks((long)(MacTimeStamp*10000000));
|
||||
}
|
||||
|
||||
public static DateTime UNIXToDateTime(Int32 UNIXTimeStamp)
|
||||
{
|
||||
return UNIXEpoch.AddSeconds(UNIXTimeStamp);
|
||||
}
|
||||
|
||||
public static DateTime UNIXUnsignedToDateTime(UInt32 UNIXTimeStamp)
|
||||
{
|
||||
return UNIXEpoch.AddSeconds(UNIXTimeStamp);
|
||||
}
|
||||
|
||||
public static DateTime ISO9660ToDateTime(byte[] VDDateTime)
|
||||
{
|
||||
int year, month, day, hour, minute, second, hundredths;
|
||||
byte[] twocharvalue = new byte[2];
|
||||
byte[] fourcharvalue = new byte[4];
|
||||
|
||||
fourcharvalue[0] = VDDateTime[0];
|
||||
fourcharvalue[1] = VDDateTime[1];
|
||||
fourcharvalue[2] = VDDateTime[2];
|
||||
fourcharvalue[3] = VDDateTime[3];
|
||||
year = Convert.ToInt32(System.Text.Encoding.ASCII.GetString(fourcharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[4];
|
||||
twocharvalue[1] = VDDateTime[5];
|
||||
month = Convert.ToInt32(System.Text.Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[6];
|
||||
twocharvalue[1] = VDDateTime[7];
|
||||
day = Convert.ToInt32(System.Text.Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[8];
|
||||
twocharvalue[1] = VDDateTime[9];
|
||||
hour = Convert.ToInt32(System.Text.Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[10];
|
||||
twocharvalue[1] = VDDateTime[11];
|
||||
minute = Convert.ToInt32(System.Text.Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[12];
|
||||
twocharvalue[1] = VDDateTime[13];
|
||||
second = Convert.ToInt32(System.Text.Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[14];
|
||||
twocharvalue[1] = VDDateTime[15];
|
||||
hundredths = Convert.ToInt32(System.Text.Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
DateTime decodedDT = new DateTime(year, month, day, hour, minute, second, hundredths * 10, DateTimeKind.Unspecified);
|
||||
|
||||
return decodedDT;
|
||||
}
|
||||
|
||||
// C# works in UTC, VMS on Julian Date, some displacement may occur on disks created outside UTC
|
||||
public static DateTime VMSToDateTime(UInt64 vmsDate)
|
||||
{
|
||||
double delta = vmsDate * 0.0001; // Tenths of microseconds to milliseconds, will lose some detail
|
||||
return JulianEpoch.AddMilliseconds(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,24 +12,24 @@
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<Optimize>False</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<Externalconsole>true</Externalconsole>
|
||||
<Externalconsole>True</Externalconsole>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<Optimize>False</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<Externalconsole>true</Externalconsole>
|
||||
<Externalconsole>True</Externalconsole>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
@@ -57,10 +57,28 @@
|
||||
<Compile Include="Plugins\HPFS.cs" />
|
||||
<Compile Include="Plugins\NTFS.cs" />
|
||||
<Compile Include="Plugins\ODS.cs" />
|
||||
<Compile Include="Plugins\Symbian.cs" />
|
||||
<Compile Include="Plugins\extFS.cs" />
|
||||
<Compile Include="Plugins\ext2FS.cs" />
|
||||
<Compile Include="DateHandlers.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
<Folder Include="Plugins\" />
|
||||
<Folder Include="PartPlugins\" />
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<MonoDevelop>
|
||||
<Properties>
|
||||
<Policies>
|
||||
<VersionControlPolicy inheritsSet="Mono">
|
||||
<CommitMessageStyle Indent=" " LastFilePostfix=":
 " IncludeDirectoryPaths="True" />
|
||||
</VersionControlPolicy>
|
||||
<ChangeLogPolicy UpdateMode="ProjectRoot" inheritsSet="Mono">
|
||||
<MessageStyle LastFilePostfix=":
 " IncludeDirectoryPaths="True" />
|
||||
</ChangeLogPolicy>
|
||||
</Policies>
|
||||
</Properties>
|
||||
</MonoDevelop>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -21,7 +21,7 @@ namespace FileSystemIDandChk
|
||||
chkFilesystems = true;
|
||||
isDebug = true;
|
||||
|
||||
Console.WriteLine ("Filesystem Identificator and Checker");
|
||||
Console.WriteLine ("Filesystem Identifier and Checker");
|
||||
Console.WriteLine ("Copyright (C) Natalia Portillo, All Rights Reserved");
|
||||
|
||||
if(args.Length==0)
|
||||
|
||||
@@ -9,8 +9,6 @@ namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class AppleHFS : Plugin
|
||||
{
|
||||
private DateTime HFSDateDelta = new DateTime(1904, 01, 01, 00, 00, 00);
|
||||
|
||||
public AppleHFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Apple Hierarchical File System";
|
||||
@@ -234,9 +232,9 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.AppendLine("Apple Hierarchical File System");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Master Directory Block:");
|
||||
sb.AppendFormat("Creation date: {0}", HFSDateDelta.AddTicks((long)(MDB.drCrDate*10000000))).AppendLine();
|
||||
sb.AppendFormat("Last modification date: {0}", HFSDateDelta.AddTicks((long)(MDB.drLsMod*10000000))).AppendLine();
|
||||
sb.AppendFormat("Last backup date: {0}", HFSDateDelta.AddTicks((long)(MDB.drVolBkUp*10000000))).AppendLine();
|
||||
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(MDB.drCrDate)).AppendLine();
|
||||
sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(MDB.drLsMod)).AppendLine();
|
||||
sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(MDB.drVolBkUp)).AppendLine();
|
||||
sb.AppendFormat("Backup sequence number: {0}", MDB.drVSeqNum).AppendLine();
|
||||
|
||||
if((MDB.drAtrb & 0x80) == 0x80)
|
||||
|
||||
@@ -9,8 +9,6 @@ namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class AppleHFSPlus : Plugin
|
||||
{
|
||||
private DateTime HFSDateDelta = new DateTime(1904, 01, 01, 00, 00, 00);
|
||||
|
||||
public AppleHFSPlus(PluginBase Core)
|
||||
{
|
||||
base.Name = "Apple HFS+ filesystem";
|
||||
@@ -291,10 +289,10 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.AppendFormat("Implementation that last mounted the volume: \"{0}\".", HPVH.lastMountedVersion).AppendLine();
|
||||
if((HPVH.attributes & 0x2000) == 0x2000)
|
||||
sb.AppendFormat("Journal starts at allocation block {0}.", HPVH.journalInfoBlock).AppendLine();
|
||||
sb.AppendFormat("Creation date: {0}", HFSDateDelta.AddTicks((long)(HPVH.createDate*10000000))).AppendLine();
|
||||
sb.AppendFormat("Last modification date: {0}", HFSDateDelta.AddTicks((long)(HPVH.modifyDate*10000000))).AppendLine();
|
||||
sb.AppendFormat("Last backup date: {0}", HFSDateDelta.AddTicks((long)(HPVH.backupDate*10000000))).AppendLine();
|
||||
sb.AppendFormat("Last check date: {0}", HFSDateDelta.AddTicks((long)(HPVH.checkedDate*10000000))).AppendLine();
|
||||
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(HPVH.createDate)).AppendLine();
|
||||
sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(HPVH.modifyDate)).AppendLine();
|
||||
sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(HPVH.backupDate)).AppendLine();
|
||||
sb.AppendFormat("Last check date: {0}", DateHandlers.MacToDateTime(HPVH.checkedDate)).AppendLine();
|
||||
sb.AppendFormat("{0} files on volume.", HPVH.fileCount).AppendLine();
|
||||
sb.AppendFormat("{0} folders on volume.", HPVH.folderCount).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per allocation block.", HPVH.blockSize).AppendLine();
|
||||
|
||||
@@ -9,8 +9,6 @@ namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class AppleMFS : Plugin
|
||||
{
|
||||
private DateTime MFSDateDelta = new DateTime(1904, 01, 01, 00, 00, 00);
|
||||
|
||||
public AppleMFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Apple Macintosh File System";
|
||||
@@ -158,8 +156,8 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.AppendLine("Apple Macintosh File System");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Master Directory Block:");
|
||||
sb.AppendFormat("Creation date: {0}", MFSDateDelta.AddTicks((long)(MDB.drCrDate*10000000))).AppendLine();
|
||||
sb.AppendFormat("Last backup date: {0}", MFSDateDelta.AddTicks((long)(MDB.drLsBkUp*10000000))).AppendLine();
|
||||
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(MDB.drCrDate)).AppendLine();
|
||||
sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(MDB.drLsBkUp)).AppendLine();
|
||||
if((MDB.drAtrb & 0x80) == 0x80)
|
||||
sb.AppendLine("Volume is locked by hardware.");
|
||||
if((MDB.drAtrb & 0x8000) == 0x8000)
|
||||
|
||||
@@ -25,6 +25,9 @@ namespace FileSystemIDandChk.Plugins
|
||||
br.BaseStream.Seek(offset + 3 + 8, SeekOrigin.Begin); // Seek to bps
|
||||
bps = br.ReadUInt16();
|
||||
|
||||
if(br.BaseStream.Length < offset + (16 * bps))
|
||||
return false;
|
||||
|
||||
br.BaseStream.Seek(offset + (16 * bps), SeekOrigin.Begin); // Seek to superblock, on logical sector 16
|
||||
magic1 = br.ReadUInt32();
|
||||
magic2 = br.ReadUInt32();
|
||||
@@ -150,8 +153,8 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.AppendFormat("Volume label: {0}", hpfs_bpb.volume_label).AppendLine();
|
||||
// sb.AppendFormat("Filesystem type: \"{0}\"", hpfs_bpb.fs_type).AppendLine();
|
||||
|
||||
DateTime last_chk = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(hpfs_sb.last_chkdsk);
|
||||
DateTime last_optim = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(hpfs_sb.last_optim);
|
||||
DateTime last_chk = DateHandlers.UNIXToDateTime(hpfs_sb.last_chkdsk);
|
||||
DateTime last_optim = DateHandlers.UNIXToDateTime(hpfs_sb.last_optim);
|
||||
|
||||
sb.AppendFormat("HPFS version: {0}", hpfs_sb.version).AppendLine();
|
||||
sb.AppendFormat("Functional version: {0}", hpfs_sb.func_version).AppendLine();
|
||||
|
||||
@@ -800,7 +800,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
if (VCTime[0] == '0' || VCTime[0] == 0x00)
|
||||
decodedVD.CreationTime = DateTime.MinValue;
|
||||
else
|
||||
decodedVD.CreationTime = DecodeVDDateTime(VCTime);
|
||||
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(VCTime);
|
||||
|
||||
if (VMTime[0] == '0' || VMTime[0] == 0x00)
|
||||
{
|
||||
@@ -809,7 +809,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
else
|
||||
{
|
||||
decodedVD.HasModificationTime = true;
|
||||
decodedVD.ModificationTime = DecodeVDDateTime(VMTime);
|
||||
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(VMTime);
|
||||
}
|
||||
|
||||
if (VXTime[0] == '0' || VXTime[0] == 0x00)
|
||||
@@ -819,7 +819,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
else
|
||||
{
|
||||
decodedVD.HasExpirationTime = true;
|
||||
decodedVD.ExpirationTime = DecodeVDDateTime(VXTime);
|
||||
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(VXTime);
|
||||
}
|
||||
|
||||
if (VETime[0] == '0' || VETime[0] == 0x00)
|
||||
@@ -829,7 +829,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
else
|
||||
{
|
||||
decodedVD.HasEffectiveTime = true;
|
||||
decodedVD.EffectiveTime = DecodeVDDateTime(VETime);
|
||||
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(VETime);
|
||||
}
|
||||
|
||||
return decodedVD;
|
||||
@@ -848,7 +848,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
if (VCTime[0] == '0' || VCTime[0] == 0x00)
|
||||
decodedVD.CreationTime = DateTime.MinValue;
|
||||
else
|
||||
decodedVD.CreationTime = DecodeVDDateTime(VCTime);
|
||||
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(VCTime);
|
||||
|
||||
if (VMTime[0] == '0' || VMTime[0] == 0x00)
|
||||
{
|
||||
@@ -857,7 +857,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
else
|
||||
{
|
||||
decodedVD.HasModificationTime = true;
|
||||
decodedVD.ModificationTime = DecodeVDDateTime(VMTime);
|
||||
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(VMTime);
|
||||
}
|
||||
|
||||
if (VXTime[0] == '0' || VXTime[0] == 0x00)
|
||||
@@ -867,7 +867,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
else
|
||||
{
|
||||
decodedVD.HasExpirationTime = true;
|
||||
decodedVD.ExpirationTime = DecodeVDDateTime(VXTime);
|
||||
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(VXTime);
|
||||
}
|
||||
|
||||
if (VETime[0] == '0' || VETime[0] == 0x00)
|
||||
@@ -877,51 +877,10 @@ namespace FileSystemIDandChk.Plugins
|
||||
else
|
||||
{
|
||||
decodedVD.HasEffectiveTime = true;
|
||||
decodedVD.EffectiveTime = DecodeVDDateTime(VETime);
|
||||
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(VETime);
|
||||
}
|
||||
|
||||
return decodedVD;
|
||||
}
|
||||
|
||||
private DateTime DecodeVDDateTime(byte[] VDDateTime)
|
||||
{
|
||||
int year, month, day, hour, minute, second, hundredths;
|
||||
byte[] twocharvalue = new byte[2];
|
||||
byte[] fourcharvalue = new byte[4];
|
||||
|
||||
fourcharvalue[0] = VDDateTime[0];
|
||||
fourcharvalue[1] = VDDateTime[1];
|
||||
fourcharvalue[2] = VDDateTime[2];
|
||||
fourcharvalue[3] = VDDateTime[3];
|
||||
year = Convert.ToInt32(Encoding.ASCII.GetString(fourcharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[4];
|
||||
twocharvalue[1] = VDDateTime[5];
|
||||
month = Convert.ToInt32(Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[6];
|
||||
twocharvalue[1] = VDDateTime[7];
|
||||
day = Convert.ToInt32(Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[8];
|
||||
twocharvalue[1] = VDDateTime[9];
|
||||
hour = Convert.ToInt32(Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[10];
|
||||
twocharvalue[1] = VDDateTime[11];
|
||||
minute = Convert.ToInt32(Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[12];
|
||||
twocharvalue[1] = VDDateTime[13];
|
||||
second = Convert.ToInt32(Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[14];
|
||||
twocharvalue[1] = VDDateTime[15];
|
||||
hundredths = Convert.ToInt32(Encoding.ASCII.GetString(twocharvalue));
|
||||
|
||||
DateTime decodedDT = new DateTime(year, month, day, hour, minute, second, hundredths * 10, DateTimeKind.Unspecified);
|
||||
|
||||
return decodedDT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,11 +130,11 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.AppendFormat("Volume owner is \"{0}\" (ID 0x{1:X8})", homeblock.ownername, homeblock.volowner).AppendLine();
|
||||
sb.AppendFormat("Volume label: \"{0}\"", homeblock.volname).AppendLine();
|
||||
sb.AppendFormat("Drive serial number: 0x{0:X8}", homeblock.serialnum).AppendLine();
|
||||
sb.AppendFormat("Volume was created on {0}", VMSDateToDateTime(homeblock.credate).ToString()).AppendLine();
|
||||
sb.AppendFormat("Volume was created on {0}", DateHandlers.VMSToDateTime(homeblock.credate).ToString()).AppendLine();
|
||||
if(homeblock.revdate > 0)
|
||||
sb.AppendFormat("Volume was last modified on {0}", VMSDateToDateTime(homeblock.revdate).ToString()).AppendLine();
|
||||
sb.AppendFormat("Volume was last modified on {0}", DateHandlers.VMSToDateTime(homeblock.revdate).ToString()).AppendLine();
|
||||
if(homeblock.copydate > 0)
|
||||
sb.AppendFormat("Volume copied on {0}", VMSDateToDateTime(homeblock.copydate).ToString()).AppendLine();
|
||||
sb.AppendFormat("Volume copied on {0}", DateHandlers.VMSToDateTime(homeblock.copydate).ToString()).AppendLine();
|
||||
sb.AppendFormat("Checksums: 0x{0:X4} and 0x{1:X4}", homeblock.checksum1, homeblock.checksum2).AppendLine();
|
||||
sb.AppendLine("Flags:");
|
||||
sb.AppendFormat("Window: {0}", homeblock.window).AppendLine();
|
||||
@@ -280,15 +280,6 @@ namespace FileSystemIDandChk.Plugins
|
||||
public UInt16 reserved2; // Reserved
|
||||
public UInt16 checksum2; // Checksum of preceding 255 words (16 bit units)
|
||||
}
|
||||
|
||||
// C# works in UTC, VMS on Julian Date, some displacement may occur on disks created outside UTC
|
||||
private DateTime VMSDateToDateTime(UInt64 vmsDate)
|
||||
{
|
||||
DateTime date = new DateTime(1858, 11, 17, 0, 0, 0); // Epoch, day 0 of Julian Date system
|
||||
double delta = vmsDate * 0.0001; // Tenths of microseconds to milliseconds, will lose some detail
|
||||
date = date.AddMilliseconds(delta);
|
||||
return date;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
332
FileSystemIDandChk/Plugins/Symbian.cs
Normal file
332
FileSystemIDandChk/Plugins/Symbian.cs
Normal file
@@ -0,0 +1,332 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
using System.Collections.Generic;
|
||||
|
||||
// Information from http://www.thoukydides.webspace.virginmedia.com/software/psifs/sis.html
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class SymbianIS : Plugin
|
||||
{
|
||||
// Magics
|
||||
private const UInt32 SymbianMagic = 0x10000419;
|
||||
private const UInt32 EPOCMagic = 0x1000006D;
|
||||
private const UInt32 EPOC6Magic = 0x10003A12;
|
||||
private const UInt32 Symbian9Magic = 0x10201A7A;
|
||||
|
||||
// Options
|
||||
private const UInt16 IsUnicode = 0x0001;
|
||||
private const UInt16 IsDistributable = 0x0002;
|
||||
private const UInt16 NoCompress = 0x0008;
|
||||
private const UInt16 ShutdownApps = 0x0010;
|
||||
|
||||
// Types
|
||||
private const UInt16 SISApp = 0x0000; // Application
|
||||
private const UInt16 SISSystem = 0x0001; // System component (library)
|
||||
private const UInt16 SISOption = 0x0002; // Optional component
|
||||
private const UInt16 SISConfig = 0x0003; // Configures an application
|
||||
private const UInt16 SISPatch = 0x0004; // Patch
|
||||
private const UInt16 SISUpgrade = 0x0005; // Upgrade
|
||||
|
||||
private enum LanguageCodes
|
||||
{
|
||||
Test,
|
||||
EN,
|
||||
FR,
|
||||
GE,
|
||||
SP,
|
||||
IT,
|
||||
SW,
|
||||
DA,
|
||||
NO,
|
||||
FI,
|
||||
AM,
|
||||
SF,
|
||||
SG,
|
||||
PO,
|
||||
TU,
|
||||
IC,
|
||||
RU,
|
||||
HU,
|
||||
DU,
|
||||
BL,
|
||||
AU,
|
||||
BF,
|
||||
AS,
|
||||
NZ,
|
||||
IF,
|
||||
CS,
|
||||
SK,
|
||||
PL,
|
||||
SL,
|
||||
TC,
|
||||
HK,
|
||||
ZH,
|
||||
JA,
|
||||
TH,
|
||||
AF,
|
||||
SQ,
|
||||
AH,
|
||||
AR,
|
||||
HY,
|
||||
TL,
|
||||
BE,
|
||||
BN,
|
||||
BG,
|
||||
MY,
|
||||
CA,
|
||||
HR,
|
||||
CE,
|
||||
IE,
|
||||
ZA,
|
||||
ET,
|
||||
FA,
|
||||
CF,
|
||||
GD,
|
||||
KA,
|
||||
EL,
|
||||
CG,
|
||||
GU,
|
||||
HE,
|
||||
HI,
|
||||
IN,
|
||||
GA,
|
||||
SZ,
|
||||
KN,
|
||||
KK,
|
||||
KM,
|
||||
KO,
|
||||
LO,
|
||||
LV,
|
||||
LT,
|
||||
MK,
|
||||
MS,
|
||||
ML,
|
||||
MR,
|
||||
MO,
|
||||
MN,
|
||||
NN,
|
||||
BP,
|
||||
PA,
|
||||
RO,
|
||||
SR,
|
||||
SI,
|
||||
SO,
|
||||
OS,
|
||||
LS,
|
||||
SH,
|
||||
FS,
|
||||
TA,
|
||||
TE,
|
||||
BO,
|
||||
TI,
|
||||
CT,
|
||||
TK,
|
||||
UK,
|
||||
UR,
|
||||
VI,
|
||||
CY,
|
||||
ZU
|
||||
};
|
||||
|
||||
public SymbianIS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Symbian Installation File Plugin";
|
||||
base.PluginUUID = new Guid("0ec84ec7-eae6-4196-83fe-943b3fe48dbd");
|
||||
}
|
||||
|
||||
public override bool Identify(FileStream fileStream, long offset)
|
||||
{
|
||||
UInt32 uid1, uid2, uid3;
|
||||
BinaryReader br = new BinaryReader(fileStream);
|
||||
|
||||
br.BaseStream.Seek(0 + offset, SeekOrigin.Begin);
|
||||
|
||||
uid1 = br.ReadUInt32();
|
||||
uid2 = br.ReadUInt32();
|
||||
uid3 = br.ReadUInt32();
|
||||
|
||||
if(uid1 == Symbian9Magic)
|
||||
return true;
|
||||
else if(uid3 == SymbianMagic)
|
||||
{
|
||||
if(uid2 == EPOCMagic || uid2 == EPOC6Magic)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (FileStream fileStream, long offset, out string information)
|
||||
{
|
||||
information = "";
|
||||
StringBuilder description = new StringBuilder();
|
||||
List<string> languages = new List<string>();
|
||||
Dictionary<UInt32, UInt32> capabilities = new Dictionary<UInt32, UInt32>();
|
||||
int ENpos = 0;
|
||||
UInt32 comp_len;
|
||||
UInt32 comp_name_ptr;
|
||||
byte[] ComponentName_b;
|
||||
string ComponentName = "";
|
||||
|
||||
SymbianHeader sh = new SymbianHeader();
|
||||
BinaryReader br = new BinaryReader(fileStream);
|
||||
|
||||
br.BaseStream.Seek(0 + offset, SeekOrigin.Begin);
|
||||
|
||||
sh.uid1 = br.ReadUInt32();
|
||||
sh.uid2 = br.ReadUInt32();
|
||||
sh.uid3 = br.ReadUInt32();
|
||||
sh.uid4 = br.ReadUInt32();
|
||||
sh.crc16 = br.ReadUInt16();
|
||||
sh.languages = br.ReadUInt16();
|
||||
sh.files = br.ReadUInt16();
|
||||
sh.requisites = br.ReadUInt16();
|
||||
sh.inst_lang = br.ReadUInt16();
|
||||
sh.inst_files = br.ReadUInt16();
|
||||
sh.inst_drive = br.ReadUInt16();
|
||||
sh.capabilities = br.ReadUInt16();
|
||||
sh.inst_version = br.ReadUInt32();
|
||||
sh.options = br.ReadUInt16();
|
||||
sh.type = br.ReadUInt16();
|
||||
sh.major = br.ReadUInt16();
|
||||
sh.minor = br.ReadUInt16();
|
||||
sh.variant = br.ReadUInt32();
|
||||
sh.lang_ptr = br.ReadUInt32();
|
||||
sh.files_ptr = br.ReadUInt32();
|
||||
sh.reqs_ptr = br.ReadUInt32();
|
||||
sh.certs_ptr = br.ReadUInt32();
|
||||
sh.comp_ptr = br.ReadUInt32();
|
||||
sh.sig_ptr = br.ReadUInt32();
|
||||
sh.caps_ptr = br.ReadUInt32();
|
||||
sh.instspace = br.ReadUInt32();
|
||||
sh.maxinsspc = br.ReadUInt32();
|
||||
sh.reserved1 = br.ReadUInt64();
|
||||
sh.reserved2 = br.ReadUInt64();
|
||||
|
||||
// Go to enumerate languages
|
||||
br.BaseStream.Seek(sh.lang_ptr + offset, SeekOrigin.Begin);
|
||||
for(int i = 0; i < sh.languages; i++)
|
||||
{
|
||||
UInt16 language = br.ReadUInt16();
|
||||
if(language == 0x0001)
|
||||
ENpos = i;
|
||||
languages.Add(((LanguageCodes)language).ToString("G"));
|
||||
}
|
||||
|
||||
// Go to component record
|
||||
br.BaseStream.Seek(sh.comp_ptr + offset, SeekOrigin.Begin);
|
||||
for(int i = 0; i < sh.languages; i++)
|
||||
{
|
||||
comp_len = br.ReadUInt32();
|
||||
comp_name_ptr = br.ReadUInt32();
|
||||
if(i == ENpos)
|
||||
{
|
||||
br.BaseStream.Seek(comp_name_ptr + offset, SeekOrigin.Begin);
|
||||
ComponentName_b = new byte[comp_len];
|
||||
ComponentName_b = br.ReadBytes((int)comp_len);
|
||||
ComponentName = Encoding.ASCII.GetString(ComponentName_b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Go to capabilities (???)
|
||||
br.BaseStream.Seek(sh.caps_ptr + offset, SeekOrigin.Begin);
|
||||
for(int i = 0; i < sh.capabilities; i++)
|
||||
{
|
||||
UInt32 cap_key = br.ReadUInt32();
|
||||
UInt32 cap_value = br.ReadUInt32();
|
||||
capabilities.Add(cap_key, cap_value);
|
||||
}
|
||||
|
||||
if(sh.uid1 == Symbian9Magic)
|
||||
{
|
||||
description.AppendLine("Symbian Installation File");
|
||||
description.AppendLine("SymbianOS 9.1 or later");
|
||||
description.AppendFormat("Application ID: 0x{0:X8}", sh.uid3).AppendLine();
|
||||
description.AppendFormat("UIDs checksum: 0x{0:X8}", sh.uid4).AppendLine();
|
||||
}
|
||||
else if(sh.uid3 == SymbianMagic)
|
||||
{
|
||||
description.AppendLine("Symbian Installation File");
|
||||
|
||||
if(sh.uid2 == EPOCMagic)
|
||||
description.AppendLine("SymbianOS 3 or later");
|
||||
else if (sh.uid2 == EPOC6Magic)
|
||||
description.AppendLine("SymbianOS 6 or later");
|
||||
else
|
||||
description.AppendFormat("Unknown EPOC magic 0x{0:X8}", sh.uid2).AppendLine();
|
||||
|
||||
description.AppendFormat("Application ID: 0x{0:X8}", sh.uid1).AppendLine();
|
||||
description.AppendFormat("UIDs checksum: 0x{0:X8}", sh.uid4).AppendLine();
|
||||
description.AppendFormat("CRC16 of header: 0x{0:X4}", sh.crc16).AppendLine();
|
||||
description.AppendLine();
|
||||
|
||||
switch(sh.type)
|
||||
{
|
||||
case SISApp:
|
||||
description.AppendLine("SIS contains an application");
|
||||
break;
|
||||
}
|
||||
|
||||
description.AppendFormat("Component: {0} v{1}.{2}", ComponentName, sh.major, sh.minor).AppendLine();
|
||||
|
||||
description.AppendFormat("File contains {0} languages:", sh.languages).AppendLine();
|
||||
for(int i = 0; i < languages.Count; i++)
|
||||
{
|
||||
if(i>0)
|
||||
description.Append(", ");
|
||||
description.AppendFormat("{0}", languages[i]);
|
||||
}
|
||||
description.AppendLine();
|
||||
|
||||
description.AppendFormat("File contains {0} files (pointer: {1})", sh.files, sh.files_ptr).AppendLine();
|
||||
description.AppendFormat("File contains {0} requisites", sh.requisites).AppendLine();
|
||||
// description.AppendLine("Capabilities:");
|
||||
// foreach(KeyValuePair<UInt32, UInt32> kvp in capabilities)
|
||||
// description.AppendFormat("{0} = {1}", kvp.Key, kvp.Value).AppendLine();
|
||||
}
|
||||
|
||||
information = description.ToString();
|
||||
}
|
||||
|
||||
private struct SymbianHeader
|
||||
{
|
||||
public UInt32 uid1; // Application UID before SymbianOS 9, magic after
|
||||
public UInt32 uid2; // EPOC release magic before SOS 9, NULLs after
|
||||
public UInt32 uid3; // Application UID after SOS 9, magic before
|
||||
public UInt32 uid4; // Checksum of UIDs 1 to 3
|
||||
public UInt16 crc16; // CRC16 of all header
|
||||
public UInt16 languages; // Number of languages
|
||||
public UInt16 files; // Number of files
|
||||
public UInt16 requisites; // Number of requisites
|
||||
public UInt16 inst_lang; // Installed language (only residual SIS)
|
||||
public UInt16 inst_files; // Installed files (only residual SIS)
|
||||
public UInt16 inst_drive; // Installed drive (only residual SIS), NULL or 0x0021
|
||||
public UInt16 capabilities; // Number of capabilities
|
||||
public UInt32 inst_version; // Version of Symbian Installer required
|
||||
public UInt16 options; // Option flags
|
||||
public UInt16 type; // Type
|
||||
public UInt16 major; // Major version of application
|
||||
public UInt16 minor; // Minor version of application
|
||||
public UInt32 variant; // Variant when SIS is a prerequisite for other SISs
|
||||
public UInt32 lang_ptr; // Pointer to language records
|
||||
public UInt32 files_ptr; // Pointer to file records
|
||||
public UInt32 reqs_ptr; // Pointer to requisite records
|
||||
public UInt32 certs_ptr; // Pointer to certificate records
|
||||
public UInt32 comp_ptr; // Pointer to component name record
|
||||
// From EPOC Release 6
|
||||
public UInt32 sig_ptr; // Pointer to signature record
|
||||
public UInt32 caps_ptr; // Pointer to capability records
|
||||
public UInt32 instspace; // Installed space (only residual SIS)
|
||||
public UInt32 maxinsspc; // Space required
|
||||
public UInt64 reserved1; // Reserved
|
||||
public UInt64 reserved2; // Reserved
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
726
FileSystemIDandChk/Plugins/ext2FS.cs
Normal file
726
FileSystemIDandChk/Plugins/ext2FS.cs
Normal file
@@ -0,0 +1,726 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
// Information from Inside Macintosh
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class ext2FS : Plugin
|
||||
{
|
||||
public ext2FS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Linux extended Filesystem 2, 3 and 4";
|
||||
base.PluginUUID = new Guid("6AA91B88-150B-4A7B-AD56-F84FB2DF4184");
|
||||
}
|
||||
|
||||
public override bool Identify(FileStream stream, long offset)
|
||||
{
|
||||
byte[] magic_b = new byte[2];
|
||||
ushort magic;
|
||||
|
||||
stream.Seek(0x400 + 56 + offset, SeekOrigin.Begin); // Here should reside magic number
|
||||
stream.Read(magic_b, 0, 2);
|
||||
magic = BitConverter.ToUInt16(magic_b, 0);
|
||||
|
||||
if(magic == ext2FSMagic || magic == ext2OldFSMagic)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (FileStream stream, long offset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
BinaryReader br = new BinaryReader(stream);
|
||||
ext2FSSuperBlock supblk = new ext2FSSuperBlock();
|
||||
byte[] forstrings;
|
||||
bool old_ext2 = false;
|
||||
bool new_ext2 = false;
|
||||
bool ext3 = false;
|
||||
bool ext4 = false;
|
||||
|
||||
byte[] guid_a = new byte[16];
|
||||
byte[] guid_b = new byte[16];
|
||||
|
||||
br.BaseStream.Seek (0x400 + offset, SeekOrigin.Begin);
|
||||
supblk.inodes = br.ReadUInt32();
|
||||
supblk.blocks = br.ReadUInt32();
|
||||
supblk.reserved_blocks = br.ReadUInt32();
|
||||
supblk.free_blocks = br.ReadUInt32();
|
||||
supblk.free_inodes = br.ReadUInt32();
|
||||
supblk.first_block = br.ReadUInt32();
|
||||
supblk.block_size = br.ReadUInt32();
|
||||
supblk.frag_size = br.ReadInt32();
|
||||
supblk.blocks_per_grp = br.ReadUInt32();
|
||||
supblk.flags_per_grp = br.ReadUInt32();
|
||||
supblk.inodes_per_grp = br.ReadUInt32();
|
||||
supblk.mount_t = br.ReadUInt32();
|
||||
supblk.write_t = br.ReadUInt32();
|
||||
supblk.mount_c = br.ReadUInt16();
|
||||
supblk.max_mount_c = br.ReadInt16();
|
||||
supblk.magic = br.ReadUInt16();
|
||||
supblk.state = br.ReadUInt16();
|
||||
supblk.err_behaviour = br.ReadUInt16();
|
||||
supblk.minor_revision = br.ReadUInt16();
|
||||
supblk.check_t = br.ReadUInt32();
|
||||
supblk.check_inv = br.ReadUInt32();
|
||||
// From 0.5a onward
|
||||
supblk.creator_os = br.ReadUInt32();
|
||||
supblk.revision = br.ReadUInt32();
|
||||
supblk.default_uid = br.ReadUInt16();
|
||||
supblk.default_gid = br.ReadUInt16();
|
||||
// From 0.5b onward
|
||||
supblk.first_inode = br.ReadUInt32();
|
||||
supblk.inode_size = br.ReadUInt16();
|
||||
supblk.block_group_no = br.ReadUInt16();
|
||||
supblk.ftr_compat = br.ReadUInt32();
|
||||
supblk.ftr_incompat = br.ReadUInt32();
|
||||
supblk.ftr_ro_compat = br.ReadUInt32();
|
||||
// Volume UUID
|
||||
guid_a = br.ReadBytes(16);
|
||||
guid_b[0] = guid_a[3];
|
||||
guid_b[1] = guid_a[2];
|
||||
guid_b[2] = guid_a[1];
|
||||
guid_b[3] = guid_a[0];
|
||||
guid_b[4] = guid_a[5];
|
||||
guid_b[5] = guid_a[4];
|
||||
guid_b[6] = guid_a[7];
|
||||
guid_b[7] = guid_a[6];
|
||||
guid_b[8] = guid_a[8];
|
||||
guid_b[9] = guid_a[9];
|
||||
guid_b[10] = guid_a[10];
|
||||
guid_b[11] = guid_a[11];
|
||||
guid_b[12] = guid_a[12];
|
||||
guid_b[13] = guid_a[13];
|
||||
guid_b[14] = guid_a[14];
|
||||
guid_b[15] = guid_a[15];
|
||||
supblk.uuid = new Guid(guid_b);
|
||||
// End of volume UUID
|
||||
forstrings = new byte[16];
|
||||
forstrings = br.ReadBytes(16);
|
||||
supblk.volume_name = StringHandlers.CToString(forstrings);
|
||||
forstrings = new byte[64];
|
||||
forstrings = br.ReadBytes(64);
|
||||
supblk.last_mount_dir = StringHandlers.CToString(forstrings);
|
||||
supblk.algo_usage_bmp = br.ReadUInt32();
|
||||
supblk.prealloc_blks = br.ReadByte();
|
||||
supblk.prealloc_dir_blks = br.ReadByte();
|
||||
supblk.rsrvd_gdt_blocks = br.ReadUInt16();
|
||||
// ext3
|
||||
guid_a = br.ReadBytes(16);
|
||||
guid_b[0] = guid_a[3];
|
||||
guid_b[1] = guid_a[2];
|
||||
guid_b[2] = guid_a[1];
|
||||
guid_b[3] = guid_a[0];
|
||||
guid_b[4] = guid_a[5];
|
||||
guid_b[5] = guid_a[4];
|
||||
guid_b[6] = guid_a[7];
|
||||
guid_b[7] = guid_a[6];
|
||||
guid_b[8] = guid_a[8];
|
||||
guid_b[9] = guid_a[9];
|
||||
guid_b[10] = guid_a[10];
|
||||
guid_b[11] = guid_a[11];
|
||||
guid_b[12] = guid_a[12];
|
||||
guid_b[13] = guid_a[13];
|
||||
guid_b[14] = guid_a[14];
|
||||
guid_b[15] = guid_a[15];
|
||||
supblk.journal_uuid = new Guid(guid_b);
|
||||
supblk.journal_inode = br.ReadUInt32();
|
||||
supblk.journal_dev = br.ReadUInt32();
|
||||
supblk.last_orphan = br.ReadUInt32();
|
||||
supblk.hash_seed_1 = br.ReadUInt32();
|
||||
supblk.hash_seed_2 = br.ReadUInt32();
|
||||
supblk.hash_seed_3 = br.ReadUInt32();
|
||||
supblk.hash_seed_4 = br.ReadUInt32();
|
||||
supblk.hash_version = br.ReadByte();
|
||||
supblk.jnl_backup_type = br.ReadByte();
|
||||
supblk.desc_grp_size = br.ReadUInt16();
|
||||
supblk.default_mnt_opts = br.ReadUInt32();
|
||||
supblk.first_meta_bg = br.ReadUInt32();
|
||||
// ext4
|
||||
supblk.mkfs_t = br.ReadUInt32();
|
||||
br.BaseStream.Seek(68, SeekOrigin.Current);
|
||||
supblk.blocks_hi = br.ReadUInt32();
|
||||
supblk.reserved_blocks_hi = br.ReadUInt32();
|
||||
supblk.free_blocks_hi = br.ReadUInt32();
|
||||
supblk.min_inode_size = br.ReadUInt16();
|
||||
supblk.rsv_inode_size = br.ReadUInt16();
|
||||
supblk.flags = br.ReadUInt32();
|
||||
supblk.raid_stride = br.ReadUInt16();
|
||||
supblk.mmp_interval = br.ReadUInt16();
|
||||
supblk.mmp_block = br.ReadUInt64();
|
||||
supblk.raid_stripe_width = br.ReadUInt32();
|
||||
supblk.flex_bg_grp_size = br.ReadByte();
|
||||
supblk.padding = br.ReadByte();
|
||||
supblk.padding2 = br.ReadUInt16();
|
||||
supblk.kbytes_written = br.ReadUInt64();
|
||||
supblk.snapshot_inum = br.ReadUInt32();
|
||||
supblk.snapshot_id = br.ReadUInt32();
|
||||
supblk.snapshot_blocks = br.ReadUInt64();
|
||||
supblk.snapshot_list = br.ReadUInt32();
|
||||
supblk.error_count = br.ReadUInt32();
|
||||
supblk.first_error_t = br.ReadUInt32();
|
||||
supblk.first_error_inode = br.ReadUInt32();
|
||||
supblk.first_error_block = br.ReadUInt64();
|
||||
forstrings = new byte[32];
|
||||
forstrings = br.ReadBytes(32);
|
||||
supblk.first_error_func = StringHandlers.CToString(forstrings);
|
||||
supblk.first_error_line = br.ReadUInt32();
|
||||
supblk.last_error_t = br.ReadUInt32();
|
||||
supblk.last_error_inode = br.ReadUInt32();
|
||||
supblk.last_error_block = br.ReadUInt64();
|
||||
forstrings = new byte[32];
|
||||
forstrings = br.ReadBytes(32);
|
||||
supblk.last_error_func = StringHandlers.CToString(forstrings);
|
||||
supblk.last_error_line = br.ReadUInt32();
|
||||
forstrings = new byte[64];
|
||||
forstrings = br.ReadBytes(64);
|
||||
supblk.mount_options = StringHandlers.CToString(forstrings);
|
||||
|
||||
if(supblk.magic == ext2OldFSMagic)
|
||||
{
|
||||
old_ext2 = true;
|
||||
sb.AppendLine("ext2 (old) filesystem");
|
||||
}
|
||||
else if(supblk.magic == ext2FSMagic)
|
||||
{
|
||||
if((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL ||
|
||||
(supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) == EXT3_FEATURE_INCOMPAT_RECOVER ||
|
||||
(supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
|
||||
{
|
||||
ext3 = true;
|
||||
}
|
||||
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) == EXT4_FEATURE_RO_COMPAT_HUGE_FILE ||
|
||||
(supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) == EXT4_FEATURE_RO_COMPAT_GDT_CSUM ||
|
||||
(supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) == EXT4_FEATURE_RO_COMPAT_DIR_NLINK ||
|
||||
(supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) == EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE ||
|
||||
(supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT ||
|
||||
(supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP) == EXT4_FEATURE_INCOMPAT_MMP ||
|
||||
(supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) == EXT4_FEATURE_INCOMPAT_FLEX_BG ||
|
||||
(supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE) == EXT4_FEATURE_INCOMPAT_EA_INODE ||
|
||||
(supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA) == EXT4_FEATURE_INCOMPAT_DIRDATA)
|
||||
{
|
||||
ext3 = false;
|
||||
ext4 = true;
|
||||
}
|
||||
|
||||
if(ext3 == false && ext4 == false)
|
||||
new_ext2 = true;
|
||||
|
||||
if(new_ext2)
|
||||
sb.AppendLine("ext2 filesystem");
|
||||
if(ext3)
|
||||
sb.AppendLine("ext3 filesystem");
|
||||
if(ext4)
|
||||
sb.AppendLine("ext4 filesystem");
|
||||
}
|
||||
else
|
||||
{
|
||||
information = "Not a ext2/3/4 filesystem" + System.Environment.NewLine;
|
||||
return;
|
||||
}
|
||||
|
||||
string ext_os;
|
||||
switch(supblk.creator_os)
|
||||
{
|
||||
case EXT2_OS_FREEBSD:
|
||||
ext_os = "FreeBSD";
|
||||
break;
|
||||
case EXT2_OS_HURD:
|
||||
ext_os = "Hurd";
|
||||
break;
|
||||
case EXT2_OS_LINUX:
|
||||
ext_os = "Linux";
|
||||
break;
|
||||
case EXT2_OS_LITES:
|
||||
ext_os = "Lites";
|
||||
break;
|
||||
case EXT2_OS_MASIX:
|
||||
ext_os = "MasIX";
|
||||
break;
|
||||
default:
|
||||
ext_os = "Unknown OS (" + supblk.creator_os.ToString() + ")";
|
||||
break;
|
||||
}
|
||||
|
||||
if(supblk.mkfs_t > 0)
|
||||
sb.AppendFormat("Volume was created on {0} for {1}", DateHandlers.UNIXUnsignedToDateTime(supblk.mkfs_t), ext_os).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("Volume was created for {0}", ext_os).AppendLine();
|
||||
|
||||
byte[] temp_lo, temp_hi;
|
||||
byte[] temp_bytes = new byte[8];
|
||||
UInt64 blocks, reserved, free;
|
||||
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT)
|
||||
{
|
||||
temp_lo = BitConverter.GetBytes (supblk.blocks);
|
||||
temp_hi = BitConverter.GetBytes (supblk.blocks_hi);
|
||||
temp_bytes[0] = temp_lo[0];
|
||||
temp_bytes[1] = temp_lo[1];
|
||||
temp_bytes[2] = temp_lo[2];
|
||||
temp_bytes[3] = temp_lo[3];
|
||||
temp_bytes[4] = temp_hi[0];
|
||||
temp_bytes[5] = temp_hi[1];
|
||||
temp_bytes[6] = temp_hi[2];
|
||||
temp_bytes[7] = temp_hi[3];
|
||||
blocks = BitConverter.ToUInt64 (temp_bytes, 0);
|
||||
|
||||
temp_lo = BitConverter.GetBytes (supblk.reserved_blocks);
|
||||
temp_hi = BitConverter.GetBytes (supblk.reserved_blocks_hi);
|
||||
temp_bytes[0] = temp_lo[0];
|
||||
temp_bytes[1] = temp_lo[1];
|
||||
temp_bytes[2] = temp_lo[2];
|
||||
temp_bytes[3] = temp_lo[3];
|
||||
temp_bytes[4] = temp_hi[0];
|
||||
temp_bytes[5] = temp_hi[1];
|
||||
temp_bytes[6] = temp_hi[2];
|
||||
temp_bytes[7] = temp_hi[3];
|
||||
reserved = BitConverter.ToUInt64 (temp_bytes, 0);
|
||||
|
||||
temp_lo = BitConverter.GetBytes (supblk.free_blocks);
|
||||
temp_hi = BitConverter.GetBytes (supblk.free_blocks_hi);
|
||||
temp_bytes[0] = temp_lo[0];
|
||||
temp_bytes[1] = temp_lo[1];
|
||||
temp_bytes[2] = temp_lo[2];
|
||||
temp_bytes[3] = temp_lo[3];
|
||||
temp_bytes[4] = temp_hi[0];
|
||||
temp_bytes[5] = temp_hi[1];
|
||||
temp_bytes[6] = temp_hi[2];
|
||||
temp_bytes[7] = temp_hi[3];
|
||||
free = BitConverter.ToUInt64 (temp_bytes, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks = supblk.blocks;
|
||||
reserved = supblk.reserved_blocks;
|
||||
free = supblk.free_blocks;
|
||||
}
|
||||
|
||||
if(supblk.block_size == 0) // Then it is 1024 bytes
|
||||
supblk.block_size = 1024;
|
||||
|
||||
sb.AppendFormat("Volume has {0} blocks of {1} bytes, for a total of {2} bytes", blocks, supblk.block_size, blocks*supblk.block_size).AppendLine();
|
||||
if(supblk.mount_t > 0 || supblk.mount_c > 0)
|
||||
{
|
||||
if(supblk.mount_t > 0)
|
||||
sb.AppendFormat("Last mounted on {0}", DateHandlers.UNIXUnsignedToDateTime(supblk.mount_t)).AppendLine();
|
||||
if(supblk.max_mount_c != -1)
|
||||
sb.AppendFormat("Volume has been mounted {0} times of a maximum of {1} mounts before checking", supblk.mount_c, supblk.max_mount_c).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("Volume has been mounted {0} times with no maximum no. of mounts before checking", supblk.mount_c).AppendLine();
|
||||
if(supblk.last_mount_dir != "")
|
||||
sb.AppendFormat("Last mounted on: \"{0}\"", supblk.last_mount_dir).AppendLine();
|
||||
if(supblk.mount_options != "")
|
||||
sb.AppendFormat("Last used mount options were: {0}", supblk.mount_options).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine("Volume has never been mounted");
|
||||
if(supblk.max_mount_c != -1)
|
||||
sb.AppendFormat("Volume can be mounted {0} times before checking", supblk.max_mount_c).AppendLine();
|
||||
else
|
||||
sb.AppendLine("Volume has no maximum no. of mounts before checking");
|
||||
}
|
||||
|
||||
if(supblk.check_t > 0)
|
||||
{
|
||||
if(supblk.check_inv > 0)
|
||||
sb.AppendFormat("Last checked on {0} (should check every {1} seconds)", DateHandlers.UNIXUnsignedToDateTime(supblk.check_t), supblk.check_inv).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("Last checked on {0}", DateHandlers.UNIXUnsignedToDateTime(supblk.check_t)).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(supblk.check_inv > 0)
|
||||
sb.AppendFormat("Volume has never been checked (should check every {0})", supblk.check_inv).AppendLine();
|
||||
else
|
||||
sb.AppendLine("Volume has never been checked");
|
||||
}
|
||||
|
||||
if(supblk.write_t > 0)
|
||||
sb.AppendFormat("Last written on {0}", DateHandlers.UNIXUnsignedToDateTime(supblk.write_t)).AppendLine();
|
||||
else
|
||||
sb.AppendLine("Volume has never been written");
|
||||
|
||||
switch(supblk.state)
|
||||
{
|
||||
case EXT2_VALID_FS:
|
||||
sb.AppendLine("Volume is clean");
|
||||
break;
|
||||
case EXT2_ERROR_FS:
|
||||
sb.AppendLine("Volume is dirty");
|
||||
break;
|
||||
case EXT3_ORPHAN_FS:
|
||||
sb.AppendLine("Volume is recovering orphan files");
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("Volume is in an unknown state ({0})", supblk.state).AppendLine();
|
||||
break;
|
||||
}
|
||||
|
||||
if(supblk.volume_name != "")
|
||||
sb.AppendFormat("Volume name: \"{0}\"", supblk.volume_name).AppendLine();
|
||||
|
||||
switch(supblk.err_behaviour)
|
||||
{
|
||||
case EXT2_ERRORS_CONTINUE:
|
||||
sb.AppendLine("On errors, filesystem should continue");
|
||||
break;
|
||||
case EXT2_ERRORS_RO:
|
||||
sb.AppendLine("On errors, filesystem should remount read-only");
|
||||
break;
|
||||
case EXT2_ERRORS_PANIC:
|
||||
sb.AppendLine("On errors, filesystem should panic");
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("On errors filesystem will do an unknown thing ({0})", supblk.err_behaviour).AppendLine();
|
||||
break;
|
||||
}
|
||||
|
||||
if(supblk.revision > 0)
|
||||
sb.AppendFormat("Filesystem revision: {0}.{1}", supblk.revision, supblk.minor_revision).AppendLine();
|
||||
|
||||
if(supblk.uuid != Guid.Empty)
|
||||
sb.AppendFormat("Volume UUID: {0}", supblk.uuid).AppendLine();
|
||||
|
||||
if(supblk.kbytes_written > 0)
|
||||
sb.AppendFormat("{0} KiB has been written on volume", supblk.kbytes_written).AppendLine();
|
||||
|
||||
sb.AppendFormat("{0} reserved and {1} free blocks", reserved, free).AppendLine();
|
||||
sb.AppendFormat("{0} inodes with {1} free inodes ({2}%)", supblk.inodes, supblk.free_inodes, supblk.free_inodes*100/supblk.inodes).AppendLine();
|
||||
if(supblk.first_inode > 0)
|
||||
sb.AppendFormat("First inode is {0}", supblk.first_inode).AppendLine();
|
||||
if(supblk.frag_size > 0)
|
||||
sb.AppendFormat("{0} bytes per fragment", supblk.frag_size).AppendLine();
|
||||
if(supblk.blocks_per_grp > 0 && supblk.flags_per_grp > 0 && supblk.inodes_per_grp > 0)
|
||||
sb.AppendFormat("{0} blocks, {1} flags and {2} inodes per group", supblk.blocks_per_grp, supblk.flags_per_grp, supblk.inodes_per_grp).AppendLine();
|
||||
if(supblk.first_block > 0)
|
||||
sb.AppendFormat("{0} is first data block", supblk.first_block).AppendLine();
|
||||
sb.AppendFormat("Default UID: {0}, GID: {1}", supblk.default_uid, supblk.default_gid).AppendLine();
|
||||
if(supblk.block_group_no > 0)
|
||||
sb.AppendFormat("Block group number is {0}", supblk.block_group_no).AppendLine();
|
||||
if(supblk.desc_grp_size > 0)
|
||||
sb.AppendFormat("Group descriptor size is {0} bytes", supblk.desc_grp_size).AppendLine();
|
||||
if(supblk.first_meta_bg > 0)
|
||||
sb.AppendFormat("First metablock group is {0}", supblk.first_meta_bg).AppendLine();
|
||||
if(supblk.raid_stride > 0)
|
||||
sb.AppendFormat("RAID stride: {0}", supblk.raid_stride).AppendLine();
|
||||
if(supblk.raid_stripe_width > 0)
|
||||
sb.AppendFormat("{0} blocks on all data disks", supblk.raid_stripe_width).AppendLine();
|
||||
if(supblk.mmp_interval > 0 && supblk.mmp_block > 0)
|
||||
sb.AppendFormat("{0} seconds for multi-mount protection wait, on block {1}", supblk.mmp_interval, supblk.mmp_block).AppendLine();
|
||||
if(supblk.flex_bg_grp_size > 0)
|
||||
sb.AppendFormat("{0} Flexible block group size", supblk.flex_bg_grp_size).AppendLine();
|
||||
if(supblk.hash_seed_1 > 0 && supblk.hash_seed_2 > 0 &&supblk.hash_seed_3 > 0 &&supblk.hash_seed_4 > 0)
|
||||
sb.AppendFormat("Hash seed: {0:X8}{1:X8}{2:X8}{3:X8}, version {4}", supblk.hash_seed_1, supblk.hash_seed_2, supblk.hash_seed_3, supblk.hash_seed_4, supblk.hash_version).AppendLine();
|
||||
|
||||
if((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL ||
|
||||
(supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
|
||||
{
|
||||
sb.AppendLine("Volume is journaled");
|
||||
if(supblk.journal_uuid != Guid.Empty)
|
||||
sb.AppendFormat("Journal UUID: {0}", supblk.journal_uuid).AppendLine();
|
||||
sb.AppendFormat("Journal has inode {0}", supblk.journal_inode).AppendLine();
|
||||
if((supblk.ftr_compat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV && supblk.journal_dev > 0)
|
||||
sb.AppendFormat("Journal is on device {0}", supblk.journal_dev).AppendLine();
|
||||
if(supblk.jnl_backup_type > 0)
|
||||
sb.AppendFormat("Journal backup type: {0}", supblk.jnl_backup_type).AppendLine();
|
||||
if(supblk.last_orphan > 0)
|
||||
sb.AppendFormat("Last orphaned inode is {0}", supblk.last_orphan).AppendLine();
|
||||
else
|
||||
sb.AppendLine("There are no orphaned inodes");
|
||||
}
|
||||
|
||||
if(ext4)
|
||||
{
|
||||
if(supblk.snapshot_id > 0)
|
||||
sb.AppendFormat("Active snapshot has ID {0}, on inode {1}, with {2} blocks reserved, list starting on block {3}", supblk.snapshot_id,
|
||||
supblk.snapshot_inum, supblk.snapshot_blocks, supblk.snapshot_list).AppendLine();
|
||||
|
||||
if(supblk.error_count > 0)
|
||||
{
|
||||
sb.AppendFormat("{0} errors registered", supblk.error_count).AppendLine();
|
||||
sb.AppendFormat("First error occurred on {0}, last on {1}", DateHandlers.UNIXUnsignedToDateTime(supblk.first_error_t), DateHandlers.UNIXUnsignedToDateTime(supblk.last_error_t)).AppendLine();
|
||||
sb.AppendFormat("First error inode is {0}, last is {1}", supblk.first_error_inode, supblk.last_error_inode).AppendLine();
|
||||
sb.AppendFormat("First error block is {0}, last is {1}", supblk.first_error_block, supblk.last_error_block).AppendLine();
|
||||
sb.AppendFormat("First error function is \"{0}\", last is \"{1}\"", supblk.first_error_func, supblk.last_error_func).AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
sb.AppendFormat("Flags…:", supblk.flags).AppendLine();
|
||||
if((supblk.flags & EXT2_FLAGS_SIGNED_HASH) == EXT2_FLAGS_SIGNED_HASH)
|
||||
sb.AppendLine("Signed directory hash is in use");
|
||||
if((supblk.flags & EXT2_FLAGS_UNSIGNED_HASH) == EXT2_FLAGS_UNSIGNED_HASH)
|
||||
sb.AppendLine("Unsigned directory hash is in use");
|
||||
if((supblk.flags & EXT2_FLAGS_TEST_FILESYS) == EXT2_FLAGS_TEST_FILESYS)
|
||||
sb.AppendLine("Volume is testing development code");
|
||||
if((supblk.flags & 0xFFFFFFF8) != 0)
|
||||
sb.AppendFormat("Unknown set flags: {0:X8}", supblk.flags);
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendFormat("Default mount options…:", supblk.default_mnt_opts).AppendLine();
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_DEBUG) == EXT2_DEFM_DEBUG)
|
||||
sb.AppendLine("(debug): Enable debugging code");
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_BSDGROUPS) == EXT2_DEFM_BSDGROUPS)
|
||||
sb.AppendLine("(bsdgroups): Emulate BSD behaviour when creating new files");
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_XATTR_USER) == EXT2_DEFM_XATTR_USER)
|
||||
sb.AppendLine("(user_xattr): Enable user-specified extended attributes");
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_ACL) == EXT2_DEFM_ACL)
|
||||
sb.AppendLine("(acl): Enable POSIX ACLs");
|
||||
if((supblk.default_mnt_opts & EXT2_DEFM_UID16) == EXT2_DEFM_UID16)
|
||||
sb.AppendLine("(uid16): Disable 32bit UIDs and GIDs");
|
||||
if((supblk.default_mnt_opts & EXT3_DEFM_JMODE_DATA) == EXT3_DEFM_JMODE_DATA)
|
||||
sb.AppendLine("(journal_data): Journal data and metadata");
|
||||
if((supblk.default_mnt_opts & EXT3_DEFM_JMODE_ORDERED) == EXT3_DEFM_JMODE_ORDERED)
|
||||
sb.AppendLine("(journal_data_ordered): Write data before journaling metadata");
|
||||
if((supblk.default_mnt_opts & EXT3_DEFM_JMODE_WBACK) == EXT3_DEFM_JMODE_WBACK)
|
||||
sb.AppendLine("(journal_data_writeback): Write journal before data");
|
||||
if((supblk.default_mnt_opts & 0xFFFFFE20) != 0)
|
||||
sb.AppendFormat("Unknown set default mount options: {0:X8}", supblk.default_mnt_opts);
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendFormat("Compatible features…:", supblk.ftr_compat).AppendLine();
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_DIR_PREALLOC) == EXT2_FEATURE_COMPAT_DIR_PREALLOC)
|
||||
sb.AppendLine("Pre-allocate directories");
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES) == EXT2_FEATURE_COMPAT_IMAGIC_INODES)
|
||||
sb.AppendLine("imagic inodes ?");
|
||||
if((supblk.ftr_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) == EXT3_FEATURE_COMPAT_HAS_JOURNAL)
|
||||
sb.AppendLine("Has journal (ext3)");
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) == EXT2_FEATURE_COMPAT_EXT_ATTR)
|
||||
sb.AppendLine("Has extended attribute blocks");
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_RESIZE_INO) == EXT2_FEATURE_COMPAT_RESIZE_INO)
|
||||
sb.AppendLine("Has online filesystem resize reservations");
|
||||
if((supblk.ftr_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) == EXT2_FEATURE_COMPAT_DIR_INDEX)
|
||||
sb.AppendLine("Can use hashed indexes on directories");
|
||||
if((supblk.ftr_compat & 0xFFFFFFC0) != 0)
|
||||
sb.AppendFormat("Unknown compatible features: {0:X8}", supblk.ftr_compat);
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendFormat("Compatible features if read-only…:", supblk.ftr_ro_compat).AppendLine();
|
||||
if((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) == EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
|
||||
sb.AppendLine("Reduced number of superblocks");
|
||||
if((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
|
||||
sb.AppendLine("Can have files bigger than 2GiB");
|
||||
if((supblk.ftr_ro_compat & EXT2_FEATURE_RO_COMPAT_BTREE_DIR) == EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
|
||||
sb.AppendLine("Uses B-Tree for directories");
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) == EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
|
||||
sb.AppendLine("Can have files bigger than 2TiB (ext4)");
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) == EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
|
||||
sb.AppendLine("Group descriptor checksums and sparse inode table (ext4)");
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_DIR_NLINK) == EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
|
||||
sb.AppendLine("More than 32000 directory entries (ext4)");
|
||||
if((supblk.ftr_ro_compat & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) == EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
|
||||
sb.AppendLine("Supports nanosecond timestamps and creation time (ext4)");
|
||||
if((supblk.ftr_ro_compat & 0xFFFFFF80) != 0)
|
||||
sb.AppendFormat("Unknown read-only compatible features: {0:X8}", supblk.ftr_ro_compat);
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendFormat("Incompatible features…:", supblk.ftr_incompat).AppendLine();
|
||||
if((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) == EXT2_FEATURE_INCOMPAT_COMPRESSION)
|
||||
sb.AppendLine("Uses compression");
|
||||
if((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE) == EXT2_FEATURE_INCOMPAT_FILETYPE)
|
||||
sb.AppendLine("Filetype in directory entries");
|
||||
if((supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) == EXT3_FEATURE_INCOMPAT_RECOVER)
|
||||
sb.AppendLine("Journal needs recovery (ext3)");
|
||||
if((supblk.ftr_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) == EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
|
||||
sb.AppendLine("Has journal on another device (ext3)");
|
||||
if((supblk.ftr_incompat & EXT2_FEATURE_INCOMPAT_META_BG) == EXT2_FEATURE_INCOMPAT_META_BG)
|
||||
sb.AppendLine("Reduced block group backups");
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EXTENTS) == EXT4_FEATURE_INCOMPAT_EXTENTS)
|
||||
sb.AppendLine("Volume use extents (ext4)");
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_64BIT) == EXT4_FEATURE_INCOMPAT_64BIT)
|
||||
sb.AppendLine("Supports volumes bigger than 2^32 blocks (ext4)");
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_MMP) == EXT4_FEATURE_INCOMPAT_MMP)
|
||||
sb.AppendLine("Multi-mount protection (ext4)");
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) == EXT4_FEATURE_INCOMPAT_FLEX_BG)
|
||||
sb.AppendLine("Flexible block group metadata location (ext4)");
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_EA_INODE) == EXT4_FEATURE_INCOMPAT_EA_INODE)
|
||||
sb.AppendLine("Extended attributes can reside in inode (ext4)");
|
||||
if((supblk.ftr_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA) == EXT4_FEATURE_INCOMPAT_DIRDATA)
|
||||
sb.AppendLine("Data can reside in directory entry (ext4)");
|
||||
if((supblk.ftr_incompat & 0xFFFFF020) != 0)
|
||||
sb.AppendFormat("Unknown incompatible features: {0:X8}", supblk.ftr_incompat);
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
public const UInt16 ext2FSMagic = 0xEF53; // Same for ext3 and ext4
|
||||
public const UInt16 ext2OldFSMagic = 0xEF51;
|
||||
|
||||
public struct ext2FSSuperBlock
|
||||
{
|
||||
public UInt32 inodes; // inodes on volume
|
||||
public UInt32 blocks; // blocks on volume
|
||||
public UInt32 reserved_blocks; // reserved blocks
|
||||
public UInt32 free_blocks; // free blocks count
|
||||
public UInt32 free_inodes; // free inodes count
|
||||
public UInt32 first_block; // first data block
|
||||
public UInt32 block_size; // block size
|
||||
public Int32 frag_size; // fragment size
|
||||
public UInt32 blocks_per_grp; // blocks per group
|
||||
public UInt32 flags_per_grp; // fragments per group
|
||||
public UInt32 inodes_per_grp; // inodes per group
|
||||
public UInt32 mount_t; // last mount time
|
||||
public UInt32 write_t; // last write time
|
||||
public UInt16 mount_c; // mounts count
|
||||
public Int16 max_mount_c; // max mounts
|
||||
public UInt16 magic; // (little endian)
|
||||
public UInt16 state; // filesystem state
|
||||
public UInt16 err_behaviour; // behaviour on errors
|
||||
public UInt16 minor_revision; // From 0.5b onward
|
||||
public UInt32 check_t; // last check time
|
||||
public UInt32 check_inv; // max time between checks
|
||||
// From 0.5a onward
|
||||
public UInt32 creator_os; // Creation OS
|
||||
public UInt32 revision; // Revison level
|
||||
public UInt16 default_uid; // Default UID for reserved blocks
|
||||
public UInt16 default_gid; // Default GID for reserved blocks
|
||||
// From 0.5b onward
|
||||
public UInt32 first_inode; // First unreserved inode
|
||||
public UInt16 inode_size; // inode size
|
||||
public UInt16 block_group_no; // Block group number of THIS superblock
|
||||
public UInt32 ftr_compat; // Compatible features set
|
||||
public UInt32 ftr_incompat; // Incompatible features set
|
||||
// Found on Linux 2.0.40
|
||||
public UInt32 ftr_ro_compat; // Read-only compatible features set
|
||||
// Found on Linux 2.1.132
|
||||
public Guid uuid; // 16 bytes, UUID
|
||||
public string volume_name; // 16 bytes, volume name
|
||||
public string last_mount_dir; // 64 bytes, where last mounted
|
||||
public UInt32 algo_usage_bmp; // Usage bitmap algorithm, for compression
|
||||
public byte prealloc_blks; // Block to try to preallocate
|
||||
public byte prealloc_dir_blks; // Blocks to try to preallocate for directories
|
||||
public UInt16 rsrvd_gdt_blocks; // Per-group desc for online growth
|
||||
// Found on Linux 2.4
|
||||
// ext3
|
||||
public Guid journal_uuid; // 16 bytes, UUID of journal superblock
|
||||
public UInt32 journal_inode; // inode no. of journal file
|
||||
public UInt32 journal_dev; // device no. of journal file
|
||||
public UInt32 last_orphan; // Start of list of inodes to delete
|
||||
public UInt32 hash_seed_1; // First byte of 128bit HTREE hash seed
|
||||
public UInt32 hash_seed_2; // Second byte of 128bit HTREE hash seed
|
||||
public UInt32 hash_seed_3; // Third byte of 128bit HTREE hash seed
|
||||
public UInt32 hash_seed_4; // Fourth byte of 128bit HTREE hash seed
|
||||
public byte hash_version; // Hash version
|
||||
public byte jnl_backup_type; // Journal backup type
|
||||
public UInt16 desc_grp_size; // Size of group descriptor
|
||||
public UInt32 default_mnt_opts; // Default mount options
|
||||
public UInt32 first_meta_bg; // First metablock block group
|
||||
// Introduced with ext4, some can be ext3
|
||||
public UInt32 mkfs_t; // Filesystem creation time
|
||||
// Follows 17 uint32 (68 bytes) of journal inode backup
|
||||
// Following 3 fields are valid if EXT4_FEATURE_COMPAT_64BIT is set
|
||||
public UInt32 blocks_hi; // High 32bits of blocks no.
|
||||
public UInt32 reserved_blocks_hi; // High 32bits of reserved blocks no.
|
||||
public UInt32 free_blocks_hi; // High 32bits of free blocks no.
|
||||
public UInt16 min_inode_size; // inodes minimal size in bytes
|
||||
public UInt16 rsv_inode_size; // Bytes reserved by new inodes
|
||||
public UInt32 flags; // Flags
|
||||
public UInt16 raid_stride; // RAID stride
|
||||
public UInt16 mmp_interval; // Waiting seconds in MMP check
|
||||
public UInt64 mmp_block; // Block for multi-mount protection
|
||||
public UInt32 raid_stripe_width; // Blocks on all data disks (N*stride)
|
||||
public byte flex_bg_grp_size; // FLEX_BG group size
|
||||
public byte padding;
|
||||
public UInt16 padding2;
|
||||
// Following are introduced with ext4
|
||||
public UInt64 kbytes_written; // Kibibytes written in volume lifetime
|
||||
public UInt32 snapshot_inum; // Active snapshot inode number
|
||||
public UInt32 snapshot_id; // Active snapshot sequential ID
|
||||
public UInt64 snapshot_blocks; // Reserved blocks for active snapshot's future use
|
||||
public UInt32 snapshot_list; // inode number of the on-disk start of the snapshot list
|
||||
// Optional ext4 error-handling features
|
||||
public UInt32 error_count; // total registered filesystem errors
|
||||
public UInt32 first_error_t; // time on first error
|
||||
public UInt32 first_error_inode; // inode involved in first error
|
||||
public UInt64 first_error_block; // block involved of first error
|
||||
public string first_error_func; // 32 bytes, function where the error happened
|
||||
public UInt32 first_error_line; // line number where error happened
|
||||
public UInt32 last_error_t; // time of most recent error
|
||||
public UInt32 last_error_inode; // inode involved in last error
|
||||
public UInt32 last_error_line; // line number where error happened
|
||||
public UInt64 last_error_block; // block involved of last error
|
||||
public string last_error_func; // 32 bytes, function where the error happened
|
||||
// End of optiona error-handling features
|
||||
public string mount_options; // 64 bytes, last used mount options
|
||||
}
|
||||
|
||||
// ext? filesystem states
|
||||
public const UInt16 EXT2_VALID_FS = 0x0001; // Cleanly-unmounted volume
|
||||
public const UInt16 EXT2_ERROR_FS = 0x0002; // Dirty volume
|
||||
public const UInt16 EXT3_ORPHAN_FS = 0x0004; // Recovering orphan files
|
||||
|
||||
// ext? default mount flags
|
||||
public const UInt32 EXT2_DEFM_DEBUG = 0x000001; // Enable debugging messages
|
||||
public const UInt32 EXT2_DEFM_BSDGROUPS = 0x000002; // Emulates BSD behaviour on new file creation
|
||||
public const UInt32 EXT2_DEFM_XATTR_USER = 0x000004; // Enable user xattrs
|
||||
public const UInt32 EXT2_DEFM_ACL = 0x000008; // Enable POSIX ACLs
|
||||
public const UInt32 EXT2_DEFM_UID16 = 0x000010; // Use 16bit UIDs
|
||||
public const UInt32 EXT3_DEFM_JMODE_DATA = 0x000040; // Journal data mode
|
||||
public const UInt32 EXT3_DEFM_JMODE_ORDERED = 0x000080; // Journal ordered mode
|
||||
public const UInt32 EXT3_DEFM_JMODE_WBACK = 0x000100; // Journal writeback mode
|
||||
|
||||
// Behaviour on errors
|
||||
public const UInt16 EXT2_ERRORS_CONTINUE = 1; // Continue execution
|
||||
public const UInt16 EXT2_ERRORS_RO = 2; // Remount fs read-only
|
||||
public const UInt16 EXT2_ERRORS_PANIC = 3; // Panic
|
||||
|
||||
// OS codes
|
||||
public const UInt32 EXT2_OS_LINUX = 0;
|
||||
public const UInt32 EXT2_OS_HURD = 1;
|
||||
public const UInt32 EXT2_OS_MASIX = 2;
|
||||
public const UInt32 EXT2_OS_FREEBSD = 3;
|
||||
public const UInt32 EXT2_OS_LITES = 4;
|
||||
|
||||
// Revision levels
|
||||
public const UInt32 EXT2_GOOD_OLD_REV = 0; /* The good old (original) format */
|
||||
public const UInt32 EXT2_DYNAMIC_REV = 1; /* V2 format w/ dynamic inode sizes */
|
||||
|
||||
// Compatible features
|
||||
public const UInt32 EXT2_FEATURE_COMPAT_DIR_PREALLOC = 0x00000001; // Pre-allocate directories
|
||||
public const UInt32 EXT2_FEATURE_COMPAT_IMAGIC_INODES = 0x00000002; // imagic inodes ?
|
||||
public const UInt32 EXT3_FEATURE_COMPAT_HAS_JOURNAL = 0x00000004; // Has journal (it's ext3)
|
||||
public const UInt32 EXT2_FEATURE_COMPAT_EXT_ATTR = 0x00000008; // EA blocks
|
||||
public const UInt32 EXT2_FEATURE_COMPAT_RESIZE_INO = 0x00000010; // Online filesystem resize reservations
|
||||
public const UInt32 EXT2_FEATURE_COMPAT_DIR_INDEX = 0x00000020; // Can use hashed indexes on directories
|
||||
|
||||
// Read-only compatible features
|
||||
public const UInt32 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER = 0x00000001; // Reduced number of superblocks
|
||||
public const UInt32 EXT2_FEATURE_RO_COMPAT_LARGE_FILE = 0x00000002; // Can have files bigger than 2GiB
|
||||
public const UInt32 EXT2_FEATURE_RO_COMPAT_BTREE_DIR = 0x00000004; // Use B-Tree for directories
|
||||
public const UInt32 EXT4_FEATURE_RO_COMPAT_HUGE_FILE = 0x00000008; // Can have files bigger than 2TiB *ext4*
|
||||
public const UInt32 EXT4_FEATURE_RO_COMPAT_GDT_CSUM = 0x00000010; // Group descriptor checksums and sparse inode table *ext4*
|
||||
public const UInt32 EXT4_FEATURE_RO_COMPAT_DIR_NLINK = 0x00000020; // More than 32000 directory entries *ext4*
|
||||
public const UInt32 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE = 0x00000040; // Nanosecond timestamps and creation time *ext4*
|
||||
|
||||
// Incompatible features
|
||||
public const UInt32 EXT2_FEATURE_INCOMPAT_COMPRESSION = 0x00000001; // Uses compression
|
||||
public const UInt32 EXT2_FEATURE_INCOMPAT_FILETYPE = 0x00000002; // Filetype in directory entries
|
||||
public const UInt32 EXT3_FEATURE_INCOMPAT_RECOVER = 0x00000004; // Journal needs recovery *ext3*
|
||||
public const UInt32 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV = 0x00000008; // Has journal on another device *ext3*
|
||||
public const UInt32 EXT2_FEATURE_INCOMPAT_META_BG = 0x00000010; // Reduced block group backups
|
||||
public const UInt32 EXT4_FEATURE_INCOMPAT_EXTENTS = 0x00000040; // Volume use extents *ext4*
|
||||
public const UInt32 EXT4_FEATURE_INCOMPAT_64BIT = 0x00000080; // Supports volumes bigger than 2^32 blocks *ext4*
|
||||
public const UInt32 EXT4_FEATURE_INCOMPAT_MMP = 0x00000100; // Multi-mount protection *ext4*
|
||||
public const UInt32 EXT4_FEATURE_INCOMPAT_FLEX_BG = 0x00000200; // Flexible block group metadata location *ext4*
|
||||
public const UInt32 EXT4_FEATURE_INCOMPAT_EA_INODE = 0x00000400; // EA in inode *ext4*
|
||||
public const UInt32 EXT4_FEATURE_INCOMPAT_DIRDATA = 0x00001000; // Data can reside in directory entry *ext4*
|
||||
|
||||
// Miscellaneous filesystem flags
|
||||
public const UInt32 EXT2_FLAGS_SIGNED_HASH = 0x00000001; // Signed dirhash in use
|
||||
public const UInt32 EXT2_FLAGS_UNSIGNED_HASH = 0x00000002; // Unsigned dirhash in use
|
||||
public const UInt32 EXT2_FLAGS_TEST_FILESYS = 0x00000004; // Testing development code
|
||||
}
|
||||
}
|
||||
|
||||
88
FileSystemIDandChk/Plugins/extFS.cs
Normal file
88
FileSystemIDandChk/Plugins/extFS.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
// Information from Inside Macintosh
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class extFS : Plugin
|
||||
{
|
||||
public extFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Linux extended Filesystem";
|
||||
base.PluginUUID = new Guid("076CB3A2-08C2-4D69-BC8A-FCAA2E502BE2");
|
||||
}
|
||||
|
||||
public override bool Identify(FileStream stream, long offset)
|
||||
{
|
||||
byte[] magic_b = new byte[2];
|
||||
ushort magic;
|
||||
|
||||
stream.Seek(0x400 + 56 + offset, SeekOrigin.Begin); // Here should reside magic number
|
||||
stream.Read(magic_b, 0, 2);
|
||||
magic = BitConverter.ToUInt16(magic_b, 0);
|
||||
|
||||
if(magic == extFSMagic)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (FileStream stream, long offset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
BinaryReader br = new BinaryReader(stream);
|
||||
extFSSuperBlock ext_sb = new extFSSuperBlock();
|
||||
|
||||
br.BaseStream.Seek(0x400 + offset, SeekOrigin.Begin);
|
||||
ext_sb.inodes = br.ReadUInt32();
|
||||
ext_sb.zones = br.ReadUInt32();
|
||||
ext_sb.firstfreeblk = br.ReadUInt32();
|
||||
ext_sb.freecountblk = br.ReadUInt32();
|
||||
ext_sb.firstfreeind = br.ReadUInt32();
|
||||
ext_sb.freecountind = br.ReadUInt32();
|
||||
ext_sb.firstdatazone = br.ReadUInt32();
|
||||
ext_sb.logzonesize = br.ReadUInt32();
|
||||
ext_sb.maxsize = br.ReadUInt32();
|
||||
|
||||
sb.AppendLine("ext filesystem");
|
||||
sb.AppendFormat("{0} zones on volume", ext_sb.zones);
|
||||
sb.AppendFormat("{0} free blocks ({1} bytes)", ext_sb.freecountblk, ext_sb.freecountblk*1024);
|
||||
sb.AppendFormat("{0} inodes on volume, {1} free ({2}%)", ext_sb.inodes, ext_sb.freecountind, ext_sb.freecountind*100/ext_sb.inodes);
|
||||
sb.AppendFormat("First free inode is {0}", ext_sb.firstfreeind);
|
||||
sb.AppendFormat("First free block is {0}", ext_sb.firstfreeblk);
|
||||
sb.AppendFormat("First data zone is {0}", ext_sb.firstdatazone);
|
||||
sb.AppendFormat("Log zone size: {0}", ext_sb.logzonesize);
|
||||
sb.AppendFormat("Max zone size: {0}", ext_sb.maxsize);
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
public const UInt16 extFSMagic = 0x137D;
|
||||
|
||||
public struct extFSSuperBlock
|
||||
{
|
||||
public UInt32 inodes; // inodes on volume
|
||||
public UInt32 zones; // zones on volume
|
||||
public UInt32 firstfreeblk; // first free block
|
||||
public UInt32 freecountblk; // free blocks count
|
||||
public UInt32 firstfreeind; // first free inode
|
||||
public UInt32 freecountind; // free inodes count
|
||||
public UInt32 firstdatazone; // first data zone
|
||||
public UInt32 logzonesize; // log zone size
|
||||
public UInt32 maxsize; // max zone size
|
||||
public UInt32 reserved1; // reserved
|
||||
public UInt32 reserved2; // reserved
|
||||
public UInt32 reserved3; // reserved
|
||||
public UInt32 reserved4; // reserved
|
||||
public UInt32 reserved5; // reserved
|
||||
public UInt16 magic; // 0x137D (little endian)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user