mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
* DiscImageChef.Helpers/BigEndianStructure.cs:
* DiscImageChef.Helpers/DiscImageChef.Helpers.csproj: Added code that directly marshals from a big-endian byte array. But untested with nested structures. * DiscImageChef.Partitions/Acorn.cs: Added support for Acorn FileCore partition, closes #4. * DiscImageChef.Partitions/BSD.cs: Moved BSD partitions from inside MBR code to separate code, as they can (and do) appear on other architectures as the only scheme. * DiscImageChef.Partitions/DEC.cs: Added support for DEC disklabels, closes #11. * DiscImageChef.Partitions/DragonFlyBSD.cs: Added support for DragonFly BSD 64-bit disklabels. * DiscImageChef.Partitions/PC98.cs: Added support for NEC PC-9800 partitions. * DiscImageChef.Partitions/RioKarma.cs: Added support for Rio Karma partitions. * DiscImageChef.Partitions/SGI.cs: Added support for SGI DVHs, closes #9. * DiscImageChef.Partitions/UNIX.cs: Moved UNIX partitions from inside MBR code to separate code, as they can (and do) appear on other architectures as the only scheme. * TODO: * README.md: * DiscImageChef.Partitions/DiscImageChef.Partitions.csproj: Added support for Acorn FileCore partition, closes #4. Added support for DEC disklabels, closes #11. Added support for SGI DVHs, closes #9. Moved BSD partitions from inside MBR code to separate code, as they can (and do) appear on other architectures as the only scheme. Added support for DragonFly BSD 64-bit disklabels. Added support for NEC PC-9800 partitions. Added support for Rio Karma partitions. Moved UNIX partitions from inside MBR code to separate code, as they can (and do) appear on other architectures as the only scheme. * DiscImageChef.Partitions/GPT.cs: Added new partition type UUIDs. * DiscImageChef.Partitions/MBR.cs: Moved BSD partitions from inside MBR code to separate code, as they can (and do) appear on other architectures as the only scheme. Moved UNIX partitions from inside MBR code to separate code, as they can (and do) appear on other architectures as the only scheme. * DiscImageChef.Partitions/Sun.cs: Added new partition types. Prepare structures for marshaling.
This commit is contained in:
118
DiscImageChef.Helpers/BigEndianStructure.cs
Normal file
118
DiscImageChef.Helpers/BigEndianStructure.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : EndianSwapStructure.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Component
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Description
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace DiscImageChef.Helpers
|
||||
{
|
||||
public static class BigEndianStructure
|
||||
{
|
||||
// TODO: Check this works
|
||||
/// <summary>
|
||||
/// Marshals a big-endian byte array to a C# structure. Dunno if it works with nested structures.
|
||||
/// </summary>
|
||||
/// <returns>The big endian byte array.</returns>
|
||||
/// <param name="bytes">Byte array.</param>
|
||||
/// <typeparam name="T">C# structure type.</typeparam>
|
||||
public static T ByteArrayToStructureBigEndian<T>(byte[] bytes) where T : struct
|
||||
{
|
||||
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||
T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
|
||||
handle.Free();
|
||||
Type t = stuff.GetType();
|
||||
FieldInfo[] fieldInfo = t.GetFields();
|
||||
foreach(FieldInfo fi in fieldInfo)
|
||||
{
|
||||
if(fi.FieldType == typeof(short))
|
||||
{
|
||||
short i16 = (short)fi.GetValue(stuff);
|
||||
byte[] b16 = BitConverter.GetBytes(i16);
|
||||
byte[] b16r = b16.Reverse().ToArray();
|
||||
fi.SetValueDirect(__makeref(stuff), BitConverter.ToInt16(b16r, 0));
|
||||
}
|
||||
else if(fi.FieldType == typeof(int))
|
||||
{
|
||||
int i32 = (int)fi.GetValue(stuff);
|
||||
byte[] b32 = BitConverter.GetBytes(i32);
|
||||
byte[] b32r = b32.Reverse().ToArray();
|
||||
fi.SetValueDirect(__makeref(stuff), BitConverter.ToInt32(b32r, 0));
|
||||
}
|
||||
else if(fi.FieldType == typeof(long))
|
||||
{
|
||||
long i64 = (long)fi.GetValue(stuff);
|
||||
byte[] b64 = BitConverter.GetBytes(i64);
|
||||
byte[] b64r = b64.Reverse().ToArray();
|
||||
fi.SetValueDirect(__makeref(stuff), BitConverter.ToInt64(b64r, 0));
|
||||
}
|
||||
else if(fi.FieldType == typeof(ushort))
|
||||
{
|
||||
ushort i16 = (ushort)fi.GetValue(stuff);
|
||||
byte[] b16 = BitConverter.GetBytes(i16);
|
||||
byte[] b16r = b16.Reverse().ToArray();
|
||||
fi.SetValueDirect(__makeref(stuff), BitConverter.ToUInt16(b16r, 0));
|
||||
}
|
||||
else if(fi.FieldType == typeof(uint))
|
||||
{
|
||||
uint i32 = (uint)fi.GetValue(stuff);
|
||||
byte[] b32 = BitConverter.GetBytes(i32);
|
||||
byte[] b32r = b32.Reverse().ToArray();
|
||||
fi.SetValueDirect(__makeref(stuff), BitConverter.ToUInt32(b32r, 0));
|
||||
}
|
||||
else if(fi.FieldType == typeof(ulong))
|
||||
{
|
||||
ulong i64 = (ulong)fi.GetValue(stuff);
|
||||
byte[] b64 = BitConverter.GetBytes(i64);
|
||||
byte[] b64r = b64.Reverse().ToArray();
|
||||
fi.SetValueDirect(__makeref(stuff), BitConverter.ToUInt64(b64r, 0));
|
||||
}
|
||||
else if(fi.FieldType == typeof(float))
|
||||
{
|
||||
float iflt = (float)fi.GetValue(stuff);
|
||||
byte[] bflt = BitConverter.GetBytes(iflt);
|
||||
byte[] bfltr = bflt.Reverse().ToArray();
|
||||
fi.SetValueDirect(__makeref(stuff), BitConverter.ToSingle(bfltr, 0));
|
||||
}
|
||||
else if(fi.FieldType == typeof(double))
|
||||
{
|
||||
double idbl = (double)fi.GetValue(stuff);
|
||||
byte[] bdbl = BitConverter.GetBytes(idbl);
|
||||
byte[] bdblr = bdbl.Reverse().ToArray();
|
||||
fi.SetValueDirect(__makeref(stuff), BitConverter.ToDouble(bdblr, 0));
|
||||
}
|
||||
}
|
||||
return stuff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
2016-08-21 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* BigEndianStructure.cs:
|
||||
* DiscImageChef.Helpers.csproj: Added code that directly
|
||||
marshals from a big-endian byte array. But untested with
|
||||
nested structures.
|
||||
|
||||
2016-08-09 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* DiscImageChef.Helpers.csproj: Bumped version to 3.2.99.2.
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<Compile Include="StringHandlers.cs" />
|
||||
<Compile Include="Swapping.cs" />
|
||||
<Compile Include="ArrayIsEmpty.cs" />
|
||||
<Compile Include="BigEndianStructure.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
||||
224
DiscImageChef.Partitions/Acorn.cs
Normal file
224
DiscImageChef.Partitions/Acorn.cs
Normal file
@@ -0,0 +1,224 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : Acorn.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Partitioning scheme plugins.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Manages Acorn FileCore partitions.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
{
|
||||
class Acorn : PartPlugin
|
||||
{
|
||||
const ulong ADFS_SB_POS = 0xC00;
|
||||
const uint LINUX_MAGIC = 0xDEAFA1DE;
|
||||
const uint SWAP_MAGIC = 0xDEAFAB1E;
|
||||
const uint RISCIX_MAGIC = 0x4A657320;
|
||||
const uint TYPE_LINUX = 9;
|
||||
const uint TYPE_RISCIX_MFM = 1;
|
||||
const uint TYPE_RISCIX_SCSI = 2;
|
||||
const uint TYPE_MASK = 15;
|
||||
|
||||
public Acorn()
|
||||
{
|
||||
Name = "Acorn FileCore partitions";
|
||||
PluginUUID = new Guid("A7C8FEBE-8D00-4933-B9F3-42184C8BA808");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
partitions = new List<Partition>();
|
||||
|
||||
ulong sbSector;
|
||||
|
||||
if(imagePlugin.GetSectorSize() > ADFS_SB_POS)
|
||||
sbSector = 0;
|
||||
else
|
||||
sbSector = ADFS_SB_POS / imagePlugin.GetSectorSize();
|
||||
|
||||
byte[] sector = imagePlugin.ReadSector(sbSector);
|
||||
|
||||
if(sector.Length < 512)
|
||||
return false;
|
||||
|
||||
AcornBootBlock bootBlock = new AcornBootBlock();
|
||||
IntPtr bbPtr = Marshal.AllocHGlobal(512);
|
||||
Marshal.Copy(sector, 0, bbPtr, 512);
|
||||
bootBlock = (AcornBootBlock)Marshal.PtrToStructure(bbPtr, typeof(AcornBootBlock));
|
||||
Marshal.FreeHGlobal(bbPtr);
|
||||
|
||||
int checksum = 0;
|
||||
for(int i = 0; i < 0x1FF; i++)
|
||||
checksum = ((checksum & 0xFF) + (checksum >> 8) + sector[i]);
|
||||
|
||||
int heads = bootBlock.discRecords.heads + ((bootBlock.discRecords.lowsector >> 6) & 1);
|
||||
int secCyl = bootBlock.discRecords.spt * heads;
|
||||
int mapSector = bootBlock.startCylinder * secCyl;
|
||||
|
||||
byte[] map = imagePlugin.ReadSector((ulong)mapSector);
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
if((bootBlock.flags & TYPE_MASK) == TYPE_LINUX)
|
||||
{
|
||||
LinuxTable table = new LinuxTable();
|
||||
IntPtr tablePtr = Marshal.AllocHGlobal(512);
|
||||
Marshal.Copy(map, 0, tablePtr, 512);
|
||||
table = (LinuxTable)Marshal.PtrToStructure(tablePtr, typeof(LinuxTable));
|
||||
Marshal.FreeHGlobal(tablePtr);
|
||||
|
||||
foreach(LinuxEntry entry in table.entries)
|
||||
{
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = (ulong)(mapSector + entry.start);
|
||||
part.PartitionStart = part.PartitionStartSector * (ulong)sector.Length;
|
||||
part.PartitionLength = entry.size;
|
||||
part.PartitionSectors = (ulong)(entry.size * sector.Length);
|
||||
part.PartitionSequence = counter;
|
||||
if(entry.magic == LINUX_MAGIC || entry.magic == SWAP_MAGIC)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((bootBlock.flags & TYPE_MASK) == TYPE_RISCIX_MFM ||
|
||||
(bootBlock.flags & TYPE_MASK) == TYPE_RISCIX_SCSI)
|
||||
{
|
||||
RiscIxTable table = new RiscIxTable();
|
||||
IntPtr tablePtr = Marshal.AllocHGlobal(512);
|
||||
Marshal.Copy(map, 0, tablePtr, 512);
|
||||
table = (RiscIxTable)Marshal.PtrToStructure(tablePtr, typeof(RiscIxTable));
|
||||
Marshal.FreeHGlobal(tablePtr);
|
||||
|
||||
if(table.magic == RISCIX_MAGIC)
|
||||
{
|
||||
foreach(RiscIxEntry entry in table.partitions)
|
||||
{
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = (ulong)(mapSector + entry.start);
|
||||
part.PartitionStart = part.PartitionStartSector * (ulong)sector.Length;
|
||||
part.PartitionLength = entry.length;
|
||||
part.PartitionSectors = (ulong)(entry.length * sector.Length);
|
||||
part.PartitionName = StringHandlers.CToString(entry.name, Encoding.GetEncoding("iso-8859-1"));
|
||||
part.PartitionSequence = counter;
|
||||
if(entry.length > 0)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !(partitions.Count == 0);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct DiscRecord
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1C0)]
|
||||
public byte[] spare;
|
||||
public byte log2secsize;
|
||||
public byte spt;
|
||||
public byte heads;
|
||||
public byte density;
|
||||
public byte idlen;
|
||||
public byte log2bpmb;
|
||||
public byte skew;
|
||||
public byte bootoption;
|
||||
public byte lowsector;
|
||||
public byte nzones;
|
||||
public ushort zone_spare;
|
||||
public uint root;
|
||||
public uint disc_size;
|
||||
public ushort disc_id;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
|
||||
public byte[] disc_name;
|
||||
public uint disc_type;
|
||||
public uint disc_size_high;
|
||||
public byte flags;
|
||||
public byte nzones_high;
|
||||
public uint format_version;
|
||||
public uint root_size;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct AcornBootBlock
|
||||
{
|
||||
public DiscRecord discRecords;
|
||||
public byte flags;
|
||||
public ushort startCylinder;
|
||||
public byte checksum;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct LinuxTable
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 42)]
|
||||
public LinuxEntry[] entries;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] padding;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct LinuxEntry
|
||||
{
|
||||
public uint magic;
|
||||
public uint start;
|
||||
public uint size;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct RiscIxTable
|
||||
{
|
||||
public uint magic;
|
||||
public uint date;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public RiscIxEntry[] partitions;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct RiscIxEntry
|
||||
{
|
||||
public uint start;
|
||||
public uint length;
|
||||
public uint one;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public byte[] name;
|
||||
}
|
||||
}
|
||||
}
|
||||
404
DiscImageChef.Partitions/BSD.cs
Normal file
404
DiscImageChef.Partitions/BSD.cs
Normal file
@@ -0,0 +1,404 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : BSD.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Partitioning scheme plugins.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Manages BSD disklabels.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
{
|
||||
class BSD : PartPlugin
|
||||
{
|
||||
public const uint DISKMAGIC = 0x82564557;
|
||||
|
||||
public BSD()
|
||||
{
|
||||
Name = "BSD disklabel";
|
||||
PluginUUID = new Guid("246A6D93-4F1A-1F8A-344D-50187A5513A9");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
partitions = new List<Partition>();
|
||||
|
||||
byte[] sector = imagePlugin.ReadSector(0);
|
||||
if(sector.Length < 512)
|
||||
return false;
|
||||
bool found = false;
|
||||
|
||||
DiskLabel dl = GetDiskLabel(sector);
|
||||
|
||||
if(dl.d_magic == DISKMAGIC || dl.d_magic2 == DISKMAGIC)
|
||||
found = true;
|
||||
else
|
||||
{
|
||||
sector = imagePlugin.ReadSector(1);
|
||||
|
||||
dl = GetDiskLabel(sector);
|
||||
|
||||
found |= (dl.d_magic == DISKMAGIC || dl.d_magic2 == DISKMAGIC);
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
ulong counter = 0;
|
||||
|
||||
foreach(BSDPartition entry in dl.d_partitions)
|
||||
{
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = entry.p_offset;
|
||||
part.PartitionStart = (entry.p_offset * dl.d_secsize);
|
||||
part.PartitionLength = entry.p_size;
|
||||
part.PartitionSectors = (entry.p_size * dl.d_secsize);
|
||||
part.PartitionType = fsTypeToString(entry.p_fstype);
|
||||
part.PartitionSequence = counter;
|
||||
if(entry.p_fstype != fsType.Unused)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <summary>Drive type</summary>
|
||||
public enum dType : ushort
|
||||
{
|
||||
/// <summary>SMD, XSMD</summary>
|
||||
SMD = 1,
|
||||
/// <summary>MSCP</summary>
|
||||
MSCP = 2,
|
||||
/// <summary>Other DEC (rk, rl)</summary>
|
||||
DEC = 3,
|
||||
/// <summary>SCSI</summary>
|
||||
SCSI = 4,
|
||||
/// <summary>ESDI</summary>
|
||||
ESDI = 5,
|
||||
/// <summary>ST506 et al</summary>
|
||||
ST506 = 6,
|
||||
/// <summary>CS/80 on HP-IB</summary>
|
||||
HPIB = 7,
|
||||
/// <summary>HP Fiber-link</summary>
|
||||
HPFL = 8,
|
||||
/// <summary>Floppy</summary>
|
||||
FLOPPY = 10,
|
||||
/// <summary>Concatenated disk</summary>
|
||||
CCD = 11,
|
||||
/// <summary>uvnode pseudo-disk</summary>
|
||||
VND = 12,
|
||||
/// <summary>DiskOnChip</summary>
|
||||
DOC2K = 13,
|
||||
/// <summary>ATAPI</summary>
|
||||
ATAPI = 13,
|
||||
/// <summary>CMU RAIDframe</summary>
|
||||
RAID = 14,
|
||||
/// <summary>Logical disk</summary>
|
||||
LD = 15,
|
||||
/// <summary>IBM JFS 2</summary>
|
||||
JFS2 = 16,
|
||||
/// <summary>Cryptographic pseudo-disk</summary>
|
||||
CGD = 17,
|
||||
/// <summary>Vinum volume</summary>
|
||||
VINUM = 18,
|
||||
/// <summary>Flash memory devices</summary>
|
||||
FLASH = 19,
|
||||
/// <summary>Device-mapper pseudo-disk devices</summary>
|
||||
DM = 20,
|
||||
/// <summary>Rump virtual disk</summary>
|
||||
RUMPD = 21,
|
||||
/// <summary>Memory disk</summary>
|
||||
MD = 22
|
||||
}
|
||||
|
||||
/// <summary>Filesystem type</summary>
|
||||
public enum fsType : byte
|
||||
{
|
||||
/// <summary>Unused entry</summary>
|
||||
Unused = 0,
|
||||
/// <summary>Swap partition</summary>
|
||||
Swap = 1,
|
||||
/// <summary>UNIX 6th Edition</summary>
|
||||
V6 = 2,
|
||||
/// <summary>UNIX 7th Edition</summary>
|
||||
V7 = 3,
|
||||
/// <summary>UNIX System V</summary>
|
||||
SystemV = 4,
|
||||
/// <summary>UNIX 7th Edition with 1K blocks</summary>
|
||||
V7_1K = 5,
|
||||
/// <summary>UNIX 8th Edition with 4K blocks</summary>
|
||||
V8 = 6,
|
||||
/// <summary>4.2BSD Fast File System</summary>
|
||||
BSDFFS = 7,
|
||||
/// <summary>MS-DOS filesystem</summary>
|
||||
MSDOS = 8,
|
||||
/// <summary>4.4LFS</summary>
|
||||
BSDLFS = 9,
|
||||
/// <summary>In use, unknown or unsupported</summary>
|
||||
Other = 10,
|
||||
/// <summary>HPFS</summary>
|
||||
HPFS = 11,
|
||||
/// <summary>ISO9660</summary>
|
||||
ISO9660 = 12,
|
||||
/// <summary>Boot partition</summary>
|
||||
Boot = 13,
|
||||
/// <summary>Amiga FFS</summary>
|
||||
AFFS = 14,
|
||||
/// <summary>Apple HFS</summary>
|
||||
HFS = 15,
|
||||
/// <summary>Acorn ADFS</summary>
|
||||
FileCore = 16,
|
||||
/// <summary>Digital Advanced File System</summary>
|
||||
ADVfs = 16,
|
||||
/// <summary>Digital LSM Public Region</summary>
|
||||
LSMpublic = 17,
|
||||
/// <summary>Linux ext2</summary>
|
||||
ext2 = 17,
|
||||
/// <summary>Digital LSM Private Region</summary>
|
||||
LSMprivate = 18,
|
||||
/// <summary>NTFS</summary>
|
||||
NTFS = 18,
|
||||
/// <summary>Digital LSM Simple Disk</summary>
|
||||
LSMsimple = 19,
|
||||
/// <summary>RAIDframe component</summary>
|
||||
RAID = 19,
|
||||
/// <summary>Concatenated disk component</summary>
|
||||
CCD = 20,
|
||||
/// <summary>IBM JFS2</summary>
|
||||
JFS2 = 21,
|
||||
/// <summary>Apple UFS</summary>
|
||||
AppleUFS = 22,
|
||||
/// <summary>Hammer filesystem</summary>
|
||||
HAMMER = 22,
|
||||
/// <summary>Hammer2 filesystem</summary>
|
||||
HAMMER2 = 23,
|
||||
/// <summary>UDF</summary>
|
||||
UDF = 24,
|
||||
/// <summary>System V Boot filesystem</summary>
|
||||
SysVBoot = 25,
|
||||
/// <summary>EFS</summary>
|
||||
EFS = 26,
|
||||
/// <summary>ZFS</summary>
|
||||
ZFS = 27,
|
||||
/// <summary>NiLFS</summary>
|
||||
NILFS = 27,
|
||||
/// <summary>Cryptographic disk</summary>
|
||||
CGD = 28,
|
||||
/// <summary>MINIX v3</summary>
|
||||
MINIX = 29,
|
||||
/// <summary>FreeBSD nandfs</summary>
|
||||
NANDFS = 30
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drive flags
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum dFlags : uint
|
||||
{
|
||||
/// <summary>Removable media</summary>
|
||||
Removable = 0x01,
|
||||
/// <summary>Drive supports ECC</summary>
|
||||
ECC = 0x02,
|
||||
/// <summary>Drive supports bad sector forwarding</summary>
|
||||
BadSectorForward = 0x04,
|
||||
/// <summary>Disk emulator</summary>
|
||||
RAMDisk = 0x08,
|
||||
/// <summary>Can do back to back transfer</summary>
|
||||
Chain = 0x10,
|
||||
/// <summary>Dynamic geometry device</summary>
|
||||
DynamicGeometry = 0x20
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct DiskLabel
|
||||
{
|
||||
/// <summary><see cref="DISKMAGIC"/></summary>
|
||||
public uint d_magic;
|
||||
/// <summary><see cref="dType"/></summary>
|
||||
public dType d_type;
|
||||
/// <summary>Disk subtype</summary>
|
||||
public ushort d_subtype;
|
||||
/// <summary>Type name</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public byte[] d_typename;
|
||||
/// <summary>Pack identifier</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public byte[] d_packname;
|
||||
/// <summary>Bytes per sector</summary>
|
||||
public uint d_secsize;
|
||||
/// <summary>Sectors per track</summary>
|
||||
public uint d_nsectors;
|
||||
/// <summary>Tracks per cylinder</summary>
|
||||
public uint d_ntracks;
|
||||
/// <summary>Cylinders per unit</summary>
|
||||
public uint d_ncylinders;
|
||||
/// <summary>Sectors per cylinder</summary>
|
||||
public uint d_secpercyl;
|
||||
/// <summary>Sectors per unit</summary>
|
||||
public uint d_secperunit;
|
||||
/// <summary>Spare sectors per track</summary>
|
||||
public ushort d_sparespertrack;
|
||||
/// <summary>Spare sectors per cylinder</summary>
|
||||
public ushort d_sparespercyl;
|
||||
/// <summary>Alternate cylinders</summary>
|
||||
public uint d_acylinders;
|
||||
/// <summary>Rotational speed</summary>
|
||||
public ushort d_rpm;
|
||||
/// <summary>Hardware sector interleave</summary>
|
||||
public ushort d_interleave;
|
||||
/// <summary>Sector 0 skew per track</summary>
|
||||
public ushort d_trackskew;
|
||||
/// <summary>Sector 0 sker per cylinder</summary>
|
||||
public ushort d_cylskeew;
|
||||
/// <summary>Head switch time in microseconds</summary>
|
||||
public uint d_headswitch;
|
||||
/// <summary>Track to track seek in microseconds</summary>
|
||||
public uint d_trkseek;
|
||||
/// <summary><see cref="dFlags"/></summary>
|
||||
public dFlags d_flags;
|
||||
/// <summary>Drive-specific information</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
public uint[] d_drivedata;
|
||||
/// <summary>Reserved</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
/// <summary></summary>
|
||||
public uint[] d_spare;
|
||||
/// <summary><see cref="DISKMAGIC"/> again</summary>
|
||||
public uint d_magic2;
|
||||
/// <summary>XOR of data</summary>
|
||||
public ushort d_checksum;
|
||||
/// <summary>How many partitions</summary>
|
||||
public ushort d_npartitions;
|
||||
/// <summary>Size of boot area in bytes</summary>
|
||||
public uint d_bbsize;
|
||||
/// <summary>Maximum size of superblock in bytes</summary>
|
||||
public uint d_sbsize;
|
||||
/// <summary>Partitions</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)]
|
||||
public BSDPartition[] d_partitions;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct BSDPartition
|
||||
{
|
||||
/// <summary>Sectors in partition</summary>
|
||||
public uint p_size;
|
||||
/// <summary>Starting sector</summary>
|
||||
public uint p_offset;
|
||||
/// <summary>Fragment size</summary>
|
||||
public uint p_fsize;
|
||||
/// <summary>Filesystem type, <see cref="fsType"/></summary>
|
||||
public fsType p_fstype;
|
||||
/// <summary>Fragment size</summary>
|
||||
public byte p_frag;
|
||||
/// <summary>Cylinder per group</summary>
|
||||
public ushort p_cpg;
|
||||
}
|
||||
|
||||
public static string fsTypeToString(fsType typ)
|
||||
{
|
||||
switch(typ)
|
||||
{
|
||||
case fsType.Unused:
|
||||
return "Unused entry";
|
||||
case fsType.Swap:
|
||||
return "Swap partition";
|
||||
case fsType.V6:
|
||||
return "UNIX 6th Edition";
|
||||
case fsType.V7:
|
||||
return "UNIX 7th Edition";
|
||||
case fsType.SystemV:
|
||||
return "UNIX System V";
|
||||
case fsType.V7_1K:
|
||||
return "UNIX 7th Edition with 1K blocks";
|
||||
case fsType.V8:
|
||||
return "UNIX 8th Edition with 4K blocks";
|
||||
case fsType.BSDFFS:
|
||||
return "4.2BSD Fast File System";
|
||||
case fsType.BSDLFS:
|
||||
return "4.4LFS";
|
||||
case fsType.HPFS:
|
||||
return "HPFS";
|
||||
case fsType.ISO9660:
|
||||
return "ISO9660";
|
||||
case fsType.Boot:
|
||||
return "Boot";
|
||||
case fsType.AFFS:
|
||||
return "Amiga FFS";
|
||||
case fsType.HFS:
|
||||
return "Apple HFS";
|
||||
case fsType.ADVfs:
|
||||
return "Digital Advanced File System";
|
||||
case fsType.LSMpublic:
|
||||
return "Digital LSM Public Region";
|
||||
case fsType.LSMprivate:
|
||||
return "Digital LSM Private Region";
|
||||
case fsType.LSMsimple:
|
||||
return "Digital LSM Simple Disk";
|
||||
case fsType.CCD:
|
||||
return "Concatenated disk";
|
||||
case fsType.JFS2:
|
||||
return "IBM JFS2";
|
||||
case fsType.HAMMER:
|
||||
return "Hammer";
|
||||
case fsType.HAMMER2:
|
||||
return "Hammer2";
|
||||
case fsType.UDF:
|
||||
return "UDF";
|
||||
case fsType.EFS:
|
||||
return "EFS";
|
||||
case fsType.ZFS:
|
||||
return "ZFS";
|
||||
case fsType.NANDFS:
|
||||
return "FreeBSD nandfs";
|
||||
case fsType.Other:
|
||||
return "Other or unknown";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public static DiskLabel GetDiskLabel(byte[] disklabel)
|
||||
{
|
||||
DiskLabel dl = new DiskLabel();
|
||||
IntPtr dlPtr = Marshal.AllocHGlobal(512);
|
||||
Marshal.Copy(disklabel, 0, dlPtr, 512);
|
||||
dl = (DiskLabel)Marshal.PtrToStructure(dlPtr, typeof(DiskLabel));
|
||||
Marshal.FreeHGlobal(dlPtr);
|
||||
return dl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,53 @@
|
||||
2016-08-21 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* Acorn.cs: Added support for Acorn FileCore partition, closes
|
||||
#4.
|
||||
|
||||
* BSD.cs: Moved BSD partitions from inside MBR code to
|
||||
separate code, as they can (and do) appear on other
|
||||
architectures as the only scheme.
|
||||
|
||||
* DEC.cs: Added support for DEC disklabels, closes #11.
|
||||
|
||||
* DragonFlyBSD.cs: Added support for DragonFly BSD 64-bit
|
||||
disklabels.
|
||||
|
||||
* PC98.cs: Added support for NEC PC-9800 partitions.
|
||||
|
||||
* RioKarma.cs: Added support for Rio Karma partitions.
|
||||
|
||||
* SGI.cs: Added support for SGI DVHs, closes #9.
|
||||
|
||||
* UNIX.cs: Moved UNIX partitions from inside MBR code to
|
||||
separate code, as they can (and do) appear on other
|
||||
architectures as the only scheme.
|
||||
|
||||
* DiscImageChef.Partitions.csproj: Added support for Acorn
|
||||
FileCore partition, closes #4.
|
||||
Added support for DEC disklabels, closes #11.
|
||||
Added support for SGI DVHs, closes #9.
|
||||
Moved BSD partitions from inside MBR code to separate code, as
|
||||
they can (and do) appear on other architectures as the only
|
||||
scheme.
|
||||
Added support for DragonFly BSD 64-bit disklabels.
|
||||
Added support for NEC PC-9800 partitions.
|
||||
Added support for Rio Karma partitions.
|
||||
Moved UNIX partitions from inside MBR code to separate code,
|
||||
as they can (and do) appear on other architectures as the only
|
||||
scheme.
|
||||
|
||||
* GPT.cs: Added new partition type UUIDs.
|
||||
|
||||
* MBR.cs: Moved BSD partitions from inside MBR code to
|
||||
separate code, as they can (and do) appear on other
|
||||
architectures as the only scheme.
|
||||
Moved UNIX partitions from inside MBR code to separate code,
|
||||
as they can (and do) appear on other architectures as the only
|
||||
scheme.
|
||||
|
||||
* Sun.cs: Added new partition types.
|
||||
Prepare structures for marshaling.
|
||||
|
||||
2016-08-09 Natalia Portillo <claunia@claunia.com>
|
||||
|
||||
* DiscImageChef.Partitions.csproj: Bumped version to 3.2.99.2.
|
||||
|
||||
107
DiscImageChef.Partitions/DEC.cs
Normal file
107
DiscImageChef.Partitions/DEC.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : DEC.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Partitioning scheme plugins.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Manages DEC disklabels.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
{
|
||||
class DEC : PartPlugin
|
||||
{
|
||||
const int PT_MAGIC = 0x032957;
|
||||
const int PT_VALID = 1;
|
||||
|
||||
public DEC()
|
||||
{
|
||||
Name = "DEC disklabel";
|
||||
PluginUUID = new Guid("58CEC3B7-3B93-4D47-86EE-D6DADE9D444F");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
partitions = new List<Partition>();
|
||||
|
||||
byte[] sector = imagePlugin.ReadSector(31);
|
||||
if(sector.Length < 512)
|
||||
return false;
|
||||
|
||||
DECLabel table = new DECLabel();
|
||||
IntPtr tablePtr = Marshal.AllocHGlobal(512);
|
||||
Marshal.Copy(sector, 0, tablePtr, 512);
|
||||
table = (DECLabel)Marshal.PtrToStructure(tablePtr, typeof(DECLabel));
|
||||
Marshal.FreeHGlobal(tablePtr);
|
||||
|
||||
if(table.pt_magic != PT_MAGIC || table.pt_valid != PT_VALID)
|
||||
return false;
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
foreach(DECPartition entry in table.pt_part)
|
||||
{
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = entry.pi_blkoff;
|
||||
part.PartitionStart = (ulong)(entry.pi_blkoff * sector.Length);
|
||||
part.PartitionLength = (ulong)entry.pi_nblocks;
|
||||
part.PartitionSectors = (ulong)(entry.pi_nblocks * sector.Length);
|
||||
part.PartitionSequence = counter;
|
||||
if(part.PartitionLength > 0)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct DECLabel
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 440)]
|
||||
public byte[] padding;
|
||||
public int pt_magic;
|
||||
public int pt_valid;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public DECPartition[] pt_part;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct DECPartition
|
||||
{
|
||||
public int pi_nblocks;
|
||||
public uint pi_blkoff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,14 @@
|
||||
<Compile Include="RDB.cs" />
|
||||
<Compile Include="Sun.cs" />
|
||||
<Compile Include="GPT.cs" />
|
||||
<Compile Include="RioKarma.cs" />
|
||||
<Compile Include="BSD.cs" />
|
||||
<Compile Include="PC98.cs" />
|
||||
<Compile Include="DEC.cs" />
|
||||
<Compile Include="SGI.cs" />
|
||||
<Compile Include="Acorn.cs" />
|
||||
<Compile Include="DragonFlyBSD.cs" />
|
||||
<Compile Include="UNIX.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
||||
133
DiscImageChef.Partitions/DragonFlyBSD.cs
Normal file
133
DiscImageChef.Partitions/DragonFlyBSD.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : DragonFlyBSD.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Partitioning scheme plugins.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Manages DragonFly BSD 64-bit disklabels.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
{
|
||||
class DragonFlyBSD : PartPlugin
|
||||
{
|
||||
const uint DISK_MAGIC64 = 0xC4464C59;
|
||||
|
||||
public DragonFlyBSD()
|
||||
{
|
||||
Name = "DragonFly BSD 64-bit disklabel";
|
||||
PluginUUID = new Guid("D49E41A6-D952-4760-9D94-03DAE2450C5F");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
partitions = new List<Partition>();
|
||||
uint nSectors = 2048 / imagePlugin.GetSectorSize();
|
||||
|
||||
byte[] sectors = imagePlugin.ReadSectors(0, nSectors);
|
||||
if(sectors.Length < 2048)
|
||||
return false;
|
||||
|
||||
Disklabel64 disklabel = new Disklabel64();
|
||||
IntPtr labelPtr = Marshal.AllocHGlobal(2048);
|
||||
Marshal.Copy(sectors, 0, labelPtr, 2048);
|
||||
disklabel = (Disklabel64)Marshal.PtrToStructure(labelPtr, typeof(Disklabel64));
|
||||
Marshal.FreeHGlobal(labelPtr);
|
||||
|
||||
if(disklabel.d_magic != 0xC4464C59)
|
||||
return false;
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
foreach(Partition64 entry in disklabel.d_partitions)
|
||||
{
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = entry.p_boffset;
|
||||
part.PartitionStart = entry.p_boffset;
|
||||
part.PartitionLength = entry.p_bsize;
|
||||
part.PartitionSectors = entry.p_bsize;
|
||||
if((BSD.fsType)entry.p_fstype == BSD.fsType.Other)
|
||||
part.PartitionType = entry.p_type_uuid.ToString();
|
||||
else
|
||||
part.PartitionType = BSD.fsTypeToString((BSD.fsType)entry.p_fstype);
|
||||
part.PartitionName = entry.p_stor_uuid.ToString();
|
||||
part.PartitionSequence = counter;
|
||||
if(entry.p_bsize > 0 && entry.p_boffset > 0)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct Disklabel64
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
|
||||
public byte[] d_reserved0;
|
||||
public uint d_magic;
|
||||
public uint d_crc;
|
||||
public uint d_align;
|
||||
public uint d_npartitions;
|
||||
public Guid d_stor_uuid;
|
||||
public ulong d_total_size;
|
||||
public ulong d_bbase;
|
||||
public ulong d_pbase;
|
||||
public ulong d_pstop;
|
||||
public ulong d_abase;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
|
||||
public byte[] d_packname;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
|
||||
public byte[] d_reserved;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public Partition64[] d_partitions;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct Partition64
|
||||
{
|
||||
public ulong p_boffset;
|
||||
public ulong p_bsize;
|
||||
public byte p_fstype;
|
||||
public byte p_unused01;
|
||||
public byte p_unused02;
|
||||
public byte p_unused03;
|
||||
public uint p_unused04;
|
||||
public uint p_unused05;
|
||||
public uint p_unused06;
|
||||
public Guid p_type_uuid;
|
||||
public Guid p_stor_uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,10 +215,14 @@ namespace DiscImageChef.PartPlugins
|
||||
return "FreeBSD Swap";
|
||||
case "516E7CB6-6ECF-11D6-8FF8-00022D09712B":
|
||||
return "FreeBSD UFS";
|
||||
case "516E7CB7-6ECF-11D6-8FF8-00022D09712B":
|
||||
return "FreeBSD UFS2";
|
||||
case "516E7CB8-6ECF-11D6-8FF8-00022D09712B":
|
||||
return "FreeBSD Vinum";
|
||||
case "516E7CBA-6ECF-11D6-8FF8-00022D09712B":
|
||||
return "FreeBSD ZFS";
|
||||
case "74BA7DD9-A689-11E1-BD04-00E081286ACF":
|
||||
return "FreeBSD nandfs";
|
||||
case "48465300-0000-11AA-AA11-00306543ECAC":
|
||||
return "Apple HFS";
|
||||
case "55465300-0000-11AA-AA11-00306543ECAC":
|
||||
@@ -323,6 +327,24 @@ namespace DiscImageChef.PartPlugins
|
||||
return "Acronis Secure Zone";
|
||||
case "7C3457EF-0000-11AA-AA11-00306543ECAC":
|
||||
return "Apple File System";
|
||||
case "9D087404-1CA5-11DC-8817-01301BB8A9F5":
|
||||
return "DragonflyBSD Label";
|
||||
case "9D58FDBD-1CA5-11DC-8817-01301BB8A9F5":
|
||||
return "DragonflyBSD Swap";
|
||||
case "9D94CE7C-1CA5-11DC-8817-01301BB8A9F5":
|
||||
return "DragonflyBSD UFS";
|
||||
case "9DD4478F-1CA5-11DC-8817-01301BB8A9F5":
|
||||
return "DragonflyBSD Vinum";
|
||||
case "DBD5211B-1CA5-11DC-8817-01301BB8A9F5":
|
||||
return "DragonflyBSD CCD";
|
||||
case "3D48CE54-1D16-11DC-8817-01301BB8A9F5":
|
||||
return "DragonflyBSD Label";
|
||||
case "BD215AB2-1D16-11DC-8696-01301BB8A9F5":
|
||||
return "DragonflyBSD Legacy";
|
||||
case "61DC63AC-6E38-11DC-8513-01301BB8A9F5":
|
||||
return "DragonflyBSD Hammer";
|
||||
case "5CBB9AD1-862D-11DC-A94D-01301BB8A9F5":
|
||||
return "DragonflyBSD Hammer2";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -137,31 +137,28 @@ namespace DiscImageChef.PartPlugins
|
||||
case 0xA9:
|
||||
case 0xB7: // BSD disklabels
|
||||
{
|
||||
uint magic = BitConverter.ToUInt32(disklabel_sector, 0);
|
||||
BSD.DiskLabel bsdDisklabel = BSD.GetDiskLabel(disklabel_sector);
|
||||
|
||||
if(magic == 0x82564557)
|
||||
if(bsdDisklabel.d_magic == BSD.DISKMAGIC && bsdDisklabel.d_magic2 == BSD.DISKMAGIC)
|
||||
{
|
||||
ushort no_parts = BitConverter.ToUInt16(disklabel_sector, 126);
|
||||
|
||||
// TODO: Handle disklabels bigger than 1 sector or search max no_parts
|
||||
for(int j = 0; j < no_parts; j++)
|
||||
foreach(BSD.BSDPartition bsdPartition in bsdDisklabel.d_partitions)
|
||||
{
|
||||
|
||||
CommonTypes.Partition part = new CommonTypes.Partition();
|
||||
byte bsd_type;
|
||||
|
||||
part.PartitionSectors = BitConverter.ToUInt32(disklabel_sector, 134 + j * 16 + 4);
|
||||
part.PartitionStartSector = BitConverter.ToUInt32(disklabel_sector, 134 + j * 16 + 0);
|
||||
part.PartitionLength = part.PartitionSectors * imagePlugin.GetSectorSize();
|
||||
part.PartitionStart = part.PartitionStartSector * imagePlugin.GetSectorSize();
|
||||
bsd_type = disklabel_sector[134 + j * 16 + 8];
|
||||
part.PartitionSectors = bsdPartition.p_size;
|
||||
part.PartitionStartSector = bsdPartition.p_offset;
|
||||
part.PartitionLength = bsdPartition.p_size * bsdDisklabel.d_secsize;
|
||||
part.PartitionStart = bsdPartition.p_offset * bsdDisklabel.d_secsize;
|
||||
|
||||
part.PartitionType = string.Format("BSD: {0}", bsd_type);
|
||||
part.PartitionName = decodeBSDType(bsd_type);
|
||||
part.PartitionType = string.Format("BSD: {0}", bsdPartition.p_fstype);
|
||||
part.PartitionName = BSD.fsTypeToString(bsdPartition.p_fstype);
|
||||
|
||||
part.PartitionSequence = counter;
|
||||
part.PartitionDescription = "Partition inside a BSD disklabel.";
|
||||
|
||||
if(bsd_type != 0)
|
||||
if(bsdPartition.p_fstype != BSD.fsType.Unused)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
@@ -178,15 +175,15 @@ namespace DiscImageChef.PartPlugins
|
||||
byte[] unix_dl_sector = imagePlugin.ReadSector(entry.lba_start + 29); // UNIX disklabel starts on sector 29 of partition
|
||||
magic = BitConverter.ToUInt32(unix_dl_sector, 4);
|
||||
|
||||
if(magic == UNIXDiskLabel_MAGIC)
|
||||
if(magic == UNIX.UNIXDiskLabel_MAGIC)
|
||||
{
|
||||
UNIXDiskLabel dl = new UNIXDiskLabel();
|
||||
UNIXVTOC vtoc = new UNIXVTOC(); // old/new
|
||||
UNIX.UNIXDiskLabel dl = new UNIX.UNIXDiskLabel();
|
||||
UNIX.UNIXVTOC vtoc = new UNIX.UNIXVTOC(); // old/new
|
||||
bool isNewDL = false;
|
||||
int vtocoffset = 0;
|
||||
|
||||
vtoc.magic = BitConverter.ToUInt32(unix_dl_sector, 172);
|
||||
if(vtoc.magic == UNIXVTOC_MAGIC)
|
||||
if(vtoc.magic == UNIX.UNIXVTOC_MAGIC)
|
||||
{
|
||||
isNewDL = true;
|
||||
vtocoffset = 72;
|
||||
@@ -194,7 +191,7 @@ namespace DiscImageChef.PartPlugins
|
||||
else
|
||||
{
|
||||
vtoc.magic = BitConverter.ToUInt32(unix_dl_sector, 172);
|
||||
if(vtoc.magic != UNIXDiskLabel_MAGIC)
|
||||
if(vtoc.magic != UNIX.UNIXDiskLabel_MAGIC)
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
@@ -225,7 +222,7 @@ namespace DiscImageChef.PartPlugins
|
||||
//dl.pad = br.ReadBytes(48); // 124
|
||||
}
|
||||
|
||||
if(vtoc.magic == UNIXVTOC_MAGIC)
|
||||
if(vtoc.magic == UNIX.UNIXVTOC_MAGIC)
|
||||
{
|
||||
vtoc.version = BitConverter.ToUInt32(unix_dl_sector, 104 + vtocoffset); // 104/176
|
||||
byte[] vtoc_name = new byte[8];
|
||||
@@ -238,14 +235,14 @@ namespace DiscImageChef.PartPlugins
|
||||
// TODO: What if number of slices overlaps sector (>23)?
|
||||
for(int j = 0; j < vtoc.slices; j++)
|
||||
{
|
||||
UNIXVTOCEntry vtoc_ent = new UNIXVTOCEntry();
|
||||
UNIX.UNIXVTOCEntry vtoc_ent = new UNIX.UNIXVTOCEntry();
|
||||
|
||||
vtoc_ent.tag = BitConverter.ToUInt16(unix_dl_sector, 160 + vtocoffset + j * 12 + 0); // 160/232 + j*12
|
||||
vtoc_ent.tag = (DiscImageChef.PartPlugins.UNIX.UNIX_TAG)BitConverter.ToUInt16(unix_dl_sector, 160 + vtocoffset + j * 12 + 0); // 160/232 + j*12
|
||||
vtoc_ent.flags = BitConverter.ToUInt16(unix_dl_sector, 160 + vtocoffset + j * 12 + 2); // 162/234 + j*12
|
||||
vtoc_ent.start = BitConverter.ToUInt32(unix_dl_sector, 160 + vtocoffset + j * 12 + 6); // 166/238 + j*12
|
||||
vtoc_ent.length = BitConverter.ToUInt32(unix_dl_sector, 160 + vtocoffset + j * 12 + 10); // 170/242 + j*12
|
||||
|
||||
if((vtoc_ent.flags & 0x200) == 0x200 && vtoc_ent.tag != UNIX_TAG_EMPTY && vtoc_ent.tag != UNIX_TAG_WHOLE)
|
||||
if((vtoc_ent.flags & 0x200) == 0x200 && vtoc_ent.tag != UNIX.UNIX_TAG.EMPTY && vtoc_ent.tag != UNIX.UNIX_TAG.WHOLE)
|
||||
{
|
||||
CommonTypes.Partition part = new CommonTypes.Partition();
|
||||
// TODO: Check if device bps == disklabel bps
|
||||
@@ -254,7 +251,7 @@ namespace DiscImageChef.PartPlugins
|
||||
part.PartitionStart = vtoc_ent.start * dl.bps;
|
||||
part.PartitionLength = vtoc_ent.length * dl.bps;
|
||||
part.PartitionSequence = counter;
|
||||
part.PartitionType = string.Format("UNIX: {0}", decodeUNIXTAG(vtoc_ent.tag, isNewDL));
|
||||
part.PartitionType = string.Format("UNIX: {0}", UNIX.decodeUNIXTAG(vtoc_ent.tag, isNewDL));
|
||||
|
||||
string info = "";
|
||||
|
||||
@@ -439,31 +436,28 @@ namespace DiscImageChef.PartPlugins
|
||||
case 0xA9:
|
||||
case 0xB7: // BSD disklabels
|
||||
{
|
||||
uint magic = BitConverter.ToUInt32(disklabel_sector, 0);
|
||||
BSD.DiskLabel bsdDisklabel = BSD.GetDiskLabel(disklabel_sector);
|
||||
|
||||
if(magic == 0x82564557)
|
||||
if(bsdDisklabel.d_magic == BSD.DISKMAGIC && bsdDisklabel.d_magic2 == BSD.DISKMAGIC)
|
||||
{
|
||||
ushort no_parts = BitConverter.ToUInt16(disklabel_sector, 126);
|
||||
|
||||
// TODO: Handle disklabels bigger than 1 sector or search max no_parts
|
||||
for(int j = 0; j < no_parts; j++)
|
||||
foreach(BSD.BSDPartition bsdPartition in bsdDisklabel.d_partitions)
|
||||
{
|
||||
|
||||
CommonTypes.Partition part = new CommonTypes.Partition();
|
||||
byte bsd_type;
|
||||
|
||||
part.PartitionSectors = BitConverter.ToUInt32(disklabel_sector, 134 + j * 16 + 4);
|
||||
part.PartitionStartSector = BitConverter.ToUInt32(disklabel_sector, 134 + j * 16 + 0);
|
||||
part.PartitionLength = part.PartitionSectors * imagePlugin.GetSectorSize();
|
||||
part.PartitionStart = part.PartitionStartSector * imagePlugin.GetSectorSize();
|
||||
bsd_type = disklabel_sector[134 + j * 16 + 8];
|
||||
part.PartitionSectors = bsdPartition.p_size;
|
||||
part.PartitionStartSector = bsdPartition.p_offset;
|
||||
part.PartitionLength = bsdPartition.p_size * bsdDisklabel.d_secsize;
|
||||
part.PartitionStart = bsdPartition.p_offset * bsdDisklabel.d_secsize;
|
||||
|
||||
part.PartitionType = string.Format("BSD: {0}", bsd_type);
|
||||
part.PartitionName = decodeBSDType(bsd_type);
|
||||
part.PartitionType = string.Format("BSD: {0}", bsdPartition.p_fstype);
|
||||
part.PartitionName = BSD.fsTypeToString(bsdPartition.p_fstype);
|
||||
|
||||
part.PartitionSequence = counter;
|
||||
part.PartitionDescription = "Partition inside a BSD disklabel.";
|
||||
|
||||
if(bsd_type != 0)
|
||||
if(bsdPartition.p_fstype != BSD.fsType.Unused)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
@@ -480,15 +474,15 @@ namespace DiscImageChef.PartPlugins
|
||||
byte[] unix_dl_sector = imagePlugin.ReadSector(entry.lba_start + 29); // UNIX disklabel starts on sector 29 of partition
|
||||
magic = BitConverter.ToUInt32(unix_dl_sector, 4);
|
||||
|
||||
if(magic == UNIXDiskLabel_MAGIC)
|
||||
if(magic == UNIX.UNIXDiskLabel_MAGIC)
|
||||
{
|
||||
UNIXDiskLabel dl = new UNIXDiskLabel();
|
||||
UNIXVTOC vtoc = new UNIXVTOC(); // old/new
|
||||
UNIX.UNIXDiskLabel dl = new UNIX.UNIXDiskLabel();
|
||||
UNIX.UNIXVTOC vtoc = new UNIX.UNIXVTOC(); // old/new
|
||||
bool isNewDL = false;
|
||||
int vtocoffset = 0;
|
||||
|
||||
vtoc.magic = BitConverter.ToUInt32(unix_dl_sector, 172);
|
||||
if(vtoc.magic == UNIXVTOC_MAGIC)
|
||||
if(vtoc.magic == UNIX.UNIXVTOC_MAGIC)
|
||||
{
|
||||
isNewDL = true;
|
||||
vtocoffset = 72;
|
||||
@@ -496,7 +490,7 @@ namespace DiscImageChef.PartPlugins
|
||||
else
|
||||
{
|
||||
vtoc.magic = BitConverter.ToUInt32(unix_dl_sector, 172);
|
||||
if(vtoc.magic != UNIXDiskLabel_MAGIC)
|
||||
if(vtoc.magic != UNIX.UNIXDiskLabel_MAGIC)
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
@@ -527,7 +521,7 @@ namespace DiscImageChef.PartPlugins
|
||||
//dl.pad = br.ReadBytes(48); // 124
|
||||
}
|
||||
|
||||
if(vtoc.magic == UNIXVTOC_MAGIC)
|
||||
if(vtoc.magic == UNIX.UNIXVTOC_MAGIC)
|
||||
{
|
||||
vtoc.version = BitConverter.ToUInt32(unix_dl_sector, 104 + vtocoffset); // 104/176
|
||||
byte[] vtoc_name = new byte[8];
|
||||
@@ -540,14 +534,14 @@ namespace DiscImageChef.PartPlugins
|
||||
// TODO: What if number of slices overlaps sector (>23)?
|
||||
for(int j = 0; j < vtoc.slices; j++)
|
||||
{
|
||||
UNIXVTOCEntry vtoc_ent = new UNIXVTOCEntry();
|
||||
UNIX.UNIXVTOCEntry vtoc_ent = new UNIX.UNIXVTOCEntry();
|
||||
|
||||
vtoc_ent.tag = BitConverter.ToUInt16(unix_dl_sector, 160 + vtocoffset + j * 12 + 0); // 160/232 + j*12
|
||||
vtoc_ent.tag = (DiscImageChef.PartPlugins.UNIX.UNIX_TAG)BitConverter.ToUInt16(unix_dl_sector, 160 + vtocoffset + j * 12 + 0); // 160/232 + j*12
|
||||
vtoc_ent.flags = BitConverter.ToUInt16(unix_dl_sector, 160 + vtocoffset + j * 12 + 2); // 162/234 + j*12
|
||||
vtoc_ent.start = BitConverter.ToUInt32(unix_dl_sector, 160 + vtocoffset + j * 12 + 6); // 166/238 + j*12
|
||||
vtoc_ent.length = BitConverter.ToUInt32(unix_dl_sector, 160 + vtocoffset + j * 12 + 10); // 170/242 + j*12
|
||||
|
||||
if((vtoc_ent.flags & 0x200) == 0x200 && vtoc_ent.tag != UNIX_TAG_EMPTY && vtoc_ent.tag != UNIX_TAG_WHOLE)
|
||||
if((vtoc_ent.flags & 0x200) == 0x200 && vtoc_ent.tag != UNIX.UNIX_TAG.EMPTY && vtoc_ent.tag != UNIX.UNIX_TAG.WHOLE)
|
||||
{
|
||||
CommonTypes.Partition part = new CommonTypes.Partition();
|
||||
// TODO: Check if device bps == disklabel bps
|
||||
@@ -556,7 +550,7 @@ namespace DiscImageChef.PartPlugins
|
||||
part.PartitionStart = vtoc_ent.start * dl.bps;
|
||||
part.PartitionLength = vtoc_ent.length * dl.bps;
|
||||
part.PartitionSequence = counter;
|
||||
part.PartitionType = string.Format("UNIX: {0}", decodeUNIXTAG(vtoc_ent.tag, isNewDL));
|
||||
part.PartitionType = string.Format("UNIX: {0}", UNIX.decodeUNIXTAG(vtoc_ent.tag, isNewDL));
|
||||
|
||||
string info = "";
|
||||
|
||||
@@ -695,43 +689,6 @@ namespace DiscImageChef.PartPlugins
|
||||
#pragma warning restore IDE0004 // Remove Unnecessary Cast
|
||||
}
|
||||
|
||||
static string decodeBSDType(byte type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case 1:
|
||||
return "Swap";
|
||||
case 2:
|
||||
return "UNIX Version 6";
|
||||
case 3:
|
||||
return "UNIX Version 7";
|
||||
case 4:
|
||||
return "System V";
|
||||
case 5:
|
||||
return "4.1BSD";
|
||||
case 6:
|
||||
return "UNIX Eigth Edition";
|
||||
case 7:
|
||||
return "4.2BSD";
|
||||
case 8:
|
||||
return "MS-DOS";
|
||||
case 9:
|
||||
return "4.4LFS";
|
||||
case 11:
|
||||
return "HPFS";
|
||||
case 12:
|
||||
return "ISO9660";
|
||||
case 13:
|
||||
return "Boot";
|
||||
case 14:
|
||||
return "Amiga FFS";
|
||||
case 15:
|
||||
return "Apple HFS";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static string decodeMBRType(byte type)
|
||||
{
|
||||
switch(type)
|
||||
@@ -1073,163 +1030,5 @@ namespace DiscImageChef.PartPlugins
|
||||
// Total sectors
|
||||
}
|
||||
|
||||
const uint UNIXDiskLabel_MAGIC = 0xCA5E600D;
|
||||
const uint UNIXVTOC_MAGIC = 0x600DDEEE;
|
||||
// Same as Solaris VTOC
|
||||
struct UNIXDiskLabel
|
||||
{
|
||||
public uint type;
|
||||
// Drive type, seems always 0
|
||||
public uint magic;
|
||||
// UNIXDiskLabel_MAGIC
|
||||
public uint version;
|
||||
// Only seen 1
|
||||
public string serial;
|
||||
// 12 bytes, serial number of the device
|
||||
public uint cyls;
|
||||
// data cylinders per device
|
||||
public uint trks;
|
||||
// data tracks per cylinder
|
||||
public uint secs;
|
||||
// data sectors per track
|
||||
public uint bps;
|
||||
// data bytes per sector
|
||||
public uint start;
|
||||
// first sector of this partition
|
||||
public byte[] unknown1;
|
||||
// 48 bytes
|
||||
public uint alt_tbl;
|
||||
// byte offset of alternate table
|
||||
public uint alt_len;
|
||||
// byte length of alternate table
|
||||
// From onward here, is not on old version
|
||||
public uint phys_cyl;
|
||||
// physical cylinders per device
|
||||
public uint phys_trk;
|
||||
// physical tracks per cylinder
|
||||
public uint phys_sec;
|
||||
// physical sectors per track
|
||||
public uint phys_bytes;
|
||||
// physical bytes per sector
|
||||
public uint unknown2;
|
||||
//
|
||||
public uint unknown3;
|
||||
//
|
||||
public byte[] pad;
|
||||
// 32bytes
|
||||
}
|
||||
|
||||
struct UNIXVTOC
|
||||
{
|
||||
public uint magic;
|
||||
// UNIXVTOC_MAGIC
|
||||
public uint version;
|
||||
// 1
|
||||
public string name;
|
||||
// 8 bytes
|
||||
public ushort slices;
|
||||
// # of slices
|
||||
public ushort unknown;
|
||||
//
|
||||
public byte[] reserved;
|
||||
// 40 bytes
|
||||
}
|
||||
|
||||
struct UNIXVTOCEntry
|
||||
{
|
||||
public ushort tag;
|
||||
// TAG
|
||||
public ushort flags;
|
||||
// Flags (see below)
|
||||
public uint start;
|
||||
// Start sector
|
||||
public uint length;
|
||||
// Length of slice in sectors
|
||||
}
|
||||
|
||||
const ushort UNIX_TAG_EMPTY = 0x0000;
|
||||
// empty
|
||||
const ushort UNIX_TAG_BOOT = 0x0001;
|
||||
// boot
|
||||
const ushort UNIX_TAG_ROOT = 0x0002;
|
||||
// root
|
||||
const ushort UNIX_TAG_SWAP = 0x0003;
|
||||
// swap
|
||||
const ushort UNIX_TAG_USER = 0x0004;
|
||||
// /usr
|
||||
const ushort UNIX_TAG_WHOLE = 0x0005;
|
||||
// whole disk
|
||||
const ushort UNIX_TAG_STAND = 0x0006;
|
||||
// stand partition ??
|
||||
const ushort UNIX_TAG_ALT_S = 0x0006;
|
||||
// alternate sector space
|
||||
const ushort UNIX_TAG_VAR = 0x0007;
|
||||
// /var
|
||||
const ushort UNIX_TAG_OTHER = 0x0007;
|
||||
// non UNIX
|
||||
const ushort UNIX_TAG_HOME = 0x0008;
|
||||
// /home
|
||||
const ushort UNIX_TAG_ALT_T = 0x0008;
|
||||
// alternate track space
|
||||
const ushort UNIX_TAG_ALT_ST = 0x0009;
|
||||
// alternate sector track
|
||||
const ushort UNIX_TAG_NEW_STAND = 0x0009;
|
||||
// stand partition ??
|
||||
const ushort UNIX_TAG_CACHE = 0x000A;
|
||||
// cache
|
||||
const ushort UNIX_TAG_NEW_VAR = 0x000A;
|
||||
// /var
|
||||
const ushort UNIX_TAG_RESERVED = 0x000B;
|
||||
// reserved
|
||||
const ushort UNIX_TAG_NEW_HOME = 0x000B;
|
||||
// /home
|
||||
const ushort UNIX_TAG_DUMP = 0x000C;
|
||||
// dump partition
|
||||
const ushort UNIX_TAG_NEW_ALT_ST = 0x000D;
|
||||
// alternate sector track
|
||||
const ushort UNIX_TAG_VM_PUBLIC = 0x000E;
|
||||
// volume mgt public partition
|
||||
const ushort UNIX_TAG_VM_PRIVATE = 0x000F;
|
||||
// volume mgt private partition
|
||||
static string decodeUNIXTAG(ushort type, bool isNew)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case UNIX_TAG_EMPTY:
|
||||
return "Unused";
|
||||
case UNIX_TAG_BOOT:
|
||||
return "Boot";
|
||||
case UNIX_TAG_ROOT:
|
||||
return "/";
|
||||
case UNIX_TAG_SWAP:
|
||||
return "Swap";
|
||||
case UNIX_TAG_USER:
|
||||
return "/usr";
|
||||
case UNIX_TAG_WHOLE:
|
||||
return "Whole disk";
|
||||
case UNIX_TAG_STAND:
|
||||
return isNew ? "Stand" : "Alternate sector space";
|
||||
case UNIX_TAG_VAR:
|
||||
return isNew ? "/var" : "non UNIX";
|
||||
case UNIX_TAG_HOME:
|
||||
return isNew ? "/home" : "Alternate track space";
|
||||
case UNIX_TAG_ALT_ST:
|
||||
return isNew ? "Alternate sector track" : "Stand";
|
||||
case UNIX_TAG_CACHE:
|
||||
return isNew ? "Cache" : "/var";
|
||||
case UNIX_TAG_RESERVED:
|
||||
return isNew ? "Reserved" : "/home";
|
||||
case UNIX_TAG_DUMP:
|
||||
return "dump";
|
||||
case UNIX_TAG_NEW_ALT_ST:
|
||||
return "Alternate sector track";
|
||||
case UNIX_TAG_VM_PUBLIC:
|
||||
return "volume mgt public partition";
|
||||
case UNIX_TAG_VM_PRIVATE:
|
||||
return "volume mgt private partition";
|
||||
default:
|
||||
return string.Format("Unknown TAG: 0x{0:X4}", type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
129
DiscImageChef.Partitions/PC98.cs
Normal file
129
DiscImageChef.Partitions/PC98.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : PC98.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Partitioning scheme plugins.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Manages NEC PC-9800 partitions.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
{
|
||||
class PC98 : PartPlugin
|
||||
{
|
||||
const ushort IntelMagic = 0xAA55;
|
||||
|
||||
public PC98()
|
||||
{
|
||||
Name = "NEC PC-9800 partitions table";
|
||||
PluginUUID = new Guid("27333401-C7C2-447D-961C-22AD0641A09A\n");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
partitions = new List<Partition>();
|
||||
|
||||
byte[] bootSector = imagePlugin.ReadSector(0);
|
||||
byte[] sector = imagePlugin.ReadSector(1);
|
||||
if(sector.Length < 512)
|
||||
return false;
|
||||
if(bootSector[0x1FE] != 0x55 || bootSector[0x1FF] != 0xAA)
|
||||
return false;
|
||||
|
||||
PC98Table table = new PC98Table();
|
||||
IntPtr tablePtr = Marshal.AllocHGlobal(512);
|
||||
Marshal.Copy(sector, 0, tablePtr, 512);
|
||||
table = (PC98Table)Marshal.PtrToStructure(tablePtr, typeof(PC98Table));
|
||||
Marshal.FreeHGlobal(tablePtr);
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
foreach(PC98Partition entry in table.entries)
|
||||
{
|
||||
if(entry.dp_ssect != entry.dp_esect &&
|
||||
entry.dp_shd != entry.dp_ehd &&
|
||||
entry.dp_scyl != entry.dp_ecyl &&
|
||||
entry.dp_ecyl > 0)
|
||||
{
|
||||
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = CHStoLBA(entry.dp_scyl, entry.dp_shd, entry.dp_ssect);
|
||||
part.PartitionStart = part.PartitionStartSector * imagePlugin.GetSectorSize();
|
||||
part.PartitionSectors = CHStoLBA(entry.dp_ecyl, entry.dp_ehd, entry.dp_esect) - part.PartitionStartSector;
|
||||
part.PartitionLength = part.PartitionSectors * imagePlugin.GetSectorSize();
|
||||
part.PartitionType = string.Format("{0}", (entry.dp_sid << 8) | entry.dp_mid);
|
||||
part.PartitionName = entry.dp_name;
|
||||
part.PartitionSequence = counter;
|
||||
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint CHStoLBA(ushort cyl, byte head, byte sector)
|
||||
{
|
||||
#pragma warning disable IDE0004 // Remove Unnecessary Cast
|
||||
return (((uint)cyl * 16) + (uint)head) * 63 + (uint)sector - 1;
|
||||
#pragma warning restore IDE0004 // Remove Unnecessary Cast
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct PC98Table
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public PC98Partition[] entries;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct PC98Partition
|
||||
{
|
||||
public byte dp_mid;
|
||||
public byte dp_sid;
|
||||
public byte dp_dum1;
|
||||
public byte dp_dum2;
|
||||
public byte dp_ipl_sct;
|
||||
public byte dp_ipl_head;
|
||||
public ushort dp_ipl_cyl;
|
||||
public byte dp_ssect;
|
||||
public byte dp_shd;
|
||||
public ushort dp_scyl;
|
||||
public byte dp_esect;
|
||||
public byte dp_ehd;
|
||||
public ushort dp_ecyl;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public string dp_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
113
DiscImageChef.Partitions/RioKarma.cs
Normal file
113
DiscImageChef.Partitions/RioKarma.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : RioKarma.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Partitioning scheme plugins.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Manages Rio Karma partitions.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
{
|
||||
class RioKarma : PartPlugin
|
||||
{
|
||||
const ushort KarmaMagic = 0xAB56;
|
||||
const byte EntryMagic = 0x4D;
|
||||
|
||||
public RioKarma()
|
||||
{
|
||||
Name = "Rio Karma partitioning";
|
||||
PluginUUID = new Guid("246A6D93-4F1A-1F8A-344D-50187A5513A9");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
partitions = new List<Partition>();
|
||||
|
||||
byte[] sector = imagePlugin.ReadSector(0);
|
||||
if(sector.Length < 512)
|
||||
return false;
|
||||
|
||||
RioKarmaTable table = new RioKarmaTable();
|
||||
IntPtr tablePtr = Marshal.AllocHGlobal(512);
|
||||
Marshal.Copy(sector, 0, tablePtr, 512);
|
||||
table = (RioKarmaTable)Marshal.PtrToStructure(tablePtr, typeof(RioKarmaTable));
|
||||
Marshal.FreeHGlobal(tablePtr);
|
||||
|
||||
if(table.magic != KarmaMagic)
|
||||
return false;
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
foreach(RioKarmaEntry entry in table.entries)
|
||||
{
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = entry.offset;
|
||||
part.PartitionStart = (ulong)(entry.offset * sector.Length);
|
||||
part.PartitionLength = entry.size;
|
||||
part.PartitionSectors = (ulong)(entry.size * sector.Length);
|
||||
part.PartitionType = "Rio Karma";
|
||||
part.PartitionSequence = counter;
|
||||
if(entry.type == EntryMagic)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct RioKarmaTable
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 270)]
|
||||
public byte[] reserved;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public RioKarmaEntry[] entries;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 208)]
|
||||
public byte[] padding;
|
||||
public ushort magic;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct RioKarmaEntry
|
||||
{
|
||||
public uint reserverd;
|
||||
public byte type;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] reserved2;
|
||||
public uint offset;
|
||||
public uint size;
|
||||
}
|
||||
}
|
||||
}
|
||||
136
DiscImageChef.Partitions/SGI.cs
Normal file
136
DiscImageChef.Partitions/SGI.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : SGI.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Partitioning scheme plugins.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Manages SGI DVHs.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.Helpers;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
{
|
||||
class SGI : PartPlugin
|
||||
{
|
||||
const int SGI_MAGIC = 0x0BE5A941;
|
||||
|
||||
public SGI()
|
||||
{
|
||||
Name = "SGI Disk Volume Header";
|
||||
PluginUUID = new Guid("AEF5AB45-4880-4CE8-8735-F0A402E2E5F2");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
partitions = new List<Partition>();
|
||||
|
||||
byte[] sector = imagePlugin.ReadSector(0);
|
||||
if(sector.Length < 512)
|
||||
return false;
|
||||
|
||||
SGILabel disklabel = BigEndianStructure.ByteArrayToStructureBigEndian<SGILabel>(sector);
|
||||
|
||||
if(disklabel.magic != SGI_MAGIC)
|
||||
return false;
|
||||
|
||||
ulong counter = 0;
|
||||
|
||||
foreach(SGIPartition entry in disklabel.partitions)
|
||||
{
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = entry.first_block;
|
||||
part.PartitionStart = (entry.first_block * 512);
|
||||
part.PartitionLength = entry.num_blocks;
|
||||
part.PartitionSectors = (entry.num_blocks * 512);
|
||||
part.PartitionType = string.Format("{0}", entry.type);
|
||||
part.PartitionSequence = counter;
|
||||
if(part.PartitionLength > 0)
|
||||
{
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct SGILabel
|
||||
{
|
||||
/// <summary></summary>
|
||||
public uint magic;
|
||||
/// <summary></summary>
|
||||
public ushort root_part_num;
|
||||
/// <summary></summary>
|
||||
public ushort swap_part_num;
|
||||
/// <summary></summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public byte[] boot_file;
|
||||
/// <summary></summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
|
||||
public byte[] device_params;
|
||||
/// <summary></summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
|
||||
public SGIVolume[] volume;
|
||||
/// <summary></summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public SGIPartition[] partitions;
|
||||
/// <summary></summary>
|
||||
public uint csum;
|
||||
/// <summary></summary>
|
||||
public uint padding;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct SGIVolume
|
||||
{
|
||||
/// <summary></summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] name;
|
||||
/// <summary></summary>
|
||||
public uint block_num;
|
||||
/// <summary></summary>
|
||||
public uint num_bytes;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct SGIPartition
|
||||
{
|
||||
/// <summary></summary>
|
||||
public uint num_blocks;
|
||||
/// <summary></summary>
|
||||
public uint first_block;
|
||||
/// <summary></summary>
|
||||
public uint type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.Console;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
@@ -52,10 +53,20 @@ namespace DiscImageChef.PartPlugins
|
||||
SunStand = 0x0006,
|
||||
SunVar = 0x0007,
|
||||
SunHome = 0x0008,
|
||||
SunAlt = 0x0009,
|
||||
SunCache = 0x000A,
|
||||
VxVmPublic = 0x000E,
|
||||
VxVmPrivate = 0x000F,
|
||||
LinuxSwap = 0x0082,
|
||||
Linux = 0x0083,
|
||||
LVM = 0x008E,
|
||||
LinuxRaid = 0x00FD
|
||||
LinuxRaid = 0x00FD,
|
||||
NetBSD = 0x00FF,
|
||||
FreeBSD_Swap = 0x0901,
|
||||
FreeBSD_UFS = 0x0902,
|
||||
FreeBSD_Vinum = 0x0903,
|
||||
FreeBSD_ZFS = 0x0904,
|
||||
FreeBSD_NANDFS = 0x0905
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -255,11 +266,13 @@ namespace DiscImageChef.PartPlugins
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SunDiskLabel
|
||||
{
|
||||
/// <summary>
|
||||
/// Offset 0x000: Informative string, 128 bytes
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
|
||||
public string info;
|
||||
/// <summary>
|
||||
/// Offset 0x080: Volume Table Of Contents
|
||||
@@ -276,6 +289,7 @@ namespace DiscImageChef.PartPlugins
|
||||
/// <summary>
|
||||
/// Offset 0x110: Unused, 148 bytes
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 148)]
|
||||
public byte[] spare;
|
||||
/// <summary>
|
||||
/// Offset 0x1A4: Rotational speed
|
||||
@@ -328,6 +342,7 @@ namespace DiscImageChef.PartPlugins
|
||||
/// <summary>
|
||||
/// Offset 0x1BC: Partitions
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public SunPartition[] partitions;
|
||||
/// <summary>
|
||||
/// Offset 0x1FC:
|
||||
@@ -339,6 +354,7 @@ namespace DiscImageChef.PartPlugins
|
||||
public ushort csum;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SunVTOC
|
||||
{
|
||||
/// <summary>
|
||||
@@ -348,6 +364,7 @@ namespace DiscImageChef.PartPlugins
|
||||
/// <summary>
|
||||
/// Offset 0x04: Volume name, 8 bytes
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public string volname;
|
||||
/// <summary>
|
||||
/// Offset 0x0C: Number of partitions
|
||||
@@ -356,6 +373,7 @@ namespace DiscImageChef.PartPlugins
|
||||
/// <summary>
|
||||
/// Offset 0x0E: Partition information, 8 entries
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public SunInfo[] infos;
|
||||
/// <summary>
|
||||
/// Offset 0x2E: Padding
|
||||
@@ -364,6 +382,7 @@ namespace DiscImageChef.PartPlugins
|
||||
/// <summary>
|
||||
/// Offset 0x30: Information needed by mboot, 3 entries
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public uint[] bootinfo;
|
||||
/// <summary>
|
||||
/// Offset 0x3C: VTOC magic
|
||||
@@ -372,13 +391,16 @@ namespace DiscImageChef.PartPlugins
|
||||
/// <summary>
|
||||
/// Offset 0x40: Reserved, 40 bytes
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
|
||||
public byte[] reserved;
|
||||
/// <summary>
|
||||
/// Offset 0x68: Partition timestamps, 8 entries
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public uint[] timestamp;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SunInfo
|
||||
{
|
||||
/// <summary>
|
||||
@@ -391,6 +413,7 @@ namespace DiscImageChef.PartPlugins
|
||||
public ushort flags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SunPartition
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
341
DiscImageChef.Partitions/UNIX.cs
Normal file
341
DiscImageChef.Partitions/UNIX.cs
Normal file
@@ -0,0 +1,341 @@
|
||||
// /***************************************************************************
|
||||
// The Disc Image Chef
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : UNIX.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Component : Partitioning scheme plugins.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Manages UNIX VTOC and disklabels.
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; either version 2.1 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright © 2011-2016 Natalia Portillo
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.ImagePlugins;
|
||||
|
||||
namespace DiscImageChef.PartPlugins
|
||||
{
|
||||
class UNIX : PartPlugin
|
||||
{
|
||||
public const uint UNIXDiskLabel_MAGIC = 0xCA5E600D;
|
||||
public const uint UNIXVTOC_MAGIC = 0x600DDEEE;
|
||||
|
||||
public UNIX()
|
||||
{
|
||||
Name = "UNIX VTOC and disklabel";
|
||||
PluginUUID = new Guid("6D35A66F-8D77-426F-A562-D88F6A1F1702");
|
||||
}
|
||||
|
||||
public override bool GetInformation(ImagePlugin imagePlugin, out List<Partition> partitions)
|
||||
{
|
||||
partitions = new List<Partition>();
|
||||
|
||||
uint magic;
|
||||
byte[] unix_dl_sector;
|
||||
|
||||
unix_dl_sector = imagePlugin.ReadSector(0);
|
||||
magic = BitConverter.ToUInt32(unix_dl_sector, 4);
|
||||
if(magic != UNIXDiskLabel_MAGIC)
|
||||
{
|
||||
unix_dl_sector = imagePlugin.ReadSector(1);
|
||||
magic = BitConverter.ToUInt32(unix_dl_sector, 4);
|
||||
if(magic != UNIXDiskLabel_MAGIC)
|
||||
{
|
||||
unix_dl_sector = imagePlugin.ReadSector(8);
|
||||
magic = BitConverter.ToUInt32(unix_dl_sector, 4);
|
||||
|
||||
if(magic != UNIXDiskLabel_MAGIC)
|
||||
{
|
||||
unix_dl_sector = imagePlugin.ReadSector(29);
|
||||
magic = BitConverter.ToUInt32(unix_dl_sector, 4);
|
||||
|
||||
if(magic != UNIXDiskLabel_MAGIC)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNIXDiskLabel dl = new UNIXDiskLabel();
|
||||
UNIXVTOC vtoc = new UNIXVTOC(); // old/new
|
||||
bool isNewDL = false;
|
||||
int vtocoffset = 0;
|
||||
ulong counter = 0;
|
||||
|
||||
vtoc.magic = BitConverter.ToUInt32(unix_dl_sector, 172);
|
||||
if(vtoc.magic == UNIXVTOC_MAGIC)
|
||||
{
|
||||
isNewDL = true;
|
||||
vtocoffset = 72;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtoc.magic = BitConverter.ToUInt32(unix_dl_sector, 172);
|
||||
if(vtoc.magic != UNIXDiskLabel_MAGIC)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
dl.version = BitConverter.ToUInt32(unix_dl_sector, 8); // 8
|
||||
byte[] dl_serial = new byte[12];
|
||||
Array.Copy(unix_dl_sector, 12, dl_serial, 0, 12);
|
||||
dl.serial = StringHandlers.CToString(dl_serial); // 12
|
||||
dl.cyls = BitConverter.ToUInt32(unix_dl_sector, 24); // 24
|
||||
dl.trks = BitConverter.ToUInt32(unix_dl_sector, 28); // 28
|
||||
dl.secs = BitConverter.ToUInt32(unix_dl_sector, 32); // 32
|
||||
dl.bps = BitConverter.ToUInt32(unix_dl_sector, 36); // 36
|
||||
dl.start = BitConverter.ToUInt32(unix_dl_sector, 40); // 40
|
||||
dl.alt_tbl = BitConverter.ToUInt32(unix_dl_sector, 92); // 92
|
||||
dl.alt_len = BitConverter.ToUInt32(unix_dl_sector, 96); // 96
|
||||
|
||||
if(isNewDL) // Old version VTOC starts here
|
||||
{
|
||||
dl.phys_cyl = BitConverter.ToUInt32(unix_dl_sector, 100); // 100
|
||||
dl.phys_trk = BitConverter.ToUInt32(unix_dl_sector, 104); // 104
|
||||
dl.phys_sec = BitConverter.ToUInt32(unix_dl_sector, 108); // 108
|
||||
dl.phys_bytes = BitConverter.ToUInt32(unix_dl_sector, 112); // 112
|
||||
dl.unknown2 = BitConverter.ToUInt32(unix_dl_sector, 116); // 116
|
||||
dl.unknown3 = BitConverter.ToUInt32(unix_dl_sector, 120); // 120
|
||||
}
|
||||
|
||||
if(vtoc.magic == UNIXVTOC_MAGIC)
|
||||
{
|
||||
vtoc.version = BitConverter.ToUInt32(unix_dl_sector, 104 + vtocoffset); // 104/176
|
||||
byte[] vtoc_name = new byte[8];
|
||||
Array.Copy(unix_dl_sector, 108 + vtocoffset, vtoc_name, 0, 8);
|
||||
vtoc.name = StringHandlers.CToString(vtoc_name); // 108/180
|
||||
vtoc.slices = BitConverter.ToUInt16(unix_dl_sector, 116 + vtocoffset); // 116/188
|
||||
vtoc.unknown = BitConverter.ToUInt16(unix_dl_sector, 118 + vtocoffset); // 118/190
|
||||
|
||||
// TODO: What if number of slices overlaps sector (>23)?
|
||||
for(int j = 0; j < vtoc.slices; j++)
|
||||
{
|
||||
UNIXVTOCEntry vtoc_ent = new UNIXVTOCEntry();
|
||||
|
||||
vtoc_ent.tag = (UNIX_TAG)BitConverter.ToUInt16(unix_dl_sector, 160 + vtocoffset + j * 12 + 0); // 160/232 + j*12
|
||||
vtoc_ent.flags = BitConverter.ToUInt16(unix_dl_sector, 160 + vtocoffset + j * 12 + 2); // 162/234 + j*12
|
||||
vtoc_ent.start = BitConverter.ToUInt32(unix_dl_sector, 160 + vtocoffset + j * 12 + 6); // 166/238 + j*12
|
||||
vtoc_ent.length = BitConverter.ToUInt32(unix_dl_sector, 160 + vtocoffset + j * 12 + 10); // 170/242 + j*12
|
||||
|
||||
if((vtoc_ent.flags & 0x200) == 0x200 && vtoc_ent.tag != UNIX_TAG.EMPTY && vtoc_ent.tag != UNIX_TAG.WHOLE)
|
||||
{
|
||||
Partition part = new Partition();
|
||||
part.PartitionStartSector = vtoc_ent.start;
|
||||
part.PartitionSectors = vtoc_ent.length;
|
||||
part.PartitionStart = vtoc_ent.start * dl.bps;
|
||||
part.PartitionLength = vtoc_ent.length * dl.bps;
|
||||
part.PartitionSequence = counter;
|
||||
part.PartitionType = string.Format("UNIX: {0}", decodeUNIXTAG(vtoc_ent.tag, isNewDL));
|
||||
|
||||
string info = "";
|
||||
|
||||
if((vtoc_ent.flags & 0x01) == 0x01)
|
||||
info += " (do not mount)";
|
||||
if((vtoc_ent.flags & 0x10) == 0x10)
|
||||
info += " (do not mount)";
|
||||
|
||||
part.PartitionDescription = "UNIX slice" + info + ".";
|
||||
|
||||
partitions.Add(part);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Same as Solaris VTOC
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct UNIXDiskLabel
|
||||
{
|
||||
/// <summary>Drive type, seems always 0</summary>
|
||||
public uint type;
|
||||
/// <summary>UNIXDiskLabel_MAGIC</summary>
|
||||
public uint magic;
|
||||
/// <summary>Only seen 1</summary>
|
||||
public uint version;
|
||||
/// <summary>12 bytes, serial number of the device</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||
public string serial;
|
||||
/// <summary>data cylinders per device</summary>
|
||||
public uint cyls;
|
||||
/// <summary>data tracks per cylinder</summary>
|
||||
public uint trks;
|
||||
/// <summary>data sectors per track</summary>
|
||||
public uint secs;
|
||||
/// <summary>data bytes per sector</summary>
|
||||
public uint bps;
|
||||
/// <summary>first sector of this partition</summary>
|
||||
public uint start;
|
||||
/// <summary>48 bytes</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
|
||||
public byte[] unknown1;
|
||||
/// <summary>byte offset of alternate table</summary>
|
||||
public uint alt_tbl;
|
||||
/// <summary>byte length of alternate table</summary>
|
||||
public uint alt_len;
|
||||
// From onward here, is not on old version
|
||||
/// <summary>physical cylinders per device</summary>
|
||||
public uint phys_cyl;
|
||||
/// <summary>physical tracks per cylinder</summary>
|
||||
public uint phys_trk;
|
||||
/// <summary>physical sectors per track</summary>
|
||||
public uint phys_sec;
|
||||
/// <summary>physical bytes per sector</summary>
|
||||
public uint phys_bytes;
|
||||
/// <summary></summary>
|
||||
public uint unknown2;
|
||||
/// <summary></summary>
|
||||
public uint unknown3;
|
||||
/// <summary>32bytes</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||
public byte[] pad;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct UNIXVTOC
|
||||
{
|
||||
/// <summary>UNIXVTOC_MAGIC</summary>
|
||||
public uint magic;
|
||||
/// <summary>1</summary>
|
||||
public uint version;
|
||||
/// <summary>8 bytes</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public string name;
|
||||
/// <summary># of slices</summary>
|
||||
public ushort slices;
|
||||
/// <summary></summary>
|
||||
public ushort unknown;
|
||||
/// <summary>40 bytes</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
|
||||
public byte[] reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct UNIXVTOCEntry
|
||||
{
|
||||
/// <summary>TAG</summary>
|
||||
public UNIX_TAG tag;
|
||||
public ushort flags;
|
||||
/// <summary>Flags (see below)</summary>
|
||||
public uint start;
|
||||
/// <summary>Start sector</summary>
|
||||
public uint length;
|
||||
/// <summary>Length of slice in sectors</summary>
|
||||
}
|
||||
|
||||
public enum UNIX_TAG : ushort
|
||||
{
|
||||
/// <summary>empty</summary>
|
||||
EMPTY = 0x0000,
|
||||
/// <summary>boot</summary>
|
||||
BOOT = 0x0001,
|
||||
/// <summary>root</summary>
|
||||
ROOT = 0x0002,
|
||||
/// <summary>swap</summary>
|
||||
SWAP = 0x0003,
|
||||
/// <summary>/usr</summary>
|
||||
USER = 0x0004,
|
||||
/// <summary>whole disk</summary>
|
||||
WHOLE = 0x0005,
|
||||
/// <summary>stand partition ??</summary>
|
||||
STAND = 0x0006,
|
||||
/// <summary>alternate sector space</summary>
|
||||
ALT_S = 0x0006,
|
||||
/// <summary>/var</summary>
|
||||
VAR = 0x0007,
|
||||
/// <summary>non UNIX</summary>
|
||||
OTHER = 0x0007,
|
||||
/// <summary>/home</summary>
|
||||
HOME = 0x0008,
|
||||
/// <summary>alternate track space</summary>
|
||||
ALT_T = 0x0008,
|
||||
/// <summary>alternate sector track</summary>
|
||||
ALT_ST = 0x0009,
|
||||
/// <summary>stand partition ??</summary>
|
||||
NEW_STAND = 0x0009,
|
||||
/// <summary>cache</summary>
|
||||
CACHE = 0x000A,
|
||||
/// <summary>/var</summary>
|
||||
NEW_VAR = 0x000A,
|
||||
/// <summary>reserved</summary>
|
||||
RESERVED = 0x000B,
|
||||
/// <summary>/home</summary>
|
||||
NEW_HOME = 0x000B,
|
||||
/// <summary>dump partition</summary>
|
||||
DUMP = 0x000C,
|
||||
/// <summary>alternate sector track</summary>
|
||||
NEW_ALT_ST = 0x000D,
|
||||
/// <summary>volume mgt public partition</summary>
|
||||
VM_PUBLIC = 0x000E,
|
||||
/// <summary>volume mgt private partition</summary>
|
||||
VM_PRIVATE = 0x000F
|
||||
}
|
||||
|
||||
public static string decodeUNIXTAG(UNIX_TAG type, bool isNew)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case UNIX_TAG.EMPTY:
|
||||
return "Unused";
|
||||
case UNIX_TAG.BOOT:
|
||||
return "Boot";
|
||||
case UNIX_TAG.ROOT:
|
||||
return "/";
|
||||
case UNIX_TAG.SWAP:
|
||||
return "Swap";
|
||||
case UNIX_TAG.USER:
|
||||
return "/usr";
|
||||
case UNIX_TAG.WHOLE:
|
||||
return "Whole disk";
|
||||
case UNIX_TAG.STAND:
|
||||
return isNew ? "Stand" : "Alternate sector space";
|
||||
case UNIX_TAG.VAR:
|
||||
return isNew ? "/var" : "non UNIX";
|
||||
case UNIX_TAG.HOME:
|
||||
return isNew ? "/home" : "Alternate track space";
|
||||
case UNIX_TAG.ALT_ST:
|
||||
return isNew ? "Alternate sector track" : "Stand";
|
||||
case UNIX_TAG.CACHE:
|
||||
return isNew ? "Cache" : "/var";
|
||||
case UNIX_TAG.RESERVED:
|
||||
return isNew ? "Reserved" : "/home";
|
||||
case UNIX_TAG.DUMP:
|
||||
return "dump";
|
||||
case UNIX_TAG.NEW_ALT_ST:
|
||||
return "Alternate sector track";
|
||||
case UNIX_TAG.VM_PUBLIC:
|
||||
return "volume mgt public partition";
|
||||
case UNIX_TAG.VM_PRIVATE:
|
||||
return "volume mgt private partition";
|
||||
default:
|
||||
return string.Format("Unknown TAG: 0x{0:X4}", type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,14 @@ Supported partitioning schemes
|
||||
* Atari AHDI and ICDPro
|
||||
* Sun disklabel
|
||||
* EFI GUID Partition Table (GPT)
|
||||
* Acorn Linux and RISCiX partitions
|
||||
* BSD disklabels
|
||||
* DragonFly BSD 64-bit disklabel
|
||||
* DEC disklabels
|
||||
* NEC PC9800 partitions
|
||||
* SGI volume headers
|
||||
* Rio Karma partitions
|
||||
* UNIX VTOC and disklabel
|
||||
|
||||
Supported file systems for read-only operations
|
||||
===============================================
|
||||
|
||||
3
TODO
3
TODO
@@ -38,10 +38,7 @@ Filesystem plugins:
|
||||
--- Add support for ECMA-67
|
||||
|
||||
Partitioning scheme plugins:
|
||||
--- Add support for Acorn partitions
|
||||
--- Add support for AIX partitions
|
||||
--- Add support for SGI partitions
|
||||
--- Add support for Ultrix partitions
|
||||
|
||||
Teledisk plugin:
|
||||
--- Add support for "advanced compression"
|
||||
|
||||
Reference in New Issue
Block a user