mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Refactor and reformat code
git-svn-id: svn://claunia.com/FileSystemIDandChk@29 17725271-3d32-4980-a8cb-9ff532f270ba
This commit is contained in:
@@ -15,8 +15,8 @@ namespace FileSystemIDandChk
|
||||
/// Indicates the byte order ("endianess") in which data is stored in this computer
|
||||
/// architecture.
|
||||
///</summary>
|
||||
public static bool IsLittleEndian { get; set; } // should default to false, which is what we want for Empire
|
||||
|
||||
public static bool IsLittleEndian { get; set; }
|
||||
// should default to false, which is what we want for Empire
|
||||
/// <summary>
|
||||
/// Converts the specified double-precision floating point number to a 64-bit
|
||||
/// signed integer.
|
||||
@@ -28,7 +28,11 @@ namespace FileSystemIDandChk
|
||||
/// Returns:
|
||||
/// A 64-bit signed integer whose value is equivalent to value.
|
||||
///</summary>
|
||||
public static long DoubleToInt64Bits(double value) { throw new NotImplementedException(); }
|
||||
public static long DoubleToInt64Bits(double value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified Boolean value as an array of bytes.
|
||||
@@ -44,6 +48,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified Unicode character value as an array of bytes.
|
||||
@@ -59,6 +64,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified double-precision floating point value as an array of
|
||||
@@ -75,6 +81,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified single-precision floating point value as an array of
|
||||
@@ -91,6 +98,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified 32-bit signed integer value as an array of bytes.
|
||||
@@ -106,6 +114,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified 64-bit signed integer value as an array of bytes.
|
||||
@@ -121,6 +130,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified 16-bit signed integer value as an array of bytes.
|
||||
@@ -136,6 +146,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified 32-bit unsigned integer value as an array of bytes.
|
||||
@@ -147,11 +158,12 @@ namespace FileSystemIDandChk
|
||||
/// Returns:
|
||||
/// An array of bytes with length 4.
|
||||
///</summary>
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static byte[] GetBytes(uint value)
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified 64-bit unsigned integer value as an array of bytes.
|
||||
@@ -163,11 +175,12 @@ namespace FileSystemIDandChk
|
||||
/// Returns:
|
||||
/// An array of bytes with length 8.
|
||||
///</summary>
|
||||
[CLSCompliant(false)]
|
||||
//[CLSCompliant(false)]
|
||||
public static byte[] GetBytes(ulong value)
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns the specified 16-bit unsigned integer value as an array of bytes.
|
||||
@@ -183,6 +196,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.GetBytes(value) : BitConverter.GetBytes(value).Reverse().ToArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Converts the specified 64-bit signed integer to a double-precision floating
|
||||
@@ -195,7 +209,11 @@ namespace FileSystemIDandChk
|
||||
/// Returns:
|
||||
/// A double-precision floating point number whose value is equivalent to value.
|
||||
///</summary>
|
||||
public static double Int64BitsToDouble(long value) { throw new NotImplementedException(); }
|
||||
public static double Int64BitsToDouble(long value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a Boolean value converted from one byte at a specified position in
|
||||
@@ -218,7 +236,11 @@ namespace FileSystemIDandChk
|
||||
/// System.ArgumentOutOfRangeException:
|
||||
/// startIndex is less than zero or greater than the length of value minus 1.
|
||||
///</summary>
|
||||
public static bool ToBoolean(byte[] value, int startIndex) { throw new NotImplementedException(); }
|
||||
public static bool ToBoolean(byte[] value, int startIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a Unicode character converted from two bytes at a specified position
|
||||
@@ -244,7 +266,11 @@ namespace FileSystemIDandChk
|
||||
/// System.ArgumentOutOfRangeException:
|
||||
/// startIndex is less than zero or greater than the length of value minus 1.
|
||||
///</summary>
|
||||
public static char ToChar(byte[] value, int startIndex) { throw new NotImplementedException(); }
|
||||
public static char ToChar(byte[] value, int startIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a double-precision floating point number converted from eight bytes
|
||||
@@ -272,7 +298,11 @@ namespace FileSystemIDandChk
|
||||
/// System.ArgumentOutOfRangeException:
|
||||
/// startIndex is less than zero or greater than the length of value minus 1.
|
||||
///</summary>
|
||||
public static double ToDouble(byte[] value, int startIndex) { throw new NotImplementedException(); }
|
||||
public static double ToDouble(byte[] value, int startIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a 16-bit signed integer converted from two bytes at a specified position
|
||||
@@ -302,6 +332,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToInt16(value, startIndex) : BitConverter.ToInt16(value.Reverse().ToArray(), value.Length - sizeof(Int16) - startIndex);
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a 32-bit signed integer converted from four bytes at a specified
|
||||
@@ -332,6 +363,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToInt32(value, startIndex) : BitConverter.ToInt32(value.Reverse().ToArray(), value.Length - sizeof(Int32) - startIndex);
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a 64-bit signed integer converted from eight bytes at a specified
|
||||
@@ -362,6 +394,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToInt64(value, startIndex) : BitConverter.ToInt64(value.Reverse().ToArray(), value.Length - sizeof(Int64) - startIndex);
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a single-precision floating point number converted from four bytes
|
||||
@@ -393,6 +426,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToSingle(value, startIndex) : BitConverter.ToSingle(value.Reverse().ToArray(), value.Length - sizeof(Single) - startIndex);
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Converts the numeric value of each element of a specified array of bytes
|
||||
@@ -414,6 +448,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToString(value) : BitConverter.ToString(value.Reverse().ToArray());
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Converts the numeric value of each element of a specified subarray of bytes
|
||||
@@ -442,6 +477,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToString(value, startIndex) : BitConverter.ToString(value.Reverse().ToArray(), startIndex);
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Converts the numeric value of each element of a specified subarray of bytes
|
||||
@@ -479,6 +515,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToString(value, startIndex, length) : BitConverter.ToString(value.Reverse().ToArray(), startIndex, length);
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a 16-bit unsigned integer converted from two bytes at a specified
|
||||
@@ -508,6 +545,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToUInt16(value, startIndex) : BitConverter.ToUInt16(value.Reverse().ToArray(), value.Length - sizeof(UInt16) - startIndex);
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a 32-bit unsigned integer converted from four bytes at a specified
|
||||
@@ -538,6 +576,7 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
return !IsLittleEndian ? BitConverter.ToUInt32(value, startIndex) : BitConverter.ToUInt32(value.Reverse().ToArray(), value.Length - sizeof(UInt32) - startIndex);
|
||||
}
|
||||
|
||||
///
|
||||
/// <summary>
|
||||
/// Returns a 64-bit unsigned integer converted from eight bytes at a specified
|
||||
|
||||
@@ -1,3 +1,39 @@
|
||||
2014-04-14 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* Main.cs:
|
||||
* Plugins.cs:
|
||||
* Swapping.cs:
|
||||
* Plugins/BFS.cs:
|
||||
* Plugins/FAT.cs:
|
||||
* Plugins/FFS.cs:
|
||||
* Plugins/ODS.cs:
|
||||
* Plugins/NTFS.cs:
|
||||
* Plugins/HPFS.cs:
|
||||
* DateHandlers.cs:
|
||||
* Plugins/SysV.cs:
|
||||
* Plugins/extFS.cs:
|
||||
* Plugins/Opera.cs:
|
||||
* Plugins/Plugin.cs:
|
||||
* StringHandlers.cs:
|
||||
* Plugins/ext2FS.cs:
|
||||
* Plugins/SolarFS.cs:
|
||||
* Plugins/UNIXBFS.cs:
|
||||
* Plugins/MinixFS.cs:
|
||||
* Plugins/ISO9660.cs:
|
||||
* PartPlugins/MBR.cs:
|
||||
* Plugins/AppleMFS.cs:
|
||||
* PartPlugins/NeXT.cs:
|
||||
* Plugins/PCEngine.cs:
|
||||
* Plugins/AppleHFS.cs:
|
||||
* ImagePlugins/CDRWin.cs:
|
||||
* PartPlugins/AppleMap.cs:
|
||||
* Plugins/AppleHFSPlus.cs:
|
||||
* BigEndianBitConverter.cs:
|
||||
* FileSystemIDandChk.csproj:
|
||||
* EndianAwareBinaryReader.cs:
|
||||
* ImagePlugins/ImagePlugin.cs:
|
||||
Refactor and reformat code
|
||||
|
||||
2014-04-14 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* Main.cs:
|
||||
|
||||
@@ -2,103 +2,103 @@ 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 class DateHandlers
|
||||
{
|
||||
static readonly DateTime MacEpoch = new DateTime(1904, 1, 1, 0, 0, 0);
|
||||
static readonly DateTime UNIXEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||
static readonly 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 MacToDateTime(ulong MacTimeStamp)
|
||||
{
|
||||
return MacEpoch.AddTicks((long)(MacTimeStamp*10000000));
|
||||
}
|
||||
public static DateTime UNIXToDateTime(Int32 UNIXTimeStamp)
|
||||
{
|
||||
return UNIXEpoch.AddSeconds(UNIXTimeStamp);
|
||||
}
|
||||
|
||||
public static DateTime UNIXToDateTime(Int32 UNIXTimeStamp)
|
||||
{
|
||||
return UNIXEpoch.AddSeconds(UNIXTimeStamp);
|
||||
}
|
||||
public static DateTime UNIXUnsignedToDateTime(UInt32 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];
|
||||
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];
|
||||
if(MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: year = \"{0}\"",StringHandlers.CToString(fourcharvalue));
|
||||
if(!Int32.TryParse(StringHandlers.CToString(fourcharvalue), out year))
|
||||
year = 0;
|
||||
fourcharvalue[0] = VDDateTime[0];
|
||||
fourcharvalue[1] = VDDateTime[1];
|
||||
fourcharvalue[2] = VDDateTime[2];
|
||||
fourcharvalue[3] = VDDateTime[3];
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: year = \"{0}\"", StringHandlers.CToString(fourcharvalue));
|
||||
if (!Int32.TryParse(StringHandlers.CToString(fourcharvalue), out year))
|
||||
year = 0;
|
||||
// year = Convert.ToInt32(StringHandlers.CToString(fourcharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[4];
|
||||
twocharvalue[1] = VDDateTime[5];
|
||||
if(MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: month = \"{0}\"",StringHandlers.CToString(twocharvalue));
|
||||
if(!Int32.TryParse(StringHandlers.CToString(twocharvalue), out month))
|
||||
month = 0;
|
||||
twocharvalue[0] = VDDateTime[4];
|
||||
twocharvalue[1] = VDDateTime[5];
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: month = \"{0}\"", StringHandlers.CToString(twocharvalue));
|
||||
if (!Int32.TryParse(StringHandlers.CToString(twocharvalue), out month))
|
||||
month = 0;
|
||||
// month = Convert.ToInt32(StringHandlers.CToString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[6];
|
||||
twocharvalue[1] = VDDateTime[7];
|
||||
if(MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: day = \"{0}\"",StringHandlers.CToString(twocharvalue));
|
||||
if(!Int32.TryParse(StringHandlers.CToString(twocharvalue), out day))
|
||||
day = 0;
|
||||
twocharvalue[0] = VDDateTime[6];
|
||||
twocharvalue[1] = VDDateTime[7];
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: day = \"{0}\"", StringHandlers.CToString(twocharvalue));
|
||||
if (!Int32.TryParse(StringHandlers.CToString(twocharvalue), out day))
|
||||
day = 0;
|
||||
// day = Convert.ToInt32(StringHandlers.CToString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[8];
|
||||
twocharvalue[1] = VDDateTime[9];
|
||||
if(MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: hour = \"{0}\"",StringHandlers.CToString(twocharvalue));
|
||||
if(!Int32.TryParse(StringHandlers.CToString(twocharvalue), out hour))
|
||||
hour = 0;
|
||||
twocharvalue[0] = VDDateTime[8];
|
||||
twocharvalue[1] = VDDateTime[9];
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: hour = \"{0}\"", StringHandlers.CToString(twocharvalue));
|
||||
if (!Int32.TryParse(StringHandlers.CToString(twocharvalue), out hour))
|
||||
hour = 0;
|
||||
// hour = Convert.ToInt32(StringHandlers.CToString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[10];
|
||||
twocharvalue[1] = VDDateTime[11];
|
||||
if(MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: minute = \"{0}\"",StringHandlers.CToString(twocharvalue));
|
||||
if(!Int32.TryParse(StringHandlers.CToString(twocharvalue), out minute))
|
||||
minute = 0;
|
||||
twocharvalue[0] = VDDateTime[10];
|
||||
twocharvalue[1] = VDDateTime[11];
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: minute = \"{0}\"", StringHandlers.CToString(twocharvalue));
|
||||
if (!Int32.TryParse(StringHandlers.CToString(twocharvalue), out minute))
|
||||
minute = 0;
|
||||
// minute = Convert.ToInt32(StringHandlers.CToString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[12];
|
||||
twocharvalue[1] = VDDateTime[13];
|
||||
if(MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: second = \"{0}\"",StringHandlers.CToString(twocharvalue));
|
||||
if(!Int32.TryParse(StringHandlers.CToString(twocharvalue), out second))
|
||||
second = 0;
|
||||
twocharvalue[0] = VDDateTime[12];
|
||||
twocharvalue[1] = VDDateTime[13];
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: second = \"{0}\"", StringHandlers.CToString(twocharvalue));
|
||||
if (!Int32.TryParse(StringHandlers.CToString(twocharvalue), out second))
|
||||
second = 0;
|
||||
// second = Convert.ToInt32(StringHandlers.CToString(twocharvalue));
|
||||
|
||||
twocharvalue[0] = VDDateTime[14];
|
||||
twocharvalue[1] = VDDateTime[15];
|
||||
if(MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: hundredths = \"{0}\"",StringHandlers.CToString(twocharvalue));
|
||||
if(!Int32.TryParse(StringHandlers.CToString(twocharvalue), out hundredths))
|
||||
hundredths = 0;
|
||||
twocharvalue[0] = VDDateTime[14];
|
||||
twocharvalue[1] = VDDateTime[15];
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: hundredths = \"{0}\"", StringHandlers.CToString(twocharvalue));
|
||||
if (!Int32.TryParse(StringHandlers.CToString(twocharvalue), out hundredths))
|
||||
hundredths = 0;
|
||||
// hundredths = Convert.ToInt32(StringHandlers.CToString(twocharvalue));
|
||||
|
||||
if(MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: decodedDT = new DateTime({0}, {1}, {2}, {3}, {4}, {5}, {6}, DateTimeKind.Unspecified);", year, month, day, hour, minute, second, hundredths *10); DateTime decodedDT = new DateTime(year, month, day, hour, minute, second, hundredths * 10, DateTimeKind.Unspecified);
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("ISO9600ToDateTime: decodedDT = new DateTime({0}, {1}, {2}, {3}, {4}, {5}, {6}, DateTimeKind.Unspecified);", year, month, day, hour, minute, second, hundredths * 10);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,123 +5,120 @@ using System.Text;
|
||||
|
||||
namespace FileSystemIDandChk
|
||||
{
|
||||
public class EndianAwareBinaryReader : BinaryReader
|
||||
{
|
||||
private bool isLittleEndian;
|
||||
private byte[] buffer = new byte[8];
|
||||
|
||||
public EndianAwareBinaryReader(Stream input, Encoding encoding, bool isLittleEndian)
|
||||
public class EndianAwareBinaryReader : BinaryReader
|
||||
{
|
||||
byte[] buffer = new byte[8];
|
||||
|
||||
public EndianAwareBinaryReader(Stream input, Encoding encoding, bool isLittleEndian)
|
||||
: base(input, encoding)
|
||||
{
|
||||
this.isLittleEndian = isLittleEndian;
|
||||
}
|
||||
|
||||
public EndianAwareBinaryReader(Stream input, bool isLittleEndian)
|
||||
{
|
||||
IsLittleEndian = isLittleEndian;
|
||||
}
|
||||
|
||||
public EndianAwareBinaryReader(Stream input, bool isLittleEndian)
|
||||
: this(input, Encoding.UTF8, isLittleEndian)
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsLittleEndian
|
||||
{
|
||||
get { return isLittleEndian; }
|
||||
set { isLittleEndian = value; }
|
||||
}
|
||||
|
||||
|
||||
public override double ReadDouble()
|
||||
{
|
||||
if (isLittleEndian)
|
||||
return base.ReadDouble();
|
||||
FillMyBuffer(8);
|
||||
return BitConverter.ToDouble(buffer.Take(8).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override short ReadInt16()
|
||||
{
|
||||
if (isLittleEndian)
|
||||
return base.ReadInt16();
|
||||
FillMyBuffer(2);
|
||||
return BitConverter.ToInt16(buffer.Take(2).Reverse().ToArray(), 0);
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsLittleEndian
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public override double ReadDouble()
|
||||
{
|
||||
if (IsLittleEndian)
|
||||
return base.ReadDouble();
|
||||
FillMyBuffer(8);
|
||||
return BitConverter.ToDouble(buffer.Take(8).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override short ReadInt16()
|
||||
{
|
||||
if (IsLittleEndian)
|
||||
return base.ReadInt16();
|
||||
FillMyBuffer(2);
|
||||
return BitConverter.ToInt16(buffer.Take(2).Reverse().ToArray(), 0);
|
||||
|
||||
}
|
||||
|
||||
public override int ReadInt32()
|
||||
{
|
||||
if (isLittleEndian)
|
||||
return base.ReadInt32();
|
||||
FillMyBuffer(4);
|
||||
return BitConverter.ToInt32(buffer.Take(4).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override int ReadInt32()
|
||||
{
|
||||
if (IsLittleEndian)
|
||||
return base.ReadInt32();
|
||||
FillMyBuffer(4);
|
||||
return BitConverter.ToInt32(buffer.Take(4).Reverse().ToArray(), 0);
|
||||
|
||||
}
|
||||
|
||||
public override long ReadInt64()
|
||||
{
|
||||
if (isLittleEndian)
|
||||
return base.ReadInt64();
|
||||
FillMyBuffer(8);
|
||||
return BitConverter.ToInt64(buffer.Take(8).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override long ReadInt64()
|
||||
{
|
||||
if (IsLittleEndian)
|
||||
return base.ReadInt64();
|
||||
FillMyBuffer(8);
|
||||
return BitConverter.ToInt64(buffer.Take(8).Reverse().ToArray(), 0);
|
||||
|
||||
}
|
||||
|
||||
public override float ReadSingle()
|
||||
{
|
||||
if (isLittleEndian)
|
||||
return base.ReadSingle();
|
||||
FillMyBuffer(4);
|
||||
return BitConverter.ToSingle(buffer.Take(4).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override ushort ReadUInt16()
|
||||
{
|
||||
if (isLittleEndian)
|
||||
return base.ReadUInt16();
|
||||
FillMyBuffer(2);
|
||||
return BitConverter.ToUInt16(buffer.Take(2).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
|
||||
public override uint ReadUInt32()
|
||||
{
|
||||
if (isLittleEndian)
|
||||
return base.ReadUInt32();
|
||||
FillMyBuffer(4);
|
||||
return BitConverter.ToUInt32(buffer.Take(4).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override ulong ReadUInt64()
|
||||
{
|
||||
if (isLittleEndian)
|
||||
return base.ReadUInt64();
|
||||
FillMyBuffer(8);
|
||||
return BitConverter.ToUInt64(buffer.Take(8).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
private void FillMyBuffer(int numBytes)
|
||||
{
|
||||
int offset = 0;
|
||||
int num2 = 0;
|
||||
if (numBytes == 1)
|
||||
{
|
||||
num2 = BaseStream.ReadByte();
|
||||
if (num2 == -1)
|
||||
{
|
||||
throw new EndOfStreamException("Attempted to read past the end of the stream.");
|
||||
}
|
||||
buffer[0] = (byte)num2;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
num2 = BaseStream.Read(buffer, offset, numBytes - offset);
|
||||
if (num2 == 0)
|
||||
{
|
||||
throw new EndOfStreamException("Attempted to read past the end of the stream.");
|
||||
}
|
||||
offset += num2;
|
||||
}
|
||||
while (offset < numBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float ReadSingle()
|
||||
{
|
||||
if (IsLittleEndian)
|
||||
return base.ReadSingle();
|
||||
FillMyBuffer(4);
|
||||
return BitConverter.ToSingle(buffer.Take(4).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override ushort ReadUInt16()
|
||||
{
|
||||
if (IsLittleEndian)
|
||||
return base.ReadUInt16();
|
||||
FillMyBuffer(2);
|
||||
return BitConverter.ToUInt16(buffer.Take(2).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override uint ReadUInt32()
|
||||
{
|
||||
if (IsLittleEndian)
|
||||
return base.ReadUInt32();
|
||||
FillMyBuffer(4);
|
||||
return BitConverter.ToUInt32(buffer.Take(4).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
public override ulong ReadUInt64()
|
||||
{
|
||||
if (IsLittleEndian)
|
||||
return base.ReadUInt64();
|
||||
FillMyBuffer(8);
|
||||
return BitConverter.ToUInt64(buffer.Take(8).Reverse().ToArray(), 0);
|
||||
}
|
||||
|
||||
void FillMyBuffer(int numBytes)
|
||||
{
|
||||
int offset = 0;
|
||||
int num2;
|
||||
if (numBytes == 1)
|
||||
{
|
||||
num2 = BaseStream.ReadByte();
|
||||
if (num2 == -1)
|
||||
{
|
||||
throw new EndOfStreamException("Attempted to read past the end of the stream.");
|
||||
}
|
||||
buffer[0] = (byte)num2;
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
num2 = BaseStream.Read(buffer, offset, numBytes - offset);
|
||||
if (num2 == 0)
|
||||
{
|
||||
throw new EndOfStreamException("Attempted to read past the end of the stream.");
|
||||
}
|
||||
offset += num2;
|
||||
}
|
||||
while (offset < numBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,63 @@
|
||||
<ChangeLogPolicy UpdateMode="ProjectRoot" VcsIntegration="RequireEntry" inheritsSet="Mono">
|
||||
<MessageStyle LastFilePostfix=":
 " IncludeDirectoryPaths="True" />
|
||||
</ChangeLogPolicy>
|
||||
<DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
|
||||
<TextStylePolicy inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
|
||||
<CSharpFormattingPolicy IndentSwitchBody="True" AnonymousMethodBraceStyle="NextLine" PropertyBraceStyle="NextLine" PropertyGetBraceStyle="NextLine" PropertySetBraceStyle="NextLine" EventBraceStyle="NextLine" EventAddBraceStyle="NextLine" EventRemoveBraceStyle="NextLine" StatementBraceStyle="NextLine" ElseNewLinePlacement="NewLine" CatchNewLinePlacement="NewLine" FinallyNewLinePlacement="NewLine" WhileNewLinePlacement="DoNotCare" ArrayInitializerWrapping="DoNotChange" ArrayInitializerBraceStyle="NextLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
|
||||
<TextStylePolicy inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
|
||||
<NameConventionPolicy>
|
||||
<Rules>
|
||||
<NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
|
||||
<RequiredPrefixes>
|
||||
<String>I</String>
|
||||
</RequiredPrefixes>
|
||||
</NamingRule>
|
||||
<NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
|
||||
<RequiredSuffixes>
|
||||
<String>Attribute</String>
|
||||
</RequiredSuffixes>
|
||||
</NamingRule>
|
||||
<NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
|
||||
<RequiredSuffixes>
|
||||
<String>EventArgs</String>
|
||||
</RequiredSuffixes>
|
||||
</NamingRule>
|
||||
<NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
|
||||
<RequiredSuffixes>
|
||||
<String>Exception</String>
|
||||
</RequiredSuffixes>
|
||||
</NamingRule>
|
||||
<NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="PascalCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Protected, Public" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
|
||||
<NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
|
||||
<AllowedPrefixes>
|
||||
<String>_</String>
|
||||
<String>m_</String>
|
||||
</AllowedPrefixes>
|
||||
</NamingRule>
|
||||
<NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
|
||||
<AllowedPrefixes>
|
||||
<String>_</String>
|
||||
<String>m_</String>
|
||||
</AllowedPrefixes>
|
||||
</NamingRule>
|
||||
<NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Parameters" AffectedEntity="Parameter" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
|
||||
<NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
|
||||
<RequiredPrefixes>
|
||||
<String>T</String>
|
||||
</RequiredPrefixes>
|
||||
</NamingRule>
|
||||
</Rules>
|
||||
</NameConventionPolicy>
|
||||
</Policies>
|
||||
</Properties>
|
||||
</MonoDevelop>
|
||||
|
||||
@@ -207,7 +207,6 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
|
||||
#region Internal variables
|
||||
|
||||
bool initialized;
|
||||
string imagePath;
|
||||
StreamReader cueStream;
|
||||
FileStream imageStream;
|
||||
@@ -622,11 +621,11 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
}
|
||||
else if (MatchFlags.Success)
|
||||
{
|
||||
// TODO: Implement FLAGS support.
|
||||
if (MainClass.isDebug)
|
||||
Console.WriteLine("DEBUG (CDRWin plugin): Found FLAGS at line {0}", line);
|
||||
if (!intrack)
|
||||
throw new FeatureUnsupportedImageException(String.Format("Found FLAGS field in incorrect place at line {0}", line));
|
||||
// TODO: Implement FLAGS support.
|
||||
}
|
||||
else if (MatchGenre.Success)
|
||||
{
|
||||
@@ -769,8 +768,6 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
currenttrack.tracktype = MatchTrack.Groups[2].Value;
|
||||
currenttrack.session = currentsession;
|
||||
intrack = true;
|
||||
|
||||
// TODO
|
||||
}
|
||||
else if (_line == "") // Empty line, ignore it
|
||||
{
|
||||
@@ -796,7 +793,6 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
for (int s = 1; s <= _sessions.Length; s++)
|
||||
{
|
||||
_sessions[s - 1].SessionSequence = 1;
|
||||
ulong _session_offset;
|
||||
|
||||
if (s > 1)
|
||||
_sessions[s - 1].StartSector = _sessions[s - 2].EndSector + 1;
|
||||
@@ -804,7 +800,6 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
_sessions[s - 1].StartSector = 0;
|
||||
|
||||
ulong session_sectors = 0;
|
||||
bool first_session_track = true;
|
||||
int last_session_track = 0;
|
||||
|
||||
for (int i = 0; i < cuetracks.Length; i++)
|
||||
@@ -1375,26 +1370,27 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
|
||||
byte[] buffer = new byte[sector_size * length];
|
||||
|
||||
this.imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader br = new BinaryReader(this.imageStream);
|
||||
|
||||
br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin);
|
||||
|
||||
if (sector_offset == 0 && sector_skip == 0)
|
||||
buffer = br.ReadBytes((int)(sector_size * length));
|
||||
else
|
||||
imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read);
|
||||
using (BinaryReader br = new BinaryReader(imageStream))
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin);
|
||||
if (sector_offset == 0 && sector_skip == 0)
|
||||
buffer = br.ReadBytes((int)(sector_size * length));
|
||||
else
|
||||
{
|
||||
byte[] sector = new byte[sector_size];
|
||||
br.BaseStream.Seek(sector_offset, SeekOrigin.Current);
|
||||
sector = br.ReadBytes((int)sector_size);
|
||||
br.BaseStream.Seek(sector_skip, SeekOrigin.Current);
|
||||
|
||||
System.Array.Copy(sector, 0, buffer, i * sector_size, sector_size);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
byte[] sector;
|
||||
br.BaseStream.Seek(sector_offset, SeekOrigin.Current);
|
||||
sector = br.ReadBytes((int)sector_size);
|
||||
br.BaseStream.Seek(sector_skip, SeekOrigin.Current);
|
||||
Array.Copy(sector, 0, buffer, i * sector_size, sector_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -1569,26 +1565,27 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
|
||||
byte[] buffer = new byte[sector_size * length];
|
||||
|
||||
this.imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader br = new BinaryReader(this.imageStream);
|
||||
|
||||
br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin);
|
||||
|
||||
if (sector_offset == 0 && sector_skip == 0)
|
||||
buffer = br.ReadBytes((int)(sector_size * length));
|
||||
else
|
||||
imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read);
|
||||
using (BinaryReader br = new BinaryReader(imageStream))
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin);
|
||||
if (sector_offset == 0 && sector_skip == 0)
|
||||
buffer = br.ReadBytes((int)(sector_size * length));
|
||||
else
|
||||
{
|
||||
byte[] sector = new byte[sector_size];
|
||||
br.BaseStream.Seek(sector_offset, SeekOrigin.Current);
|
||||
sector = br.ReadBytes((int)sector_size);
|
||||
br.BaseStream.Seek(sector_skip, SeekOrigin.Current);
|
||||
|
||||
System.Array.Copy(sector, 0, buffer, i * sector_size, sector_size);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
byte[] sector;
|
||||
br.BaseStream.Seek(sector_offset, SeekOrigin.Current);
|
||||
sector = br.ReadBytes((int)sector_size);
|
||||
br.BaseStream.Seek(sector_skip, SeekOrigin.Current);
|
||||
Array.Copy(sector, 0, buffer, i * sector_size, sector_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -1695,8 +1692,8 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
|
||||
byte[] buffer = new byte[sector_size * length];
|
||||
|
||||
this.imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader br = new BinaryReader(this.imageStream);
|
||||
imageStream = new FileStream(_track.trackfile.datafile, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader br = new BinaryReader(imageStream);
|
||||
|
||||
br.BaseStream.Seek((long)_track.trackfile.offset + (long)(sectorAddress * (sector_offset + sector_size + sector_skip)), SeekOrigin.Begin);
|
||||
|
||||
@@ -1706,12 +1703,12 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
byte[] sector = new byte[sector_size];
|
||||
byte[] sector;
|
||||
br.BaseStream.Seek(sector_offset, SeekOrigin.Current);
|
||||
sector = br.ReadBytes((int)sector_size);
|
||||
br.BaseStream.Seek(sector_skip, SeekOrigin.Current);
|
||||
|
||||
System.Array.Copy(sector, 0, buffer, i * sector_size, sector_size);
|
||||
Array.Copy(sector, 0, buffer, i * sector_size, sector_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1810,8 +1807,7 @@ namespace FileSystemIDandChk.ImagePlugins
|
||||
{
|
||||
return GetSessionTracks(session.SessionSequence);
|
||||
}
|
||||
else
|
||||
throw new ImageNotSupportedException("Session does not exist in disc image");
|
||||
throw new ImageNotSupportedException("Session does not exist in disc image");
|
||||
}
|
||||
|
||||
public override List<Track> GetSessionTracks(UInt16 session)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace FileSystemIDandChk.ImagePlugins
|
||||
{
|
||||
|
||||
@@ -7,26 +7,26 @@ using FileSystemIDandChk.ImagePlugins;
|
||||
|
||||
namespace FileSystemIDandChk
|
||||
{
|
||||
class MainClass
|
||||
{
|
||||
static PluginBase plugins;
|
||||
public static bool chkPartitions;
|
||||
public static bool chkFilesystems;
|
||||
public static bool isDebug;
|
||||
|
||||
public static void Main (string[] args)
|
||||
{
|
||||
plugins = new PluginBase();
|
||||
class MainClass
|
||||
{
|
||||
static PluginBase plugins;
|
||||
public static bool chkPartitions;
|
||||
public static bool chkFilesystems;
|
||||
public static bool isDebug;
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
plugins = new PluginBase();
|
||||
|
||||
chkPartitions = true;
|
||||
chkFilesystems = true;
|
||||
chkPartitions = true;
|
||||
chkFilesystems = true;
|
||||
// RELEASE
|
||||
//isDebug = false;
|
||||
// DEBUG
|
||||
isDebug = true;
|
||||
|
||||
Console.WriteLine ("Filesystem Identifier and Checker");
|
||||
Console.WriteLine ("Copyright (C) Natalia Portillo, All Rights Reserved");
|
||||
Console.WriteLine("Filesystem Identifier and Checker");
|
||||
Console.WriteLine("Copyright (C) Natalia Portillo, All Rights Reserved");
|
||||
|
||||
// For debug
|
||||
if (isDebug)
|
||||
@@ -82,32 +82,29 @@ namespace FileSystemIDandChk
|
||||
case "--debug":
|
||||
isDebug = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Runner(args[args.Length - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Runner (string filename)
|
||||
{
|
||||
FileStream stream;
|
||||
List<string> id_plugins;
|
||||
Plugin _plugin;
|
||||
string information;
|
||||
bool checkraw = false;
|
||||
static void Runner(string filename)
|
||||
{
|
||||
List<string> id_plugins;
|
||||
Plugin _plugin;
|
||||
string information;
|
||||
bool checkraw = false;
|
||||
ImagePlugin _imageFormat;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
_imageFormat = null;
|
||||
|
||||
foreach(ImagePlugin _imageplugin in plugins.ImagePluginsList.Values)
|
||||
foreach (ImagePlugin _imageplugin in plugins.ImagePluginsList.Values)
|
||||
{
|
||||
if(_imageplugin.IdentifyImage(filename))
|
||||
if (_imageplugin.IdentifyImage(filename))
|
||||
{
|
||||
_imageFormat = _imageplugin;
|
||||
Console.WriteLine("Image format identified by {0}.", _imageplugin.Name);
|
||||
@@ -115,7 +112,7 @@ namespace FileSystemIDandChk
|
||||
}
|
||||
}
|
||||
|
||||
if(_imageFormat == null)
|
||||
if (_imageFormat == null)
|
||||
{
|
||||
Console.WriteLine("Image format not identified, not proceeding.");
|
||||
return;
|
||||
@@ -123,21 +120,21 @@ namespace FileSystemIDandChk
|
||||
|
||||
try
|
||||
{
|
||||
if(!_imageFormat.OpenImage(filename))
|
||||
if (!_imageFormat.OpenImage(filename))
|
||||
{
|
||||
Console.WriteLine("Unable to open image format");
|
||||
Console.WriteLine("No error given");
|
||||
return;
|
||||
}
|
||||
|
||||
if(isDebug)
|
||||
if (isDebug)
|
||||
{
|
||||
Console.WriteLine("DEBUG: Correctly opened image file.");
|
||||
Console.WriteLine("DEBUG: Image without headers is {0} bytes.", _imageFormat.GetImageSize());
|
||||
Console.WriteLine("DEBUG: Image has {0} sectors.", _imageFormat.GetSectors());
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Unable to open image format");
|
||||
Console.WriteLine("Error: {0}", ex.Message);
|
||||
@@ -146,152 +143,147 @@ namespace FileSystemIDandChk
|
||||
|
||||
Console.WriteLine("Image identified as {0}.", _imageFormat.GetImageFormat());
|
||||
|
||||
if(chkPartitions)
|
||||
{
|
||||
List<Partition> partitions = new List<Partition>();
|
||||
string partition_scheme = "";
|
||||
if (chkPartitions)
|
||||
{
|
||||
List<Partition> partitions = new List<Partition>();
|
||||
string partition_scheme = "";
|
||||
|
||||
// TODO: Solve possibility of multiple partition schemes (CUE + MBR, MBR + RDB, CUE + APM, etc)
|
||||
foreach (PartPlugin _partplugin in plugins.PartPluginsList.Values)
|
||||
{
|
||||
List<Partition> _partitions;
|
||||
foreach (PartPlugin _partplugin in plugins.PartPluginsList.Values)
|
||||
{
|
||||
List<Partition> _partitions;
|
||||
|
||||
if (_partplugin.GetInformation(_imageFormat, out _partitions))
|
||||
{
|
||||
partition_scheme=_partplugin.Name;
|
||||
partitions = _partitions;
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
partition_scheme = _partplugin.Name;
|
||||
partitions = _partitions;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(_imageFormat.ImageHasPartitions())
|
||||
if (_imageFormat.ImageHasPartitions())
|
||||
{
|
||||
partition_scheme = _imageFormat.GetImageFormat();
|
||||
partitions = _imageFormat.GetPartitions();
|
||||
}
|
||||
|
||||
if(partition_scheme=="")
|
||||
{
|
||||
if (partition_scheme == "")
|
||||
{
|
||||
Console.WriteLine("DEBUG: No partitions found");
|
||||
if(!chkFilesystems)
|
||||
{
|
||||
Console.WriteLine("No partitions founds, not searching for filesystems");
|
||||
return;
|
||||
}
|
||||
else
|
||||
checkraw = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Partition scheme identified as {0}", partition_scheme);
|
||||
Console.WriteLine("{0} partitions found.", partitions.Count);
|
||||
if (!chkFilesystems)
|
||||
{
|
||||
Console.WriteLine("No partitions founds, not searching for filesystems");
|
||||
return;
|
||||
}
|
||||
checkraw = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Partition scheme identified as {0}", partition_scheme);
|
||||
Console.WriteLine("{0} partitions found.", partitions.Count);
|
||||
|
||||
for(int i = 0; i< partitions.Count; i++)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Partition {0}:", partitions[i].PartitionSequence);
|
||||
Console.WriteLine("Partition name: {0}", partitions[i].PartitionName);
|
||||
Console.WriteLine("Partition type: {0}", partitions[i].PartitionType);
|
||||
Console.WriteLine("Partition start: {0}", partitions[i].PartitionStart);
|
||||
Console.WriteLine("Partition length: {0}", partitions[i].PartitionLength);
|
||||
Console.WriteLine("Partition description:");
|
||||
Console.WriteLine(partitions[i].PartitionDescription);
|
||||
for (int i = 0; i < partitions.Count; i++)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Partition {0}:", partitions[i].PartitionSequence);
|
||||
Console.WriteLine("Partition name: {0}", partitions[i].PartitionName);
|
||||
Console.WriteLine("Partition type: {0}", partitions[i].PartitionType);
|
||||
Console.WriteLine("Partition start: {0}", partitions[i].PartitionStart);
|
||||
Console.WriteLine("Partition length: {0}", partitions[i].PartitionLength);
|
||||
Console.WriteLine("Partition description:");
|
||||
Console.WriteLine(partitions[i].PartitionDescription);
|
||||
|
||||
if(chkFilesystems)
|
||||
{
|
||||
Console.WriteLine("Identifying filesystem on partition");
|
||||
if (chkFilesystems)
|
||||
{
|
||||
Console.WriteLine("Identifying filesystem on partition");
|
||||
|
||||
Identify(_imageFormat, out id_plugins, partitions[i].PartitionStart);
|
||||
if(id_plugins.Count==0)
|
||||
Console.WriteLine("Filesystem not identified");
|
||||
else if(id_plugins.Count>1)
|
||||
{
|
||||
Console.WriteLine(String.Format("Identified by {0} plugins", id_plugins.Count));
|
||||
if (id_plugins.Count == 0)
|
||||
Console.WriteLine("Filesystem not identified");
|
||||
else if (id_plugins.Count > 1)
|
||||
{
|
||||
Console.WriteLine(String.Format("Identified by {0} plugins", id_plugins.Count));
|
||||
|
||||
foreach(string plugin_name in id_plugins)
|
||||
{
|
||||
if(plugins.PluginsList.TryGetValue(plugin_name, out _plugin))
|
||||
{
|
||||
Console.WriteLine(String.Format("As identified by {0}.", _plugin.Name));
|
||||
foreach (string plugin_name in id_plugins)
|
||||
{
|
||||
if (plugins.PluginsList.TryGetValue(plugin_name, out _plugin))
|
||||
{
|
||||
Console.WriteLine(String.Format("As identified by {0}.", _plugin.Name));
|
||||
_plugin.GetInformation(_imageFormat, partitions[i].PartitionStart, out information);
|
||||
Console.Write(information);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.PluginsList.TryGetValue(id_plugins[0], out _plugin);
|
||||
Console.WriteLine(String.Format("Identified by {0}.", _plugin.Name));
|
||||
Console.Write(information);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.PluginsList.TryGetValue(id_plugins[0], out _plugin);
|
||||
Console.WriteLine(String.Format("Identified by {0}.", _plugin.Name));
|
||||
_plugin.GetInformation(_imageFormat, partitions[i].PartitionStart, out information);
|
||||
Console.Write(information);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.Write(information);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(checkraw)
|
||||
{
|
||||
if (checkraw)
|
||||
{
|
||||
Identify(_imageFormat, out id_plugins, 0);
|
||||
if(id_plugins.Count==0)
|
||||
Console.WriteLine("Filesystem not identified");
|
||||
else if(id_plugins.Count>1)
|
||||
{
|
||||
Console.WriteLine(String.Format("Identified by {0} plugins", id_plugins.Count));
|
||||
if (id_plugins.Count == 0)
|
||||
Console.WriteLine("Filesystem not identified");
|
||||
else if (id_plugins.Count > 1)
|
||||
{
|
||||
Console.WriteLine(String.Format("Identified by {0} plugins", id_plugins.Count));
|
||||
|
||||
foreach(string plugin_name in id_plugins)
|
||||
{
|
||||
if(plugins.PluginsList.TryGetValue(plugin_name, out _plugin))
|
||||
{
|
||||
Console.WriteLine(String.Format("As identified by {0}.", _plugin.Name));
|
||||
foreach (string plugin_name in id_plugins)
|
||||
{
|
||||
if (plugins.PluginsList.TryGetValue(plugin_name, out _plugin))
|
||||
{
|
||||
Console.WriteLine(String.Format("As identified by {0}.", _plugin.Name));
|
||||
_plugin.GetInformation(_imageFormat, 0, out information);
|
||||
Console.Write(information);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.PluginsList.TryGetValue(id_plugins[0], out _plugin);
|
||||
Console.WriteLine(String.Format("Identified by {0}.", _plugin.Name));
|
||||
Console.Write(information);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugins.PluginsList.TryGetValue(id_plugins[0], out _plugin);
|
||||
Console.WriteLine(String.Format("Identified by {0}.", _plugin.Name));
|
||||
_plugin.GetInformation(_imageFormat, 0, out information);
|
||||
Console.Write(information);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Console.WriteLine(String.Format("Error reading file: {0}", ex.Message));
|
||||
if(isDebug)
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
stream = null;
|
||||
}
|
||||
}
|
||||
Console.Write(information);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(String.Format("Error reading file: {0}", ex.Message));
|
||||
if (isDebug)
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Identify (ImagePlugins.ImagePlugin imagePlugin, out List<string> id_plugins, ulong partitionOffset)
|
||||
{
|
||||
id_plugins = new List<string>();
|
||||
static void Identify(ImagePlugin imagePlugin, out List<string> id_plugins, ulong partitionOffset)
|
||||
{
|
||||
id_plugins = new List<string>();
|
||||
|
||||
foreach (Plugin _plugin in plugins.PluginsList.Values)
|
||||
foreach (Plugin _plugin in plugins.PluginsList.Values)
|
||||
{
|
||||
if (_plugin.Identify(imagePlugin, partitionOffset))
|
||||
id_plugins.Add(_plugin.Name.ToLower());
|
||||
id_plugins.Add(_plugin.Name.ToLower());
|
||||
}
|
||||
}
|
||||
|
||||
private static void Usage ()
|
||||
{
|
||||
Console.WriteLine("Usage: filesystemidandchk [options] file");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" --formats List all suported partition and filesystems");
|
||||
Console.WriteLine(" --debug Show debug information");
|
||||
Console.WriteLine(" --partitions Check only for partitions");
|
||||
Console.WriteLine(" --filesystems Check only for filesystems");
|
||||
Console.WriteLine(" --all Check for partitions and filesystems (default)");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Usage()
|
||||
{
|
||||
Console.WriteLine("Usage: filesystemidandchk [options] file");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(" --formats List all suported partition and filesystems");
|
||||
Console.WriteLine(" --debug Show debug information");
|
||||
Console.WriteLine(" --partitions Check only for partitions");
|
||||
Console.WriteLine(" --filesystems Check only for filesystems");
|
||||
Console.WriteLine(" --all Check for partitions and filesystems (default)");
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.PartPlugins
|
||||
{
|
||||
class AppleMap : PartPlugin
|
||||
{
|
||||
private const UInt16 APM_MAGIC = 0x4552; // "ER"
|
||||
private const UInt16 APM_ENTRY = 0x504D; // "PM"
|
||||
private const UInt16 APM_OLDENT = 0x5453; // "TS", old entry magic
|
||||
class AppleMap : PartPlugin
|
||||
{
|
||||
// "ER"
|
||||
const UInt16 APM_MAGIC = 0x4552;
|
||||
// "PM"
|
||||
const UInt16 APM_ENTRY = 0x504D;
|
||||
// "TS", old entry magic
|
||||
const UInt16 APM_OLDENT = 0x5453;
|
||||
|
||||
public AppleMap (PluginBase Core)
|
||||
{
|
||||
public AppleMap(PluginBase Core)
|
||||
{
|
||||
Name = "Apple Partition Map";
|
||||
PluginUUID = new Guid("36405F8D-4F1A-07F5-209C-223D735D6D22");
|
||||
}
|
||||
|
||||
public override bool GetInformation (ImagePlugins.ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
byte[] cString;
|
||||
PluginUUID = new Guid("36405F8D-4F1A-07F5-209C-223D735D6D22");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugins.ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
byte[] cString;
|
||||
|
||||
ulong apm_entries;
|
||||
ulong apm_entries;
|
||||
uint sector_size;
|
||||
|
||||
if (imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
@@ -30,10 +32,10 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
else
|
||||
sector_size = imagePlugin.GetSectorSize();
|
||||
|
||||
partitions = new List<Partition>();
|
||||
partitions = new List<Partition>();
|
||||
|
||||
AppleMapBootEntry APMB = new AppleMapBootEntry();
|
||||
AppleMapPartitionEntry APMEntry = new AppleMapPartitionEntry();
|
||||
AppleMapBootEntry APMB = new AppleMapBootEntry();
|
||||
AppleMapPartitionEntry APMEntry = new AppleMapPartitionEntry();
|
||||
|
||||
byte[] APMB_sector = imagePlugin.ReadSector(0);
|
||||
|
||||
@@ -88,8 +90,8 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
|
||||
apm_entries = APMEntry.entries;
|
||||
|
||||
for(ulong i = 0; i < apm_entries; i++) // For each partition
|
||||
{
|
||||
for (ulong i = 0; i < apm_entries; i++) // For each partition
|
||||
{
|
||||
APMEntry = new AppleMapPartitionEntry();
|
||||
APMEntry_sector = imagePlugin.ReadSector(first_sector + i);
|
||||
APMEntry.signature = BigEndianBitConverter.ToUInt16(APMEntry_sector, 0x00);
|
||||
@@ -117,90 +119,118 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
Array.Copy(APMEntry_sector, 0x78, cString, 0, 16);
|
||||
APMEntry.processor = StringHandlers.CToString(cString);
|
||||
|
||||
if(APMEntry.signature == APM_ENTRY || APMEntry.signature == APM_OLDENT) // It should have partition entry signature
|
||||
{
|
||||
Partition _partition = new Partition();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (APMEntry.signature == APM_ENTRY || APMEntry.signature == APM_OLDENT) // It should have partition entry signature
|
||||
{
|
||||
Partition _partition = new Partition();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
_partition.PartitionSequence = i;
|
||||
_partition.PartitionType = APMEntry.type;
|
||||
_partition.PartitionName = APMEntry.name;
|
||||
_partition.PartitionSequence = i;
|
||||
_partition.PartitionType = APMEntry.type;
|
||||
_partition.PartitionName = APMEntry.name;
|
||||
_partition.PartitionStart = APMEntry.start * sector_size;
|
||||
_partition.PartitionLength = APMEntry.sectors * sector_size;
|
||||
_partition.PartitionStartSector = APMEntry.start;
|
||||
_partition.PartitionSectors = APMEntry.sectors;
|
||||
|
||||
sb.AppendLine("Partition flags:");
|
||||
if((APMEntry.status & 0x01) == 0x01)
|
||||
sb.AppendLine("Partition is valid.");
|
||||
if((APMEntry.status & 0x02) == 0x02)
|
||||
sb.AppendLine("Partition entry is not available.");
|
||||
if((APMEntry.status & 0x04) == 0x04)
|
||||
sb.AppendLine("Partition is mounted.");
|
||||
if((APMEntry.status & 0x08) == 0x08)
|
||||
sb.AppendLine("Partition is bootable.");
|
||||
if((APMEntry.status & 0x10) == 0x10)
|
||||
sb.AppendLine("Partition is readable.");
|
||||
if((APMEntry.status & 0x20) == 0x20)
|
||||
sb.AppendLine("Partition is writable.");
|
||||
if((APMEntry.status & 0x40) == 0x40)
|
||||
sb.AppendLine("Partition's boot code is position independent.");
|
||||
sb.AppendLine("Partition flags:");
|
||||
if ((APMEntry.status & 0x01) == 0x01)
|
||||
sb.AppendLine("Partition is valid.");
|
||||
if ((APMEntry.status & 0x02) == 0x02)
|
||||
sb.AppendLine("Partition entry is not available.");
|
||||
if ((APMEntry.status & 0x04) == 0x04)
|
||||
sb.AppendLine("Partition is mounted.");
|
||||
if ((APMEntry.status & 0x08) == 0x08)
|
||||
sb.AppendLine("Partition is bootable.");
|
||||
if ((APMEntry.status & 0x10) == 0x10)
|
||||
sb.AppendLine("Partition is readable.");
|
||||
if ((APMEntry.status & 0x20) == 0x20)
|
||||
sb.AppendLine("Partition is writable.");
|
||||
if ((APMEntry.status & 0x40) == 0x40)
|
||||
sb.AppendLine("Partition's boot code is position independent.");
|
||||
|
||||
if((APMEntry.status & 0x08) == 0x08)
|
||||
{
|
||||
sb.AppendFormat("First boot sector: {0}", APMEntry.first_boot_block).AppendLine();
|
||||
sb.AppendFormat("Boot is {0} bytes.", APMEntry.boot_size).AppendLine();
|
||||
sb.AppendFormat("Boot load address: 0x{0:X8}", APMEntry.load_address).AppendLine();
|
||||
sb.AppendFormat("Boot entry point: 0x{0:X8}", APMEntry.entry_point).AppendLine();
|
||||
sb.AppendFormat("Boot code checksum: 0x{0:X8}", APMEntry.checksum).AppendLine();
|
||||
sb.AppendFormat("Processor: {0}", APMEntry.processor).AppendLine();
|
||||
}
|
||||
if ((APMEntry.status & 0x08) == 0x08)
|
||||
{
|
||||
sb.AppendFormat("First boot sector: {0}", APMEntry.first_boot_block).AppendLine();
|
||||
sb.AppendFormat("Boot is {0} bytes.", APMEntry.boot_size).AppendLine();
|
||||
sb.AppendFormat("Boot load address: 0x{0:X8}", APMEntry.load_address).AppendLine();
|
||||
sb.AppendFormat("Boot entry point: 0x{0:X8}", APMEntry.entry_point).AppendLine();
|
||||
sb.AppendFormat("Boot code checksum: 0x{0:X8}", APMEntry.checksum).AppendLine();
|
||||
sb.AppendFormat("Processor: {0}", APMEntry.processor).AppendLine();
|
||||
}
|
||||
|
||||
_partition.PartitionDescription = sb.ToString();
|
||||
_partition.PartitionDescription = sb.ToString();
|
||||
|
||||
if((APMEntry.status & 0x01) == 0x01)
|
||||
if(APMEntry.type != "Apple_partition_map")
|
||||
partitions.Add(_partition);
|
||||
}
|
||||
}
|
||||
if ((APMEntry.status & 0x01) == 0x01)
|
||||
if (APMEntry.type != "Apple_partition_map")
|
||||
partitions.Add(_partition);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public struct AppleMapBootEntry
|
||||
{
|
||||
public UInt16 signature; // Signature ("ER")
|
||||
public UInt16 sector_size; // Byter per sector
|
||||
public UInt32 sectors; // Sectors of the disk
|
||||
public UInt16 reserved1; // Reserved
|
||||
public UInt16 reserved2; // Reserved
|
||||
public UInt32 reserved3; // Reserved
|
||||
public UInt16 driver_entries; // Number of entries of the driver descriptor
|
||||
public UInt32 first_driver_blk; // First sector of the driver
|
||||
public UInt16 driver_size; // Size in 512bytes sectors of the driver
|
||||
public UInt16 operating_system; // Operating system (MacOS = 1)
|
||||
}
|
||||
|
||||
public struct AppleMapPartitionEntry
|
||||
{
|
||||
public UInt16 signature; // Signature ("PM" or "TS")
|
||||
public UInt16 reserved1; // Reserved
|
||||
public UInt32 entries; // Number of entries on the partition map, each one sector
|
||||
public UInt32 start; // First sector of the partition
|
||||
public UInt32 sectors; // Number of sectos of the partition
|
||||
public string name; // Partition name, 32 bytes, null-padded
|
||||
public string type; // Partition type. 32 bytes, null-padded
|
||||
public UInt32 first_data_block; // First sector of the data area
|
||||
public UInt32 data_sectors; // Number of sectors of the data area
|
||||
public UInt32 status; // Partition status
|
||||
public UInt32 first_boot_block; // First sector of the boot code
|
||||
public UInt32 boot_size; // Size in bytes of the boot code
|
||||
public UInt32 load_address; // Load address of the boot code
|
||||
public UInt32 reserved2; // Reserved
|
||||
public UInt32 entry_point; // Entry point of the boot code
|
||||
public UInt32 reserved3; // Reserved
|
||||
public UInt32 checksum; // Boot code checksum
|
||||
public string processor; // Processor type, 16 bytes, null-padded
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public struct AppleMapBootEntry
|
||||
{
|
||||
// Signature ("ER")
|
||||
public UInt16 signature;
|
||||
// Byter per sector
|
||||
public UInt16 sector_size;
|
||||
// Sectors of the disk
|
||||
public UInt32 sectors;
|
||||
// Reserved
|
||||
public UInt16 reserved1;
|
||||
// Reserved
|
||||
public UInt16 reserved2;
|
||||
// Reserved
|
||||
public UInt32 reserved3;
|
||||
// Number of entries of the driver descriptor
|
||||
public UInt16 driver_entries;
|
||||
// First sector of the driver
|
||||
public UInt32 first_driver_blk;
|
||||
// Size in 512bytes sectors of the driver
|
||||
public UInt16 driver_size;
|
||||
// Operating system (MacOS = 1)
|
||||
public UInt16 operating_system;
|
||||
}
|
||||
|
||||
public struct AppleMapPartitionEntry
|
||||
{
|
||||
// Signature ("PM" or "TS")
|
||||
public UInt16 signature;
|
||||
// Reserved
|
||||
public UInt16 reserved1;
|
||||
// Number of entries on the partition map, each one sector
|
||||
public UInt32 entries;
|
||||
// First sector of the partition
|
||||
public UInt32 start;
|
||||
// Number of sectos of the partition
|
||||
public UInt32 sectors;
|
||||
// Partition name, 32 bytes, null-padded
|
||||
public string name;
|
||||
// Partition type. 32 bytes, null-padded
|
||||
public string type;
|
||||
// First sector of the data area
|
||||
public UInt32 first_data_block;
|
||||
// Number of sectors of the data area
|
||||
public UInt32 data_sectors;
|
||||
// Partition status
|
||||
public UInt32 status;
|
||||
// First sector of the boot code
|
||||
public UInt32 first_boot_block;
|
||||
// Size in bytes of the boot code
|
||||
public UInt32 boot_size;
|
||||
// Load address of the boot code
|
||||
public UInt32 load_address;
|
||||
// Reserved
|
||||
public UInt32 reserved2;
|
||||
// Entry point of the boot code
|
||||
public UInt32 entry_point;
|
||||
// Reserved
|
||||
public UInt32 reserved3;
|
||||
// Boot code checksum
|
||||
public UInt32 checksum;
|
||||
// Processor type, 16 bytes, null-padded
|
||||
public string processor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
// TODO: Support AAP, AST, SpeedStor and Ontrack extensions
|
||||
@@ -13,15 +13,14 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
|
||||
public MBR(PluginBase Core)
|
||||
{
|
||||
base.Name = "Master Boot Record";
|
||||
base.PluginUUID = new Guid("5E8A34E8-4F1A-59E6-4BF7-7EA647063A76");
|
||||
Name = "Master Boot Record";
|
||||
PluginUUID = new Guid("5E8A34E8-4F1A-59E6-4BF7-7EA647063A76");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugins.ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
byte cyl_sect1, cyl_sect2; // For decoding cylinder and sector
|
||||
UInt16 signature;
|
||||
UInt32 serial;
|
||||
ulong counter = 0;
|
||||
|
||||
partitions = new List<Partition>();
|
||||
@@ -33,8 +32,6 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
if (signature != MBRSignature)
|
||||
return false; // Not MBR
|
||||
|
||||
serial = BitConverter.ToUInt32(sector, 0x1B8);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
MBRPartitionEntry entry = new MBRPartitionEntry();
|
||||
@@ -68,8 +65,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
|
||||
if (entry.status != 0x00 && entry.status != 0x80)
|
||||
return false; // Maybe a FAT filesystem
|
||||
if (entry.type == 0x00)
|
||||
valid = false;
|
||||
valid &= entry.type != 0x00;
|
||||
if (entry.type == 0xEE || entry.type == 0xEF)
|
||||
return false; // This is a GPT
|
||||
if (entry.type == 0x05 || entry.type == 0x0F || entry.type == 0x85)
|
||||
@@ -84,8 +80,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
disklabel = true;
|
||||
}
|
||||
|
||||
if (entry.lba_start == 0 && entry.lba_sectors == 0 && entry.start_cylinder == 0 && entry.start_head == 0 && entry.start_sector == 0 && entry.end_cylinder == 0 && entry.end_head == 0 && entry.end_sector == 0)
|
||||
valid = false;
|
||||
valid &= entry.lba_start != 0 || entry.lba_sectors != 0 || entry.start_cylinder != 0 || entry.start_head != 0 || entry.start_sector != 0 || entry.end_cylinder != 0 || entry.end_head != 0 || entry.end_sector != 0;
|
||||
if (entry.lba_start == 0 && entry.lba_sectors == 0 && valid)
|
||||
{
|
||||
entry.lba_start = CHStoLBA(entry.start_cylinder, entry.start_head, entry.start_sector);
|
||||
@@ -302,8 +297,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
if (!minix_subs)
|
||||
valid = true;
|
||||
valid |= !minix_subs;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -338,10 +332,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
part.PartitionType = String.Format("0x{0:X2}", entry.type);
|
||||
part.PartitionName = decodeMBRType(entry.type);
|
||||
part.PartitionSequence = counter;
|
||||
if (entry.status == 0x80)
|
||||
part.PartitionDescription = "Partition is bootable.";
|
||||
else
|
||||
part.PartitionDescription = "";
|
||||
part.PartitionDescription = entry.status == 0x80 ? "Partition is bootable." : "";
|
||||
|
||||
counter++;
|
||||
|
||||
@@ -388,10 +379,8 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
|
||||
// Let's start the fun...
|
||||
|
||||
if (entry2.status != 0x00 && entry2.status != 0x80)
|
||||
ext_valid = false;
|
||||
if (entry2.type == 0x00)
|
||||
valid = false;
|
||||
ext_valid &= entry2.status == 0x00 || entry2.status == 0x80;
|
||||
valid &= entry2.type != 0x00;
|
||||
if (entry2.type == 0x82 || entry2.type == 0xBF || entry2.type == 0xA5 || entry2.type == 0xA6 ||
|
||||
entry2.type == 0xA9 || entry2.type == 0xB7 || entry2.type == 0x81 || entry2.type == 0x63)
|
||||
{
|
||||
@@ -404,8 +393,8 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
ext_disklabel = false;
|
||||
ext_extended = true; // Extended partition
|
||||
}
|
||||
else if (l == 1)
|
||||
processing_extended = false;
|
||||
else
|
||||
processing_extended &= l != 1;
|
||||
|
||||
if (ext_disklabel)
|
||||
{
|
||||
@@ -610,8 +599,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
if (!minix_subs)
|
||||
ext_valid = true;
|
||||
ext_valid |= !minix_subs;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -647,10 +635,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
part.PartitionType = String.Format("0x{0:X2}", entry2.type);
|
||||
part.PartitionName = decodeMBRType(entry2.type);
|
||||
part.PartitionSequence = counter;
|
||||
if (entry2.status == 0x80)
|
||||
part.PartitionDescription = "Partition is bootable.";
|
||||
else
|
||||
part.PartitionDescription = "";
|
||||
part.PartitionDescription = entry2.status == 0x80 ? "Partition is bootable." : "";
|
||||
|
||||
counter++;
|
||||
|
||||
@@ -668,18 +653,15 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
}
|
||||
|
||||
// An empty MBR may exist, NeXT creates one and then hardcodes its disklabel
|
||||
if (partitions.Count == 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
return partitions.Count != 0;
|
||||
}
|
||||
|
||||
private UInt32 CHStoLBA(ushort cyl, byte head, byte sector)
|
||||
static UInt32 CHStoLBA(ushort cyl, byte head, byte sector)
|
||||
{
|
||||
return (((UInt32)cyl * 16) + (UInt32)head) * 63 + (UInt32)sector - 1;
|
||||
}
|
||||
|
||||
private string decodeBSDType(byte type)
|
||||
static string decodeBSDType(byte type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -716,7 +698,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
}
|
||||
}
|
||||
|
||||
private string decodeMBRType(byte type)
|
||||
static string decodeMBRType(byte type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -1057,10 +1039,10 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
// Total sectors
|
||||
}
|
||||
|
||||
private const UInt32 UNIXDiskLabel_MAGIC = 0xCA5E600D;
|
||||
private const UInt32 UNIXVTOC_MAGIC = 0x600DDEEE;
|
||||
const UInt32 UNIXDiskLabel_MAGIC = 0xCA5E600D;
|
||||
const UInt32 UNIXVTOC_MAGIC = 0x600DDEEE;
|
||||
// Same as Solaris VTOC
|
||||
private struct UNIXDiskLabel
|
||||
struct UNIXDiskLabel
|
||||
{
|
||||
public UInt32 type;
|
||||
// Drive type, seems always 0
|
||||
@@ -1103,7 +1085,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
// 32bytes
|
||||
}
|
||||
|
||||
private struct UNIXVTOC
|
||||
struct UNIXVTOC
|
||||
{
|
||||
public UInt32 magic;
|
||||
// UNIXVTOC_MAGIC
|
||||
@@ -1119,7 +1101,7 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
// 40 bytes
|
||||
}
|
||||
|
||||
private struct UNIXVTOCEntry
|
||||
struct UNIXVTOCEntry
|
||||
{
|
||||
public UInt16 tag;
|
||||
// TAG
|
||||
@@ -1131,51 +1113,51 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
// Length of slice in sectors
|
||||
}
|
||||
|
||||
private const UInt16 UNIX_TAG_EMPTY = 0x0000;
|
||||
const UInt16 UNIX_TAG_EMPTY = 0x0000;
|
||||
// empty
|
||||
private const UInt16 UNIX_TAG_BOOT = 0x0001;
|
||||
const UInt16 UNIX_TAG_BOOT = 0x0001;
|
||||
// boot
|
||||
private const UInt16 UNIX_TAG_ROOT = 0x0002;
|
||||
const UInt16 UNIX_TAG_ROOT = 0x0002;
|
||||
// root
|
||||
private const UInt16 UNIX_TAG_SWAP = 0x0003;
|
||||
const UInt16 UNIX_TAG_SWAP = 0x0003;
|
||||
// swap
|
||||
private const UInt16 UNIX_TAG_USER = 0x0004;
|
||||
const UInt16 UNIX_TAG_USER = 0x0004;
|
||||
// /usr
|
||||
private const UInt16 UNIX_TAG_WHOLE = 0x0005;
|
||||
const UInt16 UNIX_TAG_WHOLE = 0x0005;
|
||||
// whole disk
|
||||
private const UInt16 UNIX_TAG_STAND = 0x0006;
|
||||
const UInt16 UNIX_TAG_STAND = 0x0006;
|
||||
// stand partition ??
|
||||
private const UInt16 UNIX_TAG_ALT_S = 0x0006;
|
||||
const UInt16 UNIX_TAG_ALT_S = 0x0006;
|
||||
// alternate sector space
|
||||
private const UInt16 UNIX_TAG_VAR = 0x0007;
|
||||
const UInt16 UNIX_TAG_VAR = 0x0007;
|
||||
// /var
|
||||
private const UInt16 UNIX_TAG_OTHER = 0x0007;
|
||||
const UInt16 UNIX_TAG_OTHER = 0x0007;
|
||||
// non UNIX
|
||||
private const UInt16 UNIX_TAG_HOME = 0x0008;
|
||||
const UInt16 UNIX_TAG_HOME = 0x0008;
|
||||
// /home
|
||||
private const UInt16 UNIX_TAG_ALT_T = 0x0008;
|
||||
const UInt16 UNIX_TAG_ALT_T = 0x0008;
|
||||
// alternate track space
|
||||
private const UInt16 UNIX_TAG_ALT_ST = 0x0009;
|
||||
const UInt16 UNIX_TAG_ALT_ST = 0x0009;
|
||||
// alternate sector track
|
||||
private const UInt16 UNIX_TAG_NEW_STAND = 0x0009;
|
||||
const UInt16 UNIX_TAG_NEW_STAND = 0x0009;
|
||||
// stand partition ??
|
||||
private const UInt16 UNIX_TAG_CACHE = 0x000A;
|
||||
const UInt16 UNIX_TAG_CACHE = 0x000A;
|
||||
// cache
|
||||
private const UInt16 UNIX_TAG_NEW_VAR = 0x000A;
|
||||
const UInt16 UNIX_TAG_NEW_VAR = 0x000A;
|
||||
// /var
|
||||
private const UInt16 UNIX_TAG_RESERVED = 0x000B;
|
||||
const UInt16 UNIX_TAG_RESERVED = 0x000B;
|
||||
// reserved
|
||||
private const UInt16 UNIX_TAG_NEW_HOME = 0x000B;
|
||||
const UInt16 UNIX_TAG_NEW_HOME = 0x000B;
|
||||
// /home
|
||||
private const UInt16 UNIX_TAG_DUMP = 0x000C;
|
||||
const UInt16 UNIX_TAG_DUMP = 0x000C;
|
||||
// dump partition
|
||||
private const UInt16 UNIX_TAG_NEW_ALT_ST = 0x000D;
|
||||
const UInt16 UNIX_TAG_NEW_ALT_ST = 0x000D;
|
||||
// alternate sector track
|
||||
private const UInt16 UNIX_TAG_VM_PUBLIC = 0x000E;
|
||||
const UInt16 UNIX_TAG_VM_PUBLIC = 0x000E;
|
||||
// volume mgt public partition
|
||||
private const UInt16 UNIX_TAG_VM_PRIVATE = 0x000F;
|
||||
const UInt16 UNIX_TAG_VM_PRIVATE = 0x000F;
|
||||
// volume mgt private partition
|
||||
private string decodeUNIXTAG(UInt16 type, bool isNew)
|
||||
static string decodeUNIXTAG(UInt16 type, bool isNew)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -1192,35 +1174,17 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
case UNIX_TAG_WHOLE:
|
||||
return "Whole disk";
|
||||
case UNIX_TAG_STAND:
|
||||
if (isNew)
|
||||
return "Stand";
|
||||
else
|
||||
return "Alternate sector space";
|
||||
return isNew ? "Stand" : "Alternate sector space";
|
||||
case UNIX_TAG_VAR:
|
||||
if (isNew)
|
||||
return "/var";
|
||||
else
|
||||
return "non UNIX";
|
||||
return isNew ? "/var" : "non UNIX";
|
||||
case UNIX_TAG_HOME:
|
||||
if (isNew)
|
||||
return "/home";
|
||||
else
|
||||
return "Alternate track space";
|
||||
return isNew ? "/home" : "Alternate track space";
|
||||
case UNIX_TAG_ALT_ST:
|
||||
if (isNew)
|
||||
return "Alternate sector track";
|
||||
else
|
||||
return "Stand";
|
||||
return isNew ? "Alternate sector track" : "Stand";
|
||||
case UNIX_TAG_CACHE:
|
||||
if (isNew)
|
||||
return "Cache";
|
||||
else
|
||||
return "/var";
|
||||
return isNew ? "Cache" : "/var";
|
||||
case UNIX_TAG_RESERVED:
|
||||
if (isNew)
|
||||
return "Reserved";
|
||||
else
|
||||
return "/home";
|
||||
return isNew ? "Reserved" : "/home";
|
||||
case UNIX_TAG_DUMP:
|
||||
return "dump";
|
||||
case UNIX_TAG_NEW_ALT_ST:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.PartPlugins
|
||||
@@ -14,10 +13,10 @@ namespace FileSystemIDandChk.PartPlugins
|
||||
// "dlV2"
|
||||
const UInt32 NEXT_MAGIC3 = 0x646C5633;
|
||||
// "dlV3"
|
||||
|
||||
const UInt16 disktabStart = 0xB4; // 180
|
||||
const UInt16 disktabEntrySize = 0x2C; // 44
|
||||
|
||||
const UInt16 disktabStart = 0xB4;
|
||||
// 180
|
||||
const UInt16 disktabEntrySize = 0x2C;
|
||||
// 44
|
||||
public NeXTDisklabel(PluginBase Core)
|
||||
{
|
||||
Name = "NeXT Disklabel";
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using FileSystemIDandChk.Plugins;
|
||||
using FileSystemIDandChk.PartPlugins;
|
||||
using System.Reflection;
|
||||
using FileSystemIDandChk.ImagePlugins;
|
||||
using FileSystemIDandChk.PartPlugins;
|
||||
using FileSystemIDandChk.Plugins;
|
||||
|
||||
namespace FileSystemIDandChk
|
||||
{
|
||||
public class PluginBase
|
||||
{
|
||||
public Dictionary<string, Plugin> PluginsList;
|
||||
public Dictionary<string, PartPlugin> PartPluginsList;
|
||||
public class PluginBase
|
||||
{
|
||||
public Dictionary<string, Plugin> PluginsList;
|
||||
public Dictionary<string, PartPlugin> PartPluginsList;
|
||||
public Dictionary<string, ImagePlugin> ImagePluginsList;
|
||||
|
||||
public PluginBase ()
|
||||
{
|
||||
this.PluginsList = new Dictionary<string, Plugin>();
|
||||
this.PartPluginsList = new Dictionary<string, PartPlugin>();
|
||||
this.ImagePluginsList = new Dictionary<string, ImagePlugin>();
|
||||
}
|
||||
|
||||
public void RegisterAllPlugins()
|
||||
|
||||
public PluginBase()
|
||||
{
|
||||
PluginsList = new Dictionary<string, Plugin>();
|
||||
PartPluginsList = new Dictionary<string, PartPlugin>();
|
||||
ImagePluginsList = new Dictionary<string, ImagePlugin>();
|
||||
}
|
||||
|
||||
public void RegisterAllPlugins()
|
||||
{
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
@@ -30,51 +30,51 @@ namespace FileSystemIDandChk
|
||||
{
|
||||
if (type.IsSubclassOf(typeof(ImagePlugin)))
|
||||
{
|
||||
ImagePlugin plugin = (ImagePlugin)type.GetConstructor(new Type[] { typeof(PluginBase) }).Invoke(new object[] { this });
|
||||
this.RegisterImagePlugin(plugin);
|
||||
ImagePlugin plugin = (ImagePlugin)type.GetConstructor(new [] { typeof(PluginBase) }).Invoke(new object[] { this });
|
||||
RegisterImagePlugin(plugin);
|
||||
}
|
||||
if (type.IsSubclassOf(typeof(Plugin)))
|
||||
{
|
||||
Plugin plugin = (Plugin)type.GetConstructor(new Type[] { typeof(PluginBase) }).Invoke(new object[] { this });
|
||||
this.RegisterPlugin(plugin);
|
||||
Plugin plugin = (Plugin)type.GetConstructor(new [] { typeof(PluginBase) }).Invoke(new object[] { this });
|
||||
RegisterPlugin(plugin);
|
||||
}
|
||||
else if (type.IsSubclassOf(typeof(PartPlugin)))
|
||||
else if (type.IsSubclassOf(typeof(PartPlugin)))
|
||||
{
|
||||
PartPlugin partplugin = (PartPlugin)type.GetConstructor(new Type[] { typeof(PluginBase) }).Invoke(new object[] { this });
|
||||
this.RegisterPartPlugin(partplugin);
|
||||
PartPlugin partplugin = (PartPlugin)type.GetConstructor(new [] { typeof(PluginBase) }).Invoke(new object[] { this });
|
||||
RegisterPartPlugin(partplugin);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.WriteLine(exception.ToString());
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterImagePlugin(ImagePlugin plugin)
|
||||
void RegisterImagePlugin(ImagePlugin plugin)
|
||||
{
|
||||
if (!this.ImagePluginsList.ContainsKey(plugin.Name.ToLower()))
|
||||
if (!ImagePluginsList.ContainsKey(plugin.Name.ToLower()))
|
||||
{
|
||||
this.ImagePluginsList.Add(plugin.Name.ToLower(), plugin);
|
||||
ImagePluginsList.Add(plugin.Name.ToLower(), plugin);
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterPlugin(Plugin plugin)
|
||||
void RegisterPlugin(Plugin plugin)
|
||||
{
|
||||
if (!this.PluginsList.ContainsKey(plugin.Name.ToLower()))
|
||||
if (!PluginsList.ContainsKey(plugin.Name.ToLower()))
|
||||
{
|
||||
this.PluginsList.Add(plugin.Name.ToLower(), plugin);
|
||||
PluginsList.Add(plugin.Name.ToLower(), plugin);
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterPartPlugin(PartPlugin partplugin)
|
||||
void RegisterPartPlugin(PartPlugin partplugin)
|
||||
{
|
||||
if (!this.PartPluginsList.ContainsKey(partplugin.Name.ToLower()))
|
||||
if (!PartPluginsList.ContainsKey(partplugin.Name.ToLower()))
|
||||
{
|
||||
this.PartPluginsList.Add(partplugin.Name.ToLower(), partplugin);
|
||||
PartPluginsList.Add(partplugin.Name.ToLower(), partplugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,52 +7,50 @@ using FileSystemIDandChk;
|
||||
// https://developer.apple.com/legacy/library/documentation/mac/pdf/Files/File_Manager.pdf
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class AppleHFS : Plugin
|
||||
{
|
||||
private const UInt16 HFS_MAGIC = 0x4244; // "BD"
|
||||
private const UInt16 HFSP_MAGIC = 0x482B; // "H+"
|
||||
private const UInt16 HFSBB_MAGIC = 0x4C4B; // "LK"
|
||||
|
||||
public AppleHFS(PluginBase Core)
|
||||
class AppleHFS : Plugin
|
||||
{
|
||||
const UInt16 HFS_MAGIC = 0x4244;
|
||||
// "BD"
|
||||
const UInt16 HFSP_MAGIC = 0x482B;
|
||||
// "H+"
|
||||
const UInt16 HFSBB_MAGIC = 0x4C4B;
|
||||
// "LK"
|
||||
public AppleHFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Apple Hierarchical File System";
|
||||
base.PluginUUID = new Guid("36405F8D-0D26-6ECC-0BBB-1D5225FF404F");
|
||||
Name = "Apple Hierarchical File System";
|
||||
PluginUUID = new Guid("36405F8D-0D26-6ECC-0BBB-1D5225FF404F");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
{
|
||||
byte[] mdb_sector = imagePlugin.ReadSector(2 + partitionOffset);
|
||||
UInt16 drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0);
|
||||
|
||||
if(drSigWord == HFS_MAGIC)
|
||||
{
|
||||
if (drSigWord == HFS_MAGIC)
|
||||
{
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x7C); // Seek to embedded HFS+ signature
|
||||
|
||||
if(drSigWord == HFSP_MAGIC) // "H+"
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
HFS_MasterDirectoryBlock MDB = new HFS_MasterDirectoryBlock();
|
||||
HFS_BootBlock BB = new HFS_BootBlock();
|
||||
return drSigWord != HFSP_MAGIC;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] pString;
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
HFS_MasterDirectoryBlock MDB = new HFS_MasterDirectoryBlock();
|
||||
HFS_BootBlock BB = new HFS_BootBlock();
|
||||
|
||||
byte[] pString;
|
||||
|
||||
byte[] bb_sector = imagePlugin.ReadSector(2 + partitionOffset); // BB's first sector
|
||||
byte[] mdb_sector = imagePlugin.ReadSector(2 + partitionOffset); // MDB sector
|
||||
MDB.drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x000);
|
||||
if(MDB.drSigWord != HFS_MAGIC)
|
||||
return;
|
||||
if (MDB.drSigWord != HFS_MAGIC)
|
||||
return;
|
||||
|
||||
MDB.drCrDate = BigEndianBitConverter.ToUInt32(mdb_sector, 0x002);
|
||||
MDB.drLsMod = BigEndianBitConverter.ToUInt32(mdb_sector, 0x006);
|
||||
@@ -68,7 +66,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
MDB.drFreeBks = BigEndianBitConverter.ToUInt16(mdb_sector, 0x022);
|
||||
pString = new byte[28];
|
||||
Array.Copy(mdb_sector, 0x024, pString, 0, 28);
|
||||
MDB.drVN = StringHandlers.PascalToString(pString);
|
||||
MDB.drVN = StringHandlers.PascalToString(pString);
|
||||
|
||||
MDB.drVolBkUp = BigEndianBitConverter.ToUInt32(mdb_sector, 0x040);
|
||||
MDB.drVSeqNum = BigEndianBitConverter.ToUInt16(mdb_sector, 0x044);
|
||||
@@ -102,8 +100,8 @@ namespace FileSystemIDandChk.Plugins
|
||||
|
||||
BB.signature = BigEndianBitConverter.ToUInt16(bb_sector, 0x000);
|
||||
|
||||
if(BB.signature == HFSBB_MAGIC)
|
||||
{
|
||||
if (BB.signature == HFSBB_MAGIC)
|
||||
{
|
||||
BB.branch = BigEndianBitConverter.ToUInt32(bb_sector, 0x002);
|
||||
BB.boot_flags = bb_sector[0x006];
|
||||
BB.boot_version = bb_sector[0x007];
|
||||
@@ -112,100 +110,100 @@ namespace FileSystemIDandChk.Plugins
|
||||
|
||||
pString = new byte[16];
|
||||
Array.Copy(bb_sector, 0x00A, pString, 0, 16);
|
||||
BB.system_name = StringHandlers.PascalToString(pString);
|
||||
BB.system_name = StringHandlers.PascalToString(pString);
|
||||
pString = new byte[16];
|
||||
Array.Copy(bb_sector, 0x01A, pString, 0, 16);
|
||||
BB.finder_name = StringHandlers.PascalToString(pString);
|
||||
BB.finder_name = StringHandlers.PascalToString(pString);
|
||||
pString = new byte[16];
|
||||
Array.Copy(bb_sector, 0x02A, pString, 0, 16);
|
||||
BB.debug_name = StringHandlers.PascalToString(pString);
|
||||
BB.debug_name = StringHandlers.PascalToString(pString);
|
||||
pString = new byte[16];
|
||||
Array.Copy(bb_sector, 0x03A, pString, 0, 16);
|
||||
BB.disasm_name = StringHandlers.PascalToString(pString);
|
||||
BB.disasm_name = StringHandlers.PascalToString(pString);
|
||||
pString = new byte[16];
|
||||
Array.Copy(bb_sector, 0x04A, pString, 0, 16);
|
||||
BB.stupscr_name = StringHandlers.PascalToString(pString);
|
||||
BB.stupscr_name = StringHandlers.PascalToString(pString);
|
||||
pString = new byte[16];
|
||||
Array.Copy(bb_sector, 0x05A, pString, 0, 16);
|
||||
BB.bootup_name = StringHandlers.PascalToString(pString);
|
||||
BB.bootup_name = StringHandlers.PascalToString(pString);
|
||||
pString = new byte[16];
|
||||
Array.Copy(bb_sector, 0x06A, pString, 0, 16);
|
||||
BB.clipbrd_name = StringHandlers.PascalToString(pString);
|
||||
BB.clipbrd_name = StringHandlers.PascalToString(pString);
|
||||
|
||||
BB.max_files = BigEndianBitConverter.ToUInt16(bb_sector, 0x07A);
|
||||
BB.queue_size = BigEndianBitConverter.ToUInt16(bb_sector, 0x07C);
|
||||
BB.heap_128k = BigEndianBitConverter.ToUInt32(bb_sector, 0x07E);
|
||||
BB.heap_256k = BigEndianBitConverter.ToUInt32(bb_sector, 0x082);
|
||||
BB.heap_512k = BigEndianBitConverter.ToUInt32(bb_sector, 0x086);
|
||||
}
|
||||
else
|
||||
BB.signature = 0x0000;
|
||||
}
|
||||
else
|
||||
BB.signature = 0x0000;
|
||||
|
||||
sb.AppendLine("Apple Hierarchical File System");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Master Directory Block:");
|
||||
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();
|
||||
sb.AppendLine("Apple Hierarchical File System");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Master Directory Block:");
|
||||
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)
|
||||
sb.AppendLine("Volume is locked by hardware.");
|
||||
if((MDB.drAtrb & 0x100) == 0x100)
|
||||
sb.AppendLine("Volume was unmonted.");
|
||||
else
|
||||
sb.AppendLine("Volume is mounted.");
|
||||
if((MDB.drAtrb & 0x200) == 0x200)
|
||||
sb.AppendLine("Volume has spared bad blocks.");
|
||||
if((MDB.drAtrb & 0x400) == 0x400)
|
||||
sb.AppendLine("Volume does not need cache.");
|
||||
if((MDB.drAtrb & 0x800) == 0x800)
|
||||
sb.AppendLine("Boot volume is inconsistent.");
|
||||
if((MDB.drAtrb & 0x1000) == 0x1000)
|
||||
sb.AppendLine("There are reused CNIDs.");
|
||||
if((MDB.drAtrb & 0x2000) == 0x2000)
|
||||
sb.AppendLine("Volume is journaled.");
|
||||
if((MDB.drAtrb & 0x4000) == 0x4000)
|
||||
sb.AppendLine("Volume is seriously inconsistent.");
|
||||
if((MDB.drAtrb & 0x8000) == 0x8000)
|
||||
sb.AppendLine("Volume is locked by software.");
|
||||
if ((MDB.drAtrb & 0x80) == 0x80)
|
||||
sb.AppendLine("Volume is locked by hardware.");
|
||||
if ((MDB.drAtrb & 0x100) == 0x100)
|
||||
sb.AppendLine("Volume was unmonted.");
|
||||
else
|
||||
sb.AppendLine("Volume is mounted.");
|
||||
if ((MDB.drAtrb & 0x200) == 0x200)
|
||||
sb.AppendLine("Volume has spared bad blocks.");
|
||||
if ((MDB.drAtrb & 0x400) == 0x400)
|
||||
sb.AppendLine("Volume does not need cache.");
|
||||
if ((MDB.drAtrb & 0x800) == 0x800)
|
||||
sb.AppendLine("Boot volume is inconsistent.");
|
||||
if ((MDB.drAtrb & 0x1000) == 0x1000)
|
||||
sb.AppendLine("There are reused CNIDs.");
|
||||
if ((MDB.drAtrb & 0x2000) == 0x2000)
|
||||
sb.AppendLine("Volume is journaled.");
|
||||
if ((MDB.drAtrb & 0x4000) == 0x4000)
|
||||
sb.AppendLine("Volume is seriously inconsistent.");
|
||||
if ((MDB.drAtrb & 0x8000) == 0x8000)
|
||||
sb.AppendLine("Volume is locked by software.");
|
||||
|
||||
sb.AppendFormat("{0} files on root directory", MDB.drNmFls).AppendLine();
|
||||
sb.AppendFormat("{0} directories on root directory", MDB.drNmRtDirs).AppendLine();
|
||||
sb.AppendFormat("{0} files on volume", MDB.drFilCnt).AppendLine();
|
||||
sb.AppendFormat("{0} directories on volume", MDB.drDirCnt).AppendLine();
|
||||
sb.AppendFormat("Volume write count: {0}", MDB.drWrCnt).AppendLine();
|
||||
sb.AppendFormat("{0} files on root directory", MDB.drNmFls).AppendLine();
|
||||
sb.AppendFormat("{0} directories on root directory", MDB.drNmRtDirs).AppendLine();
|
||||
sb.AppendFormat("{0} files on volume", MDB.drFilCnt).AppendLine();
|
||||
sb.AppendFormat("{0} directories on volume", MDB.drDirCnt).AppendLine();
|
||||
sb.AppendFormat("Volume write count: {0}", MDB.drWrCnt).AppendLine();
|
||||
|
||||
sb.AppendFormat("Volume bitmap starting sector (in 512-bytes): {0}", MDB.drVBMSt).AppendLine();
|
||||
sb.AppendFormat("Next allocation block: {0}.", MDB.drAllocPtr).AppendLine();
|
||||
sb.AppendFormat("{0} volume allocation blocks.", MDB.drNmAlBlks).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per allocation block.", MDB.drAlBlkSiz).AppendLine();
|
||||
sb.AppendFormat("{0} bytes to allocate when extending a file.", MDB.drClpSiz).AppendLine();
|
||||
sb.AppendFormat("{0} bytes to allocate when extending a Extents B-Tree.", MDB.drXTClpSiz).AppendLine();
|
||||
sb.AppendFormat("{0} bytes to allocate when extending a Catalog B-Tree.", MDB.drCTClpSiz).AppendLine();
|
||||
sb.AppendFormat("Sector of first allocation block: {0}", MDB.drAlBlSt).AppendLine();
|
||||
sb.AppendFormat("Next unused CNID: {0}", MDB.drNxtCNID).AppendLine();
|
||||
sb.AppendFormat("{0} unused allocation blocks.", MDB.drFreeBks).AppendLine();
|
||||
sb.AppendFormat("Volume bitmap starting sector (in 512-bytes): {0}", MDB.drVBMSt).AppendLine();
|
||||
sb.AppendFormat("Next allocation block: {0}.", MDB.drAllocPtr).AppendLine();
|
||||
sb.AppendFormat("{0} volume allocation blocks.", MDB.drNmAlBlks).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per allocation block.", MDB.drAlBlkSiz).AppendLine();
|
||||
sb.AppendFormat("{0} bytes to allocate when extending a file.", MDB.drClpSiz).AppendLine();
|
||||
sb.AppendFormat("{0} bytes to allocate when extending a Extents B-Tree.", MDB.drXTClpSiz).AppendLine();
|
||||
sb.AppendFormat("{0} bytes to allocate when extending a Catalog B-Tree.", MDB.drCTClpSiz).AppendLine();
|
||||
sb.AppendFormat("Sector of first allocation block: {0}", MDB.drAlBlSt).AppendLine();
|
||||
sb.AppendFormat("Next unused CNID: {0}", MDB.drNxtCNID).AppendLine();
|
||||
sb.AppendFormat("{0} unused allocation blocks.", MDB.drFreeBks).AppendLine();
|
||||
|
||||
sb.AppendFormat("{0} bytes in the Extents B-Tree", MDB.drXTFlSize).AppendLine();
|
||||
sb.AppendFormat("{0} bytes in the Catalog B-Tree", MDB.drCTFlSize).AppendLine();
|
||||
sb.AppendFormat("{0} bytes in the Extents B-Tree", MDB.drXTFlSize).AppendLine();
|
||||
sb.AppendFormat("{0} bytes in the Catalog B-Tree", MDB.drCTFlSize).AppendLine();
|
||||
|
||||
sb.AppendFormat("Volume name: {0}", MDB.drVN).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", MDB.drVN).AppendLine();
|
||||
|
||||
sb.AppendLine("Finder info:");
|
||||
sb.AppendFormat("CNID of bootable system's directory: {0}", MDB.drFndrInfo0).AppendLine();
|
||||
sb.AppendFormat("CNID of first-run application's directory: {0}", MDB.drFndrInfo1).AppendLine();
|
||||
sb.AppendFormat("CNID of previously opened directory: {0}", MDB.drFndrInfo2).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", MDB.drFndrInfo3).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", MDB.drFndrInfo5).AppendLine();
|
||||
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", MDB.drFndrInfo6, MDB.drFndrInfo7).AppendLine();
|
||||
sb.AppendLine("Finder info:");
|
||||
sb.AppendFormat("CNID of bootable system's directory: {0}", MDB.drFndrInfo0).AppendLine();
|
||||
sb.AppendFormat("CNID of first-run application's directory: {0}", MDB.drFndrInfo1).AppendLine();
|
||||
sb.AppendFormat("CNID of previously opened directory: {0}", MDB.drFndrInfo2).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", MDB.drFndrInfo3).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", MDB.drFndrInfo5).AppendLine();
|
||||
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", MDB.drFndrInfo6, MDB.drFndrInfo7).AppendLine();
|
||||
|
||||
if(MDB.drEmbedSigWord == HFSP_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume wraps a HFS+ volume.");
|
||||
sb.AppendFormat("Starting block of the HFS+ volume: {0}", MDB.xdrStABNt).AppendLine();
|
||||
sb.AppendFormat("Allocations blocks of the HFS+ volume: {0}", MDB.xdrNumABlks).AppendLine();
|
||||
}
|
||||
if (MDB.drEmbedSigWord == HFSP_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume wraps a HFS+ volume.");
|
||||
sb.AppendFormat("Starting block of the HFS+ volume: {0}", MDB.xdrStABNt).AppendLine();
|
||||
sb.AppendFormat("Allocations blocks of the HFS+ volume: {0}", MDB.xdrNumABlks).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("{0} blocks in volume cache", MDB.drVCSize).AppendLine();
|
||||
@@ -213,112 +211,168 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.AppendFormat("{0} blocks in volume common cache", MDB.drCtlCSize).AppendLine();
|
||||
}
|
||||
|
||||
if(BB.signature == HFSBB_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume is bootable.");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Boot Block:");
|
||||
if((BB.boot_flags & 0x40) == 0x40)
|
||||
sb.AppendLine("Boot block should be executed.");
|
||||
if((BB.boot_flags & 0x80) == 0x80)
|
||||
{
|
||||
sb.AppendLine("Boot block is in new unknown format.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BB.sec_sv_pages > 0)
|
||||
sb.AppendLine("Allocate secondary sound buffer at boot.");
|
||||
else if(BB.sec_sv_pages < 0)
|
||||
sb.AppendLine("Allocate secondary sound and video buffers at boot.");
|
||||
if (BB.signature == HFSBB_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume is bootable.");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Boot Block:");
|
||||
if ((BB.boot_flags & 0x40) == 0x40)
|
||||
sb.AppendLine("Boot block should be executed.");
|
||||
if ((BB.boot_flags & 0x80) == 0x80)
|
||||
{
|
||||
sb.AppendLine("Boot block is in new unknown format.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BB.sec_sv_pages > 0)
|
||||
sb.AppendLine("Allocate secondary sound buffer at boot.");
|
||||
else if (BB.sec_sv_pages < 0)
|
||||
sb.AppendLine("Allocate secondary sound and video buffers at boot.");
|
||||
|
||||
sb.AppendFormat("System filename: {0}", BB.system_name).AppendLine();
|
||||
sb.AppendFormat("Finder filename: {0}", BB.finder_name).AppendLine();
|
||||
sb.AppendFormat("Debugger filename: {0}", BB.debug_name).AppendLine();
|
||||
sb.AppendFormat("Disassembler filename: {0}", BB.disasm_name).AppendLine();
|
||||
sb.AppendFormat("Startup screen filename: {0}", BB.stupscr_name).AppendLine();
|
||||
sb.AppendFormat("First program to execute at boot: {0}", BB.bootup_name).AppendLine();
|
||||
sb.AppendFormat("Clipboard filename: {0}", BB.clipbrd_name).AppendLine();
|
||||
sb.AppendFormat("Maximum opened files: {0}", BB.max_files*4).AppendLine();
|
||||
sb.AppendFormat("Event queue size: {0}", BB.queue_size).AppendLine();
|
||||
sb.AppendFormat("Heap size with 128KiB of RAM: {0} bytes", BB.heap_128k).AppendLine();
|
||||
sb.AppendFormat("Heap size with 256KiB of RAM: {0} bytes", BB.heap_256k).AppendLine();
|
||||
sb.AppendFormat("Heap size with 512KiB of RAM or more: {0} bytes", BB.heap_512k).AppendLine();
|
||||
}
|
||||
}
|
||||
else
|
||||
sb.AppendLine("Volume is not bootable.");
|
||||
sb.AppendFormat("System filename: {0}", BB.system_name).AppendLine();
|
||||
sb.AppendFormat("Finder filename: {0}", BB.finder_name).AppendLine();
|
||||
sb.AppendFormat("Debugger filename: {0}", BB.debug_name).AppendLine();
|
||||
sb.AppendFormat("Disassembler filename: {0}", BB.disasm_name).AppendLine();
|
||||
sb.AppendFormat("Startup screen filename: {0}", BB.stupscr_name).AppendLine();
|
||||
sb.AppendFormat("First program to execute at boot: {0}", BB.bootup_name).AppendLine();
|
||||
sb.AppendFormat("Clipboard filename: {0}", BB.clipbrd_name).AppendLine();
|
||||
sb.AppendFormat("Maximum opened files: {0}", BB.max_files * 4).AppendLine();
|
||||
sb.AppendFormat("Event queue size: {0}", BB.queue_size).AppendLine();
|
||||
sb.AppendFormat("Heap size with 128KiB of RAM: {0} bytes", BB.heap_128k).AppendLine();
|
||||
sb.AppendFormat("Heap size with 256KiB of RAM: {0} bytes", BB.heap_256k).AppendLine();
|
||||
sb.AppendFormat("Heap size with 512KiB of RAM or more: {0} bytes", BB.heap_512k).AppendLine();
|
||||
}
|
||||
}
|
||||
else
|
||||
sb.AppendLine("Volume is not bootable.");
|
||||
|
||||
information = sb.ToString();
|
||||
information = sb.ToString();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private struct HFS_MasterDirectoryBlock // Should be sector 2 in volume
|
||||
{
|
||||
public UInt16 drSigWord; // 0x000, Signature, 0x4244
|
||||
public UInt32 drCrDate; // 0x002, Volume creation date
|
||||
public UInt32 drLsMod; // 0x006, Volume last modification date
|
||||
public UInt16 drAtrb; // 0x00A, Volume attributes
|
||||
public UInt16 drNmFls; // 0x00C, Files in root directory
|
||||
public UInt16 drVBMSt; // 0x00E, Start 512-byte sector of volume bitmap
|
||||
public UInt16 drAllocPtr; // 0x010, Allocation block to begin next allocation
|
||||
public UInt16 drNmAlBlks; // 0x012, Allocation blocks
|
||||
public UInt32 drAlBlkSiz; // 0x014, Bytes per allocation block
|
||||
public UInt32 drClpSiz; // 0x018, Bytes to allocate when extending a file
|
||||
public UInt16 drAlBlSt; // 0x01C, Start 512-byte sector of first allocation block
|
||||
public UInt32 drNxtCNID; // 0x01E, CNID for next file
|
||||
public UInt16 drFreeBks; // 0x022, Free allocation blocks
|
||||
public string drVN; // 0x024, Volume name (28 bytes)
|
||||
public UInt32 drVolBkUp; // 0x040, Volume last backup time
|
||||
public UInt16 drVSeqNum; // 0x044, Volume backup sequence number
|
||||
public UInt32 drWrCnt; // 0x046, Filesystem write count
|
||||
public UInt32 drXTClpSiz; // 0x04A, Bytes to allocate when extending the extents B-Tree
|
||||
public UInt32 drCTClpSiz; // 0x04E, Bytes to allocate when extending the catalog B-Tree
|
||||
public UInt16 drNmRtDirs; // 0x052, Number of directories in root directory
|
||||
public UInt32 drFilCnt; // 0x054, Number of files in the volume
|
||||
public UInt32 drDirCnt; // 0x058, Number of directories in the volume
|
||||
public UInt32 drFndrInfo0; // 0x05C, finderInfo[0], CNID for bootable system's directory
|
||||
public UInt32 drFndrInfo1; // 0x060, finderInfo[1], CNID of the directory containing the boot application
|
||||
public UInt32 drFndrInfo2; // 0x064, finderInfo[2], CNID of the directory that should be opened on boot
|
||||
public UInt32 drFndrInfo3; // 0x068, finderInfo[3], CNID for Mac OS 8 or 9 directory
|
||||
public UInt32 drFndrInfo4; // 0x06C, finderInfo[4], Reserved
|
||||
public UInt32 drFndrInfo5; // 0x070, finderInfo[5], CNID for Mac OS X directory
|
||||
public UInt32 drFndrInfo6; // 0x074, finderInfo[6], first part of Mac OS X volume ID
|
||||
public UInt32 drFndrInfo7; // 0x078, finderInfo[7], second part of Mac OS X volume ID
|
||||
return;
|
||||
}
|
||||
|
||||
struct HFS_MasterDirectoryBlock // Should be sector 2 in volume
|
||||
{
|
||||
public UInt16 drSigWord;
|
||||
// 0x000, Signature, 0x4244
|
||||
public UInt32 drCrDate;
|
||||
// 0x002, Volume creation date
|
||||
public UInt32 drLsMod;
|
||||
// 0x006, Volume last modification date
|
||||
public UInt16 drAtrb;
|
||||
// 0x00A, Volume attributes
|
||||
public UInt16 drNmFls;
|
||||
// 0x00C, Files in root directory
|
||||
public UInt16 drVBMSt;
|
||||
// 0x00E, Start 512-byte sector of volume bitmap
|
||||
public UInt16 drAllocPtr;
|
||||
// 0x010, Allocation block to begin next allocation
|
||||
public UInt16 drNmAlBlks;
|
||||
// 0x012, Allocation blocks
|
||||
public UInt32 drAlBlkSiz;
|
||||
// 0x014, Bytes per allocation block
|
||||
public UInt32 drClpSiz;
|
||||
// 0x018, Bytes to allocate when extending a file
|
||||
public UInt16 drAlBlSt;
|
||||
// 0x01C, Start 512-byte sector of first allocation block
|
||||
public UInt32 drNxtCNID;
|
||||
// 0x01E, CNID for next file
|
||||
public UInt16 drFreeBks;
|
||||
// 0x022, Free allocation blocks
|
||||
public string drVN;
|
||||
// 0x024, Volume name (28 bytes)
|
||||
public UInt32 drVolBkUp;
|
||||
// 0x040, Volume last backup time
|
||||
public UInt16 drVSeqNum;
|
||||
// 0x044, Volume backup sequence number
|
||||
public UInt32 drWrCnt;
|
||||
// 0x046, Filesystem write count
|
||||
public UInt32 drXTClpSiz;
|
||||
// 0x04A, Bytes to allocate when extending the extents B-Tree
|
||||
public UInt32 drCTClpSiz;
|
||||
// 0x04E, Bytes to allocate when extending the catalog B-Tree
|
||||
public UInt16 drNmRtDirs;
|
||||
// 0x052, Number of directories in root directory
|
||||
public UInt32 drFilCnt;
|
||||
// 0x054, Number of files in the volume
|
||||
public UInt32 drDirCnt;
|
||||
// 0x058, Number of directories in the volume
|
||||
public UInt32 drFndrInfo0;
|
||||
// 0x05C, finderInfo[0], CNID for bootable system's directory
|
||||
public UInt32 drFndrInfo1;
|
||||
// 0x060, finderInfo[1], CNID of the directory containing the boot application
|
||||
public UInt32 drFndrInfo2;
|
||||
// 0x064, finderInfo[2], CNID of the directory that should be opened on boot
|
||||
public UInt32 drFndrInfo3;
|
||||
// 0x068, finderInfo[3], CNID for Mac OS 8 or 9 directory
|
||||
public UInt32 drFndrInfo4;
|
||||
// 0x06C, finderInfo[4], Reserved
|
||||
public UInt32 drFndrInfo5;
|
||||
// 0x070, finderInfo[5], CNID for Mac OS X directory
|
||||
public UInt32 drFndrInfo6;
|
||||
// 0x074, finderInfo[6], first part of Mac OS X volume ID
|
||||
public UInt32 drFndrInfo7;
|
||||
// 0x078, finderInfo[7], second part of Mac OS X volume ID
|
||||
// If wrapping HFS+
|
||||
public UInt16 drEmbedSigWord; // 0x07C, Embedded volume signature, "H+" if HFS+ is embedded ignore following two fields if not
|
||||
public UInt16 xdrStABNt; // 0x07E, Starting block number of embedded HFS+ volume
|
||||
public UInt16 xdrNumABlks; // 0x080, Allocation blocks used by embedded volume
|
||||
public UInt16 drEmbedSigWord;
|
||||
// 0x07C, Embedded volume signature, "H+" if HFS+ is embedded ignore following two fields if not
|
||||
public UInt16 xdrStABNt;
|
||||
// 0x07E, Starting block number of embedded HFS+ volume
|
||||
public UInt16 xdrNumABlks;
|
||||
// 0x080, Allocation blocks used by embedded volume
|
||||
// If not
|
||||
public UInt16 drVCSize; // 0x07C, Size in blocks of volume cache
|
||||
public UInt16 drVBMCSize; // 0x07E, Size in blocks of volume bitmap cache
|
||||
public UInt16 drCtlCSize; // 0x080, Size in blocks of volume common cache
|
||||
public UInt16 drVCSize;
|
||||
// 0x07C, Size in blocks of volume cache
|
||||
public UInt16 drVBMCSize;
|
||||
// 0x07E, Size in blocks of volume bitmap cache
|
||||
public UInt16 drCtlCSize;
|
||||
// 0x080, Size in blocks of volume common cache
|
||||
// End of variable variables :D
|
||||
public UInt32 drXTFlSize; // 0x082, Bytes in the extents B-Tree
|
||||
// 3 HFS extents following, 32 bits each
|
||||
public UInt32 drCTFlSize; // 0x092, Bytes in the catalog B-Tree
|
||||
// 3 HFS extents following, 32 bits each
|
||||
}
|
||||
|
||||
private struct HFS_BootBlock // Should be sectors 0 and 1 in volume
|
||||
{
|
||||
public UInt16 signature; // 0x000, Signature, 0x4C4B if bootable
|
||||
public UInt32 branch; // 0x002, Branch
|
||||
public byte boot_flags; // 0x006, Boot block flags
|
||||
public byte boot_version; // 0x007, Boot block version
|
||||
public Int16 sec_sv_pages; // 0x008, Allocate secondary buffers
|
||||
public string system_name; // 0x00A, System file name (16 bytes)
|
||||
public string finder_name; // 0x01A, Finder file name (16 bytes)
|
||||
public string debug_name; // 0x02A, Debugger file name (16 bytes)
|
||||
public string disasm_name; // 0x03A, Disassembler file name (16 bytes)
|
||||
public string stupscr_name; // 0x04A, Startup screen file name (16 bytes)
|
||||
public string bootup_name; // 0x05A, First program to execute on boot (16 bytes)
|
||||
public string clipbrd_name; // 0x06A, Clipboard file name (16 bytes)
|
||||
public UInt16 max_files; // 0x07A, 1/4 of maximum opened at a time files
|
||||
public UInt16 queue_size; // 0x07C, Event queue size
|
||||
public UInt32 heap_128k; // 0x07E, Heap size on a Mac with 128KiB of RAM
|
||||
public UInt32 heap_256k; // 0x082, Heap size on a Mac with 256KiB of RAM
|
||||
public UInt32 heap_512k; // 0x086, Heap size on a Mac with 512KiB of RAM or more
|
||||
} // Follows boot code
|
||||
}
|
||||
public UInt32 drXTFlSize;
|
||||
// 0x082, Bytes in the extents B-Tree
|
||||
// 3 HFS extents following, 32 bits each
|
||||
public UInt32 drCTFlSize;
|
||||
// 0x092, Bytes in the catalog B-Tree
|
||||
// 3 HFS extents following, 32 bits each
|
||||
}
|
||||
|
||||
struct HFS_BootBlock // Should be sectors 0 and 1 in volume
|
||||
{
|
||||
public UInt16 signature;
|
||||
// 0x000, Signature, 0x4C4B if bootable
|
||||
public UInt32 branch;
|
||||
// 0x002, Branch
|
||||
public byte boot_flags;
|
||||
// 0x006, Boot block flags
|
||||
public byte boot_version;
|
||||
// 0x007, Boot block version
|
||||
public Int16 sec_sv_pages;
|
||||
// 0x008, Allocate secondary buffers
|
||||
public string system_name;
|
||||
// 0x00A, System file name (16 bytes)
|
||||
public string finder_name;
|
||||
// 0x01A, Finder file name (16 bytes)
|
||||
public string debug_name;
|
||||
// 0x02A, Debugger file name (16 bytes)
|
||||
public string disasm_name;
|
||||
// 0x03A, Disassembler file name (16 bytes)
|
||||
public string stupscr_name;
|
||||
// 0x04A, Startup screen file name (16 bytes)
|
||||
public string bootup_name;
|
||||
// 0x05A, First program to execute on boot (16 bytes)
|
||||
public string clipbrd_name;
|
||||
// 0x06A, Clipboard file name (16 bytes)
|
||||
public UInt16 max_files;
|
||||
// 0x07A, 1/4 of maximum opened at a time files
|
||||
public UInt16 queue_size;
|
||||
// 0x07C, Event queue size
|
||||
public UInt32 heap_128k;
|
||||
// 0x07E, Heap size on a Mac with 128KiB of RAM
|
||||
public UInt32 heap_256k;
|
||||
// 0x082, Heap size on a Mac with 256KiB of RAM
|
||||
public UInt32 heap_512k;
|
||||
// 0x086, Heap size on a Mac with 512KiB of RAM or more
|
||||
}
|
||||
// Follows boot code
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
// Information from Apple TechNote 1150: https://developer.apple.com/legacy/library/technotes/tn/tn1150.html
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class AppleHFSPlus : Plugin
|
||||
{
|
||||
private const UInt16 HFS_MAGIC = 0x4244; // "BD"
|
||||
private const UInt16 HFSP_MAGIC = 0x482B; // "H+"
|
||||
private const UInt16 HFSX_MAGIC = 0x4858; // "HX"
|
||||
|
||||
public AppleHFSPlus(PluginBase Core)
|
||||
class AppleHFSPlus : Plugin
|
||||
{
|
||||
const UInt16 HFS_MAGIC = 0x4244;
|
||||
// "BD"
|
||||
const UInt16 HFSP_MAGIC = 0x482B;
|
||||
// "H+"
|
||||
const UInt16 HFSX_MAGIC = 0x4858;
|
||||
// "HX"
|
||||
public AppleHFSPlus(PluginBase Core)
|
||||
{
|
||||
base.Name = "Apple HFS+ filesystem";
|
||||
base.PluginUUID = new Guid("36405F8D-0D26-6EBE-436F-62F0586B4F08");
|
||||
Name = "Apple HFS+ filesystem";
|
||||
PluginUUID = new Guid("36405F8D-0D26-6EBE-436F-62F0586B4F08");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
UInt16 drSigWord;
|
||||
UInt16 xdrStABNt;
|
||||
UInt16 drAlBlSt;
|
||||
UInt32 drAlBlkSiz;
|
||||
{
|
||||
UInt16 drSigWord;
|
||||
UInt16 xdrStABNt;
|
||||
UInt16 drAlBlSt;
|
||||
UInt32 drAlBlkSiz;
|
||||
|
||||
byte[] vh_sector;
|
||||
ulong hfsp_offset;
|
||||
@@ -32,106 +33,105 @@ namespace FileSystemIDandChk.Plugins
|
||||
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0); // Check for HFS Wrapper MDB
|
||||
|
||||
if(drSigWord == HFS_MAGIC) // "BD"
|
||||
{
|
||||
if (drSigWord == HFS_MAGIC) // "BD"
|
||||
{
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x07C); // Read embedded HFS+ signature
|
||||
|
||||
if(drSigWord == HFSP_MAGIC) // "H+"
|
||||
{
|
||||
if (drSigWord == HFSP_MAGIC) // "H+"
|
||||
{
|
||||
xdrStABNt = BigEndianBitConverter.ToUInt16(vh_sector, 0x07E); // Starting block number of embedded HFS+ volume
|
||||
|
||||
drAlBlkSiz = BigEndianBitConverter.ToUInt32(vh_sector, 0x014); // Block size
|
||||
|
||||
drAlBlSt = BigEndianBitConverter.ToUInt16(vh_sector, 0x01C); // Start of allocated blocks (in 512-byte/block)
|
||||
|
||||
hfsp_offset = (drAlBlSt + xdrStABNt * (drAlBlkSiz / 512))*(imagePlugin.GetSectorSize() / 512);
|
||||
}
|
||||
else
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
}
|
||||
hfsp_offset = (drAlBlSt + xdrStABNt * (drAlBlkSiz / 512)) * (imagePlugin.GetSectorSize() / 512);
|
||||
}
|
||||
else
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
}
|
||||
|
||||
vh_sector = imagePlugin.ReadSector(2 + partitionOffset + hfsp_offset); // Read volume header
|
||||
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0);
|
||||
if(drSigWord == HFSP_MAGIC || drSigWord == HFSX_MAGIC)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
if (drSigWord == HFSP_MAGIC || drSigWord == HFSX_MAGIC)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
UInt16 drSigWord;
|
||||
UInt16 xdrStABNt;
|
||||
UInt16 drAlBlSt;
|
||||
UInt32 drAlBlkSiz;
|
||||
HFSPlusVolumeHeader HPVH = new HFSPlusVolumeHeader();
|
||||
UInt16 drSigWord;
|
||||
UInt16 xdrStABNt;
|
||||
UInt16 drAlBlSt;
|
||||
UInt32 drAlBlkSiz;
|
||||
HFSPlusVolumeHeader HPVH = new HFSPlusVolumeHeader();
|
||||
|
||||
ulong hfsp_offset;
|
||||
bool wrapped = false;
|
||||
bool wrapped;
|
||||
byte[] vh_sector;
|
||||
|
||||
vh_sector = imagePlugin.ReadSector(2 + partitionOffset); // Read volume header, of HFS Wrapper MDB
|
||||
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0); // Check for HFS Wrapper MDB
|
||||
|
||||
if(drSigWord == HFS_MAGIC) // "BD"
|
||||
{
|
||||
if (drSigWord == HFS_MAGIC) // "BD"
|
||||
{
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(vh_sector, 0x07C); // Read embedded HFS+ signature
|
||||
|
||||
if(drSigWord == HFSP_MAGIC) // "H+"
|
||||
{
|
||||
if (drSigWord == HFSP_MAGIC) // "H+"
|
||||
{
|
||||
xdrStABNt = BigEndianBitConverter.ToUInt16(vh_sector, 0x07E); // Starting block number of embedded HFS+ volume
|
||||
|
||||
drAlBlkSiz = BigEndianBitConverter.ToUInt32(vh_sector, 0x014); // Block size
|
||||
|
||||
drAlBlSt = BigEndianBitConverter.ToUInt16(vh_sector, 0x01C); // Start of allocated blocks (in 512-byte/block)
|
||||
|
||||
hfsp_offset = (drAlBlSt + xdrStABNt * (drAlBlkSiz / 512))*(imagePlugin.GetSectorSize() / 512);
|
||||
wrapped = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
wrapped = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
wrapped = false;
|
||||
}
|
||||
hfsp_offset = (drAlBlSt + xdrStABNt * (drAlBlkSiz / 512)) * (imagePlugin.GetSectorSize() / 512);
|
||||
wrapped = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
wrapped = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hfsp_offset = 0;
|
||||
wrapped = false;
|
||||
}
|
||||
|
||||
vh_sector = imagePlugin.ReadSector(2 + partitionOffset + hfsp_offset); // Read volume header
|
||||
|
||||
HPVH.signature = BigEndianBitConverter.ToUInt16(vh_sector, 0x000);
|
||||
if(HPVH.signature == HFSP_MAGIC || HPVH.signature == HFSX_MAGIC)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (HPVH.signature == HFSP_MAGIC || HPVH.signature == HFSX_MAGIC)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if(HPVH.signature == 0x482B)
|
||||
sb.AppendLine("HFS+ filesystem.");
|
||||
if(HPVH.signature == 0x4858)
|
||||
sb.AppendLine("HFSX filesystem.");
|
||||
if(wrapped)
|
||||
sb.AppendLine("Volume is wrapped inside an HFS volume.");
|
||||
if (HPVH.signature == 0x482B)
|
||||
sb.AppendLine("HFS+ filesystem.");
|
||||
if (HPVH.signature == 0x4858)
|
||||
sb.AppendLine("HFSX filesystem.");
|
||||
if (wrapped)
|
||||
sb.AppendLine("Volume is wrapped inside an HFS volume.");
|
||||
|
||||
HPVH.version = BigEndianBitConverter.ToUInt16(vh_sector, 0x002);
|
||||
|
||||
if(HPVH.version == 4 || HPVH.version == 5)
|
||||
{
|
||||
if (HPVH.version == 4 || HPVH.version == 5)
|
||||
{
|
||||
HPVH.attributes = BigEndianBitConverter.ToUInt32(vh_sector, 0x004);
|
||||
byte[] lastMountedVersion_b = new byte[4];
|
||||
Array.Copy(vh_sector, 0x008, lastMountedVersion_b, 0, 4);
|
||||
HPVH.lastMountedVersion = Encoding.ASCII.GetString(lastMountedVersion_b);
|
||||
HPVH.lastMountedVersion = Encoding.ASCII.GetString(lastMountedVersion_b);
|
||||
HPVH.journalInfoBlock = BigEndianBitConverter.ToUInt32(vh_sector, 0x00C);
|
||||
|
||||
HPVH.createDate = BigEndianBitConverter.ToUInt32(vh_sector, 0x010);
|
||||
@@ -167,210 +167,325 @@ namespace FileSystemIDandChk.Plugins
|
||||
HPVH.attributesFile_logicalSize = BigEndianBitConverter.ToUInt64(vh_sector, 0x170);
|
||||
HPVH.startupFile_logicalSize = BigEndianBitConverter.ToUInt64(vh_sector, 0x1C0);
|
||||
|
||||
sb.AppendFormat("Filesystem version is {0}.", HPVH.version).AppendLine();
|
||||
sb.AppendFormat("Filesystem version is {0}.", HPVH.version).AppendLine();
|
||||
|
||||
if((HPVH.attributes & 0x80) == 0x80)
|
||||
sb.AppendLine("Volume is locked on hardware.");
|
||||
if((HPVH.attributes & 0x100) == 0x100)
|
||||
sb.AppendLine("Volume is unmounted.");
|
||||
if((HPVH.attributes & 0x200) == 0x200)
|
||||
sb.AppendLine("There are bad blocks in the extents file.");
|
||||
if((HPVH.attributes & 0x400) == 0x400)
|
||||
sb.AppendLine("Volume does not require cache.");
|
||||
if((HPVH.attributes & 0x800) == 0x800)
|
||||
sb.AppendLine("Volume state is inconsistent.");
|
||||
if((HPVH.attributes & 0x1000) == 0x1000)
|
||||
sb.AppendLine("CNIDs are reused.");
|
||||
if((HPVH.attributes & 0x2000) == 0x2000)
|
||||
sb.AppendLine("Volume is journaled.");
|
||||
if((HPVH.attributes & 0x8000) == 0x8000)
|
||||
sb.AppendLine("Volume is locked on software.");
|
||||
if ((HPVH.attributes & 0x80) == 0x80)
|
||||
sb.AppendLine("Volume is locked on hardware.");
|
||||
if ((HPVH.attributes & 0x100) == 0x100)
|
||||
sb.AppendLine("Volume is unmounted.");
|
||||
if ((HPVH.attributes & 0x200) == 0x200)
|
||||
sb.AppendLine("There are bad blocks in the extents file.");
|
||||
if ((HPVH.attributes & 0x400) == 0x400)
|
||||
sb.AppendLine("Volume does not require cache.");
|
||||
if ((HPVH.attributes & 0x800) == 0x800)
|
||||
sb.AppendLine("Volume state is inconsistent.");
|
||||
if ((HPVH.attributes & 0x1000) == 0x1000)
|
||||
sb.AppendLine("CNIDs are reused.");
|
||||
if ((HPVH.attributes & 0x2000) == 0x2000)
|
||||
sb.AppendLine("Volume is journaled.");
|
||||
if ((HPVH.attributes & 0x8000) == 0x8000)
|
||||
sb.AppendLine("Volume is locked on software.");
|
||||
|
||||
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}", 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();
|
||||
sb.AppendFormat("{0} allocation blocks.", HPVH.totalBlocks).AppendLine();
|
||||
sb.AppendFormat("{0} free blocks.", HPVH.freeBlocks).AppendLine();
|
||||
sb.AppendFormat("Next allocation block: {0}.", HPVH.nextAllocation).AppendLine();
|
||||
sb.AppendFormat("Resource fork clump size: {0} bytes.", HPVH.rsrcClumpSize).AppendLine();
|
||||
sb.AppendFormat("Data fork clump size: {0} bytes.", HPVH.dataClumpSize).AppendLine();
|
||||
sb.AppendFormat("Next unused CNID: {0}.", HPVH.nextCatalogID).AppendLine();
|
||||
sb.AppendFormat("Volume has been mounted writable {0} times.", HPVH.writeCount).AppendLine();
|
||||
sb.AppendFormat("Allocation File is {0} bytes.", HPVH.allocationFile_logicalSize).AppendLine();
|
||||
sb.AppendFormat("Extents File is {0} bytes.", HPVH.extentsFile_logicalSize).AppendLine();
|
||||
sb.AppendFormat("Catalog File is {0} bytes.", HPVH.catalogFile_logicalSize).AppendLine();
|
||||
sb.AppendFormat("Attributes File is {0} bytes.", HPVH.attributesFile_logicalSize).AppendLine();
|
||||
sb.AppendFormat("Startup File is {0} bytes.", HPVH.startupFile_logicalSize).AppendLine();
|
||||
sb.AppendLine("Finder info:");
|
||||
sb.AppendFormat("CNID of bootable system's directory: {0}", HPVH.drFndrInfo0).AppendLine();
|
||||
sb.AppendFormat("CNID of first-run application's directory: {0}", HPVH.drFndrInfo1).AppendLine();
|
||||
sb.AppendFormat("CNID of previously opened directory: {0}", HPVH.drFndrInfo2).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", HPVH.drFndrInfo3).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", HPVH.drFndrInfo5).AppendLine();
|
||||
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", HPVH.drFndrInfo6, HPVH.drFndrInfo7).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("Filesystem version is {0}.", HPVH.version).AppendLine();
|
||||
sb.AppendLine("This version is not supported yet.");
|
||||
}
|
||||
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}", 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();
|
||||
sb.AppendFormat("{0} allocation blocks.", HPVH.totalBlocks).AppendLine();
|
||||
sb.AppendFormat("{0} free blocks.", HPVH.freeBlocks).AppendLine();
|
||||
sb.AppendFormat("Next allocation block: {0}.", HPVH.nextAllocation).AppendLine();
|
||||
sb.AppendFormat("Resource fork clump size: {0} bytes.", HPVH.rsrcClumpSize).AppendLine();
|
||||
sb.AppendFormat("Data fork clump size: {0} bytes.", HPVH.dataClumpSize).AppendLine();
|
||||
sb.AppendFormat("Next unused CNID: {0}.", HPVH.nextCatalogID).AppendLine();
|
||||
sb.AppendFormat("Volume has been mounted writable {0} times.", HPVH.writeCount).AppendLine();
|
||||
sb.AppendFormat("Allocation File is {0} bytes.", HPVH.allocationFile_logicalSize).AppendLine();
|
||||
sb.AppendFormat("Extents File is {0} bytes.", HPVH.extentsFile_logicalSize).AppendLine();
|
||||
sb.AppendFormat("Catalog File is {0} bytes.", HPVH.catalogFile_logicalSize).AppendLine();
|
||||
sb.AppendFormat("Attributes File is {0} bytes.", HPVH.attributesFile_logicalSize).AppendLine();
|
||||
sb.AppendFormat("Startup File is {0} bytes.", HPVH.startupFile_logicalSize).AppendLine();
|
||||
sb.AppendLine("Finder info:");
|
||||
sb.AppendFormat("CNID of bootable system's directory: {0}", HPVH.drFndrInfo0).AppendLine();
|
||||
sb.AppendFormat("CNID of first-run application's directory: {0}", HPVH.drFndrInfo1).AppendLine();
|
||||
sb.AppendFormat("CNID of previously opened directory: {0}", HPVH.drFndrInfo2).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", HPVH.drFndrInfo3).AppendLine();
|
||||
sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", HPVH.drFndrInfo5).AppendLine();
|
||||
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", HPVH.drFndrInfo6, HPVH.drFndrInfo7).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("Filesystem version is {0}.", HPVH.version).AppendLine();
|
||||
sb.AppendLine("This version is not supported yet.");
|
||||
}
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
// Size = 532 bytes
|
||||
private struct HFSPlusVolumeHeader // Should be offset 0x0400 bytes in volume
|
||||
{
|
||||
public UInt16 signature; // 0x000, "H+" for HFS+, "HX" for HFSX
|
||||
public UInt16 version; // 0x002, 4 for HFS+, 5 for HFSX
|
||||
public UInt32 attributes; // 0x004, Volume attributes
|
||||
public string lastMountedVersion; // 0x008, Implementation that last mounted the volume.
|
||||
// Reserved by Apple:
|
||||
// "8.10" Mac OS 8.1 to 9.2.2
|
||||
// "10.0" Mac OS X
|
||||
// "HFSJ" Journaled implementation
|
||||
// "fsck" /sbin/fsck
|
||||
public UInt32 journalInfoBlock; // 0x00C, Allocation block number containing the journal
|
||||
|
||||
public ulong createDate; // 0x010, Date of volume creation
|
||||
public ulong modifyDate; // 0x018, Date of last volume modification
|
||||
public ulong backupDate; // 0x020, Date of last backup
|
||||
public ulong checkedDate; // 0x028, Date of last consistency check
|
||||
|
||||
public UInt32 fileCount; // 0x030, File on the volume
|
||||
public UInt32 folderCount; // 0x034, Folders on the volume
|
||||
|
||||
public UInt32 blockSize; // 0x038, Bytes per allocation block
|
||||
public UInt32 totalBlocks; // 0x03C, Allocation blocks on the volume
|
||||
public UInt32 freeBlocks; // 0x040, Free allocation blocks
|
||||
|
||||
public UInt32 nextAllocation; // 0x044, Hint for next allocation block
|
||||
public UInt32 rsrcClumpSize; // 0x048, Resource fork clump size
|
||||
public UInt32 dataClumpSize; // 0x04C, Data fork clump size
|
||||
public UInt32 nextCatalogID; // 0x050, Next unused CNID
|
||||
|
||||
public UInt32 writeCount; // 0x054, Times that the volume has been mounted writable
|
||||
public UInt64 encodingsBitmap; // 0x058, Used text encoding hints
|
||||
|
||||
public UInt32 drFndrInfo0; // 0x060, finderInfo[0], CNID for bootable system's directory
|
||||
public UInt32 drFndrInfo1; // 0x064, finderInfo[1], CNID of the directory containing the boot application
|
||||
public UInt32 drFndrInfo2; // 0x068, finderInfo[2], CNID of the directory that should be opened on boot
|
||||
public UInt32 drFndrInfo3; // 0x06C, finderInfo[3], CNID for Mac OS 8 or 9 directory
|
||||
public UInt32 drFndrInfo4; // 0x070, finderInfo[4], Reserved
|
||||
public UInt32 drFndrInfo5; // 0x074, finderInfo[5], CNID for Mac OS X directory
|
||||
public UInt32 drFndrInfo6; // 0x078, finderInfo[6], first part of Mac OS X volume ID
|
||||
public UInt32 drFndrInfo7; // 0x07C, finderInfo[7], second part of Mac OS X volume ID
|
||||
|
||||
// HFSPlusForkData allocationFile;
|
||||
public UInt64 allocationFile_logicalSize; // 0x080
|
||||
public UInt32 allocationFile_clumpSize; // 0x088
|
||||
public UInt32 allocationFile_totalBlocks; // 0x08C
|
||||
public UInt32 allocationFile_extents_startBlock0; // 0x090
|
||||
public UInt32 allocationFile_extents_blockCount0; // 0x094
|
||||
public UInt32 allocationFile_extents_startBlock1; // 0x098
|
||||
public UInt32 allocationFile_extents_blockCount1; // 0x09C
|
||||
public UInt32 allocationFile_extents_startBlock2; // 0x0A0
|
||||
public UInt32 allocationFile_extents_blockCount2; // 0x0A4
|
||||
public UInt32 allocationFile_extents_startBlock3; // 0x0A8
|
||||
public UInt32 allocationFile_extents_blockCount3; // 0x0AC
|
||||
public UInt32 allocationFile_extents_startBlock4; // 0x0B0
|
||||
public UInt32 allocationFile_extents_blockCount4; // 0x0B4
|
||||
public UInt32 allocationFile_extents_startBlock5; // 0x0B8
|
||||
public UInt32 allocationFile_extents_blockCount5; // 0x0BC
|
||||
public UInt32 allocationFile_extents_startBlock6; // 0x0C0
|
||||
public UInt32 allocationFile_extents_blockCount6; // 0x0C4
|
||||
public UInt32 allocationFile_extents_startBlock7; // 0x0C8
|
||||
public UInt32 allocationFile_extents_blockCount7; // 0x0CC
|
||||
// HFSPlusForkData extentsFile;
|
||||
public UInt64 extentsFile_logicalSize; // 0x0D0
|
||||
public UInt32 extentsFile_clumpSize; // 0x0D8
|
||||
public UInt32 extentsFile_totalBlocks; // 0x0DC
|
||||
public UInt32 extentsFile_extents_startBlock0; // 0x0E0
|
||||
public UInt32 extentsFile_extents_blockCount0; // 0x0E4
|
||||
public UInt32 extentsFile_extents_startBlock1; // 0x0E8
|
||||
public UInt32 extentsFile_extents_blockCount1; // 0x0EC
|
||||
public UInt32 extentsFile_extents_startBlock2; // 0x0F0
|
||||
public UInt32 extentsFile_extents_blockCount2; // 0x0F4
|
||||
public UInt32 extentsFile_extents_startBlock3; // 0x0F8
|
||||
public UInt32 extentsFile_extents_blockCount3; // 0x0FC
|
||||
public UInt32 extentsFile_extents_startBlock4; // 0x100
|
||||
public UInt32 extentsFile_extents_blockCount4; // 0x104
|
||||
public UInt32 extentsFile_extents_startBlock5; // 0x108
|
||||
public UInt32 extentsFile_extents_blockCount5; // 0x10C
|
||||
public UInt32 extentsFile_extents_startBlock6; // 0x110
|
||||
public UInt32 extentsFile_extents_blockCount6; // 0x114
|
||||
public UInt32 extentsFile_extents_startBlock7; // 0x118
|
||||
public UInt32 extentsFile_extents_blockCount7; // 0x11C
|
||||
// HFSPlusForkData catalogFile;
|
||||
public UInt64 catalogFile_logicalSize; // 0x120
|
||||
public UInt32 catalogFile_clumpSize; // 0x128
|
||||
public UInt32 catalogFile_totalBlocks; // 0x12C
|
||||
public UInt32 catalogFile_extents_startBlock0; // 0x130
|
||||
public UInt32 catalogFile_extents_blockCount0; // 0x134
|
||||
public UInt32 catalogFile_extents_startBlock1; // 0x138
|
||||
public UInt32 catalogFile_extents_blockCount1; // 0x13C
|
||||
public UInt32 catalogFile_extents_startBlock2; // 0x140
|
||||
public UInt32 catalogFile_extents_blockCount2; // 0x144
|
||||
public UInt32 catalogFile_extents_startBlock3; // 0x148
|
||||
public UInt32 catalogFile_extents_blockCount3; // 0x14C
|
||||
public UInt32 catalogFile_extents_startBlock4; // 0x150
|
||||
public UInt32 catalogFile_extents_blockCount4; // 0x154
|
||||
public UInt32 catalogFile_extents_startBlock5; // 0x158
|
||||
public UInt32 catalogFile_extents_blockCount5; // 0x15C
|
||||
public UInt32 catalogFile_extents_startBlock6; // 0x160
|
||||
public UInt32 catalogFile_extents_blockCount6; // 0x164
|
||||
public UInt32 catalogFile_extents_startBlock7; // 0x168
|
||||
public UInt32 catalogFile_extents_blockCount7; // 0x16C
|
||||
// HFSPlusForkData attributesFile;
|
||||
public UInt64 attributesFile_logicalSize; // 0x170
|
||||
public UInt32 attributesFile_clumpSize; // 0x178
|
||||
public UInt32 attributesFile_totalBlocks; // 0x17C
|
||||
public UInt32 attributesFile_extents_startBlock0; // 0x180
|
||||
public UInt32 attributesFile_extents_blockCount0; // 0x184
|
||||
public UInt32 attributesFile_extents_startBlock1; // 0x188
|
||||
public UInt32 attributesFile_extents_blockCount1; // 0x18C
|
||||
public UInt32 attributesFile_extents_startBlock2; // 0x190
|
||||
public UInt32 attributesFile_extents_blockCount2; // 0x194
|
||||
public UInt32 attributesFile_extents_startBlock3; // 0x198
|
||||
public UInt32 attributesFile_extents_blockCount3; // 0x19C
|
||||
public UInt32 attributesFile_extents_startBlock4; // 0x1A0
|
||||
public UInt32 attributesFile_extents_blockCount4; // 0x1A4
|
||||
public UInt32 attributesFile_extents_startBlock5; // 0x1A8
|
||||
public UInt32 attributesFile_extents_blockCount5; // 0x1AC
|
||||
public UInt32 attributesFile_extents_startBlock6; // 0x1B0
|
||||
public UInt32 attributesFile_extents_blockCount6; // 0x1B4
|
||||
public UInt32 attributesFile_extents_startBlock7; // 0x1B8
|
||||
public UInt32 attributesFile_extents_blockCount7; // 0x1BC
|
||||
// HFSPlusForkData startupFile;
|
||||
public UInt64 startupFile_logicalSize; // 0x1C0
|
||||
public UInt32 startupFile_clumpSize; // 0x1C8
|
||||
public UInt32 startupFile_totalBlocks; // 0x1CC
|
||||
public UInt32 startupFile_extents_startBlock0; // 0x1D0
|
||||
public UInt32 startupFile_extents_blockCount0; // 0x1D4
|
||||
public UInt32 startupFile_extents_startBlock1; // 0x1D8
|
||||
public UInt32 startupFile_extents_blockCount1; // 0x1E0
|
||||
public UInt32 startupFile_extents_startBlock2; // 0x1E4
|
||||
public UInt32 startupFile_extents_blockCount2; // 0x1E8
|
||||
public UInt32 startupFile_extents_startBlock3; // 0x1EC
|
||||
public UInt32 startupFile_extents_blockCount3; // 0x1F0
|
||||
public UInt32 startupFile_extents_startBlock4; // 0x1F4
|
||||
public UInt32 startupFile_extents_blockCount4; // 0x1F8
|
||||
public UInt32 startupFile_extents_startBlock5; // 0x1FC
|
||||
public UInt32 startupFile_extents_blockCount5; // 0x200
|
||||
public UInt32 startupFile_extents_startBlock6; // 0x204
|
||||
public UInt32 startupFile_extents_blockCount6; // 0x208
|
||||
public UInt32 startupFile_extents_startBlock7; // 0x20C
|
||||
public UInt32 startupFile_extents_blockCount7; // 0x210
|
||||
}
|
||||
}
|
||||
struct HFSPlusVolumeHeader // Should be offset 0x0400 bytes in volume
|
||||
{
|
||||
public UInt16 signature;
|
||||
// 0x000, "H+" for HFS+, "HX" for HFSX
|
||||
public UInt16 version;
|
||||
// 0x002, 4 for HFS+, 5 for HFSX
|
||||
public UInt32 attributes;
|
||||
// 0x004, Volume attributes
|
||||
public string lastMountedVersion;
|
||||
// 0x008, Implementation that last mounted the volume.
|
||||
// Reserved by Apple:
|
||||
// "8.10" Mac OS 8.1 to 9.2.2
|
||||
// "10.0" Mac OS X
|
||||
// "HFSJ" Journaled implementation
|
||||
// "fsck" /sbin/fsck
|
||||
public UInt32 journalInfoBlock;
|
||||
// 0x00C, Allocation block number containing the journal
|
||||
public ulong createDate;
|
||||
// 0x010, Date of volume creation
|
||||
public ulong modifyDate;
|
||||
// 0x018, Date of last volume modification
|
||||
public ulong backupDate;
|
||||
// 0x020, Date of last backup
|
||||
public ulong checkedDate;
|
||||
// 0x028, Date of last consistency check
|
||||
public UInt32 fileCount;
|
||||
// 0x030, File on the volume
|
||||
public UInt32 folderCount;
|
||||
// 0x034, Folders on the volume
|
||||
public UInt32 blockSize;
|
||||
// 0x038, Bytes per allocation block
|
||||
public UInt32 totalBlocks;
|
||||
// 0x03C, Allocation blocks on the volume
|
||||
public UInt32 freeBlocks;
|
||||
// 0x040, Free allocation blocks
|
||||
public UInt32 nextAllocation;
|
||||
// 0x044, Hint for next allocation block
|
||||
public UInt32 rsrcClumpSize;
|
||||
// 0x048, Resource fork clump size
|
||||
public UInt32 dataClumpSize;
|
||||
// 0x04C, Data fork clump size
|
||||
public UInt32 nextCatalogID;
|
||||
// 0x050, Next unused CNID
|
||||
public UInt32 writeCount;
|
||||
// 0x054, Times that the volume has been mounted writable
|
||||
public UInt64 encodingsBitmap;
|
||||
// 0x058, Used text encoding hints
|
||||
public UInt32 drFndrInfo0;
|
||||
// 0x060, finderInfo[0], CNID for bootable system's directory
|
||||
public UInt32 drFndrInfo1;
|
||||
// 0x064, finderInfo[1], CNID of the directory containing the boot application
|
||||
public UInt32 drFndrInfo2;
|
||||
// 0x068, finderInfo[2], CNID of the directory that should be opened on boot
|
||||
public UInt32 drFndrInfo3;
|
||||
// 0x06C, finderInfo[3], CNID for Mac OS 8 or 9 directory
|
||||
public UInt32 drFndrInfo4;
|
||||
// 0x070, finderInfo[4], Reserved
|
||||
public UInt32 drFndrInfo5;
|
||||
// 0x074, finderInfo[5], CNID for Mac OS X directory
|
||||
public UInt32 drFndrInfo6;
|
||||
// 0x078, finderInfo[6], first part of Mac OS X volume ID
|
||||
public UInt32 drFndrInfo7;
|
||||
// 0x07C, finderInfo[7], second part of Mac OS X volume ID
|
||||
// HFSPlusForkData allocationFile;
|
||||
public UInt64 allocationFile_logicalSize;
|
||||
// 0x080
|
||||
public UInt32 allocationFile_clumpSize;
|
||||
// 0x088
|
||||
public UInt32 allocationFile_totalBlocks;
|
||||
// 0x08C
|
||||
public UInt32 allocationFile_extents_startBlock0;
|
||||
// 0x090
|
||||
public UInt32 allocationFile_extents_blockCount0;
|
||||
// 0x094
|
||||
public UInt32 allocationFile_extents_startBlock1;
|
||||
// 0x098
|
||||
public UInt32 allocationFile_extents_blockCount1;
|
||||
// 0x09C
|
||||
public UInt32 allocationFile_extents_startBlock2;
|
||||
// 0x0A0
|
||||
public UInt32 allocationFile_extents_blockCount2;
|
||||
// 0x0A4
|
||||
public UInt32 allocationFile_extents_startBlock3;
|
||||
// 0x0A8
|
||||
public UInt32 allocationFile_extents_blockCount3;
|
||||
// 0x0AC
|
||||
public UInt32 allocationFile_extents_startBlock4;
|
||||
// 0x0B0
|
||||
public UInt32 allocationFile_extents_blockCount4;
|
||||
// 0x0B4
|
||||
public UInt32 allocationFile_extents_startBlock5;
|
||||
// 0x0B8
|
||||
public UInt32 allocationFile_extents_blockCount5;
|
||||
// 0x0BC
|
||||
public UInt32 allocationFile_extents_startBlock6;
|
||||
// 0x0C0
|
||||
public UInt32 allocationFile_extents_blockCount6;
|
||||
// 0x0C4
|
||||
public UInt32 allocationFile_extents_startBlock7;
|
||||
// 0x0C8
|
||||
public UInt32 allocationFile_extents_blockCount7;
|
||||
// 0x0CC
|
||||
// HFSPlusForkData extentsFile;
|
||||
public UInt64 extentsFile_logicalSize;
|
||||
// 0x0D0
|
||||
public UInt32 extentsFile_clumpSize;
|
||||
// 0x0D8
|
||||
public UInt32 extentsFile_totalBlocks;
|
||||
// 0x0DC
|
||||
public UInt32 extentsFile_extents_startBlock0;
|
||||
// 0x0E0
|
||||
public UInt32 extentsFile_extents_blockCount0;
|
||||
// 0x0E4
|
||||
public UInt32 extentsFile_extents_startBlock1;
|
||||
// 0x0E8
|
||||
public UInt32 extentsFile_extents_blockCount1;
|
||||
// 0x0EC
|
||||
public UInt32 extentsFile_extents_startBlock2;
|
||||
// 0x0F0
|
||||
public UInt32 extentsFile_extents_blockCount2;
|
||||
// 0x0F4
|
||||
public UInt32 extentsFile_extents_startBlock3;
|
||||
// 0x0F8
|
||||
public UInt32 extentsFile_extents_blockCount3;
|
||||
// 0x0FC
|
||||
public UInt32 extentsFile_extents_startBlock4;
|
||||
// 0x100
|
||||
public UInt32 extentsFile_extents_blockCount4;
|
||||
// 0x104
|
||||
public UInt32 extentsFile_extents_startBlock5;
|
||||
// 0x108
|
||||
public UInt32 extentsFile_extents_blockCount5;
|
||||
// 0x10C
|
||||
public UInt32 extentsFile_extents_startBlock6;
|
||||
// 0x110
|
||||
public UInt32 extentsFile_extents_blockCount6;
|
||||
// 0x114
|
||||
public UInt32 extentsFile_extents_startBlock7;
|
||||
// 0x118
|
||||
public UInt32 extentsFile_extents_blockCount7;
|
||||
// 0x11C
|
||||
// HFSPlusForkData catalogFile;
|
||||
public UInt64 catalogFile_logicalSize;
|
||||
// 0x120
|
||||
public UInt32 catalogFile_clumpSize;
|
||||
// 0x128
|
||||
public UInt32 catalogFile_totalBlocks;
|
||||
// 0x12C
|
||||
public UInt32 catalogFile_extents_startBlock0;
|
||||
// 0x130
|
||||
public UInt32 catalogFile_extents_blockCount0;
|
||||
// 0x134
|
||||
public UInt32 catalogFile_extents_startBlock1;
|
||||
// 0x138
|
||||
public UInt32 catalogFile_extents_blockCount1;
|
||||
// 0x13C
|
||||
public UInt32 catalogFile_extents_startBlock2;
|
||||
// 0x140
|
||||
public UInt32 catalogFile_extents_blockCount2;
|
||||
// 0x144
|
||||
public UInt32 catalogFile_extents_startBlock3;
|
||||
// 0x148
|
||||
public UInt32 catalogFile_extents_blockCount3;
|
||||
// 0x14C
|
||||
public UInt32 catalogFile_extents_startBlock4;
|
||||
// 0x150
|
||||
public UInt32 catalogFile_extents_blockCount4;
|
||||
// 0x154
|
||||
public UInt32 catalogFile_extents_startBlock5;
|
||||
// 0x158
|
||||
public UInt32 catalogFile_extents_blockCount5;
|
||||
// 0x15C
|
||||
public UInt32 catalogFile_extents_startBlock6;
|
||||
// 0x160
|
||||
public UInt32 catalogFile_extents_blockCount6;
|
||||
// 0x164
|
||||
public UInt32 catalogFile_extents_startBlock7;
|
||||
// 0x168
|
||||
public UInt32 catalogFile_extents_blockCount7;
|
||||
// 0x16C
|
||||
// HFSPlusForkData attributesFile;
|
||||
public UInt64 attributesFile_logicalSize;
|
||||
// 0x170
|
||||
public UInt32 attributesFile_clumpSize;
|
||||
// 0x178
|
||||
public UInt32 attributesFile_totalBlocks;
|
||||
// 0x17C
|
||||
public UInt32 attributesFile_extents_startBlock0;
|
||||
// 0x180
|
||||
public UInt32 attributesFile_extents_blockCount0;
|
||||
// 0x184
|
||||
public UInt32 attributesFile_extents_startBlock1;
|
||||
// 0x188
|
||||
public UInt32 attributesFile_extents_blockCount1;
|
||||
// 0x18C
|
||||
public UInt32 attributesFile_extents_startBlock2;
|
||||
// 0x190
|
||||
public UInt32 attributesFile_extents_blockCount2;
|
||||
// 0x194
|
||||
public UInt32 attributesFile_extents_startBlock3;
|
||||
// 0x198
|
||||
public UInt32 attributesFile_extents_blockCount3;
|
||||
// 0x19C
|
||||
public UInt32 attributesFile_extents_startBlock4;
|
||||
// 0x1A0
|
||||
public UInt32 attributesFile_extents_blockCount4;
|
||||
// 0x1A4
|
||||
public UInt32 attributesFile_extents_startBlock5;
|
||||
// 0x1A8
|
||||
public UInt32 attributesFile_extents_blockCount5;
|
||||
// 0x1AC
|
||||
public UInt32 attributesFile_extents_startBlock6;
|
||||
// 0x1B0
|
||||
public UInt32 attributesFile_extents_blockCount6;
|
||||
// 0x1B4
|
||||
public UInt32 attributesFile_extents_startBlock7;
|
||||
// 0x1B8
|
||||
public UInt32 attributesFile_extents_blockCount7;
|
||||
// 0x1BC
|
||||
// HFSPlusForkData startupFile;
|
||||
public UInt64 startupFile_logicalSize;
|
||||
// 0x1C0
|
||||
public UInt32 startupFile_clumpSize;
|
||||
// 0x1C8
|
||||
public UInt32 startupFile_totalBlocks;
|
||||
// 0x1CC
|
||||
public UInt32 startupFile_extents_startBlock0;
|
||||
// 0x1D0
|
||||
public UInt32 startupFile_extents_blockCount0;
|
||||
// 0x1D4
|
||||
public UInt32 startupFile_extents_startBlock1;
|
||||
// 0x1D8
|
||||
public UInt32 startupFile_extents_blockCount1;
|
||||
// 0x1E0
|
||||
public UInt32 startupFile_extents_startBlock2;
|
||||
// 0x1E4
|
||||
public UInt32 startupFile_extents_blockCount2;
|
||||
// 0x1E8
|
||||
public UInt32 startupFile_extents_startBlock3;
|
||||
// 0x1EC
|
||||
public UInt32 startupFile_extents_blockCount3;
|
||||
// 0x1F0
|
||||
public UInt32 startupFile_extents_startBlock4;
|
||||
// 0x1F4
|
||||
public UInt32 startupFile_extents_blockCount4;
|
||||
// 0x1F8
|
||||
public UInt32 startupFile_extents_startBlock5;
|
||||
// 0x1FC
|
||||
public UInt32 startupFile_extents_blockCount5;
|
||||
// 0x200
|
||||
public UInt32 startupFile_extents_startBlock6;
|
||||
// 0x204
|
||||
public UInt32 startupFile_extents_blockCount6;
|
||||
// 0x208
|
||||
public UInt32 startupFile_extents_startBlock7;
|
||||
// 0x20C
|
||||
public UInt32 startupFile_extents_blockCount7;
|
||||
// 0x210
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,207 +1,234 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
// Information from Inside Macintosh
|
||||
// TODO: Implement support for disc images
|
||||
/*
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class AppleMFS : Plugin
|
||||
{
|
||||
private const UInt16 MFS_MAGIC = 0xD2D7;
|
||||
private const UInt16 MFSBB_MAGIC = 0x4C4B; // "LK"
|
||||
class AppleMFS : Plugin
|
||||
{
|
||||
const UInt16 MFS_MAGIC = 0xD2D7;
|
||||
// "LK"
|
||||
const UInt16 MFSBB_MAGIC = 0x4C4B;
|
||||
|
||||
public AppleMFS(PluginBase Core)
|
||||
public AppleMFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Apple Macintosh File System";
|
||||
base.PluginUUID = new Guid("36405F8D-0D26-4066-6538-5DBF5D065C3A");
|
||||
Name = "Apple Macintosh File System";
|
||||
PluginUUID = new Guid("36405F8D-0D26-4066-6538-5DBF5D065C3A");
|
||||
}
|
||||
|
||||
public override bool Identify(FileStream stream, long offset)
|
||||
{
|
||||
UInt16 drSigWord;
|
||||
|
||||
EndianAwareBinaryReader eabr = new EndianAwareBinaryReader(stream, false); // BigEndian
|
||||
eabr.BaseStream.Seek(0x400 + offset, SeekOrigin.Begin);
|
||||
|
||||
drSigWord = eabr.ReadUInt16();
|
||||
|
||||
if(drSigWord == MFS_MAGIC)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (FileStream stream, long offset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
MFS_MasterDirectoryBlock MDB = new MFS_MasterDirectoryBlock();
|
||||
MFS_BootBlock BB = new MFS_BootBlock();
|
||||
|
||||
byte[] pString;
|
||||
byte[] variable_size;
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
UInt16 drSigWord;
|
||||
|
||||
EndianAwareBinaryReader eabr = new EndianAwareBinaryReader(stream, false); // BigEndian
|
||||
eabr.BaseStream.Seek(0x400 + offset, SeekOrigin.Begin);
|
||||
MDB.drSigWord = eabr.ReadUInt16();
|
||||
if(MDB.drSigWord != MFS_MAGIC)
|
||||
return;
|
||||
byte[] mdb_sector = imagePlugin.ReadSector(2 + partitionOffset);
|
||||
|
||||
drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x000);
|
||||
|
||||
MDB.drCrDate = eabr.ReadUInt32();
|
||||
MDB.drLsBkUp = eabr.ReadUInt32();
|
||||
MDB.drAtrb = eabr.ReadUInt16();
|
||||
MDB.drNmFls = eabr.ReadUInt16();
|
||||
MDB.drDirSt = eabr.ReadUInt16();
|
||||
MDB.drBlLen = eabr.ReadUInt16();
|
||||
MDB.drNmAlBlks = eabr.ReadUInt16();
|
||||
MDB.drAlBlkSiz = eabr.ReadUInt32();
|
||||
MDB.drClpSiz = eabr.ReadUInt32();
|
||||
MDB.drAlBlSt = eabr.ReadUInt16();
|
||||
MDB.drNxtFNum = eabr.ReadUInt32();
|
||||
MDB.drFreeBks = eabr.ReadUInt16();
|
||||
MDB.drVNSiz = eabr.ReadByte();
|
||||
variable_size = eabr.ReadBytes(MDB.drVNSiz);
|
||||
MDB.drVN = Encoding.ASCII.GetString(variable_size);
|
||||
return drSigWord == MFS_MAGIC;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
eabr.BaseStream.Seek(0 + offset, SeekOrigin.Begin);
|
||||
BB.signature = eabr.ReadUInt16();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if(BB.signature == MFSBB_MAGIC)
|
||||
{
|
||||
BB.branch = eabr.ReadUInt32();
|
||||
BB.boot_flags = eabr.ReadByte();
|
||||
BB.boot_version = eabr.ReadByte();
|
||||
MFS_MasterDirectoryBlock MDB = new MFS_MasterDirectoryBlock();
|
||||
MFS_BootBlock BB = new MFS_BootBlock();
|
||||
|
||||
byte[] pString = new byte[16];
|
||||
byte[] variable_size;
|
||||
|
||||
byte[] mdb_sector = imagePlugin.ReadSector(2 + partitionOffset);
|
||||
byte[] bb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
|
||||
MDB.drSigWord = BigEndianBitConverter.ToUInt16(mdb_sector, 0x000);
|
||||
if (MDB.drSigWord != MFS_MAGIC)
|
||||
return;
|
||||
|
||||
MDB.drCrDate = BigEndianBitConverter.ToUInt32(mdb_sector, 0x002);
|
||||
MDB.drLsBkUp = BigEndianBitConverter.ToUInt32(mdb_sector, 0x00A);
|
||||
MDB.drAtrb = BigEndianBitConverter.ToUInt16(mdb_sector, 0x012);
|
||||
MDB.drNmFls = BigEndianBitConverter.ToUInt16(mdb_sector, 0x014);
|
||||
MDB.drDirSt = BigEndianBitConverter.ToUInt16(mdb_sector, 0x016);
|
||||
MDB.drBlLen = BigEndianBitConverter.ToUInt16(mdb_sector, 0x018);
|
||||
MDB.drNmAlBlks = BigEndianBitConverter.ToUInt16(mdb_sector, 0x01A);
|
||||
MDB.drAlBlkSiz = BigEndianBitConverter.ToUInt32(mdb_sector, 0x01C);
|
||||
MDB.drClpSiz = BigEndianBitConverter.ToUInt32(mdb_sector, 0x020);
|
||||
MDB.drAlBlSt = BigEndianBitConverter.ToUInt16(mdb_sector, 0x024);
|
||||
MDB.drNxtFNum = BigEndianBitConverter.ToUInt32(mdb_sector, 0x026);
|
||||
MDB.drFreeBks = BigEndianBitConverter.ToUInt16(mdb_sector, 0x02A);
|
||||
MDB.drVNSiz = mdb_sector[0x02C];
|
||||
variable_size = new byte[MDB.drVNSiz];
|
||||
Array.Copy(mdb_sector, 0x02D, variable_size, 0, MDB.drVNSiz);
|
||||
MDB.drVN = Encoding.ASCII.GetString(variable_size);
|
||||
|
||||
BB.signature = BigEndianBitConverter.ToUInt16(bb_sector, 0x000);
|
||||
|
||||
if (BB.signature == MFSBB_MAGIC)
|
||||
{
|
||||
BB.branch = BigEndianBitConverter.ToUInt32(bb_sector, 0x002);
|
||||
BB.boot_flags = bb_sector[0x006];
|
||||
BB.boot_version = bb_sector[0x007];
|
||||
|
||||
BB.sec_sv_pages = eabr.ReadInt16();
|
||||
BB.sec_sv_pages = BigEndianBitConverter.ToInt16(bb_sector, 0x008);
|
||||
|
||||
pString = eabr.ReadBytes(16);
|
||||
BB.system_name = StringHandlers.PascalToString(pString);
|
||||
pString = eabr.ReadBytes(16);
|
||||
BB.finder_name = StringHandlers.PascalToString(pString);
|
||||
pString = eabr.ReadBytes(16);
|
||||
BB.debug_name = StringHandlers.PascalToString(pString);
|
||||
pString = eabr.ReadBytes(16);
|
||||
BB.disasm_name = StringHandlers.PascalToString(pString);
|
||||
pString = eabr.ReadBytes(16);
|
||||
BB.stupscr_name = StringHandlers.PascalToString(pString);
|
||||
pString = eabr.ReadBytes(16);
|
||||
BB.bootup_name = StringHandlers.PascalToString(pString);
|
||||
pString = eabr.ReadBytes(16);
|
||||
BB.clipbrd_name = StringHandlers.PascalToString(pString);
|
||||
Array.Copy(mdb_sector, 0x00A, pString, 0, 16);
|
||||
BB.system_name = StringHandlers.PascalToString(pString);
|
||||
Array.Copy(mdb_sector, 0x01A, pString, 0, 16);
|
||||
BB.finder_name = StringHandlers.PascalToString(pString);
|
||||
Array.Copy(mdb_sector, 0x02A, pString, 0, 16);
|
||||
BB.debug_name = StringHandlers.PascalToString(pString);
|
||||
Array.Copy(mdb_sector, 0x03A, pString, 0, 16);
|
||||
BB.disasm_name = StringHandlers.PascalToString(pString);
|
||||
Array.Copy(mdb_sector, 0x04A, pString, 0, 16);
|
||||
BB.stupscr_name = StringHandlers.PascalToString(pString);
|
||||
Array.Copy(mdb_sector, 0x05A, pString, 0, 16);
|
||||
BB.bootup_name = StringHandlers.PascalToString(pString);
|
||||
Array.Copy(mdb_sector, 0x06A, pString, 0, 16);
|
||||
BB.clipbrd_name = StringHandlers.PascalToString(pString);
|
||||
|
||||
BB.max_files = eabr.ReadUInt16();
|
||||
BB.queue_size = eabr.ReadUInt16();
|
||||
BB.heap_128k = eabr.ReadUInt32();
|
||||
BB.heap_256k = eabr.ReadUInt32();
|
||||
BB.heap_512k = eabr.ReadUInt32();
|
||||
}
|
||||
else
|
||||
BB.signature = 0x0000;
|
||||
BB.max_files = BigEndianBitConverter.ToUInt16(bb_sector, 0x07A);
|
||||
BB.queue_size = BigEndianBitConverter.ToUInt16(bb_sector, 0x07C);
|
||||
BB.heap_128k = BigEndianBitConverter.ToUInt32(bb_sector, 0x07E);
|
||||
BB.heap_256k = BigEndianBitConverter.ToUInt32(bb_sector, 0x082);
|
||||
BB.heap_512k = BigEndianBitConverter.ToUInt32(bb_sector, 0x086);
|
||||
}
|
||||
else
|
||||
BB.signature = 0x0000;
|
||||
|
||||
sb.AppendLine("Apple Macintosh File System");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Master Directory Block:");
|
||||
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)
|
||||
sb.AppendLine("Volume is locked by software.");
|
||||
sb.AppendFormat("{0} files on volume", MDB.drNmFls).AppendLine();
|
||||
sb.AppendFormat("First directory block: {0}", MDB.drDirSt).AppendLine();
|
||||
sb.AppendFormat("{0} blocks in directory.", MDB.drBlLen).AppendLine();
|
||||
sb.AppendFormat("{0} volume allocation blocks.", MDB.drNmAlBlks).AppendLine();
|
||||
sb.AppendFormat("Size of allocation blocks: {0}", MDB.drAlBlkSiz).AppendLine();
|
||||
sb.AppendFormat("{0} bytes to allocate.", MDB.drClpSiz).AppendLine();
|
||||
sb.AppendFormat("{0} first allocation block.", MDB.drAlBlSt).AppendLine();
|
||||
sb.AppendFormat("Next unused file number: {0}", MDB.drNxtFNum).AppendLine();
|
||||
sb.AppendFormat("{0} unused allocation blocks.", MDB.drFreeBks).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", MDB.drVN).AppendLine();
|
||||
sb.AppendLine("Apple Macintosh File System");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Master Directory Block:");
|
||||
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)
|
||||
sb.AppendLine("Volume is locked by software.");
|
||||
sb.AppendFormat("{0} files on volume", MDB.drNmFls).AppendLine();
|
||||
sb.AppendFormat("First directory block: {0}", MDB.drDirSt).AppendLine();
|
||||
sb.AppendFormat("{0} blocks in directory.", MDB.drBlLen).AppendLine();
|
||||
sb.AppendFormat("{0} volume allocation blocks.", MDB.drNmAlBlks).AppendLine();
|
||||
sb.AppendFormat("Size of allocation blocks: {0}", MDB.drAlBlkSiz).AppendLine();
|
||||
sb.AppendFormat("{0} bytes to allocate.", MDB.drClpSiz).AppendLine();
|
||||
sb.AppendFormat("{0} first allocation block.", MDB.drAlBlSt).AppendLine();
|
||||
sb.AppendFormat("Next unused file number: {0}", MDB.drNxtFNum).AppendLine();
|
||||
sb.AppendFormat("{0} unused allocation blocks.", MDB.drFreeBks).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", MDB.drVN).AppendLine();
|
||||
|
||||
if(BB.signature == MFSBB_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume is bootable.");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Boot Block:");
|
||||
if((BB.boot_flags & 0x40) == 0x40)
|
||||
sb.AppendLine("Boot block should be executed.");
|
||||
if((BB.boot_flags & 0x80) == 0x80)
|
||||
{
|
||||
sb.AppendLine("Boot block is in new unknown format.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(BB.sec_sv_pages > 0)
|
||||
sb.AppendLine("Allocate secondary sound buffer at boot.");
|
||||
else if(BB.sec_sv_pages < 0)
|
||||
sb.AppendLine("Allocate secondary sound and video buffers at boot.");
|
||||
if (BB.signature == MFSBB_MAGIC)
|
||||
{
|
||||
sb.AppendLine("Volume is bootable.");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Boot Block:");
|
||||
if ((BB.boot_flags & 0x40) == 0x40)
|
||||
sb.AppendLine("Boot block should be executed.");
|
||||
if ((BB.boot_flags & 0x80) == 0x80)
|
||||
{
|
||||
sb.AppendLine("Boot block is in new unknown format.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BB.sec_sv_pages > 0)
|
||||
sb.AppendLine("Allocate secondary sound buffer at boot.");
|
||||
else if (BB.sec_sv_pages < 0)
|
||||
sb.AppendLine("Allocate secondary sound and video buffers at boot.");
|
||||
|
||||
sb.AppendFormat("System filename: {0}", BB.system_name).AppendLine();
|
||||
sb.AppendFormat("Finder filename: {0}", BB.finder_name).AppendLine();
|
||||
sb.AppendFormat("Debugger filename: {0}", BB.debug_name).AppendLine();
|
||||
sb.AppendFormat("Disassembler filename: {0}", BB.disasm_name).AppendLine();
|
||||
sb.AppendFormat("Startup screen filename: {0}", BB.stupscr_name).AppendLine();
|
||||
sb.AppendFormat("First program to execute at boot: {0}", BB.bootup_name).AppendLine();
|
||||
sb.AppendFormat("Clipboard filename: {0}", BB.clipbrd_name).AppendLine();
|
||||
sb.AppendFormat("Maximum opened files: {0}", BB.max_files*4).AppendLine();
|
||||
sb.AppendFormat("Event queue size: {0}", BB.queue_size).AppendLine();
|
||||
sb.AppendFormat("Heap size with 128KiB of RAM: {0} bytes", BB.heap_128k).AppendLine();
|
||||
sb.AppendFormat("Heap size with 256KiB of RAM: {0} bytes", BB.heap_256k).AppendLine();
|
||||
sb.AppendFormat("Heap size with 512KiB of RAM or more: {0} bytes", BB.heap_512k).AppendLine();
|
||||
}
|
||||
}
|
||||
else
|
||||
sb.AppendLine("Volume is not bootable.");
|
||||
sb.AppendFormat("System filename: {0}", BB.system_name).AppendLine();
|
||||
sb.AppendFormat("Finder filename: {0}", BB.finder_name).AppendLine();
|
||||
sb.AppendFormat("Debugger filename: {0}", BB.debug_name).AppendLine();
|
||||
sb.AppendFormat("Disassembler filename: {0}", BB.disasm_name).AppendLine();
|
||||
sb.AppendFormat("Startup screen filename: {0}", BB.stupscr_name).AppendLine();
|
||||
sb.AppendFormat("First program to execute at boot: {0}", BB.bootup_name).AppendLine();
|
||||
sb.AppendFormat("Clipboard filename: {0}", BB.clipbrd_name).AppendLine();
|
||||
sb.AppendFormat("Maximum opened files: {0}", BB.max_files * 4).AppendLine();
|
||||
sb.AppendFormat("Event queue size: {0}", BB.queue_size).AppendLine();
|
||||
sb.AppendFormat("Heap size with 128KiB of RAM: {0} bytes", BB.heap_128k).AppendLine();
|
||||
sb.AppendFormat("Heap size with 256KiB of RAM: {0} bytes", BB.heap_256k).AppendLine();
|
||||
sb.AppendFormat("Heap size with 512KiB of RAM or more: {0} bytes", BB.heap_512k).AppendLine();
|
||||
}
|
||||
}
|
||||
else
|
||||
sb.AppendLine("Volume is not bootable.");
|
||||
|
||||
information = sb.ToString();
|
||||
information = sb.ToString();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private struct MFS_MasterDirectoryBlock // Should be offset 0x0400 bytes in volume
|
||||
{
|
||||
public UInt16 drSigWord; // 0x000, Signature, 0xD2D7
|
||||
public ulong drCrDate; // 0x002, Volume creation date
|
||||
public ulong drLsBkUp; // 0x00A, Volume last backup date
|
||||
public UInt16 drAtrb; // 0x012, Volume attributes
|
||||
public UInt16 drNmFls; // 0x014, Volume number of files
|
||||
public UInt16 drDirSt; // 0x016, First directory block
|
||||
public UInt16 drBlLen; // 0x018, Length of directory in blocks
|
||||
public UInt16 drNmAlBlks; // 0x01A, Volume allocation blocks
|
||||
public UInt32 drAlBlkSiz; // 0x01C, Size of allocation blocks
|
||||
public UInt32 drClpSiz; // 0x020, Number of bytes to allocate
|
||||
public UInt16 drAlBlSt; // 0x024, First allocation block in block map
|
||||
public UInt32 drNxtFNum; // 0x026. Next unused file number
|
||||
public UInt16 drFreeBks; // 0x02A, Number of unused allocation blocks
|
||||
public byte drVNSiz; // 0x02C, Length of volume name
|
||||
public string drVN; // 0x02D, Characters of volume name
|
||||
}
|
||||
|
||||
private struct MFS_BootBlock // Should be offset 0x0000 bytes in volume
|
||||
{
|
||||
public UInt16 signature; // 0x000, Signature, 0x4C4B if bootable
|
||||
public UInt32 branch; // 0x002, Branch
|
||||
public byte boot_flags; // 0x006, Boot block flags
|
||||
public byte boot_version; // 0x007, Boot block version
|
||||
public short sec_sv_pages; // 0x008, Allocate secondary buffers
|
||||
public string system_name; // 0x00A, System file name (10 bytes)
|
||||
public string finder_name; // 0x014, Finder file name (10 bytes)
|
||||
public string debug_name; // 0x01E, Debugger file name (10 bytes)
|
||||
public string disasm_name; // 0x028, Disassembler file name (10 bytes)
|
||||
public string stupscr_name; // 0x032, Startup screen file name (10 bytes)
|
||||
public string bootup_name; // 0x03C, First program to execute on boot (10 bytes)
|
||||
public string clipbrd_name; // 0x046, Clipboard file name (10 bytes)
|
||||
public UInt16 max_files; // 0x050, 1/4 of maximum opened at a time files
|
||||
public UInt16 queue_size; // 0x052, Event queue size
|
||||
public UInt32 heap_128k; // 0x054, Heap size on a Mac with 128KiB of RAM
|
||||
public UInt32 heap_256k; // 0x058, Heap size on a Mac with 256KiB of RAM
|
||||
public UInt32 heap_512k; // 0x05C, Heap size on a Mac with 512KiB of RAM or more
|
||||
} // Follows boot code
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
struct MFS_MasterDirectoryBlock // Should be offset 0x0400 bytes in volume
|
||||
{
|
||||
public UInt16 drSigWord;
|
||||
// 0x000, Signature, 0xD2D7
|
||||
public ulong drCrDate;
|
||||
// 0x002, Volume creation date
|
||||
public ulong drLsBkUp;
|
||||
// 0x00A, Volume last backup date
|
||||
public UInt16 drAtrb;
|
||||
// 0x012, Volume attributes
|
||||
public UInt16 drNmFls;
|
||||
// 0x014, Volume number of files
|
||||
public UInt16 drDirSt;
|
||||
// 0x016, First directory block
|
||||
public UInt16 drBlLen;
|
||||
// 0x018, Length of directory in blocks
|
||||
public UInt16 drNmAlBlks;
|
||||
// 0x01A, Volume allocation blocks
|
||||
public UInt32 drAlBlkSiz;
|
||||
// 0x01C, Size of allocation blocks
|
||||
public UInt32 drClpSiz;
|
||||
// 0x020, Number of bytes to allocate
|
||||
public UInt16 drAlBlSt;
|
||||
// 0x024, First allocation block in block map
|
||||
public UInt32 drNxtFNum;
|
||||
// 0x026. Next unused file number
|
||||
public UInt16 drFreeBks;
|
||||
// 0x02A, Number of unused allocation blocks
|
||||
public byte drVNSiz;
|
||||
// 0x02C, Length of volume name
|
||||
public string drVN;
|
||||
// 0x02D, Characters of volume name
|
||||
}
|
||||
|
||||
struct MFS_BootBlock // Should be offset 0x0000 bytes in volume
|
||||
{
|
||||
public UInt16 signature;
|
||||
// 0x000, Signature, 0x4C4B if bootable
|
||||
public UInt32 branch;
|
||||
// 0x002, Branch
|
||||
public byte boot_flags;
|
||||
// 0x006, Boot block flags
|
||||
public byte boot_version;
|
||||
// 0x007, Boot block version
|
||||
public short sec_sv_pages;
|
||||
// 0x008, Allocate secondary buffers
|
||||
public string system_name;
|
||||
// 0x00A, System file name (16 bytes)
|
||||
public string finder_name;
|
||||
// 0x01A, Finder file name (16 bytes)
|
||||
public string debug_name;
|
||||
// 0x02A, Debugger file name (16 bytes)
|
||||
public string disasm_name;
|
||||
// 0x03A, Disassembler file name (16 bytes)
|
||||
public string stupscr_name;
|
||||
// 0x04A, Startup screen file name (16 bytes)
|
||||
public string bootup_name;
|
||||
// 0x05A, First program to execute on boot (16 bytes)
|
||||
public string clipbrd_name;
|
||||
// 0x06A, Clipboard file name (16 bytes)
|
||||
public UInt16 max_files;
|
||||
// 0x07A, 1/4 of maximum opened at a time files
|
||||
public UInt16 queue_size;
|
||||
// 0x07C, Event queue size
|
||||
public UInt32 heap_128k;
|
||||
// 0x07E, Heap size on a Mac with 128KiB of RAM
|
||||
public UInt32 heap_256k;
|
||||
// 0x082, Heap size on a Mac with 256KiB of RAM
|
||||
public UInt32 heap_512k;
|
||||
// 0x086, Heap size on a Mac with 512KiB of RAM or more
|
||||
}
|
||||
// Follows boot code
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -1,196 +1,212 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class BeFS : Plugin
|
||||
{
|
||||
// Little endian constants (that is, as read by .NET :p)
|
||||
private const UInt32 BEFS_MAGIC1 = 0x42465331;
|
||||
private const UInt32 BEFS_MAGIC2 = 0xDD121031;
|
||||
private const UInt32 BEFS_MAGIC3 = 0x15B6830E;
|
||||
private const UInt32 BEFS_ENDIAN = 0x42494745;
|
||||
class BeFS : Plugin
|
||||
{
|
||||
// Little endian constants (that is, as read by .NET :p)
|
||||
const UInt32 BEFS_MAGIC1 = 0x42465331;
|
||||
const UInt32 BEFS_MAGIC2 = 0xDD121031;
|
||||
const UInt32 BEFS_MAGIC3 = 0x15B6830E;
|
||||
const UInt32 BEFS_ENDIAN = 0x42494745;
|
||||
// Big endian constants
|
||||
const UInt32 BEFS_CIGAM1 = 0x31534642;
|
||||
const UInt32 BEFS_NAIDNE = 0x45474942;
|
||||
// Common constants
|
||||
const UInt32 BEFS_CLEAN = 0x434C454E;
|
||||
const UInt32 BEFS_DIRTY = 0x44495254;
|
||||
|
||||
// Big endian constants
|
||||
private const UInt32 BEFS_CIGAM1 = 0x31534642;
|
||||
private const UInt32 BEFS_NAIDNE = 0x45474942;
|
||||
|
||||
// Common constants
|
||||
private const UInt32 BEFS_CLEAN = 0x434C454E;
|
||||
private const UInt32 BEFS_DIRTY = 0x44495254;
|
||||
|
||||
public BeFS(PluginBase Core)
|
||||
public BeFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Be Filesystem";
|
||||
base.PluginUUID = new Guid("dc8572b3-b6ad-46e4-8de9-cbe123ff6672");
|
||||
Name = "Be Filesystem";
|
||||
PluginUUID = new Guid("dc8572b3-b6ad-46e4-8de9-cbe123ff6672");
|
||||
}
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
UInt32 magic;
|
||||
UInt32 magic_be;
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector (0 + partitionOffset);
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
UInt32 magic;
|
||||
UInt32 magic_be;
|
||||
|
||||
magic = BitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
magic_be = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
byte[] sb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
|
||||
if(magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
sb_sector = imagePlugin.ReadSector (1 + partitionOffset);
|
||||
magic = BitConverter.ToUInt32(sb_sector, 0x20);
|
||||
magic_be = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
|
||||
if (magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
return true;
|
||||
sb_sector = imagePlugin.ReadSector(1 + partitionOffset);
|
||||
|
||||
magic = BitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
magic_be = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
magic = BitConverter.ToUInt32(sb_sector, 0x20);
|
||||
magic_be = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
|
||||
if(magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
byte[] name_bytes = new byte[32];
|
||||
if (magic == BEFS_MAGIC1 || magic_be == BEFS_MAGIC1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
byte[] name_bytes = new byte[32];
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
BeSuperBlock besb = new BeSuperBlock();
|
||||
BeSuperBlock besb = new BeSuperBlock();
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector (0 + partitionOffset);
|
||||
byte[] sb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
|
||||
BigEndianBitConverter.IsLittleEndian = true; // Default for little-endian
|
||||
BigEndianBitConverter.IsLittleEndian = true; // Default for little-endian
|
||||
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // Magic is at offset
|
||||
{
|
||||
if(besb.magic1 == BEFS_CIGAM1)
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_sector = imagePlugin.ReadSector (1 + partitionOffset);
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
if (besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // Magic is at offset
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian &= besb.magic1 != BEFS_CIGAM1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sb_sector = imagePlugin.ReadSector(1 + partitionOffset);
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
|
||||
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
||||
{
|
||||
if(besb.magic1 == BEFS_CIGAM1)
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
if (besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
||||
{
|
||||
BigEndianBitConverter.IsLittleEndian &= besb.magic1 != BEFS_CIGAM1;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
Array.Copy (sb_sector, 0x000, name_bytes, 0, 0x20);
|
||||
besb.name = StringHandlers.CToString(name_bytes);
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
besb.fs_byte_order = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
besb.block_size = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
besb.block_shift = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
besb.num_blocks = BigEndianBitConverter.ToInt64 (sb_sector, 0x20);
|
||||
besb.used_blocks = BigEndianBitConverter.ToInt64 (sb_sector, 0x20);
|
||||
besb.inode_size = BigEndianBitConverter.ToInt32 (sb_sector, 0x20);
|
||||
besb.magic2 = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
besb.blocks_per_ag = BigEndianBitConverter.ToInt32 (sb_sector, 0x20);
|
||||
besb.ag_shift = BigEndianBitConverter.ToInt32 (sb_sector, 0x20);
|
||||
besb.num_ags = BigEndianBitConverter.ToInt32 (sb_sector, 0x20);
|
||||
besb.flags = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
besb.log_blocks_ag = BigEndianBitConverter.ToInt32 (sb_sector, 0x20);
|
||||
besb.log_blocks_start = BigEndianBitConverter.ToUInt16 (sb_sector, 0x20);
|
||||
besb.log_blocks_len = BigEndianBitConverter.ToUInt16 (sb_sector, 0x20);
|
||||
besb.log_start = BigEndianBitConverter.ToInt64 (sb_sector, 0x20);
|
||||
besb.log_end = BigEndianBitConverter.ToInt64 (sb_sector, 0x20);
|
||||
besb.magic3 = BigEndianBitConverter.ToUInt32 (sb_sector, 0x20);
|
||||
besb.root_dir_ag = BigEndianBitConverter.ToInt32 (sb_sector, 0x20);
|
||||
besb.root_dir_start = BigEndianBitConverter.ToUInt16 (sb_sector, 0x20);
|
||||
besb.root_dir_len = BigEndianBitConverter.ToUInt16 (sb_sector, 0x20);
|
||||
besb.indices_ag = BigEndianBitConverter.ToInt32 (sb_sector, 0x20);
|
||||
besb.indices_start = BigEndianBitConverter.ToUInt16 (sb_sector, 0x20);
|
||||
besb.indices_len = BigEndianBitConverter.ToUInt16 (sb_sector, 0x20);
|
||||
Array.Copy(sb_sector, 0x000, name_bytes, 0, 0x20);
|
||||
besb.name = StringHandlers.CToString(name_bytes);
|
||||
besb.magic1 = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
besb.fs_byte_order = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
besb.block_size = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
besb.block_shift = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
besb.num_blocks = BigEndianBitConverter.ToInt64(sb_sector, 0x20);
|
||||
besb.used_blocks = BigEndianBitConverter.ToInt64(sb_sector, 0x20);
|
||||
besb.inode_size = BigEndianBitConverter.ToInt32(sb_sector, 0x20);
|
||||
besb.magic2 = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
besb.blocks_per_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x20);
|
||||
besb.ag_shift = BigEndianBitConverter.ToInt32(sb_sector, 0x20);
|
||||
besb.num_ags = BigEndianBitConverter.ToInt32(sb_sector, 0x20);
|
||||
besb.flags = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
besb.log_blocks_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x20);
|
||||
besb.log_blocks_start = BigEndianBitConverter.ToUInt16(sb_sector, 0x20);
|
||||
besb.log_blocks_len = BigEndianBitConverter.ToUInt16(sb_sector, 0x20);
|
||||
besb.log_start = BigEndianBitConverter.ToInt64(sb_sector, 0x20);
|
||||
besb.log_end = BigEndianBitConverter.ToInt64(sb_sector, 0x20);
|
||||
besb.magic3 = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
||||
besb.root_dir_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x20);
|
||||
besb.root_dir_start = BigEndianBitConverter.ToUInt16(sb_sector, 0x20);
|
||||
besb.root_dir_len = BigEndianBitConverter.ToUInt16(sb_sector, 0x20);
|
||||
besb.indices_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x20);
|
||||
besb.indices_start = BigEndianBitConverter.ToUInt16(sb_sector, 0x20);
|
||||
besb.indices_len = BigEndianBitConverter.ToUInt16(sb_sector, 0x20);
|
||||
|
||||
if(!BigEndianBitConverter.IsLittleEndian) // Big-endian filesystem
|
||||
if (!BigEndianBitConverter.IsLittleEndian) // Big-endian filesystem
|
||||
sb.AppendLine("Big-endian BeFS");
|
||||
else
|
||||
sb.AppendLine("Little-endian BeFS");
|
||||
else
|
||||
sb.AppendLine("Little-endian BeFS");
|
||||
|
||||
if(besb.magic1 != BEFS_MAGIC1 || besb.fs_byte_order != BEFS_ENDIAN ||
|
||||
besb.magic2 != BEFS_MAGIC2 || besb.magic3 != BEFS_MAGIC3 ||
|
||||
besb.root_dir_len != 1 || besb.indices_len != 1 ||
|
||||
(1 << (int)besb.block_shift) != besb.block_size)
|
||||
{
|
||||
sb.AppendLine("Superblock seems corrupt, following information may be incorrect");
|
||||
sb.AppendFormat("Magic 1: 0x{0:X8} (Should be 0x42465331)", besb.magic1).AppendLine();
|
||||
sb.AppendFormat("Magic 2: 0x{0:X8} (Should be 0xDD121031)", besb.magic2).AppendLine();
|
||||
sb.AppendFormat("Magic 3: 0x{0:X8} (Should be 0x15B6830E)", besb.magic3).AppendLine();
|
||||
sb.AppendFormat("Filesystem endianness: 0x{0:X8} (Should be 0x42494745)", besb.fs_byte_order).AppendLine();
|
||||
sb.AppendFormat("Root folder's i-node size: {0} blocks (Should be 1)", besb.root_dir_len).AppendLine();
|
||||
sb.AppendFormat("Indices' i-node size: {0} blocks (Should be 1)", besb.indices_len).AppendLine();
|
||||
sb.AppendFormat("1 << block_shift == block_size => 1 << {0} == {1} (Should be {2})", besb.block_shift,
|
||||
1 << (int)besb.block_shift, besb.block_size).AppendLine();
|
||||
}
|
||||
if (besb.magic1 != BEFS_MAGIC1 || besb.fs_byte_order != BEFS_ENDIAN ||
|
||||
besb.magic2 != BEFS_MAGIC2 || besb.magic3 != BEFS_MAGIC3 ||
|
||||
besb.root_dir_len != 1 || besb.indices_len != 1 ||
|
||||
(1 << (int)besb.block_shift) != besb.block_size)
|
||||
{
|
||||
sb.AppendLine("Superblock seems corrupt, following information may be incorrect");
|
||||
sb.AppendFormat("Magic 1: 0x{0:X8} (Should be 0x42465331)", besb.magic1).AppendLine();
|
||||
sb.AppendFormat("Magic 2: 0x{0:X8} (Should be 0xDD121031)", besb.magic2).AppendLine();
|
||||
sb.AppendFormat("Magic 3: 0x{0:X8} (Should be 0x15B6830E)", besb.magic3).AppendLine();
|
||||
sb.AppendFormat("Filesystem endianness: 0x{0:X8} (Should be 0x42494745)", besb.fs_byte_order).AppendLine();
|
||||
sb.AppendFormat("Root folder's i-node size: {0} blocks (Should be 1)", besb.root_dir_len).AppendLine();
|
||||
sb.AppendFormat("Indices' i-node size: {0} blocks (Should be 1)", besb.indices_len).AppendLine();
|
||||
sb.AppendFormat("1 << block_shift == block_size => 1 << {0} == {1} (Should be {2})", besb.block_shift,
|
||||
1 << (int)besb.block_shift, besb.block_size).AppendLine();
|
||||
}
|
||||
|
||||
if(besb.flags == BEFS_CLEAN)
|
||||
{
|
||||
if(besb.log_start == besb.log_end)
|
||||
sb.AppendLine("Filesystem is clean");
|
||||
else
|
||||
sb.AppendLine("Filesystem is dirty");
|
||||
}
|
||||
else if(besb.flags == BEFS_DIRTY)
|
||||
sb.AppendLine("Filesystem is dirty");
|
||||
else
|
||||
sb.AppendFormat("Unknown flags: {0:X8}", besb.flags).AppendLine();
|
||||
if (besb.flags == BEFS_CLEAN)
|
||||
{
|
||||
if (besb.log_start == besb.log_end)
|
||||
sb.AppendLine("Filesystem is clean");
|
||||
else
|
||||
sb.AppendLine("Filesystem is dirty");
|
||||
}
|
||||
else if (besb.flags == BEFS_DIRTY)
|
||||
sb.AppendLine("Filesystem is dirty");
|
||||
else
|
||||
sb.AppendFormat("Unknown flags: {0:X8}", besb.flags).AppendLine();
|
||||
|
||||
sb.AppendFormat("Volume name: {0}", besb.name).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per block", besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} blocks in volume ({1} bytes)", besb.num_blocks, besb.num_blocks*besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} used blocks ({1} bytes)", besb.used_blocks, besb.used_blocks*besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per i-node", besb.inode_size).AppendLine();
|
||||
sb.AppendFormat("{0} blocks per allocation group ({1} bytes)", besb.blocks_per_ag, besb.blocks_per_ag*besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} allocation groups in volume", besb.num_ags).AppendLine();
|
||||
sb.AppendFormat("Journal resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)", besb.log_blocks_start,
|
||||
besb.log_blocks_ag, besb.log_blocks_len, besb.log_blocks_len*besb.block_size).AppendLine();
|
||||
sb.AppendFormat("Journal starts in byte {0} and ends in byte {1}", besb.log_start, besb.log_end).AppendLine();
|
||||
sb.AppendFormat("Root folder's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)", besb.root_dir_start,
|
||||
besb.root_dir_ag, besb.root_dir_len, besb.root_dir_len*besb.block_size).AppendLine();
|
||||
sb.AppendFormat("Indices' i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)", besb.indices_start,
|
||||
besb.indices_ag, besb.indices_len, besb.indices_len*besb.block_size).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", besb.name).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per block", besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} blocks in volume ({1} bytes)", besb.num_blocks, besb.num_blocks * besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} used blocks ({1} bytes)", besb.used_blocks, besb.used_blocks * besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per i-node", besb.inode_size).AppendLine();
|
||||
sb.AppendFormat("{0} blocks per allocation group ({1} bytes)", besb.blocks_per_ag, besb.blocks_per_ag * besb.block_size).AppendLine();
|
||||
sb.AppendFormat("{0} allocation groups in volume", besb.num_ags).AppendLine();
|
||||
sb.AppendFormat("Journal resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)", besb.log_blocks_start,
|
||||
besb.log_blocks_ag, besb.log_blocks_len, besb.log_blocks_len * besb.block_size).AppendLine();
|
||||
sb.AppendFormat("Journal starts in byte {0} and ends in byte {1}", besb.log_start, besb.log_end).AppendLine();
|
||||
sb.AppendFormat("Root folder's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)", besb.root_dir_start,
|
||||
besb.root_dir_ag, besb.root_dir_len, besb.root_dir_len * besb.block_size).AppendLine();
|
||||
sb.AppendFormat("Indices' i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)", besb.indices_start,
|
||||
besb.indices_ag, besb.indices_len, besb.indices_len * besb.block_size).AppendLine();
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
private struct BeSuperBlock
|
||||
{
|
||||
public string name; // 0x000, Volume name, 32 bytes
|
||||
public UInt32 magic1; // 0x020, "BFS1", 0x42465331
|
||||
public UInt32 fs_byte_order; // 0x024, "BIGE", 0x42494745
|
||||
public UInt32 block_size; // 0x028, Bytes per block
|
||||
public UInt32 block_shift; // 0x02C, 1 << block_shift == block_size
|
||||
public Int64 num_blocks; // 0x030, Blocks in volume
|
||||
public Int64 used_blocks; // 0x038, Used blocks in volume
|
||||
public Int32 inode_size; // 0x040, Bytes per inode
|
||||
public UInt32 magic2; // 0x044, 0xDD121031
|
||||
public Int32 blocks_per_ag; // 0x048, Blocks per allocation group
|
||||
public Int32 ag_shift; // 0x04C, 1 << ag_shift == blocks_per_ag
|
||||
public Int32 num_ags; // 0x050, Allocation groups in volume
|
||||
public UInt32 flags; // 0x054, 0x434c454e if clean, 0x44495254 if dirty
|
||||
public Int32 log_blocks_ag; // 0x058, Allocation group of journal
|
||||
public UInt16 log_blocks_start; // 0x05C, Start block of journal, inside ag
|
||||
public UInt16 log_blocks_len; // 0x05E, Length in blocks of journal, inside ag
|
||||
public Int64 log_start; // 0x060, Start of journal
|
||||
public Int64 log_end; // 0x068, End of journal
|
||||
public UInt32 magic3; // 0x070, 0x15B6830E
|
||||
public Int32 root_dir_ag; // 0x074, Allocation group where root folder's i-node resides
|
||||
public UInt16 root_dir_start; // 0x078, Start in ag of root folder's i-node
|
||||
public UInt16 root_dir_len; // 0x07A, As this is part of inode_addr, this is 1
|
||||
public Int32 indices_ag; // 0x07C, Allocation group where indices' i-node resides
|
||||
public UInt16 indices_start; // 0x080, Start in ag of indices' i-node
|
||||
public UInt16 indices_len; // 0x082, As this is part of inode_addr, this is 1
|
||||
}
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
struct BeSuperBlock
|
||||
{
|
||||
public string name;
|
||||
// 0x000, Volume name, 32 bytes
|
||||
public UInt32 magic1;
|
||||
// 0x020, "BFS1", 0x42465331
|
||||
public UInt32 fs_byte_order;
|
||||
// 0x024, "BIGE", 0x42494745
|
||||
public UInt32 block_size;
|
||||
// 0x028, Bytes per block
|
||||
public UInt32 block_shift;
|
||||
// 0x02C, 1 << block_shift == block_size
|
||||
public Int64 num_blocks;
|
||||
// 0x030, Blocks in volume
|
||||
public Int64 used_blocks;
|
||||
// 0x038, Used blocks in volume
|
||||
public Int32 inode_size;
|
||||
// 0x040, Bytes per inode
|
||||
public UInt32 magic2;
|
||||
// 0x044, 0xDD121031
|
||||
public Int32 blocks_per_ag;
|
||||
// 0x048, Blocks per allocation group
|
||||
public Int32 ag_shift;
|
||||
// 0x04C, 1 << ag_shift == blocks_per_ag
|
||||
public Int32 num_ags;
|
||||
// 0x050, Allocation groups in volume
|
||||
public UInt32 flags;
|
||||
// 0x054, 0x434c454e if clean, 0x44495254 if dirty
|
||||
public Int32 log_blocks_ag;
|
||||
// 0x058, Allocation group of journal
|
||||
public UInt16 log_blocks_start;
|
||||
// 0x05C, Start block of journal, inside ag
|
||||
public UInt16 log_blocks_len;
|
||||
// 0x05E, Length in blocks of journal, inside ag
|
||||
public Int64 log_start;
|
||||
// 0x060, Start of journal
|
||||
public Int64 log_end;
|
||||
// 0x068, End of journal
|
||||
public UInt32 magic3;
|
||||
// 0x070, 0x15B6830E
|
||||
public Int32 root_dir_ag;
|
||||
// 0x074, Allocation group where root folder's i-node resides
|
||||
public UInt16 root_dir_start;
|
||||
// 0x078, Start in ag of root folder's i-node
|
||||
public UInt16 root_dir_len;
|
||||
// 0x07A, As this is part of inode_addr, this is 1
|
||||
public Int32 indices_ag;
|
||||
// 0x07C, Allocation group where indices' i-node resides
|
||||
public UInt16 indices_start;
|
||||
// 0x080, Start in ag of indices' i-node
|
||||
public UInt16 indices_len;
|
||||
// 0x082, As this is part of inode_addr, this is 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
@@ -7,130 +6,130 @@ using FileSystemIDandChk;
|
||||
// TODO: Implement detecting Atari TOS bootable disks and printing corresponding fields
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class FAT : Plugin
|
||||
{
|
||||
public FAT(PluginBase Core)
|
||||
class FAT : Plugin
|
||||
{
|
||||
public FAT(PluginBase Core)
|
||||
{
|
||||
base.Name = "Microsoft File Allocation Table";
|
||||
base.PluginUUID = new Guid("33513B2C-0D26-0D2D-32C3-79D8611158E0");
|
||||
Name = "Microsoft File Allocation Table";
|
||||
PluginUUID = new Guid("33513B2C-0D26-0D2D-32C3-79D8611158E0");
|
||||
}
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
byte media_descriptor; // Not present on DOS <= 3, present on TOS but != of first FAT entry
|
||||
byte fats_no; // Must be 1 or 2. Dunno if it can be 0 in the wild, but it CANNOT BE bigger than 2
|
||||
byte[] fat32_signature = new byte[8]; // "FAT32 "
|
||||
UInt32 first_fat_entry; // No matter FAT size we read 4 bytes for checking
|
||||
UInt16 bps, rsectors;
|
||||
|
||||
byte[] bpb_sector = imagePlugin.ReadSector (0 + partitionOffset);
|
||||
byte[] fat_sector;
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
byte media_descriptor; // Not present on DOS <= 3, present on TOS but != of first FAT entry
|
||||
byte fats_no; // Must be 1 or 2. Dunno if it can be 0 in the wild, but it CANNOT BE bigger than 2
|
||||
byte[] fat32_signature = new byte[8]; // "FAT32 "
|
||||
UInt32 first_fat_entry; // No matter FAT size we read 4 bytes for checking
|
||||
UInt16 bps, rsectors;
|
||||
|
||||
fats_no = bpb_sector[0x010]; // FATs, 1 or 2, maybe 0, never bigger
|
||||
media_descriptor = bpb_sector[0x015]; // Media Descriptor if present is in 0x15
|
||||
Array.Copy (bpb_sector, 0x52, fat32_signature, 0, 8); // FAT32 signature, if present, is in 0x52
|
||||
bps = BitConverter.ToUInt16(bpb_sector, 0x00B); // Bytes per sector
|
||||
if(bps==0)
|
||||
bps=0x200;
|
||||
rsectors = BitConverter.ToUInt16 (bpb_sector, 0x00E); // Sectors between BPB and FAT, including the BPB sector => [BPB,FAT)
|
||||
if(rsectors==0)
|
||||
rsectors=1;
|
||||
if(imagePlugin.GetSectors() > ((ulong)rsectors + partitionOffset))
|
||||
fat_sector = imagePlugin.ReadSector(rsectors + partitionOffset); // First FAT entry
|
||||
byte[] bpb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
byte[] fat_sector;
|
||||
|
||||
fats_no = bpb_sector[0x010]; // FATs, 1 or 2, maybe 0, never bigger
|
||||
media_descriptor = bpb_sector[0x015]; // Media Descriptor if present is in 0x15
|
||||
Array.Copy(bpb_sector, 0x52, fat32_signature, 0, 8); // FAT32 signature, if present, is in 0x52
|
||||
bps = BitConverter.ToUInt16(bpb_sector, 0x00B); // Bytes per sector
|
||||
if (bps == 0)
|
||||
bps = 0x200;
|
||||
rsectors = BitConverter.ToUInt16(bpb_sector, 0x00E); // Sectors between BPB and FAT, including the BPB sector => [BPB,FAT)
|
||||
if (rsectors == 0)
|
||||
rsectors = 1;
|
||||
if (imagePlugin.GetSectors() > ((ulong)rsectors + partitionOffset))
|
||||
fat_sector = imagePlugin.ReadSector(rsectors + partitionOffset); // First FAT entry
|
||||
else
|
||||
return false;
|
||||
first_fat_entry = BitConverter.ToUInt32 (fat_sector, 0); // Easier to manage
|
||||
return false;
|
||||
first_fat_entry = BitConverter.ToUInt32(fat_sector, 0); // Easier to manage
|
||||
|
||||
if(MainClass.isDebug)
|
||||
{
|
||||
Console.WriteLine("FAT: fats_no = {0}", fats_no);
|
||||
Console.WriteLine("FAT: media_descriptor = 0x{0:X2}", media_descriptor);
|
||||
Console.WriteLine("FAT: fat32_signature = {0}", StringHandlers.CToString(fat32_signature));
|
||||
Console.WriteLine("FAT: bps = {0}", bps);
|
||||
Console.WriteLine("FAT: first_fat_entry = 0x{0:X8}", first_fat_entry);
|
||||
}
|
||||
if (MainClass.isDebug)
|
||||
{
|
||||
Console.WriteLine("FAT: fats_no = {0}", fats_no);
|
||||
Console.WriteLine("FAT: media_descriptor = 0x{0:X2}", media_descriptor);
|
||||
Console.WriteLine("FAT: fat32_signature = {0}", StringHandlers.CToString(fat32_signature));
|
||||
Console.WriteLine("FAT: bps = {0}", bps);
|
||||
Console.WriteLine("FAT: first_fat_entry = 0x{0:X8}", first_fat_entry);
|
||||
}
|
||||
|
||||
if(fats_no > 2) // Must be 1 or 2, but as TOS makes strange things and I have not checked if it puts this to 0, ignore if 0. MUST NOT BE BIGGER THAN 2!
|
||||
if (fats_no > 2) // Must be 1 or 2, but as TOS makes strange things and I have not checked if it puts this to 0, ignore if 0. MUST NOT BE BIGGER THAN 2!
|
||||
return false;
|
||||
|
||||
// Let's start the fun
|
||||
if(Encoding.ASCII.GetString(fat32_signature) == "FAT32 ")
|
||||
return true; // Seems easy, check reading
|
||||
// Let's start the fun
|
||||
if (Encoding.ASCII.GetString(fat32_signature) == "FAT32 ")
|
||||
return true; // Seems easy, check reading
|
||||
|
||||
if((first_fat_entry & 0xFFFFFFF0) == 0xFFFFFFF0) // Seems to be FAT16
|
||||
{
|
||||
if((first_fat_entry & 0xFF) == media_descriptor)
|
||||
return true; // It MUST be FAT16, or... maybe not :S
|
||||
}
|
||||
else if((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
{
|
||||
//if((first_fat_entry & 0xFF) == media_descriptor) // Pre DOS<4 does not implement this, TOS does and is !=
|
||||
return true; // It MUST be FAT12, or... maybe not :S
|
||||
}
|
||||
if ((first_fat_entry & 0xFFFFFFF0) == 0xFFFFFFF0) // Seems to be FAT16
|
||||
{
|
||||
if ((first_fat_entry & 0xFF) == media_descriptor)
|
||||
return true; // It MUST be FAT16, or... maybe not :S
|
||||
}
|
||||
else if ((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
{
|
||||
//if((first_fat_entry & 0xFF) == media_descriptor) // Pre DOS<4 does not implement this, TOS does and is !=
|
||||
return true; // It MUST be FAT12, or... maybe not :S
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
byte[] dosString; // Space-padded
|
||||
bool isFAT32 = false;
|
||||
UInt32 first_fat_entry;
|
||||
byte media_descriptor, fats_no;
|
||||
string fat32_signature;
|
||||
UInt16 bps, rsectors;
|
||||
byte[] dosString; // Space-padded
|
||||
bool isFAT32 = false;
|
||||
UInt32 first_fat_entry;
|
||||
byte media_descriptor, fats_no;
|
||||
string fat32_signature;
|
||||
UInt16 bps, rsectors;
|
||||
|
||||
byte[] bpb_sector = imagePlugin.ReadSector (0 + partitionOffset);
|
||||
byte[] fat_sector;
|
||||
byte[] bpb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
byte[] fat_sector;
|
||||
|
||||
fats_no = bpb_sector[0x010]; // FATs, 1 or 2, maybe 0, never bigger
|
||||
media_descriptor = bpb_sector[0x015]; // Media Descriptor if present is in 0x15
|
||||
fats_no = bpb_sector[0x010]; // FATs, 1 or 2, maybe 0, never bigger
|
||||
media_descriptor = bpb_sector[0x015]; // Media Descriptor if present is in 0x15
|
||||
dosString = new byte[8];
|
||||
Array.Copy (bpb_sector, 0x52, dosString, 0, 8); // FAT32 signature, if present, is in 0x52
|
||||
Array.Copy(bpb_sector, 0x52, dosString, 0, 8); // FAT32 signature, if present, is in 0x52
|
||||
fat32_signature = Encoding.ASCII.GetString(dosString);
|
||||
bps = BitConverter.ToUInt16(bpb_sector, 0x00B); // Bytes per sector
|
||||
if(bps==0)
|
||||
bps=0x200;
|
||||
rsectors = BitConverter.ToUInt16 (bpb_sector, 0x00E); // Sectors between BPB and FAT, including the BPB sector => [BPB,FAT)
|
||||
if(rsectors==0)
|
||||
rsectors=1;
|
||||
fat_sector = imagePlugin.ReadSector(rsectors + partitionOffset); // First FAT entry
|
||||
first_fat_entry = BitConverter.ToUInt32 (fat_sector, 0); // Easier to manage
|
||||
bps = BitConverter.ToUInt16(bpb_sector, 0x00B); // Bytes per sector
|
||||
if (bps == 0)
|
||||
bps = 0x200;
|
||||
rsectors = BitConverter.ToUInt16(bpb_sector, 0x00E); // Sectors between BPB and FAT, including the BPB sector => [BPB,FAT)
|
||||
if (rsectors == 0)
|
||||
rsectors = 1;
|
||||
fat_sector = imagePlugin.ReadSector(rsectors + partitionOffset); // First FAT entry
|
||||
first_fat_entry = BitConverter.ToUInt32(fat_sector, 0); // Easier to manage
|
||||
|
||||
if(fats_no > 2) // Must be 1 or 2, but as TOS makes strange things and I have not checked if it puts this to 0, ignore if 0. MUST NOT BE BIGGER THAN 2!
|
||||
if (fats_no > 2) // Must be 1 or 2, but as TOS makes strange things and I have not checked if it puts this to 0, ignore if 0. MUST NOT BE BIGGER THAN 2!
|
||||
return;
|
||||
|
||||
// Let's start the fun
|
||||
if(fat32_signature == "FAT32 ")
|
||||
{
|
||||
sb.AppendLine("Microsoft FAT32"); // Seems easy, check reading
|
||||
isFAT32 = true;
|
||||
}
|
||||
else if((first_fat_entry & 0xFFFFFFF0) == 0xFFFFFFF0) // Seems to be FAT16
|
||||
{
|
||||
if((first_fat_entry & 0xFF) == media_descriptor)
|
||||
sb.AppendLine("Microsoft FAT16"); // It MUST be FAT16, or... maybe not :S
|
||||
}
|
||||
else if((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
{
|
||||
//if((first_fat_entry & 0xFF) == media_descriptor) // Pre DOS<4 does not implement this, TOS does and is !=
|
||||
sb.AppendLine("Microsoft FAT12"); // It MUST be FAT12, or... maybe not :S
|
||||
}
|
||||
else
|
||||
return;
|
||||
// Let's start the fun
|
||||
if (fat32_signature == "FAT32 ")
|
||||
{
|
||||
sb.AppendLine("Microsoft FAT32"); // Seems easy, check reading
|
||||
isFAT32 = true;
|
||||
}
|
||||
else if ((first_fat_entry & 0xFFFFFFF0) == 0xFFFFFFF0) // Seems to be FAT16
|
||||
{
|
||||
if ((first_fat_entry & 0xFF) == media_descriptor)
|
||||
sb.AppendLine("Microsoft FAT16"); // It MUST be FAT16, or... maybe not :S
|
||||
}
|
||||
else if ((first_fat_entry & 0x00FFFFF0) == 0x00FFFFF0)
|
||||
{
|
||||
//if((first_fat_entry & 0xFF) == media_descriptor) // Pre DOS<4 does not implement this, TOS does and is !=
|
||||
sb.AppendLine("Microsoft FAT12"); // It MUST be FAT12, or... maybe not :S
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
BIOSParameterBlock BPB = new BIOSParameterBlock();
|
||||
ExtendedParameterBlock EPB = new ExtendedParameterBlock();
|
||||
FAT32ParameterBlock FAT32PB = new FAT32ParameterBlock();
|
||||
BIOSParameterBlock BPB = new BIOSParameterBlock();
|
||||
ExtendedParameterBlock EPB = new ExtendedParameterBlock();
|
||||
FAT32ParameterBlock FAT32PB = new FAT32ParameterBlock();
|
||||
|
||||
dosString = new byte[8];
|
||||
Array.Copy (bpb_sector, 0x03, dosString, 0, 8);
|
||||
BPB.OEMName = Encoding.ASCII.GetString(dosString);
|
||||
BPB.bps = BitConverter.ToUInt16(bpb_sector, 0x0B);;
|
||||
Array.Copy(bpb_sector, 0x03, dosString, 0, 8);
|
||||
BPB.OEMName = Encoding.ASCII.GetString(dosString);
|
||||
BPB.bps = BitConverter.ToUInt16(bpb_sector, 0x0B);
|
||||
BPB.spc = bpb_sector[0x0D];
|
||||
BPB.rsectors = BitConverter.ToUInt16(bpb_sector, 0x0E);
|
||||
BPB.fats_no = bpb_sector[0x10];
|
||||
@@ -143,8 +142,8 @@ namespace FileSystemIDandChk.Plugins
|
||||
BPB.hsectors = BitConverter.ToUInt32(bpb_sector, 0x1C);
|
||||
BPB.big_sectors = BitConverter.ToUInt32(bpb_sector, 0x20);
|
||||
|
||||
if(isFAT32)
|
||||
{
|
||||
if (isFAT32)
|
||||
{
|
||||
FAT32PB.spfat = BitConverter.ToUInt32(bpb_sector, 0x24);
|
||||
FAT32PB.fat_flags = BitConverter.ToUInt16(bpb_sector, 0x28);
|
||||
FAT32PB.version = BitConverter.ToUInt16(bpb_sector, 0x2A);
|
||||
@@ -156,144 +155,186 @@ namespace FileSystemIDandChk.Plugins
|
||||
FAT32PB.signature = bpb_sector[0x42];
|
||||
FAT32PB.serial_no = BitConverter.ToUInt32(bpb_sector, 0x43);
|
||||
dosString = new byte[11];
|
||||
Array.Copy (bpb_sector, 0x47, dosString, 0, 11);
|
||||
FAT32PB.volume_label = Encoding.ASCII.GetString(dosString);
|
||||
Array.Copy(bpb_sector, 0x47, dosString, 0, 11);
|
||||
FAT32PB.volume_label = Encoding.ASCII.GetString(dosString);
|
||||
dosString = new byte[8];
|
||||
Array.Copy (bpb_sector, 0x52, dosString, 0, 8);
|
||||
FAT32PB.fs_type = Encoding.ASCII.GetString(dosString);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(bpb_sector, 0x52, dosString, 0, 8);
|
||||
FAT32PB.fs_type = Encoding.ASCII.GetString(dosString);
|
||||
}
|
||||
else
|
||||
{
|
||||
EPB.drive_no = bpb_sector[0x24];
|
||||
EPB.nt_flags = bpb_sector[0x25];
|
||||
EPB.signature = bpb_sector[0x26];
|
||||
EPB.serial_no = BitConverter.ToUInt32(bpb_sector, 0x27);
|
||||
dosString = new byte[11];
|
||||
Array.Copy (bpb_sector, 0x2B, dosString, 0, 11);
|
||||
EPB.volume_label = Encoding.ASCII.GetString(dosString);
|
||||
Array.Copy(bpb_sector, 0x2B, dosString, 0, 11);
|
||||
EPB.volume_label = Encoding.ASCII.GetString(dosString);
|
||||
dosString = new byte[8];
|
||||
Array.Copy (bpb_sector, 0x36, dosString, 0, 8);
|
||||
EPB.fs_type = Encoding.ASCII.GetString(dosString);
|
||||
}
|
||||
Array.Copy(bpb_sector, 0x36, dosString, 0, 8);
|
||||
EPB.fs_type = Encoding.ASCII.GetString(dosString);
|
||||
}
|
||||
|
||||
sb.AppendFormat("OEM Name: {0}", BPB.OEMName).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector.", BPB.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster.", BPB.spc).AppendLine();
|
||||
sb.AppendFormat("{0} sectors reserved between BPB and FAT.", BPB.rsectors).AppendLine();
|
||||
sb.AppendFormat("{0} FATs.", BPB.fats_no).AppendLine();
|
||||
sb.AppendFormat("{0} entires on root directory.", BPB.root_ent).AppendLine();
|
||||
if(BPB.sectors==0)
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes).", BPB.big_sectors, BPB.big_sectors*BPB.bps).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes).", BPB.sectors, BPB.sectors*BPB.bps).AppendLine();
|
||||
if((BPB.media & 0xF0) == 0xF0)
|
||||
sb.AppendFormat("Media format: 0x{0:X2}", BPB.media).AppendLine();
|
||||
if(fat32_signature == "FAT32 ")
|
||||
sb.AppendFormat("{0} sectors per FAT.", FAT32PB.spfat).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} sectors per FAT.", BPB.spfat).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track.", BPB.sptrk).AppendLine();
|
||||
sb.AppendFormat("{0} heads.", BPB.heads).AppendLine();
|
||||
sb.AppendFormat("{0} hidden sectors before BPB.", BPB.hsectors).AppendLine();
|
||||
sb.AppendFormat("OEM Name: {0}", BPB.OEMName).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector.", BPB.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster.", BPB.spc).AppendLine();
|
||||
sb.AppendFormat("{0} sectors reserved between BPB and FAT.", BPB.rsectors).AppendLine();
|
||||
sb.AppendFormat("{0} FATs.", BPB.fats_no).AppendLine();
|
||||
sb.AppendFormat("{0} entires on root directory.", BPB.root_ent).AppendLine();
|
||||
if (BPB.sectors == 0)
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes).", BPB.big_sectors, BPB.big_sectors * BPB.bps).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes).", BPB.sectors, BPB.sectors * BPB.bps).AppendLine();
|
||||
if ((BPB.media & 0xF0) == 0xF0)
|
||||
sb.AppendFormat("Media format: 0x{0:X2}", BPB.media).AppendLine();
|
||||
if (fat32_signature == "FAT32 ")
|
||||
sb.AppendFormat("{0} sectors per FAT.", FAT32PB.spfat).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} sectors per FAT.", BPB.spfat).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track.", BPB.sptrk).AppendLine();
|
||||
sb.AppendFormat("{0} heads.", BPB.heads).AppendLine();
|
||||
sb.AppendFormat("{0} hidden sectors before BPB.", BPB.hsectors).AppendLine();
|
||||
|
||||
if(isFAT32)
|
||||
{
|
||||
sb.AppendFormat("Cluster of root directory: {0}", FAT32PB.root_cluster).AppendLine();
|
||||
sb.AppendFormat("Sector of FSINFO structure: {0}", FAT32PB.fsinfo_sector).AppendLine();
|
||||
sb.AppendFormat("Sector of backup FAT32 parameter block: {0}", FAT32PB.backup_sector).AppendLine();
|
||||
sb.AppendFormat("Drive number: 0x{0:X2}", FAT32PB.drive_no).AppendLine();
|
||||
sb.AppendFormat("Volume Serial Number: 0x{0:X8}", FAT32PB.serial_no).AppendLine();
|
||||
if((FAT32PB.nt_flags & 0x01) == 0x01)
|
||||
{
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
if((EPB.nt_flags & 0x02) == 0x02)
|
||||
sb.AppendLine("Disk surface should be checked also.");
|
||||
}
|
||||
if (isFAT32)
|
||||
{
|
||||
sb.AppendFormat("Cluster of root directory: {0}", FAT32PB.root_cluster).AppendLine();
|
||||
sb.AppendFormat("Sector of FSINFO structure: {0}", FAT32PB.fsinfo_sector).AppendLine();
|
||||
sb.AppendFormat("Sector of backup FAT32 parameter block: {0}", FAT32PB.backup_sector).AppendLine();
|
||||
sb.AppendFormat("Drive number: 0x{0:X2}", FAT32PB.drive_no).AppendLine();
|
||||
sb.AppendFormat("Volume Serial Number: 0x{0:X8}", FAT32PB.serial_no).AppendLine();
|
||||
if ((FAT32PB.nt_flags & 0x01) == 0x01)
|
||||
{
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
if ((EPB.nt_flags & 0x02) == 0x02)
|
||||
sb.AppendLine("Disk surface should be checked also.");
|
||||
}
|
||||
|
||||
sb.AppendFormat("Volume label: {0}", EPB.volume_label).AppendLine();
|
||||
sb.AppendFormat("Filesystem type: {0}", EPB.fs_type).AppendLine();
|
||||
}
|
||||
else if(EPB.signature == 0x28 || EPB.signature == 0x29)
|
||||
{
|
||||
sb.AppendFormat("Drive number: 0x{0:X2}", EPB.drive_no).AppendLine();
|
||||
sb.AppendFormat("Volume Serial Number: 0x{0:X8}", EPB.serial_no).AppendLine();
|
||||
if(EPB.signature==0x29)
|
||||
{
|
||||
if((EPB.nt_flags & 0x01) == 0x01)
|
||||
{
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
if((EPB.nt_flags & 0x02) == 0x02)
|
||||
sb.AppendLine("Disk surface should be checked also.");
|
||||
}
|
||||
sb.AppendFormat("Volume label: {0}", EPB.volume_label).AppendLine();
|
||||
sb.AppendFormat("Filesystem type: {0}", EPB.fs_type).AppendLine();
|
||||
}
|
||||
else if (EPB.signature == 0x28 || EPB.signature == 0x29)
|
||||
{
|
||||
sb.AppendFormat("Drive number: 0x{0:X2}", EPB.drive_no).AppendLine();
|
||||
sb.AppendFormat("Volume Serial Number: 0x{0:X8}", EPB.serial_no).AppendLine();
|
||||
if (EPB.signature == 0x29)
|
||||
{
|
||||
if ((EPB.nt_flags & 0x01) == 0x01)
|
||||
{
|
||||
sb.AppendLine("Volume should be checked on next mount.");
|
||||
if ((EPB.nt_flags & 0x02) == 0x02)
|
||||
sb.AppendLine("Disk surface should be checked also.");
|
||||
}
|
||||
|
||||
sb.AppendFormat("Volume label: {0}", EPB.volume_label).AppendLine();
|
||||
sb.AppendFormat("Filesystem type: {0}", EPB.fs_type).AppendLine();
|
||||
}
|
||||
}
|
||||
sb.AppendFormat("Volume label: {0}", EPB.volume_label).AppendLine();
|
||||
sb.AppendFormat("Filesystem type: {0}", EPB.fs_type).AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
public struct BIOSParameterBlock
|
||||
{
|
||||
public string OEMName; // 0x03, OEM Name, 8 bytes, space-padded
|
||||
public UInt16 bps; // 0x0B, Bytes per sector
|
||||
public byte spc; // 0x0D, Sectors per cluster
|
||||
public UInt16 rsectors; // 0x0E, Reserved sectors between BPB and FAT
|
||||
public byte fats_no; // 0x10, Number of FATs
|
||||
public UInt16 root_ent; // 0x11, Number of entries on root directory
|
||||
public UInt16 sectors; // 0x13, Sectors in volume
|
||||
public byte media; // 0x15, Media descriptor
|
||||
public UInt16 spfat; // 0x16, Sectors per FAT
|
||||
public UInt16 sptrk; // 0x18, Sectors per track
|
||||
public UInt16 heads; // 0x1A, Heads
|
||||
public UInt32 hsectors; // 0x1C, Hidden sectors before BPB
|
||||
public UInt32 big_sectors; // 0x20, Sectors in volume if > 65535
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
// This only applies for bootable disks
|
||||
// From http://info-coach.fr/atari/software/FD-Soft.php
|
||||
public struct AtariBootBlock
|
||||
{
|
||||
public UInt16 hsectors; // 0x01C, Atari ST use 16 bit for hidden sectors, probably so did old DOS
|
||||
public UInt16 xflag; // 0x01E, indicates if COMMAND.PRG must be executed after OS load
|
||||
public UInt16 ldmode; // 0x020, load mode for, or 0 if fname indicates boot file
|
||||
public UInt16 bsect; // 0x022, sector from which to boot
|
||||
public UInt16 bsects_no; // 0x024, how many sectors to boot
|
||||
public UInt32 ldaddr; // 0x026, RAM address where boot should be located
|
||||
public UInt32 fatbuf; // 0x02A, RAM address to copy the FAT and root directory
|
||||
public string fname; // 0x02E, 11 bytes, name of boot file
|
||||
public UInt16 reserved; // 0x039, unused
|
||||
public byte[] boot_code; // 0x03B, 451 bytes boot code
|
||||
public UInt16 checksum; // 0x1FE, the sum of all the BPB+ABB must be 0x1234, so this bigendian value works as adjustment
|
||||
}
|
||||
|
||||
public struct ExtendedParameterBlock
|
||||
{
|
||||
public byte drive_no; // 0x24, Drive number
|
||||
public byte nt_flags; // 0x25, Volume flags if NT (must be 0x29 signature)
|
||||
public byte signature; // 0x26, EPB signature, 0x28 or 0x29
|
||||
public UInt32 serial_no; // 0x27, Volume serial number
|
||||
/* Present only if signature == 0x29 */
|
||||
public string volume_label; // 0x2B, Volume label, 11 bytes, space-padded
|
||||
public string fs_type; // 0x36, Filesystem type, 8 bytes, space-padded
|
||||
}
|
||||
|
||||
public struct FAT32ParameterBlock
|
||||
{
|
||||
public UInt32 spfat; // 0x24, Sectors per FAT
|
||||
public UInt16 fat_flags; // 0x28, FAT flags
|
||||
public UInt16 version; // 0x2A, FAT32 version
|
||||
public UInt32 root_cluster; // 0x2C, Cluster of root directory
|
||||
public UInt16 fsinfo_sector; // 0x30, Sector of FSINFO structure
|
||||
public UInt16 backup_sector; // 0x32, Sector of FAT32PB bacup
|
||||
byte[] reserved; // 0x34, 12 reserved bytes
|
||||
public byte drive_no; // 0x40, Drive number
|
||||
public byte nt_flags; // 0x41, Volume flags
|
||||
public byte signature; // 0x42, FAT32PB signature, should be 0x29
|
||||
public UInt32 serial_no; // 0x43, Volume serial number
|
||||
public string volume_label; // 0x47, Volume label, 11 bytes, space-padded
|
||||
public string fs_type; // 0x52, Filesystem type, 8 bytes, space-padded, must be "FAT32 "
|
||||
}
|
||||
}
|
||||
public struct BIOSParameterBlock
|
||||
{
|
||||
public string OEMName;
|
||||
// 0x03, OEM Name, 8 bytes, space-padded
|
||||
public UInt16 bps;
|
||||
// 0x0B, Bytes per sector
|
||||
public byte spc;
|
||||
// 0x0D, Sectors per cluster
|
||||
public UInt16 rsectors;
|
||||
// 0x0E, Reserved sectors between BPB and FAT
|
||||
public byte fats_no;
|
||||
// 0x10, Number of FATs
|
||||
public UInt16 root_ent;
|
||||
// 0x11, Number of entries on root directory
|
||||
public UInt16 sectors;
|
||||
// 0x13, Sectors in volume
|
||||
public byte media;
|
||||
// 0x15, Media descriptor
|
||||
public UInt16 spfat;
|
||||
// 0x16, Sectors per FAT
|
||||
public UInt16 sptrk;
|
||||
// 0x18, Sectors per track
|
||||
public UInt16 heads;
|
||||
// 0x1A, Heads
|
||||
public UInt32 hsectors;
|
||||
// 0x1C, Hidden sectors before BPB
|
||||
public UInt32 big_sectors;
|
||||
// 0x20, Sectors in volume if > 65535
|
||||
}
|
||||
// This only applies for bootable disks
|
||||
// From http://info-coach.fr/atari/software/FD-Soft.php
|
||||
public struct AtariBootBlock
|
||||
{
|
||||
public UInt16 hsectors;
|
||||
// 0x01C, Atari ST use 16 bit for hidden sectors, probably so did old DOS
|
||||
public UInt16 xflag;
|
||||
// 0x01E, indicates if COMMAND.PRG must be executed after OS load
|
||||
public UInt16 ldmode;
|
||||
// 0x020, load mode for, or 0 if fname indicates boot file
|
||||
public UInt16 bsect;
|
||||
// 0x022, sector from which to boot
|
||||
public UInt16 bsects_no;
|
||||
// 0x024, how many sectors to boot
|
||||
public UInt32 ldaddr;
|
||||
// 0x026, RAM address where boot should be located
|
||||
public UInt32 fatbuf;
|
||||
// 0x02A, RAM address to copy the FAT and root directory
|
||||
public string fname;
|
||||
// 0x02E, 11 bytes, name of boot file
|
||||
public UInt16 reserved;
|
||||
// 0x039, unused
|
||||
public byte[] boot_code;
|
||||
// 0x03B, 451 bytes boot code
|
||||
public UInt16 checksum;
|
||||
// 0x1FE, the sum of all the BPB+ABB must be 0x1234, so this bigendian value works as adjustment
|
||||
}
|
||||
|
||||
public struct ExtendedParameterBlock
|
||||
{
|
||||
public byte drive_no;
|
||||
// 0x24, Drive number
|
||||
public byte nt_flags;
|
||||
// 0x25, Volume flags if NT (must be 0x29 signature)
|
||||
public byte signature;
|
||||
// 0x26, EPB signature, 0x28 or 0x29
|
||||
public UInt32 serial_no;
|
||||
// 0x27, Volume serial number
|
||||
/* Present only if signature == 0x29 */
|
||||
public string volume_label;
|
||||
// 0x2B, Volume label, 11 bytes, space-padded
|
||||
public string fs_type;
|
||||
// 0x36, Filesystem type, 8 bytes, space-padded
|
||||
}
|
||||
|
||||
public struct FAT32ParameterBlock
|
||||
{
|
||||
public UInt32 spfat;
|
||||
// 0x24, Sectors per FAT
|
||||
public UInt16 fat_flags;
|
||||
// 0x28, FAT flags
|
||||
public UInt16 version;
|
||||
// 0x2A, FAT32 version
|
||||
public UInt32 root_cluster;
|
||||
// 0x2C, Cluster of root directory
|
||||
public UInt16 fsinfo_sector;
|
||||
// 0x30, Sector of FSINFO structure
|
||||
public UInt16 backup_sector;
|
||||
// 0x32, Sector of FAT32PB bacup
|
||||
byte[] reserved;
|
||||
// 0x34, 12 reserved bytes
|
||||
public byte drive_no;
|
||||
// 0x40, Drive number
|
||||
public byte nt_flags;
|
||||
// 0x41, Volume flags
|
||||
public byte signature;
|
||||
// 0x42, FAT32PB signature, should be 0x29
|
||||
public UInt32 serial_no;
|
||||
// 0x43, Volume serial number
|
||||
public string volume_label;
|
||||
// 0x47, Volume label, 11 bytes, space-padded
|
||||
public string fs_type;
|
||||
// 0x52, Filesystem type, 8 bytes, space-padded, must be "FAT32 "
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,44 +1,42 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class HPFS : Plugin
|
||||
{
|
||||
public HPFS(PluginBase Core)
|
||||
class HPFS : Plugin
|
||||
{
|
||||
public HPFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "OS/2 High Performance File System";
|
||||
base.PluginUUID = new Guid("33513B2C-f590-4acb-8bf2-0b1d5e19dec5");
|
||||
Name = "OS/2 High Performance File System";
|
||||
PluginUUID = new Guid("33513B2C-f590-4acb-8bf2-0b1d5e19dec5");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
UInt32 magic1, magic2;
|
||||
{
|
||||
UInt32 magic1, magic2;
|
||||
|
||||
byte[] hpfs_sb_sector = imagePlugin.ReadSector(16 + partitionOffset); // Seek to superblock, on logical sector 16
|
||||
magic1 = BitConverter.ToUInt32(hpfs_sb_sector, 0x000);
|
||||
magic2 = BitConverter.ToUInt32(hpfs_sb_sector, 0x004);
|
||||
|
||||
if(magic1 == 0xF995E849 && magic2 == 0xFA53E9C5)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
if (magic1 == 0xF995E849 && magic2 == 0xFA53E9C5)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
HPFS_BIOSParameterBlock hpfs_bpb = new HPFS_BIOSParameterBlock();
|
||||
HPFS_SuperBlock hpfs_sb = new HPFS_SuperBlock();
|
||||
HPFS_SpareBlock hpfs_sp = new HPFS_SpareBlock();
|
||||
HPFS_BIOSParameterBlock hpfs_bpb = new HPFS_BIOSParameterBlock();
|
||||
HPFS_SuperBlock hpfs_sb = new HPFS_SuperBlock();
|
||||
HPFS_SpareBlock hpfs_sp = new HPFS_SpareBlock();
|
||||
|
||||
byte[] oem_name = new byte[8];
|
||||
byte[] volume_name = new byte[11];
|
||||
byte[] oem_name = new byte[8];
|
||||
byte[] volume_name = new byte[11];
|
||||
|
||||
byte[] hpfs_bpb_sector = imagePlugin.ReadSector(0 + partitionOffset); // Seek to BIOS parameter block, on logical sector 0
|
||||
byte[] hpfs_sb_sector = imagePlugin.ReadSector(16 + partitionOffset); // Seek to superblock, on logical sector 16
|
||||
@@ -47,7 +45,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
hpfs_bpb.jmp1 = hpfs_bpb_sector[0x000];
|
||||
hpfs_bpb.jmp2 = BitConverter.ToUInt16(hpfs_bpb_sector, 0x001);
|
||||
Array.Copy(hpfs_bpb_sector, 0x003, oem_name, 0, 8);
|
||||
hpfs_bpb.OEMName = StringHandlers.CToString(oem_name);
|
||||
hpfs_bpb.OEMName = StringHandlers.CToString(oem_name);
|
||||
hpfs_bpb.bps = BitConverter.ToUInt16(hpfs_bpb_sector, 0x00B);
|
||||
hpfs_bpb.spc = hpfs_bpb_sector[0x00D];
|
||||
hpfs_bpb.rsectors = BitConverter.ToUInt16(hpfs_bpb_sector, 0x00E);
|
||||
@@ -65,11 +63,11 @@ namespace FileSystemIDandChk.Plugins
|
||||
hpfs_bpb.signature = hpfs_bpb_sector[0x02A];
|
||||
hpfs_bpb.serial_no = BitConverter.ToUInt32(hpfs_bpb_sector, 0x02B);
|
||||
Array.Copy(hpfs_bpb_sector, 0x02F, volume_name, 0, 11);
|
||||
hpfs_bpb.volume_label = StringHandlers.CToString(volume_name);
|
||||
hpfs_bpb.volume_label = StringHandlers.CToString(volume_name);
|
||||
Array.Copy(hpfs_bpb_sector, 0x03A, oem_name, 0, 8);
|
||||
hpfs_bpb.fs_type = StringHandlers.CToString(oem_name);
|
||||
hpfs_bpb.fs_type = StringHandlers.CToString(oem_name);
|
||||
|
||||
hpfs_sb.magic1 = BitConverter.ToUInt32(hpfs_sb_sector, 0x000);
|
||||
hpfs_sb.magic1 = BitConverter.ToUInt32(hpfs_sb_sector, 0x000);
|
||||
hpfs_sb.magic2 = BitConverter.ToUInt32(hpfs_sb_sector, 0x004);
|
||||
hpfs_sb.version = hpfs_sb_sector[0x008];
|
||||
hpfs_sb.func_version = hpfs_sb_sector[0x009];
|
||||
@@ -108,176 +106,234 @@ namespace FileSystemIDandChk.Plugins
|
||||
hpfs_sp.sb_crc32 = BitConverter.ToUInt32(hpfs_sp_sector, 0x028);
|
||||
hpfs_sp.sp_crc32 = BitConverter.ToUInt32(hpfs_sp_sector, 0x02C);
|
||||
|
||||
if(hpfs_bpb.fs_type != "HPFS " ||
|
||||
hpfs_sb.magic1 != 0xF995E849 || hpfs_sb.magic2 != 0xFA53E9C5 ||
|
||||
hpfs_sp.magic1 != 0xF9911849 || hpfs_sp.magic2 != 0xFA5229C5)
|
||||
{
|
||||
sb.AppendLine("This may not be HPFS, following information may be not correct.");
|
||||
sb.AppendFormat("File system type: \"{0}\" (Should be \"HPFS \")", hpfs_bpb.fs_type).AppendLine();
|
||||
sb.AppendFormat("Superblock magic1: 0x{0:X8} (Should be 0xF995E849)", hpfs_sb.magic1).AppendLine();
|
||||
sb.AppendFormat("Superblock magic2: 0x{0:X8} (Should be 0xFA53E9C5)", hpfs_sb.magic2).AppendLine();
|
||||
sb.AppendFormat("Spareblock magic1: 0x{0:X8} (Should be 0xF9911849)", hpfs_sp.magic1).AppendLine();
|
||||
sb.AppendFormat("Spareblock magic2: 0x{0:X8} (Should be 0xFA5229C5)", hpfs_sp.magic2).AppendLine();
|
||||
}
|
||||
if (hpfs_bpb.fs_type != "HPFS " ||
|
||||
hpfs_sb.magic1 != 0xF995E849 || hpfs_sb.magic2 != 0xFA53E9C5 ||
|
||||
hpfs_sp.magic1 != 0xF9911849 || hpfs_sp.magic2 != 0xFA5229C5)
|
||||
{
|
||||
sb.AppendLine("This may not be HPFS, following information may be not correct.");
|
||||
sb.AppendFormat("File system type: \"{0}\" (Should be \"HPFS \")", hpfs_bpb.fs_type).AppendLine();
|
||||
sb.AppendFormat("Superblock magic1: 0x{0:X8} (Should be 0xF995E849)", hpfs_sb.magic1).AppendLine();
|
||||
sb.AppendFormat("Superblock magic2: 0x{0:X8} (Should be 0xFA53E9C5)", hpfs_sb.magic2).AppendLine();
|
||||
sb.AppendFormat("Spareblock magic1: 0x{0:X8} (Should be 0xF9911849)", hpfs_sp.magic1).AppendLine();
|
||||
sb.AppendFormat("Spareblock magic2: 0x{0:X8} (Should be 0xFA5229C5)", hpfs_sp.magic2).AppendLine();
|
||||
}
|
||||
|
||||
sb.AppendFormat("OEM name: {0}", hpfs_bpb.OEMName).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector", hpfs_bpb.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster", hpfs_bpb.spc).AppendLine();
|
||||
sb.AppendFormat("OEM name: {0}", hpfs_bpb.OEMName).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector", hpfs_bpb.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster", hpfs_bpb.spc).AppendLine();
|
||||
// sb.AppendFormat("{0} reserved sectors", hpfs_bpb.rsectors).AppendLine();
|
||||
// sb.AppendFormat("{0} FATs", hpfs_bpb.fats_no).AppendLine();
|
||||
// sb.AppendFormat("{0} entries on root directory", hpfs_bpb.root_ent).AppendLine();
|
||||
// sb.AppendFormat("{0} mini sectors on volume", hpfs_bpb.sectors).AppendLine();
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", hpfs_bpb.media).AppendLine();
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", hpfs_bpb.media).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per FAT", hpfs_bpb.spfat).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per track", hpfs_bpb.sptrk).AppendLine();
|
||||
// sb.AppendFormat("{0} heads", hpfs_bpb.heads).AppendLine();
|
||||
sb.AppendFormat("{0} sectors hidden before BPB", hpfs_bpb.hsectors).AppendLine();
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfs_bpb.big_sectors, hpfs_bpb.big_sectors*hpfs_bpb.bps).AppendLine();
|
||||
sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", hpfs_bpb.drive_no).AppendLine();
|
||||
sb.AppendFormat("{0} sectors hidden before BPB", hpfs_bpb.hsectors).AppendLine();
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfs_bpb.big_sectors, hpfs_bpb.big_sectors * hpfs_bpb.bps).AppendLine();
|
||||
sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", hpfs_bpb.drive_no).AppendLine();
|
||||
// sb.AppendFormat("NT Flags: 0x{0:X2}", hpfs_bpb.nt_flags).AppendLine();
|
||||
sb.AppendFormat("Signature: 0x{0:X2}", hpfs_bpb.signature).AppendLine();
|
||||
sb.AppendFormat("Serial number: 0x{0:X8}", hpfs_bpb.serial_no).AppendLine();
|
||||
sb.AppendFormat("Volume label: {0}", hpfs_bpb.volume_label).AppendLine();
|
||||
sb.AppendFormat("Signature: 0x{0:X2}", hpfs_bpb.signature).AppendLine();
|
||||
sb.AppendFormat("Serial number: 0x{0:X8}", hpfs_bpb.serial_no).AppendLine();
|
||||
sb.AppendFormat("Volume label: {0}", hpfs_bpb.volume_label).AppendLine();
|
||||
// sb.AppendFormat("Filesystem type: \"{0}\"", hpfs_bpb.fs_type).AppendLine();
|
||||
|
||||
DateTime last_chk = DateHandlers.UNIXToDateTime(hpfs_sb.last_chkdsk);
|
||||
DateTime last_optim = DateHandlers.UNIXToDateTime(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();
|
||||
sb.AppendFormat("Sector of root directory FNode: {0}", hpfs_sb.root_fnode).AppendLine();
|
||||
sb.AppendFormat("HPFS version: {0}", hpfs_sb.version).AppendLine();
|
||||
sb.AppendFormat("Functional version: {0}", hpfs_sb.func_version).AppendLine();
|
||||
sb.AppendFormat("Sector of root directory FNode: {0}", hpfs_sb.root_fnode).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume", hpfs_sb.sectors).AppendLine();
|
||||
sb.AppendFormat("{0} sectors are marked bad", hpfs_sb.badblocks).AppendLine();
|
||||
sb.AppendFormat("Sector of free space bitmaps: {0}", hpfs_sb.bitmap_lsn).AppendLine();
|
||||
sb.AppendFormat("Sector of bad blocks list: {0}", hpfs_sb.badblock_lsn).AppendLine();
|
||||
sb.AppendFormat("Date of last integrity check: {0}", last_chk).AppendLine();
|
||||
if(hpfs_sb.last_optim>0)
|
||||
sb.AppendFormat("Date of last optimization {0}", last_optim).AppendLine();
|
||||
else
|
||||
sb.AppendLine("Filesystem has never been optimized");
|
||||
sb.AppendFormat("Directory band has {0} sectors", hpfs_sb.dband_sectors).AppendLine();
|
||||
sb.AppendFormat("Directory band starts at sector {0}", hpfs_sb.dband_start).AppendLine();
|
||||
sb.AppendFormat("Directory band ends at sector {0}", hpfs_sb.dband_last).AppendLine();
|
||||
sb.AppendFormat("Sector of directory band bitmap: {0}", hpfs_sb.dband_bitmap).AppendLine();
|
||||
sb.AppendFormat("Sector of ACL directory: {0}", hpfs_sb.acl_start).AppendLine();
|
||||
sb.AppendFormat("{0} sectors are marked bad", hpfs_sb.badblocks).AppendLine();
|
||||
sb.AppendFormat("Sector of free space bitmaps: {0}", hpfs_sb.bitmap_lsn).AppendLine();
|
||||
sb.AppendFormat("Sector of bad blocks list: {0}", hpfs_sb.badblock_lsn).AppendLine();
|
||||
sb.AppendFormat("Date of last integrity check: {0}", last_chk).AppendLine();
|
||||
if (hpfs_sb.last_optim > 0)
|
||||
sb.AppendFormat("Date of last optimization {0}", last_optim).AppendLine();
|
||||
else
|
||||
sb.AppendLine("Filesystem has never been optimized");
|
||||
sb.AppendFormat("Directory band has {0} sectors", hpfs_sb.dband_sectors).AppendLine();
|
||||
sb.AppendFormat("Directory band starts at sector {0}", hpfs_sb.dband_start).AppendLine();
|
||||
sb.AppendFormat("Directory band ends at sector {0}", hpfs_sb.dband_last).AppendLine();
|
||||
sb.AppendFormat("Sector of directory band bitmap: {0}", hpfs_sb.dband_bitmap).AppendLine();
|
||||
sb.AppendFormat("Sector of ACL directory: {0}", hpfs_sb.acl_start).AppendLine();
|
||||
|
||||
sb.AppendFormat("Sector of Hotfix directory: {0}", hpfs_sp.hotfix_start).AppendLine();
|
||||
sb.AppendFormat("{0} used Hotfix entries", hpfs_sp.hotfix_used).AppendLine();
|
||||
sb.AppendFormat("{0} total Hotfix entries", hpfs_sp.hotfix_entries).AppendLine();
|
||||
sb.AppendFormat("{0} free spare DNodes", hpfs_sp.spare_dnodes_free).AppendLine();
|
||||
sb.AppendFormat("{0} total spare DNodes", hpfs_sp.spare_dnodes).AppendLine();
|
||||
sb.AppendFormat("Sector of codepage directory: {0}", hpfs_sp.codepage_lsn).AppendLine();
|
||||
sb.AppendFormat("{0} codepages used in the volume", hpfs_sp.codepages).AppendLine();
|
||||
sb.AppendFormat("SuperBlock CRC32: {0:X8}", hpfs_sp.sb_crc32).AppendLine();
|
||||
sb.AppendFormat("SpareBlock CRC32: {0:X8}", hpfs_sp.sp_crc32).AppendLine();
|
||||
sb.AppendFormat("Sector of Hotfix directory: {0}", hpfs_sp.hotfix_start).AppendLine();
|
||||
sb.AppendFormat("{0} used Hotfix entries", hpfs_sp.hotfix_used).AppendLine();
|
||||
sb.AppendFormat("{0} total Hotfix entries", hpfs_sp.hotfix_entries).AppendLine();
|
||||
sb.AppendFormat("{0} free spare DNodes", hpfs_sp.spare_dnodes_free).AppendLine();
|
||||
sb.AppendFormat("{0} total spare DNodes", hpfs_sp.spare_dnodes).AppendLine();
|
||||
sb.AppendFormat("Sector of codepage directory: {0}", hpfs_sp.codepage_lsn).AppendLine();
|
||||
sb.AppendFormat("{0} codepages used in the volume", hpfs_sp.codepages).AppendLine();
|
||||
sb.AppendFormat("SuperBlock CRC32: {0:X8}", hpfs_sp.sb_crc32).AppendLine();
|
||||
sb.AppendFormat("SpareBlock CRC32: {0:X8}", hpfs_sp.sp_crc32).AppendLine();
|
||||
|
||||
sb.AppendLine("Flags:");
|
||||
if((hpfs_sp.flags1 & 0x01) == 0x01)
|
||||
sb.AppendLine("Filesystem is dirty.");
|
||||
else
|
||||
sb.AppendLine("Filesystem is clean.");
|
||||
if((hpfs_sp.flags1 & 0x02) == 0x02)
|
||||
sb.AppendLine("Spare directory blocks are in use");
|
||||
if((hpfs_sp.flags1 & 0x04) == 0x04)
|
||||
sb.AppendLine("Hotfixes are in use");
|
||||
if((hpfs_sp.flags1 & 0x08) == 0x08)
|
||||
sb.AppendLine("Disk contains bad sectors");
|
||||
if((hpfs_sp.flags1 & 0x10) == 0x10)
|
||||
sb.AppendLine("Disk has a bad bitmap");
|
||||
if((hpfs_sp.flags1 & 0x20) == 0x20)
|
||||
sb.AppendLine("Filesystem was formatted fast");
|
||||
if((hpfs_sp.flags1 & 0x40) == 0x40)
|
||||
sb.AppendLine("Unknown flag 0x40 on flags1 is active");
|
||||
if((hpfs_sp.flags1 & 0x80) == 0x80)
|
||||
sb.AppendLine("Filesystem has been mounted by an old IFS");
|
||||
if((hpfs_sp.flags2 & 0x01) == 0x01)
|
||||
sb.AppendLine("Install DASD limits");
|
||||
if((hpfs_sp.flags2 & 0x02) == 0x02)
|
||||
sb.AppendLine("Resync DASD limits");
|
||||
if((hpfs_sp.flags2 & 0x04) == 0x04)
|
||||
sb.AppendLine("DASD limits are operational");
|
||||
if((hpfs_sp.flags2 & 0x08) == 0x08)
|
||||
sb.AppendLine("Multimedia is active");
|
||||
if((hpfs_sp.flags2 & 0x10) == 0x10)
|
||||
sb.AppendLine("DCE ACLs are active");
|
||||
if((hpfs_sp.flags2 & 0x20) == 0x20)
|
||||
sb.AppendLine("DASD limits are dirty");
|
||||
if((hpfs_sp.flags2 & 0x40) == 0x40)
|
||||
sb.AppendLine("Unknown flag 0x40 on flags2 is active");
|
||||
if((hpfs_sp.flags2 & 0x80) == 0x80)
|
||||
sb.AppendLine("Unknown flag 0x80 on flags2 is active");
|
||||
sb.AppendLine("Flags:");
|
||||
if ((hpfs_sp.flags1 & 0x01) == 0x01)
|
||||
sb.AppendLine("Filesystem is dirty.");
|
||||
else
|
||||
sb.AppendLine("Filesystem is clean.");
|
||||
if ((hpfs_sp.flags1 & 0x02) == 0x02)
|
||||
sb.AppendLine("Spare directory blocks are in use");
|
||||
if ((hpfs_sp.flags1 & 0x04) == 0x04)
|
||||
sb.AppendLine("Hotfixes are in use");
|
||||
if ((hpfs_sp.flags1 & 0x08) == 0x08)
|
||||
sb.AppendLine("Disk contains bad sectors");
|
||||
if ((hpfs_sp.flags1 & 0x10) == 0x10)
|
||||
sb.AppendLine("Disk has a bad bitmap");
|
||||
if ((hpfs_sp.flags1 & 0x20) == 0x20)
|
||||
sb.AppendLine("Filesystem was formatted fast");
|
||||
if ((hpfs_sp.flags1 & 0x40) == 0x40)
|
||||
sb.AppendLine("Unknown flag 0x40 on flags1 is active");
|
||||
if ((hpfs_sp.flags1 & 0x80) == 0x80)
|
||||
sb.AppendLine("Filesystem has been mounted by an old IFS");
|
||||
if ((hpfs_sp.flags2 & 0x01) == 0x01)
|
||||
sb.AppendLine("Install DASD limits");
|
||||
if ((hpfs_sp.flags2 & 0x02) == 0x02)
|
||||
sb.AppendLine("Resync DASD limits");
|
||||
if ((hpfs_sp.flags2 & 0x04) == 0x04)
|
||||
sb.AppendLine("DASD limits are operational");
|
||||
if ((hpfs_sp.flags2 & 0x08) == 0x08)
|
||||
sb.AppendLine("Multimedia is active");
|
||||
if ((hpfs_sp.flags2 & 0x10) == 0x10)
|
||||
sb.AppendLine("DCE ACLs are active");
|
||||
if ((hpfs_sp.flags2 & 0x20) == 0x20)
|
||||
sb.AppendLine("DASD limits are dirty");
|
||||
if ((hpfs_sp.flags2 & 0x40) == 0x40)
|
||||
sb.AppendLine("Unknown flag 0x40 on flags2 is active");
|
||||
if ((hpfs_sp.flags2 & 0x80) == 0x80)
|
||||
sb.AppendLine("Unknown flag 0x80 on flags2 is active");
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
private struct HPFS_BIOSParameterBlock // Sector 0
|
||||
{
|
||||
public byte jmp1; // 0x000, Jump to boot code
|
||||
public UInt16 jmp2; // 0x001, ...;
|
||||
public string OEMName; // 0x003, OEM Name, 8 bytes, space-padded
|
||||
public UInt16 bps; // 0x00B, Bytes per sector
|
||||
public byte spc; // 0x00D, Sectors per cluster
|
||||
public UInt16 rsectors; // 0x00E, Reserved sectors between BPB and... does it have sense in HPFS?
|
||||
public byte fats_no; // 0x010, Number of FATs... seriously?
|
||||
public UInt16 root_ent; // 0x011, Number of entries on root directory... ok
|
||||
public UInt16 sectors; // 0x013, Sectors in volume... doubt it
|
||||
public byte media; // 0x015, Media descriptor
|
||||
public UInt16 spfat; // 0x016, Sectors per FAT... again
|
||||
public UInt16 sptrk; // 0x018, Sectors per track... you're kidding
|
||||
public UInt16 heads; // 0x01A, Heads... stop!
|
||||
public UInt32 hsectors; // 0x01C, Hidden sectors before BPB
|
||||
public UInt32 big_sectors; // 0x024, Sectors in volume if > 65535...
|
||||
public byte drive_no; // 0x028, Drive number
|
||||
public byte nt_flags; // 0x029, Volume flags?
|
||||
public byte signature; // 0x02A, EPB signature, 0x29
|
||||
public UInt32 serial_no; // 0x02B, Volume serial number
|
||||
public string volume_label; // 0x02F, Volume label, 11 bytes, space-padded
|
||||
public string fs_type; // 0x03A, Filesystem type, 8 bytes, space-padded ("HPFS ")
|
||||
}
|
||||
|
||||
private struct HPFS_SuperBlock // Sector 16
|
||||
{
|
||||
public UInt32 magic1; // 0x000, 0xF995E849
|
||||
public UInt32 magic2; // 0x004, 0xFA53E9C5
|
||||
public byte version; // 0x008, HPFS version
|
||||
public byte func_version; // 0x009, 2 if <= 4 GiB, 3 if > 4 GiB
|
||||
public UInt16 dummy; // 0x00A, Alignment
|
||||
public UInt32 root_fnode; // 0x00C, LSN pointer to root fnode
|
||||
public UInt32 sectors; // 0x010, Sectors on volume
|
||||
public UInt32 badblocks; // 0x014, Bad blocks on volume
|
||||
public UInt32 bitmap_lsn; // 0x018, LSN pointer to volume bitmap
|
||||
public UInt32 zero1; // 0x01C, 0
|
||||
public UInt32 badblock_lsn; // 0x020, LSN pointer to badblock directory
|
||||
public UInt32 zero2; // 0x024, 0
|
||||
public Int32 last_chkdsk; // 0x028, Time of last CHKDSK
|
||||
public Int32 last_optim; // 0x02C, Time of last optimization
|
||||
public UInt32 dband_sectors; // 0x030, Sectors of dir band
|
||||
public UInt32 dband_start; // 0x034, Start sector of dir band
|
||||
public UInt32 dband_last; // 0x038, Last sector of dir band
|
||||
public UInt32 dband_bitmap; // 0x03C, LSN of free space bitmap
|
||||
public UInt64 zero3; // 0x040, Can be used for volume name (32 bytes)
|
||||
public UInt64 zero4; // 0x048, ...
|
||||
public UInt64 zero5; // 0x04C, ...
|
||||
public UInt64 zero6; // 0x050, ...;
|
||||
public UInt32 acl_start; // 0x058, LSN pointer to ACLs (only HPFS386)
|
||||
}
|
||||
|
||||
private struct HPFS_SpareBlock // Sector 17
|
||||
{
|
||||
public UInt32 magic1; // 0x000, 0xF9911849
|
||||
public UInt32 magic2; // 0x004, 0xFA5229C5
|
||||
public byte flags1; // 0x008, HPFS flags
|
||||
public byte flags2; // 0x009, HPFS386 flags
|
||||
public UInt16 dummy; // 0x00A, Alignment
|
||||
public UInt32 hotfix_start; // 0x00C, LSN of hotfix directory
|
||||
public UInt32 hotfix_used; // 0x010, Used hotfixes
|
||||
public UInt32 hotfix_entries; // 0x014, Total hotfixes available
|
||||
public UInt32 spare_dnodes_free; // 0x018, Unused spare dnodes
|
||||
public UInt32 spare_dnodes; // 0x01C, Length of spare dnodes list
|
||||
public UInt32 codepage_lsn; // 0x020, LSN of codepage directory
|
||||
public UInt32 codepages; // 0x024, Number of codepages used
|
||||
public UInt32 sb_crc32; // 0x028, SuperBlock CRC32 (only HPFS386)
|
||||
public UInt32 sp_crc32; // 0x02C, SpareBlock CRC32 (only HPFS386)
|
||||
}
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
struct HPFS_BIOSParameterBlock // Sector 0
|
||||
{
|
||||
public byte jmp1;
|
||||
// 0x000, Jump to boot code
|
||||
public UInt16 jmp2;
|
||||
// 0x001, ...;
|
||||
public string OEMName;
|
||||
// 0x003, OEM Name, 8 bytes, space-padded
|
||||
public UInt16 bps;
|
||||
// 0x00B, Bytes per sector
|
||||
public byte spc;
|
||||
// 0x00D, Sectors per cluster
|
||||
public UInt16 rsectors;
|
||||
// 0x00E, Reserved sectors between BPB and... does it have sense in HPFS?
|
||||
public byte fats_no;
|
||||
// 0x010, Number of FATs... seriously?
|
||||
public UInt16 root_ent;
|
||||
// 0x011, Number of entries on root directory... ok
|
||||
public UInt16 sectors;
|
||||
// 0x013, Sectors in volume... doubt it
|
||||
public byte media;
|
||||
// 0x015, Media descriptor
|
||||
public UInt16 spfat;
|
||||
// 0x016, Sectors per FAT... again
|
||||
public UInt16 sptrk;
|
||||
// 0x018, Sectors per track... you're kidding
|
||||
public UInt16 heads;
|
||||
// 0x01A, Heads... stop!
|
||||
public UInt32 hsectors;
|
||||
// 0x01C, Hidden sectors before BPB
|
||||
public UInt32 big_sectors;
|
||||
// 0x024, Sectors in volume if > 65535...
|
||||
public byte drive_no;
|
||||
// 0x028, Drive number
|
||||
public byte nt_flags;
|
||||
// 0x029, Volume flags?
|
||||
public byte signature;
|
||||
// 0x02A, EPB signature, 0x29
|
||||
public UInt32 serial_no;
|
||||
// 0x02B, Volume serial number
|
||||
public string volume_label;
|
||||
// 0x02F, Volume label, 11 bytes, space-padded
|
||||
public string fs_type;
|
||||
// 0x03A, Filesystem type, 8 bytes, space-padded ("HPFS ")
|
||||
}
|
||||
|
||||
struct HPFS_SuperBlock // Sector 16
|
||||
{
|
||||
public UInt32 magic1;
|
||||
// 0x000, 0xF995E849
|
||||
public UInt32 magic2;
|
||||
// 0x004, 0xFA53E9C5
|
||||
public byte version;
|
||||
// 0x008, HPFS version
|
||||
public byte func_version;
|
||||
// 0x009, 2 if <= 4 GiB, 3 if > 4 GiB
|
||||
public UInt16 dummy;
|
||||
// 0x00A, Alignment
|
||||
public UInt32 root_fnode;
|
||||
// 0x00C, LSN pointer to root fnode
|
||||
public UInt32 sectors;
|
||||
// 0x010, Sectors on volume
|
||||
public UInt32 badblocks;
|
||||
// 0x014, Bad blocks on volume
|
||||
public UInt32 bitmap_lsn;
|
||||
// 0x018, LSN pointer to volume bitmap
|
||||
public UInt32 zero1;
|
||||
// 0x01C, 0
|
||||
public UInt32 badblock_lsn;
|
||||
// 0x020, LSN pointer to badblock directory
|
||||
public UInt32 zero2;
|
||||
// 0x024, 0
|
||||
public Int32 last_chkdsk;
|
||||
// 0x028, Time of last CHKDSK
|
||||
public Int32 last_optim;
|
||||
// 0x02C, Time of last optimization
|
||||
public UInt32 dband_sectors;
|
||||
// 0x030, Sectors of dir band
|
||||
public UInt32 dband_start;
|
||||
// 0x034, Start sector of dir band
|
||||
public UInt32 dband_last;
|
||||
// 0x038, Last sector of dir band
|
||||
public UInt32 dband_bitmap;
|
||||
// 0x03C, LSN of free space bitmap
|
||||
public UInt64 zero3;
|
||||
// 0x040, Can be used for volume name (32 bytes)
|
||||
public UInt64 zero4;
|
||||
// 0x048, ...
|
||||
public UInt64 zero5;
|
||||
// 0x04C, ...
|
||||
public UInt64 zero6;
|
||||
// 0x050, ...;
|
||||
public UInt32 acl_start;
|
||||
// 0x058, LSN pointer to ACLs (only HPFS386)
|
||||
}
|
||||
|
||||
struct HPFS_SpareBlock // Sector 17
|
||||
{
|
||||
public UInt32 magic1;
|
||||
// 0x000, 0xF9911849
|
||||
public UInt32 magic2;
|
||||
// 0x004, 0xFA5229C5
|
||||
public byte flags1;
|
||||
// 0x008, HPFS flags
|
||||
public byte flags2;
|
||||
// 0x009, HPFS386 flags
|
||||
public UInt16 dummy;
|
||||
// 0x00A, Alignment
|
||||
public UInt32 hotfix_start;
|
||||
// 0x00C, LSN of hotfix directory
|
||||
public UInt32 hotfix_used;
|
||||
// 0x010, Used hotfixes
|
||||
public UInt32 hotfix_entries;
|
||||
// 0x014, Total hotfixes available
|
||||
public UInt32 spare_dnodes_free;
|
||||
// 0x018, Unused spare dnodes
|
||||
public UInt32 spare_dnodes;
|
||||
// 0x01C, Length of spare dnodes list
|
||||
public UInt32 codepage_lsn;
|
||||
// 0x020, LSN of codepage directory
|
||||
public UInt32 codepages;
|
||||
// 0x024, Number of codepages used
|
||||
public UInt32 sb_crc32;
|
||||
// 0x028, SuperBlock CRC32 (only HPFS386)
|
||||
public UInt32 sp_crc32;
|
||||
// 0x02C, SpareBlock CRC32 (only HPFS386)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
// This is coded following ECMA-119.
|
||||
@@ -13,16 +12,16 @@ namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class ISO9660Plugin : Plugin
|
||||
{
|
||||
private static bool alreadyLaunched;
|
||||
static bool alreadyLaunched;
|
||||
|
||||
public ISO9660Plugin(PluginBase Core)
|
||||
{
|
||||
base.Name = "ISO9660 Filesystem";
|
||||
base.PluginUUID = new Guid("d812f4d3-c357-400d-90fd-3b22ef786aa8");
|
||||
Name = "ISO9660 Filesystem";
|
||||
PluginUUID = new Guid("d812f4d3-c357-400d-90fd-3b22ef786aa8");
|
||||
alreadyLaunched = false;
|
||||
}
|
||||
|
||||
private struct DecodedVolumeDescriptor
|
||||
struct DecodedVolumeDescriptor
|
||||
{
|
||||
public string SystemIdentifier;
|
||||
public string VolumeIdentifier;
|
||||
@@ -41,12 +40,11 @@ namespace FileSystemIDandChk.Plugins
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
if(alreadyLaunched)
|
||||
return false;
|
||||
else
|
||||
alreadyLaunched = true;
|
||||
if (alreadyLaunched)
|
||||
return false;
|
||||
alreadyLaunched = true;
|
||||
|
||||
byte VDType;
|
||||
byte VDType;
|
||||
|
||||
// ISO9660 is designed for 2048 bytes/sector devices
|
||||
if (imagePlugin.GetSectorSize() < 2048)
|
||||
@@ -60,19 +58,16 @@ namespace FileSystemIDandChk.Plugins
|
||||
byte[] vd_sector = imagePlugin.ReadSector(16 + partitionOffset);
|
||||
|
||||
VDType = vd_sector[0];
|
||||
byte[] VDMagic = new byte[5];
|
||||
byte[] VDMagic = new byte[5];
|
||||
|
||||
// Wrong, VDs can be any order!
|
||||
// Wrong, VDs can be any order!
|
||||
if (VDType == 255) // Supposedly we are in the PVD.
|
||||
return false;
|
||||
|
||||
Array.Copy(vd_sector, 0x001, VDMagic, 0, 5);
|
||||
|
||||
if (Encoding.ASCII.GetString(VDMagic) != "CD001") // Recognized, it is an ISO9660, now check for rest of data.
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return Encoding.ASCII.GetString(VDMagic) == "CD001";
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
@@ -246,10 +241,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
if (Encoding.ASCII.GetString(SUSPMagic) == "SP")
|
||||
{
|
||||
Array.Copy(root_dir, 0x29, RRMagic, 0, 2);
|
||||
if (Encoding.ASCII.GetString(RRMagic) == "RR")
|
||||
{
|
||||
RockRidge = true;
|
||||
}
|
||||
RockRidge |= Encoding.ASCII.GetString(RRMagic) == "RR";
|
||||
}
|
||||
|
||||
#region SEGA IP.BIN Read and decoding
|
||||
@@ -345,7 +337,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
Array.Copy(ipbin_sector, 0x1B0, spare_space7, 0, 64); // Inside here should be modem information, but I need to get a modem-enabled game
|
||||
Array.Copy(ipbin_sector, 0x1F0, region_codes, 0, 16); // Region codes, space-filled
|
||||
// Decoding all data
|
||||
DateTime ipbindate = new DateTime();
|
||||
DateTime ipbindate;
|
||||
CultureInfo provider = CultureInfo.InvariantCulture;
|
||||
ipbindate = DateTime.ParseExact(Encoding.ASCII.GetString(release_date), "MMddyyyy", provider);
|
||||
|
||||
@@ -377,7 +369,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
IPBinInformation.AppendFormat("System program load size: {0} bytes", BitConverter.ToInt32(sp_loadsize, 0)).AppendLine();
|
||||
IPBinInformation.AppendFormat("System program entry address: 0x{0}", BitConverter.ToInt32(sp_entry_address, 0).ToString("X")).AppendLine();
|
||||
IPBinInformation.AppendFormat("System program work RAM: {0} bytes", BitConverter.ToInt32(sp_work_ram_size, 0)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Release date: {0}", ipbindate.ToString()).AppendLine();
|
||||
IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine();
|
||||
IPBinInformation.AppendFormat("Release date (other format): {0}", Encoding.ASCII.GetString(release_date2)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Hardware ID: {0}", Encoding.ASCII.GetString(hardware_id)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Developer code: {0}", Encoding.ASCII.GetString(developer_code)).AppendLine();
|
||||
@@ -425,7 +417,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
IPBinInformation.AppendFormat("Game supports unknown peripheral {0}.", peripheral.ToString()).AppendLine();
|
||||
IPBinInformation.AppendFormat("Game supports unknown peripheral {0}.", peripheral).AppendLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -446,7 +438,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
IPBinInformation.AppendFormat("Game supports unknown region {0}.", region.ToString()).AppendLine();
|
||||
IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -488,13 +480,13 @@ namespace FileSystemIDandChk.Plugins
|
||||
Array.Copy(ipbin_sector, 0x050, peripherals, 0, 16); // Supported peripherals, see above
|
||||
Array.Copy(ipbin_sector, 0x060, product_name, 0, 112); // Game name, space-filled
|
||||
// Decoding all data
|
||||
DateTime ipbindate = new DateTime();
|
||||
DateTime ipbindate;
|
||||
CultureInfo provider = CultureInfo.InvariantCulture;
|
||||
ipbindate = DateTime.ParseExact(Encoding.ASCII.GetString(release_date), "yyyyMMdd", provider);
|
||||
IPBinInformation.AppendFormat("Product name: {0}", Encoding.ASCII.GetString(product_name)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Product number: {0}", Encoding.ASCII.GetString(product_no)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Product version: {0}", Encoding.ASCII.GetString(product_version)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Release date: {0}", ipbindate.ToString()).AppendLine();
|
||||
IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine();
|
||||
IPBinInformation.AppendFormat("Disc number {0} of {1}", Encoding.ASCII.GetString(disc_no), Encoding.ASCII.GetString(disc_total_nos)).AppendLine();
|
||||
|
||||
IPBinInformation.AppendFormat("Peripherals:").AppendLine();
|
||||
@@ -523,7 +515,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
IPBinInformation.AppendFormat("Game supports unknown peripheral {0}.", peripheral.ToString()).AppendLine();
|
||||
IPBinInformation.AppendFormat("Game supports unknown peripheral {0}.", peripheral).AppendLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -547,7 +539,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
IPBinInformation.AppendFormat("Game supports unknown region {0}.", region.ToString()).AppendLine();
|
||||
IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -599,7 +591,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
Array.Copy(ipbin_sector, 0x068, producer, 0, 16); // Game producer, space-filled
|
||||
Array.Copy(ipbin_sector, 0x078, product_name, 0, 128); // Game name, space-filled
|
||||
// Decoding all data
|
||||
DateTime ipbindate = new DateTime();
|
||||
DateTime ipbindate;
|
||||
CultureInfo provider = CultureInfo.InvariantCulture;
|
||||
ipbindate = DateTime.ParseExact(Encoding.ASCII.GetString(release_date), "yyyyMMdd", provider);
|
||||
IPBinInformation.AppendFormat("Product name: {0}", Encoding.ASCII.GetString(product_name)).AppendLine();
|
||||
@@ -607,7 +599,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
IPBinInformation.AppendFormat("Producer: {0}", Encoding.ASCII.GetString(producer)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Disc media: {0}", Encoding.ASCII.GetString(dreamcast_media)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Disc number {0} of {1}", Encoding.ASCII.GetString(disc_no), Encoding.ASCII.GetString(disc_total_nos)).AppendLine();
|
||||
IPBinInformation.AppendFormat("Release date: {0}", ipbindate.ToString()).AppendLine();
|
||||
IPBinInformation.AppendFormat("Release date: {0}", ipbindate).AppendLine();
|
||||
switch (Encoding.ASCII.GetString(boot_filename))
|
||||
{
|
||||
case "1ST_READ.BIN":
|
||||
@@ -637,7 +629,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
IPBinInformation.AppendFormat("Game supports unknown region {0}.", region.ToString()).AppendLine();
|
||||
IPBinInformation.AppendFormat("Game supports unknown region {0}.", region).AppendLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -728,17 +720,17 @@ namespace FileSystemIDandChk.Plugins
|
||||
ISOMetadata.AppendFormat("Publisher identifier: {0}", decodedVD.PublisherIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Data preparer identifier: {0}", decodedVD.DataPreparerIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Application identifier: {0}", decodedVD.ApplicationIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedVD.CreationTime.ToString()).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedVD.CreationTime).AppendLine();
|
||||
if (decodedVD.HasModificationTime)
|
||||
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedVD.ModificationTime.ToString()).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedVD.ModificationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has not been modified.").AppendLine();
|
||||
if (decodedVD.HasExpirationTime)
|
||||
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedVD.ExpirationTime.ToString()).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedVD.ExpirationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume does not expire.").AppendLine();
|
||||
if (decodedVD.HasEffectiveTime)
|
||||
ISOMetadata.AppendFormat("Volume effective date: {0}", decodedVD.EffectiveTime.ToString()).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume effective date: {0}", decodedVD.EffectiveTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
||||
|
||||
@@ -753,17 +745,17 @@ namespace FileSystemIDandChk.Plugins
|
||||
ISOMetadata.AppendFormat("Publisher identifier: {0}", decodedJolietVD.PublisherIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Data preparer identifier: {0}", decodedJolietVD.DataPreparerIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Application identifier: {0}", decodedJolietVD.ApplicationIdentifier).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedJolietVD.CreationTime.ToString()).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedJolietVD.CreationTime).AppendLine();
|
||||
if (decodedJolietVD.HasModificationTime)
|
||||
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedJolietVD.ModificationTime.ToString()).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedJolietVD.ModificationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has not been modified.").AppendLine();
|
||||
if (decodedJolietVD.HasExpirationTime)
|
||||
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedJolietVD.ExpirationTime.ToString()).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedJolietVD.ExpirationTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume does not expire.").AppendLine();
|
||||
if (decodedJolietVD.HasEffectiveTime)
|
||||
ISOMetadata.AppendFormat("Volume effective date: {0}", decodedJolietVD.EffectiveTime.ToString()).AppendLine();
|
||||
ISOMetadata.AppendFormat("Volume effective date: {0}", decodedJolietVD.EffectiveTime).AppendLine();
|
||||
else
|
||||
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
||||
}
|
||||
@@ -771,7 +763,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
information = ISOMetadata.ToString();
|
||||
}
|
||||
|
||||
private DecodedVolumeDescriptor DecodeJolietDescriptor(byte[] VDSysId, byte[] VDVolId, byte[] VDVolSetId, byte[] VDPubId, byte[] VDDataPrepId, byte[] VDAppId, byte[] VCTime, byte[] VMTime, byte[] VXTime, byte[] VETime)
|
||||
static DecodedVolumeDescriptor DecodeJolietDescriptor(byte[] VDSysId, byte[] VDVolId, byte[] VDVolSetId, byte[] VDPubId, byte[] VDDataPrepId, byte[] VDAppId, byte[] VCTime, byte[] VMTime, byte[] VXTime, byte[] VETime)
|
||||
{
|
||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||
|
||||
@@ -819,7 +811,7 @@ namespace FileSystemIDandChk.Plugins
|
||||
return decodedVD;
|
||||
}
|
||||
|
||||
private DecodedVolumeDescriptor DecodeVolumeDescriptor(byte[] VDSysId, byte[] VDVolId, byte[] VDVolSetId, byte[] VDPubId, byte[] VDDataPrepId, byte[] VDAppId, byte[] VCTime, byte[] VMTime, byte[] VXTime, byte[] VETime)
|
||||
static DecodedVolumeDescriptor DecodeVolumeDescriptor(byte[] VDSysId, byte[] VDVolId, byte[] VDVolSetId, byte[] VDPubId, byte[] VDDataPrepId, byte[] VDAppId, byte[] VCTime, byte[] VMTime, byte[] VXTime, byte[] VETime)
|
||||
{
|
||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||
|
||||
|
||||
@@ -1,133 +1,132 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class MinixFS : Plugin
|
||||
{
|
||||
private const UInt16 MINIX_MAGIC = 0x137F; // Minix v1, 14 char filenames
|
||||
private const UInt16 MINIX_MAGIC2 = 0x138F; // Minix v1, 30 char filenames
|
||||
private const UInt16 MINIX2_MAGIC = 0x2468; // Minix v2, 14 char filenames
|
||||
private const UInt16 MINIX2_MAGIC2 = 0x2478; // Minix v2, 30 char filenames
|
||||
private const UInt16 MINIX3_MAGIC = 0x4D5A; // Minix v3, 60 char filenames
|
||||
class MinixFS : Plugin
|
||||
{
|
||||
const UInt16 MINIX_MAGIC = 0x137F;
|
||||
// Minix v1, 14 char filenames
|
||||
const UInt16 MINIX_MAGIC2 = 0x138F;
|
||||
// Minix v1, 30 char filenames
|
||||
const UInt16 MINIX2_MAGIC = 0x2468;
|
||||
// Minix v2, 14 char filenames
|
||||
const UInt16 MINIX2_MAGIC2 = 0x2478;
|
||||
// Minix v2, 30 char filenames
|
||||
const UInt16 MINIX3_MAGIC = 0x4D5A;
|
||||
// Minix v3, 60 char filenames
|
||||
// Byteswapped
|
||||
const UInt16 MINIX_CIGAM = 0x7F13;
|
||||
// Minix v1, 14 char filenames
|
||||
const UInt16 MINIX_CIGAM2 = 0x8F13;
|
||||
// Minix v1, 30 char filenames
|
||||
const UInt16 MINIX2_CIGAM = 0x6824;
|
||||
// Minix v2, 14 char filenames
|
||||
const UInt16 MINIX2_CIGAM2 = 0x7824;
|
||||
// Minix v2, 30 char filenames
|
||||
const UInt16 MINIX3_CIGAM = 0x5A4D;
|
||||
// Minix v3, 60 char filenames
|
||||
|
||||
// Byteswapped
|
||||
private const UInt16 MINIX_CIGAM = 0x7F13; // Minix v1, 14 char filenames
|
||||
private const UInt16 MINIX_CIGAM2 = 0x8F13; // Minix v1, 30 char filenames
|
||||
private const UInt16 MINIX2_CIGAM = 0x6824; // Minix v2, 14 char filenames
|
||||
private const UInt16 MINIX2_CIGAM2 = 0x7824; // Minix v2, 30 char filenames
|
||||
private const UInt16 MINIX3_CIGAM = 0x5A4D; // Minix v3, 60 char filenames
|
||||
|
||||
public MinixFS(PluginBase Core)
|
||||
public MinixFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Minix Filesystem";
|
||||
base.PluginUUID = new Guid("FE248C3B-B727-4AE5-A39F-79EA9A07D4B3");
|
||||
Name = "Minix Filesystem";
|
||||
PluginUUID = new Guid("FE248C3B-B727-4AE5-A39F-79EA9A07D4B3");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
UInt16 magic;
|
||||
{
|
||||
UInt16 magic;
|
||||
byte[] minix_sb_sector = imagePlugin.ReadSector(2 + partitionOffset);
|
||||
|
||||
magic = BitConverter.ToUInt16(minix_sb_sector, 0x010); // Here should reside magic number on Minix V1 & V2
|
||||
|
||||
if(magic == MINIX_MAGIC || magic == MINIX_MAGIC2 || magic == MINIX2_MAGIC || magic == MINIX2_MAGIC2 ||
|
||||
magic == MINIX_CIGAM || magic == MINIX_CIGAM2 || magic == MINIX2_CIGAM || magic == MINIX2_CIGAM2)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
magic = BitConverter.ToUInt16(minix_sb_sector, 0x018); // Here should reside magic number on Minix V3
|
||||
if (magic == MINIX_MAGIC || magic == MINIX_MAGIC2 || magic == MINIX2_MAGIC || magic == MINIX2_MAGIC2 ||
|
||||
magic == MINIX_CIGAM || magic == MINIX_CIGAM2 || magic == MINIX2_CIGAM || magic == MINIX2_CIGAM2)
|
||||
return true;
|
||||
magic = BitConverter.ToUInt16(minix_sb_sector, 0x018); // Here should reside magic number on Minix V3
|
||||
|
||||
if(magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
if (magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
bool littleendian = true;
|
||||
bool minix3 = false;
|
||||
int filenamesize = 0;
|
||||
string minixVersion;
|
||||
UInt16 magic;
|
||||
bool minix3 = false;
|
||||
int filenamesize;
|
||||
string minixVersion;
|
||||
UInt16 magic;
|
||||
byte[] minix_sb_sector = imagePlugin.ReadSector(2 + partitionOffset);
|
||||
|
||||
magic = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x018);
|
||||
|
||||
if(magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||
{
|
||||
filenamesize = 60;
|
||||
minixVersion = "Minix V3 filesystem";
|
||||
if(magic == MINIX3_CIGAM)
|
||||
littleendian = false;
|
||||
else
|
||||
littleendian = true;
|
||||
if (magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||
{
|
||||
filenamesize = 60;
|
||||
minixVersion = "Minix V3 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = magic != MINIX3_CIGAM;
|
||||
|
||||
minix3 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
magic = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x010);
|
||||
minix3 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
magic = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x010);
|
||||
|
||||
switch(magic)
|
||||
{
|
||||
case MINIX_MAGIC:
|
||||
filenamesize = 14;
|
||||
minixVersion = "Minix V1 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
break;
|
||||
case MINIX_MAGIC2:
|
||||
filenamesize = 30;
|
||||
minixVersion = "Minix V1 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
break;
|
||||
case MINIX2_MAGIC:
|
||||
filenamesize = 14;
|
||||
minixVersion = "Minix V2 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
break;
|
||||
case MINIX2_MAGIC2:
|
||||
filenamesize = 30;
|
||||
minixVersion = "Minix V2 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
break;
|
||||
case MINIX_CIGAM:
|
||||
filenamesize = 14;
|
||||
minixVersion = "Minix V1 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
break;
|
||||
case MINIX_CIGAM2:
|
||||
filenamesize = 30;
|
||||
minixVersion = "Minix V1 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
break;
|
||||
case MINIX2_CIGAM:
|
||||
filenamesize = 14;
|
||||
minixVersion = "Minix V2 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
break;
|
||||
case MINIX2_CIGAM2:
|
||||
filenamesize = 30;
|
||||
minixVersion = "Minix V2 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (magic)
|
||||
{
|
||||
case MINIX_MAGIC:
|
||||
filenamesize = 14;
|
||||
minixVersion = "Minix V1 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
break;
|
||||
case MINIX_MAGIC2:
|
||||
filenamesize = 30;
|
||||
minixVersion = "Minix V1 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
break;
|
||||
case MINIX2_MAGIC:
|
||||
filenamesize = 14;
|
||||
minixVersion = "Minix V2 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
break;
|
||||
case MINIX2_MAGIC2:
|
||||
filenamesize = 30;
|
||||
minixVersion = "Minix V2 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = true;
|
||||
break;
|
||||
case MINIX_CIGAM:
|
||||
filenamesize = 14;
|
||||
minixVersion = "Minix V1 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
break;
|
||||
case MINIX_CIGAM2:
|
||||
filenamesize = 30;
|
||||
minixVersion = "Minix V1 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
break;
|
||||
case MINIX2_CIGAM:
|
||||
filenamesize = 14;
|
||||
minixVersion = "Minix V2 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
break;
|
||||
case MINIX2_CIGAM2:
|
||||
filenamesize = 30;
|
||||
minixVersion = "Minix V2 filesystem";
|
||||
BigEndianBitConverter.IsLittleEndian = false;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(minix3)
|
||||
{
|
||||
Minix3SuperBlock mnx_sb = new Minix3SuperBlock();
|
||||
if (minix3)
|
||||
{
|
||||
Minix3SuperBlock mnx_sb = new Minix3SuperBlock();
|
||||
|
||||
mnx_sb.s_ninodes = BigEndianBitConverter.ToUInt32(minix_sb_sector, 0x00);
|
||||
mnx_sb.s_pad0 = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x04);
|
||||
@@ -143,21 +142,21 @@ namespace FileSystemIDandChk.Plugins
|
||||
mnx_sb.s_blocksize = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x1C);
|
||||
mnx_sb.s_disk_version = minix_sb_sector[0x1E];
|
||||
|
||||
sb.AppendLine(minixVersion);
|
||||
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_zones, mnx_sb.s_zones*mnx_sb.s_blocksize).AppendLine();
|
||||
sb.AppendFormat("{0} bytes/block", mnx_sb.s_blocksize).AppendLine();
|
||||
sb.AppendFormat("{0} inodes on volume", mnx_sb.s_ninodes).AppendLine();
|
||||
sb.AppendFormat("{0} blocks on inode map ({1} bytes)", mnx_sb.s_imap_blocks, mnx_sb.s_imap_blocks*mnx_sb.s_blocksize).AppendLine();
|
||||
sb.AppendFormat("{0} blocks on zone map ({1} bytes)", mnx_sb.s_zmap_blocks, mnx_sb.s_zmap_blocks*mnx_sb.s_blocksize).AppendLine();
|
||||
sb.AppendFormat("First data zone: {0}", mnx_sb.s_firstdatazone).AppendLine();
|
||||
//sb.AppendFormat("log2 of blocks/zone: {0}", mnx_sb.s_log_zone_size).AppendLine(); // Apparently 0
|
||||
sb.AppendFormat("{0} bytes maximum per file", mnx_sb.s_max_size).AppendLine();
|
||||
sb.AppendFormat("On-disk filesystem version: {0}", mnx_sb.s_disk_version).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
MinixSuperBlock mnx_sb = new MinixSuperBlock();
|
||||
sb.AppendLine(minixVersion);
|
||||
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_zones, mnx_sb.s_zones * mnx_sb.s_blocksize).AppendLine();
|
||||
sb.AppendFormat("{0} bytes/block", mnx_sb.s_blocksize).AppendLine();
|
||||
sb.AppendFormat("{0} inodes on volume", mnx_sb.s_ninodes).AppendLine();
|
||||
sb.AppendFormat("{0} blocks on inode map ({1} bytes)", mnx_sb.s_imap_blocks, mnx_sb.s_imap_blocks * mnx_sb.s_blocksize).AppendLine();
|
||||
sb.AppendFormat("{0} blocks on zone map ({1} bytes)", mnx_sb.s_zmap_blocks, mnx_sb.s_zmap_blocks * mnx_sb.s_blocksize).AppendLine();
|
||||
sb.AppendFormat("First data zone: {0}", mnx_sb.s_firstdatazone).AppendLine();
|
||||
//sb.AppendFormat("log2 of blocks/zone: {0}", mnx_sb.s_log_zone_size).AppendLine(); // Apparently 0
|
||||
sb.AppendFormat("{0} bytes maximum per file", mnx_sb.s_max_size).AppendLine();
|
||||
sb.AppendFormat("On-disk filesystem version: {0}", mnx_sb.s_disk_version).AppendLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
MinixSuperBlock mnx_sb = new MinixSuperBlock();
|
||||
|
||||
mnx_sb.s_ninodes = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x00);
|
||||
mnx_sb.s_nzones = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x02);
|
||||
@@ -170,53 +169,76 @@ namespace FileSystemIDandChk.Plugins
|
||||
mnx_sb.s_state = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x12);
|
||||
mnx_sb.s_zones = BigEndianBitConverter.ToUInt32(minix_sb_sector, 0x14);
|
||||
|
||||
sb.AppendLine(minixVersion);
|
||||
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
||||
if(mnx_sb.s_zones > 0) // On V2
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_zones, mnx_sb.s_zones*1024).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_nzones, mnx_sb.s_nzones*1024).AppendLine();
|
||||
sb.AppendFormat("{0} inodes on volume", mnx_sb.s_ninodes).AppendLine();
|
||||
sb.AppendFormat("{0} blocks on inode map ({1} bytes)", mnx_sb.s_imap_blocks, mnx_sb.s_imap_blocks*1024).AppendLine();
|
||||
sb.AppendFormat("{0} blocks on zone map ({1} bytes)", mnx_sb.s_zmap_blocks, mnx_sb.s_zmap_blocks*1024).AppendLine();
|
||||
sb.AppendFormat("First data zone: {0}", mnx_sb.s_firstdatazone).AppendLine();
|
||||
//sb.AppendFormat("log2 of blocks/zone: {0}", mnx_sb.s_log_zone_size).AppendLine(); // Apparently 0
|
||||
sb.AppendFormat("{0} bytes maximum per file", mnx_sb.s_max_size).AppendLine();
|
||||
sb.AppendFormat("Filesystem state: {0:X4}", mnx_sb.s_state).AppendLine();
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
sb.AppendLine(minixVersion);
|
||||
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
||||
if (mnx_sb.s_zones > 0) // On V2
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_zones, mnx_sb.s_zones * 1024).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} zones on volume ({1} bytes)", mnx_sb.s_nzones, mnx_sb.s_nzones * 1024).AppendLine();
|
||||
sb.AppendFormat("{0} inodes on volume", mnx_sb.s_ninodes).AppendLine();
|
||||
sb.AppendFormat("{0} blocks on inode map ({1} bytes)", mnx_sb.s_imap_blocks, mnx_sb.s_imap_blocks * 1024).AppendLine();
|
||||
sb.AppendFormat("{0} blocks on zone map ({1} bytes)", mnx_sb.s_zmap_blocks, mnx_sb.s_zmap_blocks * 1024).AppendLine();
|
||||
sb.AppendFormat("First data zone: {0}", mnx_sb.s_firstdatazone).AppendLine();
|
||||
//sb.AppendFormat("log2 of blocks/zone: {0}", mnx_sb.s_log_zone_size).AppendLine(); // Apparently 0
|
||||
sb.AppendFormat("{0} bytes maximum per file", mnx_sb.s_max_size).AppendLine();
|
||||
sb.AppendFormat("Filesystem state: {0:X4}", mnx_sb.s_state).AppendLine();
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
public struct MinixSuperBlock
|
||||
{
|
||||
public UInt16 s_ninodes; // 0x00, inodes on volume
|
||||
public UInt16 s_nzones; // 0x02, zones on volume
|
||||
public UInt16 s_imap_blocks; // 0x04, blocks on inode map
|
||||
public UInt16 s_zmap_blocks; // 0x06, blocks on zone map
|
||||
public UInt16 s_firstdatazone; // 0x08, first data zone
|
||||
public UInt16 s_log_zone_size; // 0x0A, log2 of blocks/zone
|
||||
public UInt32 s_max_size; // 0x0C, max file size
|
||||
public UInt16 s_magic; // 0x10, magic
|
||||
public UInt16 s_state; // 0x12, filesystem state
|
||||
public UInt32 s_zones; // 0x14, number of zones
|
||||
}
|
||||
public struct MinixSuperBlock
|
||||
{
|
||||
public UInt16 s_ninodes;
|
||||
// 0x00, inodes on volume
|
||||
public UInt16 s_nzones;
|
||||
// 0x02, zones on volume
|
||||
public UInt16 s_imap_blocks;
|
||||
// 0x04, blocks on inode map
|
||||
public UInt16 s_zmap_blocks;
|
||||
// 0x06, blocks on zone map
|
||||
public UInt16 s_firstdatazone;
|
||||
// 0x08, first data zone
|
||||
public UInt16 s_log_zone_size;
|
||||
// 0x0A, log2 of blocks/zone
|
||||
public UInt32 s_max_size;
|
||||
// 0x0C, max file size
|
||||
public UInt16 s_magic;
|
||||
// 0x10, magic
|
||||
public UInt16 s_state;
|
||||
// 0x12, filesystem state
|
||||
public UInt32 s_zones;
|
||||
// 0x14, number of zones
|
||||
}
|
||||
|
||||
public struct Minix3SuperBlock
|
||||
{
|
||||
public UInt32 s_ninodes; // 0x00, inodes on volume
|
||||
public UInt16 s_pad0; // 0x04, padding
|
||||
public UInt16 s_imap_blocks; // 0x06, blocks on inode map
|
||||
public UInt16 s_zmap_blocks; // 0x08, blocks on zone map
|
||||
public UInt16 s_firstdatazone; // 0x0A, first data zone
|
||||
public UInt16 s_log_zone_size; // 0x0C, log2 of blocks/zone
|
||||
public UInt16 s_pad1; // 0x0E, padding
|
||||
public UInt32 s_max_size; // 0x10, max file size
|
||||
public UInt32 s_zones; // 0x14, number of zones
|
||||
public UInt16 s_magic; // 0x18, magic
|
||||
public UInt16 s_pad2; // 0x1A, padding
|
||||
public UInt16 s_blocksize; // 0x1C, bytes in a block
|
||||
public byte s_disk_version; // 0x1E, on-disk structures version
|
||||
}
|
||||
}
|
||||
public struct Minix3SuperBlock
|
||||
{
|
||||
public UInt32 s_ninodes;
|
||||
// 0x00, inodes on volume
|
||||
public UInt16 s_pad0;
|
||||
// 0x04, padding
|
||||
public UInt16 s_imap_blocks;
|
||||
// 0x06, blocks on inode map
|
||||
public UInt16 s_zmap_blocks;
|
||||
// 0x08, blocks on zone map
|
||||
public UInt16 s_firstdatazone;
|
||||
// 0x0A, first data zone
|
||||
public UInt16 s_log_zone_size;
|
||||
// 0x0C, log2 of blocks/zone
|
||||
public UInt16 s_pad1;
|
||||
// 0x0E, padding
|
||||
public UInt32 s_max_size;
|
||||
// 0x10, max file size
|
||||
public UInt32 s_zones;
|
||||
// 0x14, number of zones
|
||||
public UInt16 s_magic;
|
||||
// 0x18, magic
|
||||
public UInt16 s_pad2;
|
||||
// 0x1A, padding
|
||||
public UInt16 s_blocksize;
|
||||
// 0x1C, bytes in a block
|
||||
public byte s_disk_version;
|
||||
// 0x1E, on-disk structures version
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,72 +1,69 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class NTFS : Plugin
|
||||
{
|
||||
public NTFS(PluginBase Core)
|
||||
class NTFS : Plugin
|
||||
{
|
||||
public NTFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "New Technology File System (NTFS)";
|
||||
base.PluginUUID = new Guid("33513B2C-1e6d-4d21-a660-0bbc789c3871");
|
||||
Name = "New Technology File System (NTFS)";
|
||||
PluginUUID = new Guid("33513B2C-1e6d-4d21-a660-0bbc789c3871");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
byte[] eigth_bytes = new byte[8];
|
||||
byte signature1, fats_no;
|
||||
UInt16 spfat, signature2;
|
||||
string oem_name;
|
||||
{
|
||||
byte[] eigth_bytes = new byte[8];
|
||||
byte signature1, fats_no;
|
||||
UInt16 spfat, signature2;
|
||||
string oem_name;
|
||||
|
||||
byte[] ntfs_bpb = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
|
||||
Array.Copy(ntfs_bpb, 0x003, eigth_bytes, 0, 8);
|
||||
oem_name = StringHandlers.CToString(eigth_bytes);
|
||||
oem_name = StringHandlers.CToString(eigth_bytes);
|
||||
|
||||
if(oem_name != "NTFS ")
|
||||
return false;
|
||||
if (oem_name != "NTFS ")
|
||||
return false;
|
||||
|
||||
fats_no = ntfs_bpb[0x010];
|
||||
|
||||
if(fats_no != 0)
|
||||
return false;
|
||||
if (fats_no != 0)
|
||||
return false;
|
||||
|
||||
spfat = BitConverter.ToUInt16(ntfs_bpb, 0x016);
|
||||
|
||||
if(spfat != 0)
|
||||
return false;
|
||||
if (spfat != 0)
|
||||
return false;
|
||||
|
||||
signature1 = ntfs_bpb[0x026];
|
||||
|
||||
if(signature1 != 0x80)
|
||||
return false;
|
||||
if (signature1 != 0x80)
|
||||
return false;
|
||||
|
||||
signature2 = BitConverter.ToUInt16(ntfs_bpb, 0x1FE);
|
||||
|
||||
if(signature2 != 0xAA55)
|
||||
return false;
|
||||
return signature2 == 0xAA55;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
byte[] ntfs_bpb = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
|
||||
NTFS_BootBlock ntfs_bb = new NTFS_BootBlock();
|
||||
NTFS_BootBlock ntfs_bb = new NTFS_BootBlock();
|
||||
|
||||
byte[] oem_name = new byte[8];
|
||||
byte[] oem_name = new byte[8];
|
||||
|
||||
ntfs_bb.jmp1 = ntfs_bpb[0x000];
|
||||
ntfs_bb.jmp1 = ntfs_bpb[0x000];
|
||||
ntfs_bb.jmp2 = BitConverter.ToUInt16(ntfs_bpb, 0x001);
|
||||
Array.Copy(ntfs_bpb, 0x003, oem_name, 0, 8);
|
||||
ntfs_bb.OEMName = StringHandlers.CToString(oem_name);
|
||||
ntfs_bb.OEMName = StringHandlers.CToString(oem_name);
|
||||
ntfs_bb.bps = BitConverter.ToUInt16(ntfs_bpb, 0x00B);
|
||||
ntfs_bb.spc = ntfs_bpb[0x00D];
|
||||
ntfs_bb.rsectors = BitConverter.ToUInt16(ntfs_bpb, 0x00E);
|
||||
@@ -95,78 +92,108 @@ namespace FileSystemIDandChk.Plugins
|
||||
ntfs_bb.serial_no = BitConverter.ToUInt64(ntfs_bpb, 0x048);
|
||||
ntfs_bb.signature2 = BitConverter.ToUInt16(ntfs_bpb, 0x1FE);
|
||||
|
||||
sb.AppendFormat("{0} bytes per sector", ntfs_bb.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster ({1} bytes)", ntfs_bb.spc, ntfs_bb.spc*ntfs_bb.bps).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector", ntfs_bb.bps).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster ({1} bytes)", ntfs_bb.spc, ntfs_bb.spc * ntfs_bb.bps).AppendLine();
|
||||
// sb.AppendFormat("{0} reserved sectors", ntfs_bb.rsectors).AppendLine();
|
||||
// sb.AppendFormat("{0} FATs", ntfs_bb.fats_no).AppendLine();
|
||||
// sb.AppendFormat("{0} entries in the root folder", ntfs_bb.root_ent).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume (small)", ntfs_bb.sml_sectors).AppendLine();
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", ntfs_bb.media).AppendLine();
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", ntfs_bb.media).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors per FAT", ntfs_bb.spfat).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track", ntfs_bb.sptrk).AppendLine();
|
||||
sb.AppendFormat("{0} heads", ntfs_bb.heads).AppendLine();
|
||||
sb.AppendFormat("{0} hidden sectors before filesystem", ntfs_bb.hsectors).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track", ntfs_bb.sptrk).AppendLine();
|
||||
sb.AppendFormat("{0} heads", ntfs_bb.heads).AppendLine();
|
||||
sb.AppendFormat("{0} hidden sectors before filesystem", ntfs_bb.hsectors).AppendLine();
|
||||
// sb.AppendFormat("{0} sectors on volume (big)", ntfs_bb.big_sectors).AppendLine();
|
||||
sb.AppendFormat("BIOS drive number: 0x{0:X2}", ntfs_bb.drive_no).AppendLine();
|
||||
sb.AppendFormat("BIOS drive number: 0x{0:X2}", ntfs_bb.drive_no).AppendLine();
|
||||
// sb.AppendFormat("NT flags: 0x{0:X2}", ntfs_bb.nt_flags).AppendLine();
|
||||
// sb.AppendFormat("Signature 1: 0x{0:X2}", ntfs_bb.signature1).AppendLine();
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", ntfs_bb.sectors, ntfs_bb.sectors*ntfs_bb.bps).AppendLine();
|
||||
sb.AppendFormat("Sectors where $MFT starts: {0}", ntfs_bb.mft_lsn).AppendLine();
|
||||
sb.AppendFormat("Sectors where $MFTMirr starts: {0}", ntfs_bb.mftmirror_lsn).AppendLine();
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", ntfs_bb.sectors, ntfs_bb.sectors * ntfs_bb.bps).AppendLine();
|
||||
sb.AppendFormat("Sectors where $MFT starts: {0}", ntfs_bb.mft_lsn).AppendLine();
|
||||
sb.AppendFormat("Sectors where $MFTMirr starts: {0}", ntfs_bb.mftmirror_lsn).AppendLine();
|
||||
|
||||
if (ntfs_bb.mft_rc_clusters > 0)
|
||||
sb.AppendFormat("{0} clusters per MFT record ({1} bytes)", ntfs_bb.mft_rc_clusters,
|
||||
ntfs_bb.mft_rc_clusters*ntfs_bb.bps*ntfs_bb.spc).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} bytes per MFT record", 1 << -ntfs_bb.mft_rc_clusters).AppendLine();
|
||||
if (ntfs_bb.index_blk_cts > 0)
|
||||
sb.AppendFormat("{0} clusters per Index block ({1} bytes)", ntfs_bb.index_blk_cts,
|
||||
ntfs_bb.index_blk_cts*ntfs_bb.bps*ntfs_bb.spc).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} bytes per Index block", 1 << -ntfs_bb.index_blk_cts).AppendLine();
|
||||
if (ntfs_bb.mft_rc_clusters > 0)
|
||||
sb.AppendFormat("{0} clusters per MFT record ({1} bytes)", ntfs_bb.mft_rc_clusters,
|
||||
ntfs_bb.mft_rc_clusters * ntfs_bb.bps * ntfs_bb.spc).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} bytes per MFT record", 1 << -ntfs_bb.mft_rc_clusters).AppendLine();
|
||||
if (ntfs_bb.index_blk_cts > 0)
|
||||
sb.AppendFormat("{0} clusters per Index block ({1} bytes)", ntfs_bb.index_blk_cts,
|
||||
ntfs_bb.index_blk_cts * ntfs_bb.bps * ntfs_bb.spc).AppendLine();
|
||||
else
|
||||
sb.AppendFormat("{0} bytes per Index block", 1 << -ntfs_bb.index_blk_cts).AppendLine();
|
||||
|
||||
sb.AppendFormat("Volume serial number: {0:X16}", ntfs_bb.serial_no).AppendLine();
|
||||
sb.AppendFormat("Volume serial number: {0:X16}", ntfs_bb.serial_no).AppendLine();
|
||||
// sb.AppendFormat("Signature 2: 0x{0:X4}", ntfs_bb.signature2).AppendLine();
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
private struct NTFS_BootBlock // Sector 0
|
||||
{
|
||||
// BIOS Parameter Block
|
||||
public byte jmp1; // 0x000, Jump to boot code
|
||||
public UInt16 jmp2; // 0x001, ...;
|
||||
public string OEMName; // 0x003, OEM Name, 8 bytes, space-padded, must be "NTFS "
|
||||
public UInt16 bps; // 0x00B, Bytes per sector
|
||||
public byte spc; // 0x00D, Sectors per cluster
|
||||
public UInt16 rsectors; // 0x00E, Reserved sectors, seems 0
|
||||
public byte fats_no; // 0x010, Number of FATs... obviously, 0
|
||||
public UInt16 root_ent; // 0x011, Number of entries on root directory... 0
|
||||
public UInt16 sml_sectors; // 0x013, Sectors in volume... 0
|
||||
public byte media; // 0x015, Media descriptor
|
||||
public UInt16 spfat; // 0x016, Sectors per FAT... 0
|
||||
public UInt16 sptrk; // 0x018, Sectors per track, required to boot
|
||||
public UInt16 heads; // 0x01A, Heads... required to boot
|
||||
public UInt32 hsectors; // 0x01C, Hidden sectors before BPB
|
||||
public UInt32 big_sectors; // 0x020, Sectors in volume if > 65535... 0
|
||||
public byte drive_no; // 0x024, Drive number
|
||||
public byte nt_flags; // 0x025, 0
|
||||
public byte signature1; // 0x026, EPB signature, 0x80
|
||||
public byte dummy; // 0x027, Alignment
|
||||
// End of BIOS Parameter Block
|
||||
// NTFS real superblock
|
||||
public Int64 sectors; // 0x028, Sectors on volume
|
||||
public Int64 mft_lsn; // 0x030, LSN of $MFT
|
||||
public Int64 mftmirror_lsn; // 0x038, LSN of $MFTMirror
|
||||
public sbyte mft_rc_clusters; // 0x040, Clusters per MFT record
|
||||
public byte dummy2; // 0x041, Alignment
|
||||
public UInt16 dummy3; // 0x042, Alignment
|
||||
public sbyte index_blk_cts; // 0x044, Clusters per index block
|
||||
public byte dummy4; // 0x045, Alignment
|
||||
public UInt16 dummy5; // 0x046, Alignment
|
||||
public UInt64 serial_no; // 0x048, Volume serial number
|
||||
// End of NTFS superblock, followed by 430 bytes of boot code
|
||||
public UInt16 signature2; // 0x1FE, 0xAA55
|
||||
}
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
struct NTFS_BootBlock // Sector 0
|
||||
{
|
||||
// BIOS Parameter Block
|
||||
public byte jmp1;
|
||||
// 0x000, Jump to boot code
|
||||
public UInt16 jmp2;
|
||||
// 0x001, ...;
|
||||
public string OEMName;
|
||||
// 0x003, OEM Name, 8 bytes, space-padded, must be "NTFS "
|
||||
public UInt16 bps;
|
||||
// 0x00B, Bytes per sector
|
||||
public byte spc;
|
||||
// 0x00D, Sectors per cluster
|
||||
public UInt16 rsectors;
|
||||
// 0x00E, Reserved sectors, seems 0
|
||||
public byte fats_no;
|
||||
// 0x010, Number of FATs... obviously, 0
|
||||
public UInt16 root_ent;
|
||||
// 0x011, Number of entries on root directory... 0
|
||||
public UInt16 sml_sectors;
|
||||
// 0x013, Sectors in volume... 0
|
||||
public byte media;
|
||||
// 0x015, Media descriptor
|
||||
public UInt16 spfat;
|
||||
// 0x016, Sectors per FAT... 0
|
||||
public UInt16 sptrk;
|
||||
// 0x018, Sectors per track, required to boot
|
||||
public UInt16 heads;
|
||||
// 0x01A, Heads... required to boot
|
||||
public UInt32 hsectors;
|
||||
// 0x01C, Hidden sectors before BPB
|
||||
public UInt32 big_sectors;
|
||||
// 0x020, Sectors in volume if > 65535... 0
|
||||
public byte drive_no;
|
||||
// 0x024, Drive number
|
||||
public byte nt_flags;
|
||||
// 0x025, 0
|
||||
public byte signature1;
|
||||
// 0x026, EPB signature, 0x80
|
||||
public byte dummy;
|
||||
// 0x027, Alignment
|
||||
// End of BIOS Parameter Block
|
||||
// NTFS real superblock
|
||||
public Int64 sectors;
|
||||
// 0x028, Sectors on volume
|
||||
public Int64 mft_lsn;
|
||||
// 0x030, LSN of $MFT
|
||||
public Int64 mftmirror_lsn;
|
||||
// 0x038, LSN of $MFTMirror
|
||||
public sbyte mft_rc_clusters;
|
||||
// 0x040, Clusters per MFT record
|
||||
public byte dummy2;
|
||||
// 0x041, Alignment
|
||||
public UInt16 dummy3;
|
||||
// 0x042, Alignment
|
||||
public sbyte index_blk_cts;
|
||||
// 0x044, Clusters per index block
|
||||
public byte dummy4;
|
||||
// 0x045, Alignment
|
||||
public UInt16 dummy5;
|
||||
// 0x046, Alignment
|
||||
public UInt64 serial_no;
|
||||
// 0x048, Volume serial number
|
||||
// End of NTFS superblock, followed by 430 bytes of boot code
|
||||
public UInt16 signature2;
|
||||
// 0x1FE, 0xAA55
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +1,47 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
// Information from VMS File System Internals by Kirby McCoy
|
||||
// ISBN: 1-55558-056-4
|
||||
// With some hints from http://www.decuslib.com/DECUS/vmslt97b/gnusoftware/gccaxp/7_1/vms/hm2def.h
|
||||
|
||||
// Expects the home block to be always in sector #1 (does not check deltas)
|
||||
// Assumes a sector size of 512 bytes (VMS does on HDDs and optical drives, dunno about M.O.)
|
||||
// Book only describes ODS-2. Need to test ODS-1 and OSD-5
|
||||
// There is an ODS with signature "DECFILES11A", yet to be seen
|
||||
|
||||
// Time is a 64 bit unsigned integer, tenths of microseconds since 1858/11/17 00:00:00.
|
||||
|
||||
// TODO: Implement checksum
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class ODS : Plugin
|
||||
{
|
||||
public ODS(PluginBase Core)
|
||||
class ODS : Plugin
|
||||
{
|
||||
public ODS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Files-11 On-Disk Structure";
|
||||
base.PluginUUID = new Guid("de20633c-8021-4384-aeb0-83b0df14491f");
|
||||
Name = "Files-11 On-Disk Structure";
|
||||
PluginUUID = new Guid("de20633c-8021-4384-aeb0-83b0df14491f");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
byte[] magic_b = new byte[12];
|
||||
string magic;
|
||||
{
|
||||
byte[] magic_b = new byte[12];
|
||||
string magic;
|
||||
byte[] hb_sector = imagePlugin.ReadSector(1 + partitionOffset);
|
||||
|
||||
Array.Copy(hb_sector, 0x1F0, magic_b, 0, 12);
|
||||
magic = Encoding.ASCII.GetString(magic_b);
|
||||
magic = Encoding.ASCII.GetString(magic_b);
|
||||
|
||||
if(magic == "DECFILE11A " || magic == "DECFILE11B ")
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
return magic == "DECFILE11A " || magic == "DECFILE11B ";
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
ODSHomeBlock homeblock = new ODSHomeBlock();
|
||||
byte[] temp_string = new byte[12];
|
||||
homeblock.min_class = new byte[20];
|
||||
homeblock.max_class = new byte[20];
|
||||
StringBuilder sb = new StringBuilder();
|
||||
ODSHomeBlock homeblock = new ODSHomeBlock();
|
||||
byte[] temp_string = new byte[12];
|
||||
homeblock.min_class = new byte[20];
|
||||
homeblock.max_class = new byte[20];
|
||||
|
||||
byte[] hb_sector = imagePlugin.ReadSector(1 + partitionOffset);
|
||||
|
||||
@@ -93,186 +85,232 @@ namespace FileSystemIDandChk.Plugins
|
||||
homeblock.copydate = BitConverter.ToUInt64(hb_sector, 0x092);
|
||||
homeblock.serialnum = BitConverter.ToUInt32(hb_sector, 0x1C8);
|
||||
Array.Copy(hb_sector, 0x1CC, temp_string, 0, 12);
|
||||
homeblock.strucname = StringHandlers.CToString(temp_string);
|
||||
homeblock.strucname = StringHandlers.CToString(temp_string);
|
||||
Array.Copy(hb_sector, 0x1D8, temp_string, 0, 12);
|
||||
homeblock.volname = StringHandlers.CToString(temp_string);
|
||||
homeblock.volname = StringHandlers.CToString(temp_string);
|
||||
Array.Copy(hb_sector, 0x1E4, temp_string, 0, 12);
|
||||
homeblock.ownername = StringHandlers.CToString(temp_string);
|
||||
homeblock.ownername = StringHandlers.CToString(temp_string);
|
||||
Array.Copy(hb_sector, 0x1F0, temp_string, 0, 12);
|
||||
homeblock.format = StringHandlers.CToString(temp_string);
|
||||
homeblock.format = StringHandlers.CToString(temp_string);
|
||||
homeblock.checksum2 = BitConverter.ToUInt16(hb_sector, 0x1FE);
|
||||
|
||||
if((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 || homeblock.format != "DECFILE11B ")
|
||||
sb.AppendLine("The following information may be incorrect for this volume.");
|
||||
if(homeblock.resfiles < 5 || homeblock.devtype != 0)
|
||||
sb.AppendLine("This volume may be corrupted.");
|
||||
if ((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 || homeblock.format != "DECFILE11B ")
|
||||
sb.AppendLine("The following information may be incorrect for this volume.");
|
||||
if (homeblock.resfiles < 5 || homeblock.devtype != 0)
|
||||
sb.AppendLine("This volume may be corrupted.");
|
||||
|
||||
sb.AppendFormat("Volume format is {0}", homeblock.format).AppendLine();
|
||||
sb.AppendFormat("Volume is Level {0} revision {1}", (homeblock.struclev&0xFF00)>>8, homeblock.struclev&0xFF).AppendLine();
|
||||
sb.AppendFormat("Lowest structure in the volume is Level {0}, revision {1}", (homeblock.lowstruclev&0xFF00)>>8, homeblock.lowstruclev&0xFF).AppendLine();
|
||||
sb.AppendFormat("Highest structure in the volume is Level {0}, revision {1}", (homeblock.highstruclev&0xFF00)>>8, homeblock.highstruclev&0xFF).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster*512).AppendLine();
|
||||
sb.AppendFormat("This home block is on sector {0} (cluster {1})", homeblock.homelbn, homeblock.homevbn).AppendLine();
|
||||
sb.AppendFormat("Secondary home block is on sector {0} (cluster {1})", homeblock.alhomelbn, homeblock.alhomevbn).AppendLine();
|
||||
sb.AppendFormat("Volume bitmap starts in sector {0} (cluster {1})", homeblock.ibmaplbn, homeblock.ibmapvbn).AppendLine();
|
||||
sb.AppendFormat("Volume bitmap runs for {0} sectors ({1} bytes)", homeblock.ibmapsize, homeblock.ibmapsize*512).AppendLine();
|
||||
sb.AppendFormat("Backup INDEXF.SYS;1 is in sector {0} (cluster {1})", homeblock.altidxlbn, homeblock.altidxvbn).AppendLine();
|
||||
sb.AppendFormat("{0} maximum files on the volume", homeblock.maxfiles).AppendLine();
|
||||
sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();
|
||||
if(homeblock.rvn > 0 && homeblock.setcount > 0 && homeblock.strucname != " ")
|
||||
sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount, homeblock.strucname).AppendLine();
|
||||
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}", DateHandlers.VMSToDateTime(homeblock.credate).ToString()).AppendLine();
|
||||
if(homeblock.revdate > 0)
|
||||
sb.AppendFormat("Volume was last modified on {0}", DateHandlers.VMSToDateTime(homeblock.revdate).ToString()).AppendLine();
|
||||
if(homeblock.copydate > 0)
|
||||
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();
|
||||
sb.AppendFormat("Cached directores: {0}", homeblock.lru_lim).AppendLine();
|
||||
sb.AppendFormat("Default allocation: {0} blocks", homeblock.extend).AppendLine();
|
||||
if((homeblock.volchar & 0x01) == 0x01)
|
||||
sb.AppendLine("Readings should be verified");
|
||||
if((homeblock.volchar & 0x02) == 0x02)
|
||||
sb.AppendLine("Writings should be verified");
|
||||
if((homeblock.volchar & 0x04) == 0x04)
|
||||
sb.AppendLine("Files should be erased or overwritten when deleted");
|
||||
if((homeblock.volchar & 0x08) == 0x08)
|
||||
sb.AppendLine("Highwater mark is to be disabled");
|
||||
if((homeblock.volchar & 0x10) == 0x10)
|
||||
sb.AppendLine("Classification checks are enabled");
|
||||
sb.AppendLine("Volume permissions (r = read, w = write, c = create, d = delete)");
|
||||
sb.AppendLine("System, owner, group, world");
|
||||
// System
|
||||
if((homeblock.protect & 0x1000) == 0x1000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if((homeblock.protect & 0x2000) == 0x2000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if((homeblock.protect & 0x4000) == 0x4000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if((homeblock.protect & 0x8000) == 0x8000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// Owner
|
||||
if((homeblock.protect & 0x100) == 0x100)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if((homeblock.protect & 0x200) == 0x200)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if((homeblock.protect & 0x400) == 0x400)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if((homeblock.protect & 0x800) == 0x800)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// Group
|
||||
if((homeblock.protect & 0x10) == 0x10)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if((homeblock.protect & 0x20) == 0x20)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if((homeblock.protect & 0x40) == 0x40)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if((homeblock.protect & 0x80) == 0x80)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// World (other)
|
||||
if((homeblock.protect & 0x1) == 0x1)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if((homeblock.protect & 0x2) == 0x2)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if((homeblock.protect & 0x4) == 0x4)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if((homeblock.protect & 0x8) == 0x8)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
sb.AppendFormat("Volume format is {0}", homeblock.format).AppendLine();
|
||||
sb.AppendFormat("Volume is Level {0} revision {1}", (homeblock.struclev & 0xFF00) >> 8, homeblock.struclev & 0xFF).AppendLine();
|
||||
sb.AppendFormat("Lowest structure in the volume is Level {0}, revision {1}", (homeblock.lowstruclev & 0xFF00) >> 8, homeblock.lowstruclev & 0xFF).AppendLine();
|
||||
sb.AppendFormat("Highest structure in the volume is Level {0}, revision {1}", (homeblock.highstruclev & 0xFF00) >> 8, homeblock.highstruclev & 0xFF).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per cluster ({1} bytes)", homeblock.cluster, homeblock.cluster * 512).AppendLine();
|
||||
sb.AppendFormat("This home block is on sector {0} (cluster {1})", homeblock.homelbn, homeblock.homevbn).AppendLine();
|
||||
sb.AppendFormat("Secondary home block is on sector {0} (cluster {1})", homeblock.alhomelbn, homeblock.alhomevbn).AppendLine();
|
||||
sb.AppendFormat("Volume bitmap starts in sector {0} (cluster {1})", homeblock.ibmaplbn, homeblock.ibmapvbn).AppendLine();
|
||||
sb.AppendFormat("Volume bitmap runs for {0} sectors ({1} bytes)", homeblock.ibmapsize, homeblock.ibmapsize * 512).AppendLine();
|
||||
sb.AppendFormat("Backup INDEXF.SYS;1 is in sector {0} (cluster {1})", homeblock.altidxlbn, homeblock.altidxvbn).AppendLine();
|
||||
sb.AppendFormat("{0} maximum files on the volume", homeblock.maxfiles).AppendLine();
|
||||
sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();
|
||||
if (homeblock.rvn > 0 && homeblock.setcount > 0 && homeblock.strucname != " ")
|
||||
sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount, homeblock.strucname).AppendLine();
|
||||
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}", DateHandlers.VMSToDateTime(homeblock.credate)).AppendLine();
|
||||
if (homeblock.revdate > 0)
|
||||
sb.AppendFormat("Volume was last modified on {0}", DateHandlers.VMSToDateTime(homeblock.revdate)).AppendLine();
|
||||
if (homeblock.copydate > 0)
|
||||
sb.AppendFormat("Volume copied on {0}", DateHandlers.VMSToDateTime(homeblock.copydate)).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();
|
||||
sb.AppendFormat("Cached directores: {0}", homeblock.lru_lim).AppendLine();
|
||||
sb.AppendFormat("Default allocation: {0} blocks", homeblock.extend).AppendLine();
|
||||
if ((homeblock.volchar & 0x01) == 0x01)
|
||||
sb.AppendLine("Readings should be verified");
|
||||
if ((homeblock.volchar & 0x02) == 0x02)
|
||||
sb.AppendLine("Writings should be verified");
|
||||
if ((homeblock.volchar & 0x04) == 0x04)
|
||||
sb.AppendLine("Files should be erased or overwritten when deleted");
|
||||
if ((homeblock.volchar & 0x08) == 0x08)
|
||||
sb.AppendLine("Highwater mark is to be disabled");
|
||||
if ((homeblock.volchar & 0x10) == 0x10)
|
||||
sb.AppendLine("Classification checks are enabled");
|
||||
sb.AppendLine("Volume permissions (r = read, w = write, c = create, d = delete)");
|
||||
sb.AppendLine("System, owner, group, world");
|
||||
// System
|
||||
if ((homeblock.protect & 0x1000) == 0x1000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if ((homeblock.protect & 0x2000) == 0x2000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if ((homeblock.protect & 0x4000) == 0x4000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if ((homeblock.protect & 0x8000) == 0x8000)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// Owner
|
||||
if ((homeblock.protect & 0x100) == 0x100)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if ((homeblock.protect & 0x200) == 0x200)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if ((homeblock.protect & 0x400) == 0x400)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if ((homeblock.protect & 0x800) == 0x800)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// Group
|
||||
if ((homeblock.protect & 0x10) == 0x10)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if ((homeblock.protect & 0x20) == 0x20)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if ((homeblock.protect & 0x40) == 0x40)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if ((homeblock.protect & 0x80) == 0x80)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
// World (other)
|
||||
if ((homeblock.protect & 0x1) == 0x1)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("r");
|
||||
if ((homeblock.protect & 0x2) == 0x2)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("w");
|
||||
if ((homeblock.protect & 0x4) == 0x4)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("c");
|
||||
if ((homeblock.protect & 0x8) == 0x8)
|
||||
sb.Append("-");
|
||||
else
|
||||
sb.Append("d");
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine("Unknown structures:");
|
||||
sb.AppendFormat("Security mask: 0x{0:X8}", homeblock.sec_mask).AppendLine();
|
||||
sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine();
|
||||
sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine();
|
||||
sb.AppendLine("Unknown structures:");
|
||||
sb.AppendFormat("Security mask: 0x{0:X8}", homeblock.sec_mask).AppendLine();
|
||||
sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine();
|
||||
sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine();
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
private struct ODSHomeBlock
|
||||
{
|
||||
public UInt32 homelbn; // 0x000, LBN of THIS home block
|
||||
public UInt32 alhomelbn; // 0x004, LBN of the secondary home block
|
||||
public UInt32 altidxlbn; // 0x008, LBN of backup INDEXF.SYS;1
|
||||
public UInt16 struclev; // 0x00C, High byte contains filesystem version (1, 2 or 5), low byte contains revision (1)
|
||||
public UInt16 cluster; // 0x00E, Number of blocks each bit of the volume bitmap represents
|
||||
public UInt16 homevbn; // 0x010, VBN of THIS home block
|
||||
public UInt16 alhomevbn; // 0x012, VBN of the secondary home block
|
||||
public UInt16 altidxvbn; // 0x014, VBN of backup INDEXF.SYS;1
|
||||
public UInt16 ibmapvbn; // 0x016, VBN of the bitmap
|
||||
public UInt32 ibmaplbn; // 0x018, LBN of the bitmap
|
||||
public UInt32 maxfiles; // 0x01C, Max files on volume
|
||||
public UInt16 ibmapsize; // 0x020, Bitmap size in sectors
|
||||
public UInt16 resfiles; // 0x022, Reserved files, 5 at minimum
|
||||
public UInt16 devtype; // 0x024, Device type, ODS-2 defines it as always 0
|
||||
public UInt16 rvn; // 0x026, Relative volume number (number of the volume in a set)
|
||||
public UInt16 setcount; // 0x028, Total number of volumes in the set this volume is
|
||||
public UInt16 volchar; // 0x02A, Flags
|
||||
public UInt32 volowner; // 0x02C, User ID of the volume owner
|
||||
public UInt32 sec_mask; // 0x030, Security mask (??)
|
||||
public UInt16 protect; // 0x034, Volume permissions (system, owner, group and other)
|
||||
public UInt16 fileprot; // 0x036, Default file protection, unsupported in ODS-2
|
||||
public UInt16 recprot; // 0x038, Default file record protection
|
||||
public UInt16 checksum1; // 0x03A, Checksum of all preceding entries
|
||||
public UInt64 credate; // 0x03C, Creation date
|
||||
public byte window; // 0x044, Window size (pointers for the window)
|
||||
public byte lru_lim; // 0x045, Directories to be stored in cache
|
||||
public UInt16 extend; // 0x046, Default allocation size in blocks
|
||||
public UInt64 retainmin; // 0x048, Minimum file retention period
|
||||
public UInt64 retainmax; // 0x050, Maximum file retention period
|
||||
public UInt64 revdate; // 0x058, Last modification date
|
||||
public byte[] min_class; // 0x060, Minimum security class, 20 bytes
|
||||
public byte[] max_class; // 0x074, Maximum security class, 20 bytes
|
||||
public UInt16 filetab_fid1; // 0x088, File lookup table FID
|
||||
public UInt16 filetab_fid2; // 0x08A, File lookup table FID
|
||||
public UInt16 filetab_fid3; // 0x08C, File lookup table FID
|
||||
public UInt16 lowstruclev; // 0x08E, Lowest structure level on the volume
|
||||
public UInt16 highstruclev; // 0x090, Highest structure level on the volume
|
||||
public UInt64 copydate; // 0x092, Volume copy date (??)
|
||||
public byte[] reserved1; // 0x09A, 302 bytes
|
||||
public UInt32 serialnum; // 0x1C8, Physical drive serial number
|
||||
public string strucname; // 0x1CC, Name of the volume set, 12 bytes
|
||||
public string volname; // 0x1D8, Volume label, 12 bytes
|
||||
public string ownername; // 0x1E4, Name of the volume owner, 12 bytes
|
||||
public string format; // 0x1F0, ODS-2 defines it as "DECFILE11B", 12 bytes
|
||||
public UInt16 reserved2; // 0x1FC, Reserved
|
||||
public UInt16 checksum2; // 0x1FE, Checksum of preceding 255 words (16 bit units)
|
||||
}
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
struct ODSHomeBlock
|
||||
{
|
||||
public UInt32 homelbn;
|
||||
// 0x000, LBN of THIS home block
|
||||
public UInt32 alhomelbn;
|
||||
// 0x004, LBN of the secondary home block
|
||||
public UInt32 altidxlbn;
|
||||
// 0x008, LBN of backup INDEXF.SYS;1
|
||||
public UInt16 struclev;
|
||||
// 0x00C, High byte contains filesystem version (1, 2 or 5), low byte contains revision (1)
|
||||
public UInt16 cluster;
|
||||
// 0x00E, Number of blocks each bit of the volume bitmap represents
|
||||
public UInt16 homevbn;
|
||||
// 0x010, VBN of THIS home block
|
||||
public UInt16 alhomevbn;
|
||||
// 0x012, VBN of the secondary home block
|
||||
public UInt16 altidxvbn;
|
||||
// 0x014, VBN of backup INDEXF.SYS;1
|
||||
public UInt16 ibmapvbn;
|
||||
// 0x016, VBN of the bitmap
|
||||
public UInt32 ibmaplbn;
|
||||
// 0x018, LBN of the bitmap
|
||||
public UInt32 maxfiles;
|
||||
// 0x01C, Max files on volume
|
||||
public UInt16 ibmapsize;
|
||||
// 0x020, Bitmap size in sectors
|
||||
public UInt16 resfiles;
|
||||
// 0x022, Reserved files, 5 at minimum
|
||||
public UInt16 devtype;
|
||||
// 0x024, Device type, ODS-2 defines it as always 0
|
||||
public UInt16 rvn;
|
||||
// 0x026, Relative volume number (number of the volume in a set)
|
||||
public UInt16 setcount;
|
||||
// 0x028, Total number of volumes in the set this volume is
|
||||
public UInt16 volchar;
|
||||
// 0x02A, Flags
|
||||
public UInt32 volowner;
|
||||
// 0x02C, User ID of the volume owner
|
||||
public UInt32 sec_mask;
|
||||
// 0x030, Security mask (??)
|
||||
public UInt16 protect;
|
||||
// 0x034, Volume permissions (system, owner, group and other)
|
||||
public UInt16 fileprot;
|
||||
// 0x036, Default file protection, unsupported in ODS-2
|
||||
public UInt16 recprot;
|
||||
// 0x038, Default file record protection
|
||||
public UInt16 checksum1;
|
||||
// 0x03A, Checksum of all preceding entries
|
||||
public UInt64 credate;
|
||||
// 0x03C, Creation date
|
||||
public byte window;
|
||||
// 0x044, Window size (pointers for the window)
|
||||
public byte lru_lim;
|
||||
// 0x045, Directories to be stored in cache
|
||||
public UInt16 extend;
|
||||
// 0x046, Default allocation size in blocks
|
||||
public UInt64 retainmin;
|
||||
// 0x048, Minimum file retention period
|
||||
public UInt64 retainmax;
|
||||
// 0x050, Maximum file retention period
|
||||
public UInt64 revdate;
|
||||
// 0x058, Last modification date
|
||||
public byte[] min_class;
|
||||
// 0x060, Minimum security class, 20 bytes
|
||||
public byte[] max_class;
|
||||
// 0x074, Maximum security class, 20 bytes
|
||||
public UInt16 filetab_fid1;
|
||||
// 0x088, File lookup table FID
|
||||
public UInt16 filetab_fid2;
|
||||
// 0x08A, File lookup table FID
|
||||
public UInt16 filetab_fid3;
|
||||
// 0x08C, File lookup table FID
|
||||
public UInt16 lowstruclev;
|
||||
// 0x08E, Lowest structure level on the volume
|
||||
public UInt16 highstruclev;
|
||||
// 0x090, Highest structure level on the volume
|
||||
public UInt64 copydate;
|
||||
// 0x092, Volume copy date (??)
|
||||
public byte[] reserved1;
|
||||
// 0x09A, 302 bytes
|
||||
public UInt32 serialnum;
|
||||
// 0x1C8, Physical drive serial number
|
||||
public string strucname;
|
||||
// 0x1CC, Name of the volume set, 12 bytes
|
||||
public string volname;
|
||||
// 0x1D8, Volume label, 12 bytes
|
||||
public string ownername;
|
||||
// 0x1E4, Name of the volume owner, 12 bytes
|
||||
public string format;
|
||||
// 0x1F0, ODS-2 defines it as "DECFILE11B", 12 bytes
|
||||
public UInt16 reserved2;
|
||||
// 0x1FC, Reserved
|
||||
public UInt16 checksum2;
|
||||
// 0x1FE, Checksum of preceding 255 words (16 bit units)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,19 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class OperaFS : Plugin
|
||||
{
|
||||
public OperaFS(PluginBase Core)
|
||||
class OperaFS : Plugin
|
||||
{
|
||||
public OperaFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Opera Filesystem Plugin";
|
||||
base.PluginUUID = new Guid("0ec84ec7-eae6-4196-83fe-943b3fe46dbd");
|
||||
Name = "Opera Filesystem Plugin";
|
||||
PluginUUID = new Guid("0ec84ec7-eae6-4196-83fe-943b3fe46dbd");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
{
|
||||
byte[] sb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
|
||||
byte record_type;
|
||||
@@ -26,22 +24,20 @@ namespace FileSystemIDandChk.Plugins
|
||||
Array.Copy(sb_sector, 0x001, sync_bytes, 0, 5);
|
||||
record_version = sb_sector[0x006];
|
||||
|
||||
if (record_type != 1 || record_version != 1)
|
||||
return false;
|
||||
if(Encoding.ASCII.GetString(sync_bytes) != "ZZZZZ")
|
||||
if (record_type != 1 || record_version != 1)
|
||||
return false;
|
||||
return Encoding.ASCII.GetString(sync_bytes) == "ZZZZZ";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
StringBuilder SuperBlockMetadata = new StringBuilder();
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
|
||||
OperaSuperBlock sb = new OperaSuperBlock();
|
||||
OperaSuperBlock sb = new OperaSuperBlock();
|
||||
byte[] cString = new byte[32];
|
||||
sb.sync_bytes = new byte[5];
|
||||
|
||||
@@ -50,9 +46,9 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.record_version = sb_sector[0x006];
|
||||
sb.volume_flags = sb_sector[0x007];
|
||||
Array.Copy(sb_sector, 0x008, cString, 0, 32);
|
||||
sb.volume_comment = StringHandlers.CToString(cString);
|
||||
sb.volume_comment = StringHandlers.CToString(cString);
|
||||
Array.Copy(sb_sector, 0x028, cString, 0, 32);
|
||||
sb.volume_label = StringHandlers.CToString(cString);
|
||||
sb.volume_label = StringHandlers.CToString(cString);
|
||||
sb.volume_id = BigEndianBitConverter.ToInt32(sb_sector, 0x048);
|
||||
sb.block_size = BigEndianBitConverter.ToInt32(sb_sector, 0x04C);
|
||||
sb.block_count = BigEndianBitConverter.ToInt32(sb_sector, 0x050);
|
||||
@@ -61,22 +57,22 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.rootdir_bsize = BigEndianBitConverter.ToInt32(sb_sector, 0x05C);
|
||||
sb.last_root_copy = BigEndianBitConverter.ToInt32(sb_sector, 0x060);
|
||||
|
||||
if (sb.record_type != 1 || sb.record_version != 1)
|
||||
if (sb.record_type != 1 || sb.record_version != 1)
|
||||
return;
|
||||
if(Encoding.ASCII.GetString(sb.sync_bytes) != "ZZZZZ")
|
||||
if (Encoding.ASCII.GetString(sb.sync_bytes) != "ZZZZZ")
|
||||
return;
|
||||
|
||||
if (sb.volume_comment.Length == 0)
|
||||
sb.volume_comment = "Not set.";
|
||||
if (sb.volume_comment.Length == 0)
|
||||
sb.volume_comment = "Not set.";
|
||||
|
||||
if (sb.volume_label.Length == 0)
|
||||
sb.volume_label = "Not set.";
|
||||
if (sb.volume_label.Length == 0)
|
||||
sb.volume_label = "Not set.";
|
||||
|
||||
SuperBlockMetadata.AppendFormat("Opera filesystem disc.").AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Volume label: {0}", sb.volume_label).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Volume comment: {0}", sb.volume_comment).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Volume identifier: 0x{0:X8}", sb.volume_id).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Block size: {0} bytes", sb.block_size).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Volume label: {0}", sb.volume_label).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Volume comment: {0}", sb.volume_comment).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Volume identifier: 0x{0:X8}", sb.volume_id).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Block size: {0} bytes", sb.block_size).AppendLine();
|
||||
if (imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
{
|
||||
if (sb.block_size != 2048)
|
||||
@@ -84,32 +80,45 @@ namespace FileSystemIDandChk.Plugins
|
||||
}
|
||||
else if (imagePlugin.GetSectorSize() != sb.block_size)
|
||||
SuperBlockMetadata.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block", sb.block_size, imagePlugin.GetSectorSize());
|
||||
SuperBlockMetadata.AppendFormat("Volume size: {0} blocks, {1} bytes", sb.block_count, sb.block_size*sb.block_count).AppendLine();
|
||||
if((ulong)sb.block_count > imagePlugin.GetSectors())
|
||||
SuperBlockMetadata.AppendFormat("Volume size: {0} blocks, {1} bytes", sb.block_count, sb.block_size * sb.block_count).AppendLine();
|
||||
if ((ulong)sb.block_count > imagePlugin.GetSectors())
|
||||
SuperBlockMetadata.AppendFormat("WARNING: Filesystem indicates {0} blocks while device indicates {1} blocks", sb.block_count, imagePlugin.GetSectors());
|
||||
SuperBlockMetadata.AppendFormat("Root directory identifier: 0x{0:X8}", sb.root_dirid).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Root directory block size: {0} bytes", sb.rootdir_bsize).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Root directory size: {0} blocks, {1} bytes", sb.rootdir_blocks, sb.rootdir_bsize*sb.rootdir_blocks).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Last root directory copy: {0}", sb.last_root_copy).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Root directory identifier: 0x{0:X8}", sb.root_dirid).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Root directory block size: {0} bytes", sb.rootdir_bsize).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Root directory size: {0} blocks, {1} bytes", sb.rootdir_blocks, sb.rootdir_bsize * sb.rootdir_blocks).AppendLine();
|
||||
SuperBlockMetadata.AppendFormat("Last root directory copy: {0}", sb.last_root_copy).AppendLine();
|
||||
|
||||
information = SuperBlockMetadata.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private struct OperaSuperBlock
|
||||
{
|
||||
public byte record_type; // 0x000, Record type, must be 1
|
||||
public byte[] sync_bytes; // 0x001, 5 bytes, "ZZZZZ" = new byte[5];
|
||||
public byte record_version; // 0x006, Record version, must be 1
|
||||
public byte volume_flags; // 0x007, Volume flags
|
||||
public string volume_comment; // 0x008, 32 bytes, volume comment
|
||||
public string volume_label; // 0x028, 32 bytes, volume label
|
||||
public Int32 volume_id; // 0x048, Volume ID
|
||||
public Int32 block_size; // 0x04C, Block size in bytes
|
||||
public Int32 block_count; // 0x050, Blocks in volume
|
||||
public Int32 root_dirid; // 0x054, Root directory ID
|
||||
public Int32 rootdir_blocks; // 0x058, Root directory blocks
|
||||
public Int32 rootdir_bsize; // 0x05C, Root directory block size
|
||||
public Int32 last_root_copy; // 0x060, Last root directory copy
|
||||
}
|
||||
}
|
||||
struct OperaSuperBlock
|
||||
{
|
||||
public byte record_type;
|
||||
// 0x000, Record type, must be 1
|
||||
public byte[] sync_bytes;
|
||||
// 0x001, 5 bytes, "ZZZZZ" = new byte[5];
|
||||
public byte record_version;
|
||||
// 0x006, Record version, must be 1
|
||||
public byte volume_flags;
|
||||
// 0x007, Volume flags
|
||||
public string volume_comment;
|
||||
// 0x008, 32 bytes, volume comment
|
||||
public string volume_label;
|
||||
// 0x028, 32 bytes, volume label
|
||||
public Int32 volume_id;
|
||||
// 0x048, Volume ID
|
||||
public Int32 block_size;
|
||||
// 0x04C, Block size in bytes
|
||||
public Int32 block_count;
|
||||
// 0x050, Blocks in volume
|
||||
public Int32 root_dirid;
|
||||
// 0x054, Root directory ID
|
||||
public Int32 rootdir_blocks;
|
||||
// 0x058, Root directory blocks
|
||||
public Int32 rootdir_bsize;
|
||||
// 0x05C, Root directory block size
|
||||
public Int32 last_root_copy;
|
||||
// 0x060, Last root directory copy
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,30 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class PCEnginePlugin : Plugin
|
||||
{
|
||||
public PCEnginePlugin(PluginBase Core)
|
||||
class PCEnginePlugin : Plugin
|
||||
{
|
||||
public PCEnginePlugin(PluginBase Core)
|
||||
{
|
||||
base.Name = "PC Engine CD Plugin";
|
||||
base.PluginUUID = new Guid("e5ee6d7c-90fa-49bd-ac89-14ef750b8af3");
|
||||
Name = "PC Engine CD Plugin";
|
||||
PluginUUID = new Guid("e5ee6d7c-90fa-49bd-ac89-14ef750b8af3");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
{
|
||||
byte[] system_descriptor = new byte[23];
|
||||
byte[] sector = imagePlugin.ReadSector(1 + partitionOffset);
|
||||
|
||||
Array.Copy(sector, 0x20, system_descriptor, 0, 23);
|
||||
|
||||
if(Encoding.ASCII.GetString(system_descriptor) == "PC Engine CD-ROM SYSTEM")
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
}
|
||||
}
|
||||
return Encoding.ASCII.GetString(system_descriptor) == "PC Engine CD-ROM SYSTEM";
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
|
||||
@@ -1,47 +1,45 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
// Based on FAT's BPB, cannot find a FAT or directory
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class SolarFS : Plugin
|
||||
{
|
||||
public SolarFS(PluginBase Core)
|
||||
class SolarFS : Plugin
|
||||
{
|
||||
public SolarFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Solar_OS filesystem";
|
||||
base.PluginUUID = new Guid("EA3101C1-E777-4B4F-B5A3-8C57F50F6E65");
|
||||
Name = "Solar_OS filesystem";
|
||||
PluginUUID = new Guid("EA3101C1-E777-4B4F-B5A3-8C57F50F6E65");
|
||||
}
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
byte signature; // 0x29
|
||||
string fs_type; // "SOL_FS "
|
||||
|
||||
byte[] bpb = imagePlugin.ReadSector (0 + partitionOffset);
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
byte signature; // 0x29
|
||||
string fs_type; // "SOL_FS "
|
||||
|
||||
byte[] bpb = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
|
||||
byte[] fs_type_b = new byte[8];
|
||||
|
||||
signature = bpb [0x25];
|
||||
Array.Copy (bpb, 0x35, fs_type_b, 0, 8);
|
||||
fs_type = StringHandlers.CToString(fs_type_b);
|
||||
signature = bpb[0x25];
|
||||
Array.Copy(bpb, 0x35, fs_type_b, 0, 8);
|
||||
fs_type = StringHandlers.CToString(fs_type_b);
|
||||
|
||||
if(signature == 0x29 && fs_type == "SOL_FS ")
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
if (signature == 0x29 && fs_type == "SOL_FS ")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] bpb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
byte[] bpb_strings;
|
||||
|
||||
SolarOSParameterBlock BPB = new SolarOSParameterBlock();
|
||||
SolarOSParameterBlock BPB = new SolarOSParameterBlock();
|
||||
|
||||
bpb_strings = new byte[8];
|
||||
Array.Copy(bpb_sector, 0x03, bpb_strings, 0, 8);
|
||||
@@ -61,8 +59,8 @@ namespace FileSystemIDandChk.Plugins
|
||||
Array.Copy(bpb_sector, 0x35, bpb_strings, 0, 8);
|
||||
BPB.fs_type = StringHandlers.CToString(bpb_strings);
|
||||
|
||||
if(MainClass.isDebug)
|
||||
{
|
||||
if (MainClass.isDebug)
|
||||
{
|
||||
BPB.x86_jump = new byte[3];
|
||||
Array.Copy(bpb_sector, 0x00, BPB.x86_jump, 0, 3);
|
||||
BPB.unk1 = bpb_sector[0x0D];
|
||||
@@ -71,27 +69,27 @@ namespace FileSystemIDandChk.Plugins
|
||||
Array.Copy(bpb_sector, 0x1B, BPB.unk3, 0, 10);
|
||||
BPB.unk4 = BitConverter.ToUInt32(bpb_sector, 0x26);
|
||||
|
||||
Console.WriteLine("(SolarFS) BPB.x86_jump: 0x{0:X2}{1:X2}{2:X2}", BPB.x86_jump[0], BPB.x86_jump[1], BPB.x86_jump[2]);
|
||||
Console.WriteLine("(SolarFS) BPB.OEMName: \"{0}\"", BPB.OEMName);
|
||||
Console.WriteLine("(SolarFS) BPB.bps: {0}", BPB.bps);
|
||||
Console.WriteLine("(SolarFS) BPB.unk1: 0x{0:X2}", BPB.unk1);
|
||||
Console.WriteLine("(SolarFS) BPB.unk2: 0x{0:X4}", BPB.unk2);
|
||||
Console.WriteLine("(SolarFS) BPB.root_ent: {0}", BPB.root_ent);
|
||||
Console.WriteLine("(SolarFS) BPB.sectors: {0}", BPB.sectors);
|
||||
Console.WriteLine("(SolarFS) BPB.media: 0x{0:X2}", BPB.media);
|
||||
Console.WriteLine("(SolarFS) BPB.spfat: {0}", BPB.spfat);
|
||||
Console.WriteLine("(SolarFS) BPB.sptrk: {0}", BPB.sptrk);
|
||||
Console.WriteLine("(SolarFS) BPB.heads: {0}", BPB.heads);
|
||||
Console.WriteLine("(SolarFS) BPB.unk3: 0x{0:X2}{1:X2}{2:X2}{3:X2}{4:X2}{5:X2}{6:X2}{7:X2}{8:X2}{9:X2}", BPB.unk3[0], BPB.unk3[1], BPB.unk3[2], BPB.unk3[3], BPB.unk3[4], BPB.unk3[5], BPB.unk3[6], BPB.unk3[7], BPB.unk3[8], BPB.unk3[9]);
|
||||
Console.WriteLine("(SolarFS) BPB.signature: 0x{0:X2}", BPB.signature);
|
||||
Console.WriteLine("(SolarFS) BPB.unk4: 0x{0:X8}", BPB.unk4);
|
||||
Console.WriteLine("(SolarFS) BPB.vol_name: \"{0}\"", BPB.vol_name);
|
||||
Console.WriteLine("(SolarFS) BPB.fs_type: \"{0}\"", BPB.fs_type);
|
||||
}
|
||||
Console.WriteLine("(SolarFS) BPB.x86_jump: 0x{0:X2}{1:X2}{2:X2}", BPB.x86_jump[0], BPB.x86_jump[1], BPB.x86_jump[2]);
|
||||
Console.WriteLine("(SolarFS) BPB.OEMName: \"{0}\"", BPB.OEMName);
|
||||
Console.WriteLine("(SolarFS) BPB.bps: {0}", BPB.bps);
|
||||
Console.WriteLine("(SolarFS) BPB.unk1: 0x{0:X2}", BPB.unk1);
|
||||
Console.WriteLine("(SolarFS) BPB.unk2: 0x{0:X4}", BPB.unk2);
|
||||
Console.WriteLine("(SolarFS) BPB.root_ent: {0}", BPB.root_ent);
|
||||
Console.WriteLine("(SolarFS) BPB.sectors: {0}", BPB.sectors);
|
||||
Console.WriteLine("(SolarFS) BPB.media: 0x{0:X2}", BPB.media);
|
||||
Console.WriteLine("(SolarFS) BPB.spfat: {0}", BPB.spfat);
|
||||
Console.WriteLine("(SolarFS) BPB.sptrk: {0}", BPB.sptrk);
|
||||
Console.WriteLine("(SolarFS) BPB.heads: {0}", BPB.heads);
|
||||
Console.WriteLine("(SolarFS) BPB.unk3: 0x{0:X2}{1:X2}{2:X2}{3:X2}{4:X2}{5:X2}{6:X2}{7:X2}{8:X2}{9:X2}", BPB.unk3[0], BPB.unk3[1], BPB.unk3[2], BPB.unk3[3], BPB.unk3[4], BPB.unk3[5], BPB.unk3[6], BPB.unk3[7], BPB.unk3[8], BPB.unk3[9]);
|
||||
Console.WriteLine("(SolarFS) BPB.signature: 0x{0:X2}", BPB.signature);
|
||||
Console.WriteLine("(SolarFS) BPB.unk4: 0x{0:X8}", BPB.unk4);
|
||||
Console.WriteLine("(SolarFS) BPB.vol_name: \"{0}\"", BPB.vol_name);
|
||||
Console.WriteLine("(SolarFS) BPB.fs_type: \"{0}\"", BPB.fs_type);
|
||||
}
|
||||
|
||||
sb.AppendLine("Solar_OS filesystem");
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", BPB.media).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector", BPB.bps).AppendLine();
|
||||
sb.AppendLine("Solar_OS filesystem");
|
||||
sb.AppendFormat("Media descriptor: 0x{0:X2}", BPB.media).AppendLine();
|
||||
sb.AppendFormat("{0} bytes per sector", BPB.bps).AppendLine();
|
||||
if (imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||
{
|
||||
if (BPB.bps != imagePlugin.GetSectorSize())
|
||||
@@ -99,39 +97,54 @@ namespace FileSystemIDandChk.Plugins
|
||||
sb.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector", BPB.bps, 2048).AppendLine();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (BPB.bps != imagePlugin.GetSectorSize())
|
||||
{
|
||||
sb.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector", BPB.bps, imagePlugin.GetSectorSize()).AppendLine();
|
||||
}
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", BPB.sectors, BPB.sectors*BPB.bps).AppendLine();
|
||||
else if (BPB.bps != imagePlugin.GetSectorSize())
|
||||
{
|
||||
sb.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector", BPB.bps, imagePlugin.GetSectorSize()).AppendLine();
|
||||
}
|
||||
sb.AppendFormat("{0} sectors on volume ({1} bytes)", BPB.sectors, BPB.sectors * BPB.bps).AppendLine();
|
||||
if (BPB.sectors > imagePlugin.GetSectors())
|
||||
sb.AppendFormat("WARNING: Filesystem describes a {0} sectors volume, bigger than device ({1} sectors)", BPB.sectors, imagePlugin.GetSectors());
|
||||
sb.AppendFormat("{0} heads", BPB.heads).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track", BPB.sptrk).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", BPB.vol_name).AppendLine();
|
||||
sb.AppendFormat("{0} heads", BPB.heads).AppendLine();
|
||||
sb.AppendFormat("{0} sectors per track", BPB.sptrk).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", BPB.vol_name).AppendLine();
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
public struct SolarOSParameterBlock
|
||||
{
|
||||
public byte[] x86_jump; // 0x00, x86 jump (3 bytes), jumps to 0x60
|
||||
public string OEMName; // 0x03, 8 bytes, "SOLAR_OS"
|
||||
public UInt16 bps; // 0x0B, Bytes per sector
|
||||
public byte unk1; // 0x0D, unknown, 0x01
|
||||
public UInt16 unk2; // 0x0E, unknown, 0x0201
|
||||
public UInt16 root_ent; // 0x10, Number of entries on root directory ? (no root directory found)
|
||||
public UInt16 sectors; // 0x12, Sectors in volume
|
||||
public byte media; // 0x14, Media descriptor
|
||||
public UInt16 spfat; // 0x15, Sectors per FAT ? (no FAT found)
|
||||
public UInt16 sptrk; // 0x17, Sectors per track
|
||||
public UInt16 heads; // 0x19, Heads
|
||||
public byte[] unk3; // 0x1B, unknown, 10 bytes, zero-filled
|
||||
public byte signature; // 0x25, 0x29
|
||||
public UInt32 unk4; // 0x26, unknown, zero-filled
|
||||
public string vol_name; // 0x2A, 11 bytes, volume name, space-padded
|
||||
public string fs_type; // 0x35, 8 bytes, "SOL_FS "
|
||||
}
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
public struct SolarOSParameterBlock
|
||||
{
|
||||
public byte[] x86_jump;
|
||||
// 0x00, x86 jump (3 bytes), jumps to 0x60
|
||||
public string OEMName;
|
||||
// 0x03, 8 bytes, "SOLAR_OS"
|
||||
public UInt16 bps;
|
||||
// 0x0B, Bytes per sector
|
||||
public byte unk1;
|
||||
// 0x0D, unknown, 0x01
|
||||
public UInt16 unk2;
|
||||
// 0x0E, unknown, 0x0201
|
||||
public UInt16 root_ent;
|
||||
// 0x10, Number of entries on root directory ? (no root directory found)
|
||||
public UInt16 sectors;
|
||||
// 0x12, Sectors in volume
|
||||
public byte media;
|
||||
// 0x14, Media descriptor
|
||||
public UInt16 spfat;
|
||||
// 0x15, Sectors per FAT ? (no FAT found)
|
||||
public UInt16 sptrk;
|
||||
// 0x17, Sectors per track
|
||||
public UInt16 heads;
|
||||
// 0x19, Heads
|
||||
public byte[] unk3;
|
||||
// 0x1B, unknown, 10 bytes, zero-filled
|
||||
public byte signature;
|
||||
// 0x25, 0x29
|
||||
public UInt32 unk4;
|
||||
// 0x26, unknown, zero-filled
|
||||
public string vol_name;
|
||||
// 0x2A, 11 bytes, volume name, space-padded
|
||||
public string fs_type;
|
||||
// 0x35, 8 bytes, "SOL_FS "
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,86 +1,91 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class BFS : Plugin
|
||||
{
|
||||
private const UInt32 BFS_MAGIC = 0x1BADFACE;
|
||||
class BFS : Plugin
|
||||
{
|
||||
const UInt32 BFS_MAGIC = 0x1BADFACE;
|
||||
|
||||
public BFS(PluginBase Core)
|
||||
public BFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "UNIX Boot filesystem";
|
||||
base.PluginUUID = new Guid("1E6E0DA6-F7E4-494C-80C6-CB5929E96155");
|
||||
Name = "UNIX Boot filesystem";
|
||||
PluginUUID = new Guid("1E6E0DA6-F7E4-494C-80C6-CB5929E96155");
|
||||
}
|
||||
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
UInt32 magic;
|
||||
{
|
||||
UInt32 magic;
|
||||
|
||||
magic = BitConverter.ToUInt32 (imagePlugin.ReadSector (0 + partitionOffset), 0);
|
||||
magic = BitConverter.ToUInt32(imagePlugin.ReadSector(0 + partitionOffset), 0);
|
||||
|
||||
if(magic == BFS_MAGIC)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
return magic == BFS_MAGIC;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] bfs_sb_sector = imagePlugin.ReadSector (0 + partitionOffset);
|
||||
byte[] sb_strings = new byte[6];
|
||||
StringBuilder sb = new StringBuilder();
|
||||
byte[] bfs_sb_sector = imagePlugin.ReadSector(0 + partitionOffset);
|
||||
byte[] sb_strings = new byte[6];
|
||||
|
||||
BFSSuperBlock bfs_sb = new BFSSuperBlock();
|
||||
BFSSuperBlock bfs_sb = new BFSSuperBlock();
|
||||
|
||||
bfs_sb.s_magic = BitConverter.ToUInt32 (bfs_sb_sector, 0x00);
|
||||
bfs_sb.s_start = BitConverter.ToUInt32 (bfs_sb_sector, 0x04);
|
||||
bfs_sb.s_end = BitConverter.ToUInt32 (bfs_sb_sector, 0x08);
|
||||
bfs_sb.s_from = BitConverter.ToUInt32 (bfs_sb_sector, 0x0C);
|
||||
bfs_sb.s_to = BitConverter.ToUInt32 (bfs_sb_sector, 0x10);
|
||||
bfs_sb.s_bfrom = BitConverter.ToInt32 (bfs_sb_sector, 0x14);
|
||||
bfs_sb.s_bto = BitConverter.ToInt32 (bfs_sb_sector, 0x18);
|
||||
Array.Copy (bfs_sb_sector, 0x1C, sb_strings, 0, 6);
|
||||
bfs_sb.s_fsname = StringHandlers.CToString(sb_strings);
|
||||
Array.Copy (bfs_sb_sector, 0x22, sb_strings, 0, 6);
|
||||
bfs_sb.s_volume = StringHandlers.CToString(sb_strings);
|
||||
bfs_sb.s_magic = BitConverter.ToUInt32(bfs_sb_sector, 0x00);
|
||||
bfs_sb.s_start = BitConverter.ToUInt32(bfs_sb_sector, 0x04);
|
||||
bfs_sb.s_end = BitConverter.ToUInt32(bfs_sb_sector, 0x08);
|
||||
bfs_sb.s_from = BitConverter.ToUInt32(bfs_sb_sector, 0x0C);
|
||||
bfs_sb.s_to = BitConverter.ToUInt32(bfs_sb_sector, 0x10);
|
||||
bfs_sb.s_bfrom = BitConverter.ToInt32(bfs_sb_sector, 0x14);
|
||||
bfs_sb.s_bto = BitConverter.ToInt32(bfs_sb_sector, 0x18);
|
||||
Array.Copy(bfs_sb_sector, 0x1C, sb_strings, 0, 6);
|
||||
bfs_sb.s_fsname = StringHandlers.CToString(sb_strings);
|
||||
Array.Copy(bfs_sb_sector, 0x22, sb_strings, 0, 6);
|
||||
bfs_sb.s_volume = StringHandlers.CToString(sb_strings);
|
||||
|
||||
if(MainClass.isDebug)
|
||||
{
|
||||
Console.WriteLine("(BFS) bfs_sb.s_magic: 0x{0:X8}", bfs_sb.s_magic);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_start: 0x{0:X8}", bfs_sb.s_start);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_end: 0x{0:X8}", bfs_sb.s_end);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_from: 0x{0:X8}", bfs_sb.s_from);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_to: 0x{0:X8}", bfs_sb.s_to);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_bfrom: 0x{0:X8}", bfs_sb.s_bfrom);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_bto: 0x{0:X8}", bfs_sb.s_bto);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_fsname: 0x{0}", bfs_sb.s_fsname);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_volume: 0x{0}", bfs_sb.s_volume);
|
||||
}
|
||||
if (MainClass.isDebug)
|
||||
{
|
||||
Console.WriteLine("(BFS) bfs_sb.s_magic: 0x{0:X8}", bfs_sb.s_magic);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_start: 0x{0:X8}", bfs_sb.s_start);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_end: 0x{0:X8}", bfs_sb.s_end);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_from: 0x{0:X8}", bfs_sb.s_from);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_to: 0x{0:X8}", bfs_sb.s_to);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_bfrom: 0x{0:X8}", bfs_sb.s_bfrom);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_bto: 0x{0:X8}", bfs_sb.s_bto);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_fsname: 0x{0}", bfs_sb.s_fsname);
|
||||
Console.WriteLine("(BFS) bfs_sb.s_volume: 0x{0}", bfs_sb.s_volume);
|
||||
}
|
||||
|
||||
sb.AppendLine("UNIX Boot filesystem");
|
||||
sb.AppendFormat("Volume goes from byte {0} to byte {1}, for {2} bytes", bfs_sb.s_start, bfs_sb.s_end, bfs_sb.s_end-bfs_sb.s_start).AppendLine();
|
||||
sb.AppendFormat("Filesystem name: {0}", bfs_sb.s_fsname).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", bfs_sb.s_volume).AppendLine();
|
||||
sb.AppendLine("UNIX Boot filesystem");
|
||||
sb.AppendFormat("Volume goes from byte {0} to byte {1}, for {2} bytes", bfs_sb.s_start, bfs_sb.s_end, bfs_sb.s_end - bfs_sb.s_start).AppendLine();
|
||||
sb.AppendFormat("Filesystem name: {0}", bfs_sb.s_fsname).AppendLine();
|
||||
sb.AppendFormat("Volume name: {0}", bfs_sb.s_volume).AppendLine();
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
private struct BFSSuperBlock
|
||||
{
|
||||
public UInt32 s_magic; // 0x00, 0x1BADFACE
|
||||
public UInt32 s_start; // 0x04, start in bytes of volume
|
||||
public UInt32 s_end; // 0x08, end in bytes of volume
|
||||
public UInt32 s_from; // 0x0C, unknown :p
|
||||
public UInt32 s_to; // 0x10, unknown :p
|
||||
public Int32 s_bfrom; // 0x14, unknown :p
|
||||
public Int32 s_bto; // 0x18, unknown :p
|
||||
public string s_fsname; // 0x1C, 6 bytes, filesystem name
|
||||
public string s_volume; // 0x22, 6 bytes, volume name
|
||||
}
|
||||
}
|
||||
struct BFSSuperBlock
|
||||
{
|
||||
public UInt32 s_magic;
|
||||
// 0x00, 0x1BADFACE
|
||||
public UInt32 s_start;
|
||||
// 0x04, start in bytes of volume
|
||||
public UInt32 s_end;
|
||||
// 0x08, end in bytes of volume
|
||||
public UInt32 s_from;
|
||||
// 0x0C, unknown :p
|
||||
public UInt32 s_to;
|
||||
// 0x10, unknown :p
|
||||
public Int32 s_bfrom;
|
||||
// 0x14, unknown :p
|
||||
public Int32 s_bto;
|
||||
// 0x18, unknown :p
|
||||
public string s_fsname;
|
||||
// 0x1C, 6 bytes, filesystem name
|
||||
public string s_volume;
|
||||
// 0x22, 6 bytes, volume name
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,81 +1,92 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using FileSystemIDandChk;
|
||||
|
||||
namespace FileSystemIDandChk.Plugins
|
||||
{
|
||||
class extFS : Plugin
|
||||
{
|
||||
public extFS(PluginBase Core)
|
||||
class extFS : Plugin
|
||||
{
|
||||
public extFS(PluginBase Core)
|
||||
{
|
||||
base.Name = "Linux extended Filesystem";
|
||||
base.PluginUUID = new Guid("076CB3A2-08C2-4D69-BC8A-FCAA2E502BE2");
|
||||
Name = "Linux extended Filesystem";
|
||||
PluginUUID = new Guid("076CB3A2-08C2-4D69-BC8A-FCAA2E502BE2");
|
||||
}
|
||||
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
byte[] sb_sector = imagePlugin.ReadSector (2 + partitionOffset); // Superblock resides at 0x400
|
||||
|
||||
UInt16 magic = BitConverter.ToUInt16(sb_sector, 0x038); // Here should reside magic number
|
||||
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset)
|
||||
{
|
||||
byte[] sb_sector = imagePlugin.ReadSector(2 + partitionOffset); // Superblock resides at 0x400
|
||||
|
||||
UInt16 magic = BitConverter.ToUInt16(sb_sector, 0x038); // Here should reside magic number
|
||||
|
||||
if(magic == extFSMagic)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void GetInformation (ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
return magic == extFSMagic;
|
||||
}
|
||||
|
||||
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, ulong partitionOffset, out string information)
|
||||
{
|
||||
information = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
byte[] sb_sector = imagePlugin.ReadSector (2 + partitionOffset); // Superblock resides at 0x400
|
||||
extFSSuperBlock ext_sb = new extFSSuperBlock();
|
||||
byte[] sb_sector = imagePlugin.ReadSector(2 + partitionOffset); // Superblock resides at 0x400
|
||||
extFSSuperBlock ext_sb = new extFSSuperBlock();
|
||||
|
||||
ext_sb.inodes = BitConverter.ToUInt32(sb_sector, 0x000);
|
||||
ext_sb.zones = BitConverter.ToUInt32(sb_sector, 0x004);
|
||||
ext_sb.firstfreeblk = BitConverter.ToUInt32(sb_sector, 0x008);
|
||||
ext_sb.freecountblk = BitConverter.ToUInt32(sb_sector, 0x00C);
|
||||
ext_sb.firstfreeind = BitConverter.ToUInt32(sb_sector, 0x010);
|
||||
ext_sb.freecountind = BitConverter.ToUInt32(sb_sector, 0x014);
|
||||
ext_sb.firstdatazone = BitConverter.ToUInt32(sb_sector, 0x018);
|
||||
ext_sb.logzonesize = BitConverter.ToUInt32(sb_sector, 0x01C);
|
||||
ext_sb.maxsize = BitConverter.ToUInt32(sb_sector, 0x020);
|
||||
ext_sb.inodes = BitConverter.ToUInt32(sb_sector, 0x000);
|
||||
ext_sb.zones = BitConverter.ToUInt32(sb_sector, 0x004);
|
||||
ext_sb.firstfreeblk = BitConverter.ToUInt32(sb_sector, 0x008);
|
||||
ext_sb.freecountblk = BitConverter.ToUInt32(sb_sector, 0x00C);
|
||||
ext_sb.firstfreeind = BitConverter.ToUInt32(sb_sector, 0x010);
|
||||
ext_sb.freecountind = BitConverter.ToUInt32(sb_sector, 0x014);
|
||||
ext_sb.firstdatazone = BitConverter.ToUInt32(sb_sector, 0x018);
|
||||
ext_sb.logzonesize = BitConverter.ToUInt32(sb_sector, 0x01C);
|
||||
ext_sb.maxsize = BitConverter.ToUInt32(sb_sector, 0x020);
|
||||
|
||||
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);
|
||||
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();
|
||||
}
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
public const UInt16 extFSMagic = 0x137D;
|
||||
public const UInt16 extFSMagic = 0x137D;
|
||||
|
||||
public struct extFSSuperBlock
|
||||
{
|
||||
public UInt32 inodes; // 0x000, inodes on volume
|
||||
public UInt32 zones; // 0x004, zones on volume
|
||||
public UInt32 firstfreeblk; // 0x008, first free block
|
||||
public UInt32 freecountblk; // 0x00C, free blocks count
|
||||
public UInt32 firstfreeind; // 0x010, first free inode
|
||||
public UInt32 freecountind; // 0x014, free inodes count
|
||||
public UInt32 firstdatazone; // 0x018, first data zone
|
||||
public UInt32 logzonesize; // 0x01C, log zone size
|
||||
public UInt32 maxsize; // 0x020, max zone size
|
||||
public UInt32 reserved1; // 0x024, reserved
|
||||
public UInt32 reserved2; // 0x028, reserved
|
||||
public UInt32 reserved3; // 0x02C, reserved
|
||||
public UInt32 reserved4; // 0x030, reserved
|
||||
public UInt32 reserved5; // 0x034, reserved
|
||||
public UInt16 magic; // 0x038, 0x137D (little endian)
|
||||
}
|
||||
}
|
||||
public struct extFSSuperBlock
|
||||
{
|
||||
public UInt32 inodes;
|
||||
// 0x000, inodes on volume
|
||||
public UInt32 zones;
|
||||
// 0x004, zones on volume
|
||||
public UInt32 firstfreeblk;
|
||||
// 0x008, first free block
|
||||
public UInt32 freecountblk;
|
||||
// 0x00C, free blocks count
|
||||
public UInt32 firstfreeind;
|
||||
// 0x010, first free inode
|
||||
public UInt32 freecountind;
|
||||
// 0x014, free inodes count
|
||||
public UInt32 firstdatazone;
|
||||
// 0x018, first data zone
|
||||
public UInt32 logzonesize;
|
||||
// 0x01C, log zone size
|
||||
public UInt32 maxsize;
|
||||
// 0x020, max zone size
|
||||
public UInt32 reserved1;
|
||||
// 0x024, reserved
|
||||
public UInt32 reserved2;
|
||||
// 0x028, reserved
|
||||
public UInt32 reserved3;
|
||||
// 0x02C, reserved
|
||||
public UInt32 reserved4;
|
||||
// 0x030, reserved
|
||||
public UInt32 reserved5;
|
||||
// 0x034, reserved
|
||||
public UInt16 magic;
|
||||
// 0x038, 0x137D (little endian)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,36 +3,36 @@ using System.Text;
|
||||
|
||||
namespace FileSystemIDandChk
|
||||
{
|
||||
public static class StringHandlers
|
||||
{
|
||||
public static string CToString (byte[] CString)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
public static class StringHandlers
|
||||
{
|
||||
public static string CToString(byte[] CString)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for(int i = 0; i<CString.Length; i++)
|
||||
{
|
||||
if(CString[i]==0)
|
||||
break;
|
||||
for (int i = 0; i < CString.Length; i++)
|
||||
{
|
||||
if (CString[i] == 0)
|
||||
break;
|
||||
|
||||
sb.Append(Encoding.ASCII.GetString(CString, i, 1));
|
||||
}
|
||||
sb.Append(Encoding.ASCII.GetString(CString, i, 1));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string PascalToString (byte[] PascalString)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
public static string PascalToString(byte[] PascalString)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
byte length = PascalString[0];
|
||||
byte length = PascalString[0];
|
||||
|
||||
for(int i = 1; i < length+1; i++)
|
||||
{
|
||||
sb.Append(Encoding.ASCII.GetString (PascalString, i, 1));
|
||||
}
|
||||
for (int i = 1; i < length + 1; i++)
|
||||
{
|
||||
sb.Append(Encoding.ASCII.GetString(PascalString, i, 1));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,14 +60,14 @@ namespace FileSystemIDandChk
|
||||
return destination;
|
||||
}
|
||||
|
||||
public static UInt32 PDPFromLittleEndian(UInt32 x)
|
||||
{
|
||||
return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16);
|
||||
}
|
||||
public static UInt32 PDPFromLittleEndian(UInt32 x)
|
||||
{
|
||||
return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16);
|
||||
}
|
||||
|
||||
public static UInt32 PDPFromBigEndian(UInt32 x)
|
||||
{
|
||||
return ((x & 0xff00ff) << 8) | ((x & 0xff00ff00) >> 8);
|
||||
}
|
||||
public static UInt32 PDPFromBigEndian(UInt32 x)
|
||||
{
|
||||
return ((x & 0xff00ff) << 8) | ((x & 0xff00ff00) >> 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user