mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Use marshalling.
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
|
|
||||||
@@ -113,12 +114,12 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
byte[] sb_sector = imagePlugin.ReadSector(0 + partition.Start);
|
byte[] sb_sector = imagePlugin.ReadSector(0 + partition.Start);
|
||||||
|
|
||||||
BigEndianBitConverter.IsLittleEndian = true; // Default for little-endian
|
bool littleEndian = true;
|
||||||
|
|
||||||
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
|
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // Magic is at offset
|
||||||
{
|
{
|
||||||
BigEndianBitConverter.IsLittleEndian &= besb.magic1 != BEFS_CIGAM1;
|
littleEndian = besb.magic1 == BEFS_CIGAM1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -127,7 +128,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
||||||
{
|
{
|
||||||
BigEndianBitConverter.IsLittleEndian &= besb.magic1 != BEFS_CIGAM1;
|
littleEndian = besb.magic1 == BEFS_CIGAM1;
|
||||||
}
|
}
|
||||||
else if(sb_sector.Length >= 0x400)
|
else if(sb_sector.Length >= 0x400)
|
||||||
{
|
{
|
||||||
@@ -136,7 +137,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
|
||||||
{
|
{
|
||||||
BigEndianBitConverter.IsLittleEndian &= besb.magic1 != BEFS_CIGAM1;
|
littleEndian = besb.magic1 == BEFS_CIGAM1;
|
||||||
sb_sector = new byte[0x200];
|
sb_sector = new byte[0x200];
|
||||||
Array.Copy(temp, 0x200, sb_sector, 0, 0x200);
|
Array.Copy(temp, 0x200, sb_sector, 0, 0x200);
|
||||||
}
|
}
|
||||||
@@ -147,34 +148,16 @@ namespace DiscImageChef.Filesystems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.Copy(sb_sector, 0x000, name_bytes, 0, 0x20);
|
if(littleEndian)
|
||||||
besb.name = StringHandlers.CToString(name_bytes, CurrentEncoding);
|
{
|
||||||
besb.magic1 = BigEndianBitConverter.ToUInt32(sb_sector, 0x20);
|
GCHandle handle = GCHandle.Alloc(sb_sector, GCHandleType.Pinned);
|
||||||
besb.fs_byte_order = BigEndianBitConverter.ToUInt32(sb_sector, 0x24);
|
besb = (BeSuperBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(BeSuperBlock));
|
||||||
besb.block_size = BigEndianBitConverter.ToUInt32(sb_sector, 0x28);
|
handle.Free();
|
||||||
besb.block_shift = BigEndianBitConverter.ToUInt32(sb_sector, 0x2C);
|
}
|
||||||
besb.num_blocks = BigEndianBitConverter.ToInt64(sb_sector, 0x30);
|
else
|
||||||
besb.used_blocks = BigEndianBitConverter.ToInt64(sb_sector, 0x38);
|
besb = BigEndianMarshal.ByteArrayToStructureBigEndian<BeSuperBlock>(sb_sector);
|
||||||
besb.inode_size = BigEndianBitConverter.ToInt32(sb_sector, 0x40);
|
|
||||||
besb.magic2 = BigEndianBitConverter.ToUInt32(sb_sector, 0x44);
|
|
||||||
besb.blocks_per_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x48);
|
|
||||||
besb.ag_shift = BigEndianBitConverter.ToInt32(sb_sector, 0x4C);
|
|
||||||
besb.num_ags = BigEndianBitConverter.ToInt32(sb_sector, 0x50);
|
|
||||||
besb.flags = BigEndianBitConverter.ToUInt32(sb_sector, 0x54);
|
|
||||||
besb.log_blocks_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x58);
|
|
||||||
besb.log_blocks_start = BigEndianBitConverter.ToUInt16(sb_sector, 0x5C);
|
|
||||||
besb.log_blocks_len = BigEndianBitConverter.ToUInt16(sb_sector, 0x5E);
|
|
||||||
besb.log_start = BigEndianBitConverter.ToInt64(sb_sector, 0x60);
|
|
||||||
besb.log_end = BigEndianBitConverter.ToInt64(sb_sector, 0x68);
|
|
||||||
besb.magic3 = BigEndianBitConverter.ToUInt32(sb_sector, 0x70);
|
|
||||||
besb.root_dir_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x74);
|
|
||||||
besb.root_dir_start = BigEndianBitConverter.ToUInt16(sb_sector, 0x78);
|
|
||||||
besb.root_dir_len = BigEndianBitConverter.ToUInt16(sb_sector, 0x7A);
|
|
||||||
besb.indices_ag = BigEndianBitConverter.ToInt32(sb_sector, 0x7C);
|
|
||||||
besb.indices_start = BigEndianBitConverter.ToUInt16(sb_sector, 0x80);
|
|
||||||
besb.indices_len = BigEndianBitConverter.ToUInt16(sb_sector, 0x82);
|
|
||||||
|
|
||||||
if(!BigEndianBitConverter.IsLittleEndian) // Big-endian filesystem
|
if(littleEndian) // Big-endian filesystem
|
||||||
sb.AppendLine("Little-endian BeFS");
|
sb.AppendLine("Little-endian BeFS");
|
||||||
else
|
else
|
||||||
sb.AppendLine("Big-endian BeFS");
|
sb.AppendLine("Big-endian BeFS");
|
||||||
@@ -207,7 +190,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
else
|
else
|
||||||
sb.AppendFormat("Unknown flags: {0:X8}", besb.flags).AppendLine();
|
sb.AppendFormat("Unknown flags: {0:X8}", besb.flags).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Volume name: {0}", besb.name).AppendLine();
|
sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(besb.name, CurrentEncoding)).AppendLine();
|
||||||
sb.AppendFormat("{0} bytes per block", besb.block_size).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} 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} used blocks ({1} bytes)", besb.used_blocks, besb.used_blocks * besb.block_size).AppendLine();
|
||||||
@@ -231,16 +214,18 @@ namespace DiscImageChef.Filesystems
|
|||||||
xmlFSType.FreeClusters = besb.num_blocks - besb.used_blocks;
|
xmlFSType.FreeClusters = besb.num_blocks - besb.used_blocks;
|
||||||
xmlFSType.FreeClustersSpecified = true;
|
xmlFSType.FreeClustersSpecified = true;
|
||||||
xmlFSType.Type = "BeFS";
|
xmlFSType.Type = "BeFS";
|
||||||
xmlFSType.VolumeName = besb.name;
|
xmlFSType.VolumeName = StringHandlers.CToString(besb.name, CurrentEncoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Be superblock
|
/// Be superblock
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct BeSuperBlock
|
struct BeSuperBlock
|
||||||
{
|
{
|
||||||
/// <summary>0x000, Volume name, 32 bytes</summary>
|
/// <summary>0x000, Volume name, 32 bytes</summary>
|
||||||
public string name;
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] name;
|
||||||
/// <summary>0x020, "BFS1", 0x42465331</summary>
|
/// <summary>0x020, "BFS1", 0x42465331</summary>
|
||||||
public uint magic1;
|
public uint magic1;
|
||||||
/// <summary>0x024, "BIGE", 0x42494745</summary>
|
/// <summary>0x024, "BIGE", 0x42494745</summary>
|
||||||
|
|||||||
@@ -144,7 +144,6 @@ namespace DiscImageChef.Filesystems
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("Crash");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
|
|
||||||
@@ -113,11 +114,13 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
xmlFSType = new Schemas.FileSystemType();
|
xmlFSType = new Schemas.FileSystemType();
|
||||||
|
|
||||||
|
bool littleEndian = true;
|
||||||
|
|
||||||
if(magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
if(magic == MINIX3_MAGIC || magic == MINIX3_CIGAM)
|
||||||
{
|
{
|
||||||
filenamesize = 60;
|
filenamesize = 60;
|
||||||
minixVersion = "Minix V3 filesystem";
|
minixVersion = "Minix V3 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = magic != MINIX3_CIGAM;
|
littleEndian = magic != MINIX3_CIGAM;
|
||||||
|
|
||||||
xmlFSType.Type = "Minix V3";
|
xmlFSType.Type = "Minix V3";
|
||||||
|
|
||||||
@@ -132,49 +135,49 @@ namespace DiscImageChef.Filesystems
|
|||||||
case MINIX_MAGIC:
|
case MINIX_MAGIC:
|
||||||
filenamesize = 14;
|
filenamesize = 14;
|
||||||
minixVersion = "Minix V1 filesystem";
|
minixVersion = "Minix V1 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = true;
|
littleEndian = true;
|
||||||
xmlFSType.Type = "Minix V1";
|
xmlFSType.Type = "Minix V1";
|
||||||
break;
|
break;
|
||||||
case MINIX_MAGIC2:
|
case MINIX_MAGIC2:
|
||||||
filenamesize = 30;
|
filenamesize = 30;
|
||||||
minixVersion = "Minix V1 filesystem";
|
minixVersion = "Minix V1 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = true;
|
littleEndian = true;
|
||||||
xmlFSType.Type = "Minix V1";
|
xmlFSType.Type = "Minix V1";
|
||||||
break;
|
break;
|
||||||
case MINIX2_MAGIC:
|
case MINIX2_MAGIC:
|
||||||
filenamesize = 14;
|
filenamesize = 14;
|
||||||
minixVersion = "Minix V2 filesystem";
|
minixVersion = "Minix V2 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = true;
|
littleEndian = true;
|
||||||
xmlFSType.Type = "Minix V2";
|
xmlFSType.Type = "Minix V2";
|
||||||
break;
|
break;
|
||||||
case MINIX2_MAGIC2:
|
case MINIX2_MAGIC2:
|
||||||
filenamesize = 30;
|
filenamesize = 30;
|
||||||
minixVersion = "Minix V2 filesystem";
|
minixVersion = "Minix V2 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = true;
|
littleEndian = true;
|
||||||
xmlFSType.Type = "Minix V2";
|
xmlFSType.Type = "Minix V2";
|
||||||
break;
|
break;
|
||||||
case MINIX_CIGAM:
|
case MINIX_CIGAM:
|
||||||
filenamesize = 14;
|
filenamesize = 14;
|
||||||
minixVersion = "Minix V1 filesystem";
|
minixVersion = "Minix V1 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = false;
|
littleEndian = false;
|
||||||
xmlFSType.Type = "Minix V1";
|
xmlFSType.Type = "Minix V1";
|
||||||
break;
|
break;
|
||||||
case MINIX_CIGAM2:
|
case MINIX_CIGAM2:
|
||||||
filenamesize = 30;
|
filenamesize = 30;
|
||||||
minixVersion = "Minix V1 filesystem";
|
minixVersion = "Minix V1 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = false;
|
littleEndian = false;
|
||||||
xmlFSType.Type = "Minix V1";
|
xmlFSType.Type = "Minix V1";
|
||||||
break;
|
break;
|
||||||
case MINIX2_CIGAM:
|
case MINIX2_CIGAM:
|
||||||
filenamesize = 14;
|
filenamesize = 14;
|
||||||
minixVersion = "Minix V2 filesystem";
|
minixVersion = "Minix V2 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = false;
|
littleEndian = false;
|
||||||
xmlFSType.Type = "Minix V2";
|
xmlFSType.Type = "Minix V2";
|
||||||
break;
|
break;
|
||||||
case MINIX2_CIGAM2:
|
case MINIX2_CIGAM2:
|
||||||
filenamesize = 30;
|
filenamesize = 30;
|
||||||
minixVersion = "Minix V2 filesystem";
|
minixVersion = "Minix V2 filesystem";
|
||||||
BigEndianBitConverter.IsLittleEndian = false;
|
littleEndian = false;
|
||||||
xmlFSType.Type = "Minix V2";
|
xmlFSType.Type = "Minix V2";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -186,19 +189,14 @@ namespace DiscImageChef.Filesystems
|
|||||||
{
|
{
|
||||||
Minix3SuperBlock mnx_sb = new Minix3SuperBlock();
|
Minix3SuperBlock mnx_sb = new Minix3SuperBlock();
|
||||||
|
|
||||||
mnx_sb.s_ninodes = BigEndianBitConverter.ToUInt32(minix_sb_sector, 0x00);
|
if(littleEndian)
|
||||||
mnx_sb.s_pad0 = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x04);
|
{
|
||||||
mnx_sb.s_imap_blocks = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x06);
|
GCHandle handle = GCHandle.Alloc(minix_sb_sector, GCHandleType.Pinned);
|
||||||
mnx_sb.s_zmap_blocks = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x08);
|
mnx_sb = (Minix3SuperBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Minix3SuperBlock));
|
||||||
mnx_sb.s_firstdatazone = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x0A);
|
handle.Free();
|
||||||
mnx_sb.s_log_zone_size = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x0C);
|
}
|
||||||
mnx_sb.s_pad1 = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x0E);
|
else
|
||||||
mnx_sb.s_max_size = BigEndianBitConverter.ToUInt32(minix_sb_sector, 0x10);
|
mnx_sb = BigEndianMarshal.ByteArrayToStructureBigEndian<Minix3SuperBlock>(minix_sb_sector);
|
||||||
mnx_sb.s_zones = BigEndianBitConverter.ToUInt32(minix_sb_sector, 0x14);
|
|
||||||
mnx_sb.s_magic = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x18);
|
|
||||||
mnx_sb.s_pad2 = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x1A);
|
|
||||||
mnx_sb.s_blocksize = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x1C);
|
|
||||||
mnx_sb.s_disk_version = minix_sb_sector[0x1E];
|
|
||||||
|
|
||||||
sb.AppendLine(minixVersion);
|
sb.AppendLine(minixVersion);
|
||||||
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
||||||
@@ -219,16 +217,14 @@ namespace DiscImageChef.Filesystems
|
|||||||
{
|
{
|
||||||
MinixSuperBlock mnx_sb = new MinixSuperBlock();
|
MinixSuperBlock mnx_sb = new MinixSuperBlock();
|
||||||
|
|
||||||
mnx_sb.s_ninodes = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x00);
|
if(littleEndian)
|
||||||
mnx_sb.s_nzones = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x02);
|
{
|
||||||
mnx_sb.s_imap_blocks = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x04);
|
GCHandle handle = GCHandle.Alloc(minix_sb_sector, GCHandleType.Pinned);
|
||||||
mnx_sb.s_zmap_blocks = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x06);
|
mnx_sb = (MinixSuperBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MinixSuperBlock));
|
||||||
mnx_sb.s_firstdatazone = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x08);
|
handle.Free();
|
||||||
mnx_sb.s_log_zone_size = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x0A);
|
}
|
||||||
mnx_sb.s_max_size = BigEndianBitConverter.ToUInt32(minix_sb_sector, 0x0C);
|
else
|
||||||
mnx_sb.s_magic = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x10);
|
mnx_sb = BigEndianMarshal.ByteArrayToStructureBigEndian<MinixSuperBlock>(minix_sb_sector);
|
||||||
mnx_sb.s_state = BigEndianBitConverter.ToUInt16(minix_sb_sector, 0x12);
|
|
||||||
mnx_sb.s_zones = BigEndianBitConverter.ToUInt32(minix_sb_sector, 0x14);
|
|
||||||
|
|
||||||
sb.AppendLine(minixVersion);
|
sb.AppendLine(minixVersion);
|
||||||
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
sb.AppendFormat("{0} chars in filename", filenamesize).AppendLine();
|
||||||
@@ -252,6 +248,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Superblock for Minix V1 and V2 filesystems
|
/// Superblock for Minix V1 and V2 filesystems
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct MinixSuperBlock
|
public struct MinixSuperBlock
|
||||||
{
|
{
|
||||||
/// <summary>0x00, inodes on volume</summary>
|
/// <summary>0x00, inodes on volume</summary>
|
||||||
@@ -279,6 +276,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Superblock for Minix V3 filesystems
|
/// Superblock for Minix V3 filesystems
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct Minix3SuperBlock
|
public struct Minix3SuperBlock
|
||||||
{
|
{
|
||||||
/// <summary>0x00, inodes on volume</summary>
|
/// <summary>0x00, inodes on volume</summary>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
|
|
||||||
@@ -93,56 +94,12 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
byte[] hb_sector = imagePlugin.ReadSector(1 + partition.Start);
|
byte[] hb_sector = imagePlugin.ReadSector(1 + partition.Start);
|
||||||
|
|
||||||
homeblock.homelbn = BitConverter.ToUInt32(hb_sector, 0x000);
|
GCHandle handle = GCHandle.Alloc(hb_sector, GCHandleType.Pinned);
|
||||||
homeblock.alhomelbn = BitConverter.ToUInt32(hb_sector, 0x004);
|
homeblock = (ODSHomeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(ODSHomeBlock));
|
||||||
homeblock.altidxlbn = BitConverter.ToUInt32(hb_sector, 0x008);
|
handle.Free();
|
||||||
homeblock.struclev = BitConverter.ToUInt16(hb_sector, 0x00C);
|
|
||||||
homeblock.cluster = BitConverter.ToUInt16(hb_sector, 0x00E);
|
|
||||||
homeblock.homevbn = BitConverter.ToUInt16(hb_sector, 0x010);
|
|
||||||
homeblock.alhomevbn = BitConverter.ToUInt16(hb_sector, 0x012);
|
|
||||||
homeblock.altidxvbn = BitConverter.ToUInt16(hb_sector, 0x014);
|
|
||||||
homeblock.ibmapvbn = BitConverter.ToUInt16(hb_sector, 0x016);
|
|
||||||
homeblock.ibmaplbn = BitConverter.ToUInt32(hb_sector, 0x018);
|
|
||||||
homeblock.maxfiles = BitConverter.ToUInt32(hb_sector, 0x01C);
|
|
||||||
homeblock.ibmapsize = BitConverter.ToUInt16(hb_sector, 0x020);
|
|
||||||
homeblock.resfiles = BitConverter.ToUInt16(hb_sector, 0x022);
|
|
||||||
homeblock.devtype = BitConverter.ToUInt16(hb_sector, 0x024);
|
|
||||||
homeblock.rvn = BitConverter.ToUInt16(hb_sector, 0x026);
|
|
||||||
homeblock.setcount = BitConverter.ToUInt16(hb_sector, 0x028);
|
|
||||||
homeblock.volchar = BitConverter.ToUInt16(hb_sector, 0x02A);
|
|
||||||
homeblock.volowner = BitConverter.ToUInt32(hb_sector, 0x02C);
|
|
||||||
homeblock.sec_mask = BitConverter.ToUInt32(hb_sector, 0x030);
|
|
||||||
homeblock.protect = BitConverter.ToUInt16(hb_sector, 0x034);
|
|
||||||
homeblock.fileprot = BitConverter.ToUInt16(hb_sector, 0x036);
|
|
||||||
homeblock.recprot = BitConverter.ToUInt16(hb_sector, 0x038);
|
|
||||||
homeblock.checksum1 = BitConverter.ToUInt16(hb_sector, 0x03A);
|
|
||||||
homeblock.credate = BitConverter.ToUInt64(hb_sector, 0x03C);
|
|
||||||
homeblock.window = hb_sector[0x044];
|
|
||||||
homeblock.lru_lim = hb_sector[0x045];
|
|
||||||
homeblock.extend = BitConverter.ToUInt16(hb_sector, 0x046);
|
|
||||||
homeblock.retainmin = BitConverter.ToUInt64(hb_sector, 0x048);
|
|
||||||
homeblock.retainmax = BitConverter.ToUInt64(hb_sector, 0x050);
|
|
||||||
homeblock.revdate = BitConverter.ToUInt64(hb_sector, 0x058);
|
|
||||||
Array.Copy(hb_sector, 0x060, homeblock.min_class, 0, 20);
|
|
||||||
Array.Copy(hb_sector, 0x074, homeblock.max_class, 0, 20);
|
|
||||||
homeblock.filetab_fid1 = BitConverter.ToUInt16(hb_sector, 0x088);
|
|
||||||
homeblock.filetab_fid2 = BitConverter.ToUInt16(hb_sector, 0x08A);
|
|
||||||
homeblock.filetab_fid3 = BitConverter.ToUInt16(hb_sector, 0x08C);
|
|
||||||
homeblock.lowstruclev = BitConverter.ToUInt16(hb_sector, 0x08E);
|
|
||||||
homeblock.highstruclev = BitConverter.ToUInt16(hb_sector, 0x090);
|
|
||||||
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, CurrentEncoding);
|
|
||||||
Array.Copy(hb_sector, 0x1D8, temp_string, 0, 12);
|
|
||||||
homeblock.volname = StringHandlers.CToString(temp_string, CurrentEncoding);
|
|
||||||
Array.Copy(hb_sector, 0x1E4, temp_string, 0, 12);
|
|
||||||
homeblock.ownername = StringHandlers.CToString(temp_string, CurrentEncoding);
|
|
||||||
Array.Copy(hb_sector, 0x1F0, temp_string, 0, 12);
|
|
||||||
homeblock.format = StringHandlers.CToString(temp_string, CurrentEncoding);
|
|
||||||
homeblock.checksum2 = BitConverter.ToUInt16(hb_sector, 0x1FE);
|
|
||||||
|
|
||||||
if((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 || homeblock.format != "DECFILE11B ")
|
|
||||||
|
if((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 || StringHandlers.CToString(homeblock.format) != "DECFILE11B ")
|
||||||
sb.AppendLine("The following information may be incorrect for this volume.");
|
sb.AppendLine("The following information may be incorrect for this volume.");
|
||||||
if(homeblock.resfiles < 5 || homeblock.devtype != 0)
|
if(homeblock.resfiles < 5 || homeblock.devtype != 0)
|
||||||
sb.AppendLine("This volume may be corrupted.");
|
sb.AppendLine("This volume may be corrupted.");
|
||||||
@@ -159,7 +116,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
sb.AppendFormat("Backup INDEXF.SYS;1 is in sector {0} (cluster {1})", homeblock.altidxlbn, homeblock.altidxvbn).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} maximum files on the volume", homeblock.maxfiles).AppendLine();
|
||||||
sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();
|
sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();
|
||||||
if(homeblock.rvn > 0 && homeblock.setcount > 0 && homeblock.strucname != " ")
|
if(homeblock.rvn > 0 && homeblock.setcount > 0 && StringHandlers.CToString(homeblock.strucname) != " ")
|
||||||
sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount, homeblock.strucname).AppendLine();
|
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 owner is \"{0}\" (ID 0x{1:X8})", homeblock.ownername, homeblock.volowner).AppendLine();
|
||||||
sb.AppendFormat("Volume label: \"{0}\"", homeblock.volname).AppendLine();
|
sb.AppendFormat("Volume label: \"{0}\"", homeblock.volname).AppendLine();
|
||||||
@@ -262,12 +219,14 @@ namespace DiscImageChef.Filesystems
|
|||||||
sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine();
|
sb.AppendFormat("File protection: 0x{0:X4}", homeblock.fileprot).AppendLine();
|
||||||
sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine();
|
sb.AppendFormat("Record protection: 0x{0:X4}", homeblock.recprot).AppendLine();
|
||||||
|
|
||||||
xmlFSType = new Schemas.FileSystemType();
|
xmlFSType = new Schemas.FileSystemType
|
||||||
xmlFSType.Type = "FILES-11";
|
{
|
||||||
xmlFSType.ClusterSize = homeblock.cluster * 512;
|
Type = "FILES-11",
|
||||||
xmlFSType.Clusters = homeblock.cluster;
|
ClusterSize = homeblock.cluster * 512,
|
||||||
xmlFSType.VolumeName = homeblock.volname;
|
Clusters = homeblock.cluster,
|
||||||
xmlFSType.VolumeSerial = string.Format("{0:X8}", homeblock.serialnum);
|
VolumeName = StringHandlers.CToString(homeblock.volname, CurrentEncoding),
|
||||||
|
VolumeSerial = string.Format("{0:X8}", homeblock.serialnum)
|
||||||
|
};
|
||||||
if(homeblock.credate > 0)
|
if(homeblock.credate > 0)
|
||||||
{
|
{
|
||||||
xmlFSType.CreationDate = DateHandlers.VMSToDateTime(homeblock.credate);
|
xmlFSType.CreationDate = DateHandlers.VMSToDateTime(homeblock.credate);
|
||||||
@@ -282,6 +241,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
information = sb.ToString();
|
information = sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct ODSHomeBlock
|
struct ODSHomeBlock
|
||||||
{
|
{
|
||||||
/// <summary>0x000, LBN of THIS home block</summary>
|
/// <summary>0x000, LBN of THIS home block</summary>
|
||||||
@@ -345,8 +305,10 @@ namespace DiscImageChef.Filesystems
|
|||||||
/// <summary>0x058, Last modification date</summary>
|
/// <summary>0x058, Last modification date</summary>
|
||||||
public ulong revdate;
|
public ulong revdate;
|
||||||
/// <summary>0x060, Minimum security class, 20 bytes</summary>
|
/// <summary>0x060, Minimum security class, 20 bytes</summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
|
||||||
public byte[] min_class;
|
public byte[] min_class;
|
||||||
/// <summary>0x074, Maximum security class, 20 bytes</summary>
|
/// <summary>0x074, Maximum security class, 20 bytes</summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
|
||||||
public byte[] max_class;
|
public byte[] max_class;
|
||||||
/// <summary>0x088, File lookup table FID</summary>
|
/// <summary>0x088, File lookup table FID</summary>
|
||||||
public ushort filetab_fid1;
|
public ushort filetab_fid1;
|
||||||
@@ -361,17 +323,22 @@ namespace DiscImageChef.Filesystems
|
|||||||
/// <summary>0x092, Volume copy date (??)</summary>
|
/// <summary>0x092, Volume copy date (??)</summary>
|
||||||
public ulong copydate;
|
public ulong copydate;
|
||||||
/// <summary>0x09A, 302 bytes</summary>
|
/// <summary>0x09A, 302 bytes</summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 302)]
|
||||||
public byte[] reserved1;
|
public byte[] reserved1;
|
||||||
/// <summary>0x1C8, Physical drive serial number</summary>
|
/// <summary>0x1C8, Physical drive serial number</summary>
|
||||||
public uint serialnum;
|
public uint serialnum;
|
||||||
/// <summary>0x1CC, Name of the volume set, 12 bytes</summary>
|
/// <summary>0x1CC, Name of the volume set, 12 bytes</summary>
|
||||||
public string strucname;
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||||
|
public byte[] strucname;
|
||||||
/// <summary>0x1D8, Volume label, 12 bytes</summary>
|
/// <summary>0x1D8, Volume label, 12 bytes</summary>
|
||||||
public string volname;
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||||
|
public byte[] volname;
|
||||||
/// <summary>0x1E4, Name of the volume owner, 12 bytes</summary>
|
/// <summary>0x1E4, Name of the volume owner, 12 bytes</summary>
|
||||||
public string ownername;
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||||
|
public byte[] ownername;
|
||||||
/// <summary>0x1F0, ODS-2 defines it as "DECFILE11B", 12 bytes</summary>
|
/// <summary>0x1F0, ODS-2 defines it as "DECFILE11B", 12 bytes</summary>
|
||||||
public string format;
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
|
||||||
|
public byte[] format;
|
||||||
/// <summary>0x1FC, Reserved</summary>
|
/// <summary>0x1FC, Reserved</summary>
|
||||||
public ushort reserved2;
|
public ushort reserved2;
|
||||||
/// <summary>0x1FE, Checksum of preceding 255 words (16 bit units)</summary>
|
/// <summary>0x1FE, Checksum of preceding 255 words (16 bit units)</summary>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
|
|
||||||
@@ -82,40 +83,21 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
byte[] sb_sector = imagePlugin.ReadSector(0 + partition.Start);
|
byte[] sb_sector = imagePlugin.ReadSector(0 + partition.Start);
|
||||||
|
|
||||||
OperaSuperBlock sb = new OperaSuperBlock();
|
OperaSuperBlock sb = BigEndianMarshal.ByteArrayToStructureBigEndian<OperaSuperBlock>(sb_sector);
|
||||||
byte[] cString = new byte[32];
|
byte[] cString = new byte[32];
|
||||||
sb.sync_bytes = new byte[5];
|
sb.sync_bytes = new byte[5];
|
||||||
|
|
||||||
sb.record_type = sb_sector[0x000];
|
|
||||||
Array.Copy(sb_sector, 0x001, sb.sync_bytes, 0, 5);
|
|
||||||
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);
|
|
||||||
Array.Copy(sb_sector, 0x028, cString, 0, 32);
|
|
||||||
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);
|
|
||||||
sb.root_dirid = BigEndianBitConverter.ToInt32(sb_sector, 0x054);
|
|
||||||
sb.rootdir_blocks = BigEndianBitConverter.ToInt32(sb_sector, 0x058);
|
|
||||||
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;
|
return;
|
||||||
if(Encoding.ASCII.GetString(sb.sync_bytes) != "ZZZZZ")
|
if(Encoding.ASCII.GetString(sb.sync_bytes) != "ZZZZZ")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(sb.volume_comment.Length == 0)
|
|
||||||
sb.volume_comment = "Not set.";
|
|
||||||
|
|
||||||
if(sb.volume_label.Length == 0)
|
|
||||||
sb.volume_label = "Not set.";
|
|
||||||
|
|
||||||
SuperBlockMetadata.AppendFormat("Opera filesystem disc.").AppendLine();
|
SuperBlockMetadata.AppendFormat("Opera filesystem disc.").AppendLine();
|
||||||
SuperBlockMetadata.AppendFormat("Volume label: {0}", sb.volume_label).AppendLine();
|
if(!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_label, CurrentEncoding)))
|
||||||
SuperBlockMetadata.AppendFormat("Volume comment: {0}", sb.volume_comment).AppendLine();
|
SuperBlockMetadata.AppendFormat("Volume label: {0}", StringHandlers.CToString(sb.volume_label, CurrentEncoding)).AppendLine();
|
||||||
|
if(!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_comment, CurrentEncoding)))
|
||||||
|
SuperBlockMetadata.AppendFormat("Volume comment: {0}", StringHandlers.CToString(sb.volume_comment, CurrentEncoding)).AppendLine();
|
||||||
SuperBlockMetadata.AppendFormat("Volume identifier: 0x{0:X8}", sb.volume_id).AppendLine();
|
SuperBlockMetadata.AppendFormat("Volume identifier: 0x{0:X8}", sb.volume_id).AppendLine();
|
||||||
SuperBlockMetadata.AppendFormat("Block size: {0} bytes", sb.block_size).AppendLine();
|
SuperBlockMetadata.AppendFormat("Block size: {0} bytes", sb.block_size).AppendLine();
|
||||||
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
if(imagePlugin.GetSectorSize() == 2336 || imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
|
||||||
@@ -135,27 +117,33 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
information = SuperBlockMetadata.ToString();
|
information = SuperBlockMetadata.ToString();
|
||||||
|
|
||||||
xmlFSType = new Schemas.FileSystemType();
|
xmlFSType = new Schemas.FileSystemType
|
||||||
xmlFSType.Type = "Opera";
|
{
|
||||||
xmlFSType.VolumeName = sb.volume_label;
|
Type = "Opera",
|
||||||
xmlFSType.ClusterSize = sb.block_size;
|
VolumeName = StringHandlers.CToString(sb.volume_label, CurrentEncoding),
|
||||||
xmlFSType.Clusters = sb.block_count;
|
ClusterSize = sb.block_size,
|
||||||
|
Clusters = sb.block_count
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct OperaSuperBlock
|
struct OperaSuperBlock
|
||||||
{
|
{
|
||||||
/// <summary>0x000, Record type, must be 1</summary>
|
/// <summary>0x000, Record type, must be 1</summary>
|
||||||
public byte record_type;
|
public byte record_type;
|
||||||
/// <summary>0x001, 5 bytes, "ZZZZZ"</summary>
|
/// <summary>0x001, 5 bytes, "ZZZZZ"</summary>
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||||
public byte[] sync_bytes;
|
public byte[] sync_bytes;
|
||||||
/// <summary>0x006, Record version, must be 1</summary>
|
/// <summary>0x006, Record version, must be 1</summary>
|
||||||
public byte record_version;
|
public byte record_version;
|
||||||
/// <summary>0x007, Volume flags</summary>
|
/// <summary>0x007, Volume flags</summary>
|
||||||
public byte volume_flags;
|
public byte volume_flags;
|
||||||
/// <summary>0x008, 32 bytes, volume comment</summary>
|
/// <summary>0x008, 32 bytes, volume comment</summary>
|
||||||
public string volume_comment;
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] volume_comment;
|
||||||
/// <summary>0x028, 32 bytes, volume label</summary>
|
/// <summary>0x028, 32 bytes, volume label</summary>
|
||||||
public string volume_label;
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] volume_label;
|
||||||
/// <summary>0x048, Volume ID</summary>
|
/// <summary>0x048, Volume ID</summary>
|
||||||
public int volume_id;
|
public int volume_id;
|
||||||
/// <summary>0x04C, Block size in bytes</summary>
|
/// <summary>0x04C, Block size in bytes</summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user