2017-07-19 16:31:08 +01:00
|
|
|
|
// /***************************************************************************
|
2020-02-27 12:31:25 +00:00
|
|
|
|
// Aaru Data Preservation Suite
|
2016-07-28 18:13:49 +01:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
//
|
2017-10-08 20:41:54 +01:00
|
|
|
|
// Filename : Info.cs
|
2016-07-28 18:13:49 +01:00
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
|
//
|
2017-12-19 03:50:57 +00:00
|
|
|
|
// Component : ISO9660 filesystem plugin.
|
2016-07-28 18:13:49 +01:00
|
|
|
|
//
|
|
|
|
|
|
// --[ 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/>.
|
|
|
|
|
|
//
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2022-12-03 16:07:10 +00:00
|
|
|
|
// Copyright © 2011-2023 Natalia Portillo
|
2019-07-31 20:19:22 +01:00
|
|
|
|
// In the loving memory of Facunda "Tata" Suárez Domínguez, R.I.P. 2019/07/24
|
2016-07-28 18:13:49 +01:00
|
|
|
|
// ****************************************************************************/
|
2017-12-19 19:33:46 +00:00
|
|
|
|
|
2011-03-03 18:34:33 +00:00
|
|
|
|
using System;
|
2017-10-09 11:25:47 +01:00
|
|
|
|
using System.Collections.Generic;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
using System.Text;
|
2020-02-27 00:33:26 +00:00
|
|
|
|
using Aaru.Checksums;
|
2022-12-15 22:21:07 +00:00
|
|
|
|
using Aaru.CommonTypes.AaruMetadata;
|
2021-09-19 21:16:47 +01:00
|
|
|
|
using Aaru.CommonTypes.Enums;
|
2020-02-27 00:33:26 +00:00
|
|
|
|
using Aaru.CommonTypes.Interfaces;
|
|
|
|
|
|
using Aaru.Console;
|
|
|
|
|
|
using Aaru.Decoders.Sega;
|
|
|
|
|
|
using Aaru.Helpers;
|
2022-12-15 22:21:07 +00:00
|
|
|
|
using Partition = Aaru.CommonTypes.Partition;
|
2015-10-18 22:04:03 +01:00
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
|
namespace Aaru.Filesystems;
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
public sealed partial class ISO9660
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2023-10-03 23:22:08 +01:00
|
|
|
|
#region IReadOnlyFilesystem Members
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public bool Identify(IMediaImage imagePlugin, Partition partition)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// ISO9660 is designed for 2048 bytes/sector devices
|
|
|
|
|
|
if(imagePlugin.Info.SectorSize < 2048)
|
|
|
|
|
|
return false;
|
2014-04-14 01:14:20 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size.
|
|
|
|
|
|
if(partition.End <= 16 + partition.Start)
|
|
|
|
|
|
return false;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// Read to Volume Descriptor
|
|
|
|
|
|
ErrorNumber errno = imagePlugin.ReadSector(16 + partition.Start, out byte[] vdSector);
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(errno != ErrorNumber.NoError)
|
|
|
|
|
|
return false;
|
2014-04-14 01:14:20 +00:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var xaOff = 0;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(vdSector.Length == 2336)
|
|
|
|
|
|
xaOff = 8;
|
2015-12-06 07:51:46 +00:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
byte vdType = vdSector[0 + xaOff];
|
|
|
|
|
|
var vdMagic = new byte[5];
|
|
|
|
|
|
var hsMagic = new byte[5];
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// This indicates the end of a volume descriptor. HighSierra here would have 16 so no problem
|
|
|
|
|
|
if(vdType == 255)
|
|
|
|
|
|
return false;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Array.Copy(vdSector, 0x001 + xaOff, vdMagic, 0, 5);
|
|
|
|
|
|
Array.Copy(vdSector, 0x009 + xaOff, hsMagic, 0, 5);
|
2015-12-06 07:51:46 +00:00
|
|
|
|
|
2023-10-03 17:47:32 +01:00
|
|
|
|
AaruConsole.DebugWriteLine(MODULE_NAME, "VDMagic = {0}", Encoding.ASCII.GetString(vdMagic));
|
|
|
|
|
|
AaruConsole.DebugWriteLine(MODULE_NAME, "HSMagic = {0}", Encoding.ASCII.GetString(hsMagic));
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
return Encoding.ASCII.GetString(vdMagic) == ISO_MAGIC ||
|
2023-10-04 17:34:40 +01:00
|
|
|
|
Encoding.ASCII.GetString(hsMagic) == HIGH_SIERRA_MAGIC ||
|
|
|
|
|
|
Encoding.ASCII.GetString(vdMagic) == CDI_MAGIC;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
/// <inheritdoc />
|
2022-12-17 22:41:56 +00:00
|
|
|
|
public void GetInformation(IMediaImage imagePlugin, Partition partition, Encoding encoding, out string information,
|
|
|
|
|
|
out FileSystem metadata)
|
2022-03-06 13:29:38 +00:00
|
|
|
|
{
|
2022-12-17 23:17:18 +00:00
|
|
|
|
encoding ??= Encoding.ASCII;
|
|
|
|
|
|
information = "";
|
|
|
|
|
|
metadata = new FileSystem();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var isoMetadata = new StringBuilder();
|
|
|
|
|
|
var vdMagic = new byte[5]; // Volume Descriptor magic "CD001"
|
|
|
|
|
|
var hsMagic = new byte[5]; // Volume Descriptor magic "CDROM"
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var bootSpec = "";
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
PrimaryVolumeDescriptor? pvd = null;
|
|
|
|
|
|
PrimaryVolumeDescriptor? jolietvd = null;
|
|
|
|
|
|
BootRecord? bvd = null;
|
|
|
|
|
|
HighSierraPrimaryVolumeDescriptor? hsvd = null;
|
|
|
|
|
|
FileStructureVolumeDescriptor? fsvd = null;
|
|
|
|
|
|
ElToritoBootRecord? torito = null;
|
|
|
|
|
|
|
|
|
|
|
|
// ISO9660 is designed for 2048 bytes/sector devices
|
|
|
|
|
|
if(imagePlugin.Info.SectorSize < 2048)
|
|
|
|
|
|
return;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size.
|
|
|
|
|
|
if(partition.End < 16)
|
|
|
|
|
|
return;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ulong counter = 0;
|
|
|
|
|
|
|
2022-03-17 23:54:41 +00:00
|
|
|
|
ErrorNumber errno = imagePlugin.ReadSector(16 + partition.Start, out byte[] vdSector);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
if(errno != ErrorNumber.NoError)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
int xaOff = vdSector.Length == 2336 ? 8 : 0;
|
|
|
|
|
|
Array.Copy(vdSector, 0x009 + xaOff, hsMagic, 0, 5);
|
2022-12-17 23:17:18 +00:00
|
|
|
|
bool highSierraInfo = encoding.GetString(hsMagic) == HIGH_SIERRA_MAGIC;
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var hsOff = 0;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
if(highSierraInfo)
|
|
|
|
|
|
hsOff = 8;
|
|
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var cdiInfo = false;
|
|
|
|
|
|
var evd = false;
|
|
|
|
|
|
var vpd = false;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
while(true)
|
|
|
|
|
|
{
|
2023-10-03 17:47:32 +01:00
|
|
|
|
AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Processing_VD_loop_no_0, counter);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
// Seek to Volume Descriptor
|
2023-10-03 17:47:32 +01:00
|
|
|
|
AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Reading_sector_0, 16 + counter + partition.Start);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
errno = imagePlugin.ReadSector(16 + counter + partition.Start, out byte[] vdSectorTmp);
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
|
|
|
|
|
if(errno != ErrorNumber.NoError)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
vdSector = new byte[vdSectorTmp.Length - xaOff];
|
|
|
|
|
|
Array.Copy(vdSectorTmp, xaOff, vdSector, 0, vdSector.Length);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
byte vdType = vdSector[0 + hsOff]; // Volume Descriptor Type, should be 1 or 2.
|
2023-10-03 17:47:32 +01:00
|
|
|
|
AaruConsole.DebugWriteLine(MODULE_NAME, "VDType = {0}", vdType);
|
2017-10-08 22:47:09 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(vdType == 255) // Supposedly we are in the PVD.
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(counter == 0)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Array.Copy(vdSector, 0x001, vdMagic, 0, 5);
|
|
|
|
|
|
Array.Copy(vdSector, 0x009, hsMagic, 0, 5);
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2022-12-17 23:17:18 +00:00
|
|
|
|
if(encoding.GetString(vdMagic) != ISO_MAGIC &&
|
|
|
|
|
|
encoding.GetString(hsMagic) != HIGH_SIERRA_MAGIC &&
|
|
|
|
|
|
encoding.GetString(vdMagic) != CDI_MAGIC) // Recognized, it is an ISO9660, now check for rest of data.
|
2022-03-06 13:29:38 +00:00
|
|
|
|
{
|
|
|
|
|
|
if(counter == 0)
|
2021-09-19 21:16:47 +01:00
|
|
|
|
return;
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-12-17 23:17:18 +00:00
|
|
|
|
cdiInfo |= encoding.GetString(vdMagic) == CDI_MAGIC;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
switch(vdType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0:
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
bvd = Marshal.ByteArrayToStructureLittleEndian<BootRecord>(vdSector, hsOff, 2048 - hsOff);
|
|
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
bootSpec = Localization.Unknown_specification;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
2022-12-17 23:17:18 +00:00
|
|
|
|
if(encoding.GetString(bvd.Value.system_id)[..23] == "EL TORITO SPECIFICATION")
|
2022-03-06 13:29:38 +00:00
|
|
|
|
{
|
|
|
|
|
|
bootSpec = "El Torito";
|
|
|
|
|
|
|
|
|
|
|
|
torito =
|
2022-03-07 07:36:44 +00:00
|
|
|
|
Marshal.ByteArrayToStructureLittleEndian<ElToritoBootRecord>(vdSector, hsOff, 2048 - hsOff);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2011-03-03 18:34:33 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
case 1:
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(highSierraInfo)
|
2022-03-07 07:36:44 +00:00
|
|
|
|
hsvd = Marshal.ByteArrayToStructureLittleEndian<HighSierraPrimaryVolumeDescriptor>(vdSector);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else if(cdiInfo)
|
|
|
|
|
|
fsvd = Marshal.ByteArrayToStructureBigEndian<FileStructureVolumeDescriptor>(vdSector);
|
|
|
|
|
|
else
|
|
|
|
|
|
pvd = Marshal.ByteArrayToStructureLittleEndian<PrimaryVolumeDescriptor>(vdSector);
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2011-03-03 18:34:33 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
case 2:
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
PrimaryVolumeDescriptor svd =
|
|
|
|
|
|
Marshal.ByteArrayToStructureLittleEndian<PrimaryVolumeDescriptor>(vdSector);
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// Check if this is Joliet
|
|
|
|
|
|
if(svd.version == 1)
|
|
|
|
|
|
{
|
2023-10-04 17:34:40 +01:00
|
|
|
|
if(svd.escape_sequences[0] == '%' && svd.escape_sequences[1] == '/')
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(svd.escape_sequences[2] == '@' ||
|
|
|
|
|
|
svd.escape_sequences[2] == 'C' ||
|
|
|
|
|
|
svd.escape_sequences[2] == 'E')
|
|
|
|
|
|
jolietvd = svd;
|
|
|
|
|
|
else
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2023-10-03 17:47:32 +01:00
|
|
|
|
AaruConsole.WriteLine(MODULE_NAME,
|
2022-11-28 02:59:53 +00:00
|
|
|
|
Localization.Found_unknown_supplementary_volume_descriptor);
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
evd = true;
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
case 3:
|
|
|
|
|
|
{
|
|
|
|
|
|
vpd = true;
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-05-11 20:49:32 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
counter++;
|
|
|
|
|
|
}
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
DecodedVolumeDescriptor decodedVd;
|
|
|
|
|
|
var decodedJolietVd = new DecodedVolumeDescriptor();
|
2019-05-11 20:49:32 +01:00
|
|
|
|
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata = new FileSystem();
|
2017-10-08 20:28:56 +01:00
|
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
|
if(pvd == null && hsvd == null && fsvd == null)
|
2022-03-06 13:29:38 +00:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
information = Localization.ERROR_Could_not_find_primary_volume_descriptor;
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2019-07-31 04:51:00 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(highSierraInfo)
|
|
|
|
|
|
decodedVd = DecodeVolumeDescriptor(hsvd.Value);
|
|
|
|
|
|
else if(cdiInfo)
|
|
|
|
|
|
decodedVd = DecodeVolumeDescriptor(fsvd.Value);
|
|
|
|
|
|
else
|
|
|
|
|
|
decodedVd = DecodeVolumeDescriptor(pvd.Value);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(jolietvd != null)
|
|
|
|
|
|
decodedJolietVd = DecodeJolietDescriptor(jolietvd.Value);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
uint rootLocation = 0;
|
|
|
|
|
|
uint rootSize = 0;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// No need to read root on CD-i, as extensions are not supported...
|
|
|
|
|
|
if(!cdiInfo)
|
|
|
|
|
|
{
|
2023-10-03 23:22:08 +01:00
|
|
|
|
rootLocation = highSierraInfo
|
|
|
|
|
|
? hsvd.Value.root_directory_record.extent
|
2022-03-06 13:29:38 +00:00
|
|
|
|
: pvd.Value.root_directory_record.extent;
|
2012-08-03 05:43:58 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(highSierraInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
rootSize = hsvd.Value.root_directory_record.size / hsvd.Value.logical_block_size;
|
2017-10-08 20:28:56 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(hsvd.Value.root_directory_record.size % hsvd.Value.logical_block_size > 0)
|
|
|
|
|
|
rootSize++;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2017-10-08 20:28:56 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
rootSize = pvd.Value.root_directory_record.size / pvd.Value.logical_block_size;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(pvd.Value.root_directory_record.size % pvd.Value.logical_block_size > 0)
|
|
|
|
|
|
rootSize++;
|
2017-10-08 20:28:56 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
2017-10-08 20:28:56 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
byte[] rootDir = Array.Empty<byte>();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var rootOff = 0;
|
|
|
|
|
|
var xaExtensions = false;
|
|
|
|
|
|
var apple = false;
|
|
|
|
|
|
var susp = false;
|
|
|
|
|
|
var rrip = false;
|
|
|
|
|
|
var ziso = false;
|
|
|
|
|
|
var amiga = false;
|
|
|
|
|
|
var aaip = false;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
List<ContinuationArea> contareas = new();
|
|
|
|
|
|
List<byte[]> refareas = new();
|
|
|
|
|
|
var suspInformation = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
|
|
if(rootLocation + rootSize < imagePlugin.Info.Sectors)
|
|
|
|
|
|
{
|
|
|
|
|
|
errno = imagePlugin.ReadSectors(rootLocation, rootSize, out rootDir);
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(errno != ErrorNumber.NoError)
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Walk thru root directory to see system area extensions in use
|
2023-10-04 17:34:40 +01:00
|
|
|
|
while(rootOff + Marshal.SizeOf<DirectoryRecord>() < rootDir.Length && !cdiInfo)
|
2022-03-06 13:29:38 +00:00
|
|
|
|
{
|
|
|
|
|
|
DirectoryRecord record =
|
|
|
|
|
|
Marshal.ByteArrayToStructureLittleEndian<DirectoryRecord>(rootDir, rootOff,
|
|
|
|
|
|
Marshal.SizeOf<DirectoryRecord>());
|
2012-08-03 05:43:58 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
int saOff = Marshal.SizeOf<DirectoryRecord>() + record.name_len;
|
|
|
|
|
|
saOff += saOff % 2;
|
|
|
|
|
|
int saLen = record.length - saOff;
|
2017-10-09 09:21:30 +01:00
|
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
|
if(saLen > 0 && rootOff + saOff + saLen <= rootDir.Length)
|
2017-10-09 09:21:30 +01:00
|
|
|
|
{
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var sa = new byte[saLen];
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Array.Copy(rootDir, rootOff + saOff, sa, 0, saLen);
|
|
|
|
|
|
saOff = 0;
|
2017-10-13 22:15:44 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
while(saOff < saLen)
|
2017-10-13 22:15:44 +01:00
|
|
|
|
{
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var noneFound = true;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(Marshal.SizeOf<CdromXa>() + saOff <= saLen)
|
|
|
|
|
|
{
|
|
|
|
|
|
CdromXa xa = Marshal.ByteArrayToStructureBigEndian<CdromXa>(sa);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(xa.signature == XA_MAGIC)
|
|
|
|
|
|
{
|
|
|
|
|
|
xaExtensions = true;
|
|
|
|
|
|
saOff += Marshal.SizeOf<CdromXa>();
|
|
|
|
|
|
noneFound = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-10-09 02:26:45 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(saOff + 2 >= saLen)
|
|
|
|
|
|
break;
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var nextSignature = BigEndianBitConverter.ToUInt16(sa, saOff);
|
2018-02-08 02:59:42 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
switch(nextSignature)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Easy, contains size field
|
|
|
|
|
|
case APPLE_MAGIC:
|
|
|
|
|
|
apple = true;
|
|
|
|
|
|
saOff += sa[saOff + 2];
|
|
|
|
|
|
noneFound = false;
|
2017-10-09 02:26:45 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
2017-10-09 02:26:45 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// Not easy, contains size field
|
|
|
|
|
|
case APPLE_MAGIC_OLD:
|
|
|
|
|
|
apple = true;
|
|
|
|
|
|
var appleId = (AppleOldId)sa[saOff + 2];
|
|
|
|
|
|
noneFound = false;
|
2017-10-09 02:26:45 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
switch(appleId)
|
|
|
|
|
|
{
|
|
|
|
|
|
case AppleOldId.ProDOS:
|
|
|
|
|
|
saOff += Marshal.SizeOf<AppleProDOSOldSystemUse>();
|
2017-10-09 09:48:28 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case AppleOldId.TypeCreator:
|
|
|
|
|
|
case AppleOldId.TypeCreatorBundle:
|
|
|
|
|
|
saOff += Marshal.SizeOf<AppleHFSTypeCreatorSystemUse>();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case AppleOldId.TypeCreatorIcon:
|
|
|
|
|
|
case AppleOldId.TypeCreatorIconBundle:
|
|
|
|
|
|
saOff += Marshal.SizeOf<AppleHFSIconSystemUse>();
|
2017-10-09 09:48:28 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case AppleOldId.HFS:
|
|
|
|
|
|
saOff += Marshal.SizeOf<AppleHFSOldSystemUse>();
|
2017-10-09 09:48:28 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-10-09 09:48:28 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// IEEE-P1281 aka SUSP 1.12
|
|
|
|
|
|
case SUSP_INDICATOR:
|
|
|
|
|
|
susp = true;
|
|
|
|
|
|
saOff += sa[saOff + 2];
|
|
|
|
|
|
noneFound = false;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
while(saOff + 2 < saLen)
|
|
|
|
|
|
{
|
|
|
|
|
|
nextSignature = BigEndianBitConverter.ToUInt16(sa, saOff);
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
switch(nextSignature)
|
2017-10-09 11:25:47 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
case APPLE_MAGIC:
|
2023-10-04 17:34:40 +01:00
|
|
|
|
if(sa[saOff + 3] == 1 && sa[saOff + 2] == 7)
|
2022-03-06 13:29:38 +00:00
|
|
|
|
apple = true;
|
|
|
|
|
|
else
|
|
|
|
|
|
apple |= sa[saOff + 3] != 1;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
break;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
case SUSP_CONTINUATION when saOff + sa[saOff + 2] <= saLen:
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var ce = new byte[sa[saOff + 2]];
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Array.Copy(sa, saOff, ce, 0, ce.Length);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ContinuationArea ca =
|
|
|
|
|
|
Marshal.ByteArrayToStructureBigEndian<ContinuationArea>(ce);
|
|
|
|
|
|
|
|
|
|
|
|
contareas.Add(ca);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
break;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
case SUSP_REFERENCE when saOff + sa[saOff + 2] <= saLen:
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var er = new byte[sa[saOff + 2]];
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Array.Copy(sa, saOff, er, 0, er.Length);
|
|
|
|
|
|
refareas.Add(er);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2017-12-21 04:43:29 +00:00
|
|
|
|
break;
|
2017-10-09 11:25:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-16 11:47:00 +00:00
|
|
|
|
rrip |= nextSignature is RRIP_MAGIC or RRIP_POSIX_ATTRIBUTES or RRIP_POSIX_DEV_NO
|
2023-10-03 23:22:08 +01:00
|
|
|
|
or RRIP_SYMLINK or RRIP_NAME or RRIP_CHILDLINK or RRIP_PARENTLINK
|
|
|
|
|
|
or RRIP_RELOCATED_DIR or RRIP_TIMESTAMPS or RRIP_SPARSE;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ziso |= nextSignature == ZISO_MAGIC;
|
|
|
|
|
|
amiga |= nextSignature == AMIGA_MAGIC;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
|
aaip |= nextSignature == AAIP_MAGIC ||
|
|
|
|
|
|
nextSignature == AAIP_MAGIC_OLD && sa[saOff + 3] == 1 && sa[saOff + 2] >= 9;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
saOff += sa[saOff + 2];
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(nextSignature == SUSP_TERMINATOR)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(noneFound)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
rootOff += record.length;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(record.length == 0)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
foreach(ContinuationArea ca in contareas)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint caLen = (ca.ca_length_be + ca.offset_be) /
|
|
|
|
|
|
(highSierraInfo ? hsvd.Value.logical_block_size : pvd.Value.logical_block_size);
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if((ca.ca_length_be + ca.offset_be) %
|
2023-10-04 17:34:40 +01:00
|
|
|
|
(highSierraInfo ? hsvd.Value.logical_block_size : pvd.Value.logical_block_size) >
|
|
|
|
|
|
0)
|
2022-03-06 13:29:38 +00:00
|
|
|
|
caLen++;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
errno = imagePlugin.ReadSectors(ca.block_be, caLen, out byte[] caSectors);
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(errno != ErrorNumber.NoError)
|
|
|
|
|
|
return;
|
2017-12-21 04:43:29 +00:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var caData = new byte[ca.ca_length_be];
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Array.Copy(caSectors, ca.offset_be, caData, 0, ca.ca_length_be);
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var caOff = 0;
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
while(caOff < ca.ca_length_be)
|
|
|
|
|
|
{
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var nextSignature = BigEndianBitConverter.ToUInt16(caData, caOff);
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
switch(nextSignature)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Apple never said to include its extensions inside a continuation area, but just in case
|
|
|
|
|
|
case APPLE_MAGIC:
|
2023-10-04 17:34:40 +01:00
|
|
|
|
if(caData[caOff + 3] == 1 && caData[caOff + 2] == 7)
|
2022-03-06 13:29:38 +00:00
|
|
|
|
apple = true;
|
|
|
|
|
|
else
|
|
|
|
|
|
apple |= caData[caOff + 3] != 1;
|
2017-10-09 02:26:45 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case SUSP_REFERENCE when caOff + caData[caOff + 2] <= ca.ca_length_be:
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var er = new byte[caData[caOff + 2]];
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Array.Copy(caData, caOff, er, 0, er.Length);
|
|
|
|
|
|
refareas.Add(er);
|
2017-10-09 02:26:45 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-10-09 02:26:45 +01:00
|
|
|
|
|
2022-03-16 11:47:00 +00:00
|
|
|
|
rrip |= nextSignature is RRIP_MAGIC or RRIP_POSIX_ATTRIBUTES or RRIP_POSIX_DEV_NO or RRIP_SYMLINK
|
2023-10-03 23:22:08 +01:00
|
|
|
|
or RRIP_NAME or RRIP_CHILDLINK or RRIP_PARENTLINK or RRIP_RELOCATED_DIR
|
2023-10-04 17:34:40 +01:00
|
|
|
|
or RRIP_TIMESTAMPS or RRIP_SPARSE;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ziso |= nextSignature == ZISO_MAGIC;
|
|
|
|
|
|
amiga |= nextSignature == AMIGA_MAGIC;
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
|
aaip |= nextSignature == AAIP_MAGIC ||
|
|
|
|
|
|
nextSignature == AAIP_MAGIC_OLD && caData[caOff + 3] == 1 && caData[caOff + 2] >= 9;
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
caOff += caData[caOff + 2];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(refareas.Count > 0)
|
|
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
suspInformation.AppendLine(Localization.SYSTEM_USE_SHARING_PROTOCOL_INFORMATION_border);
|
|
|
|
|
|
suspInformation.AppendLine(Localization.SYSTEM_USE_SHARING_PROTOCOL_INFORMATION);
|
|
|
|
|
|
suspInformation.AppendLine(Localization.SYSTEM_USE_SHARING_PROTOCOL_INFORMATION_border);
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
counter = 1;
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
foreach(byte[] erb in refareas)
|
|
|
|
|
|
{
|
|
|
|
|
|
ReferenceArea er = Marshal.ByteArrayToStructureBigEndian<ReferenceArea>(erb);
|
2022-12-17 23:17:18 +00:00
|
|
|
|
string extId = encoding.GetString(erb, Marshal.SizeOf<ReferenceArea>(), er.id_len);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-12-17 23:17:18 +00:00
|
|
|
|
string extDes = encoding.GetString(erb, Marshal.SizeOf<ReferenceArea>() + er.id_len, er.des_len);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-12-17 23:17:18 +00:00
|
|
|
|
string extSrc = encoding.GetString(erb, Marshal.SizeOf<ReferenceArea>() + er.id_len + er.des_len,
|
2022-03-06 13:29:38 +00:00
|
|
|
|
er.src_len);
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
suspInformation.AppendFormat(Localization.Extension_0, counter).AppendLine();
|
2022-11-28 02:59:53 +00:00
|
|
|
|
suspInformation.AppendFormat("\t" + Localization.ID_0_version_1, extId, er.ext_ver).AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
suspInformation.AppendFormat("\t" + Localization.Description_0, extDes).AppendLine();
|
|
|
|
|
|
suspInformation.AppendFormat("\t" + Localization.Source_0, extSrc).AppendLine();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
counter++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-10-09 12:07:48 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
errno = imagePlugin.ReadSector(0 + partition.Start, out byte[] ipbinSector);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(errno != ErrorNumber.NoError)
|
|
|
|
|
|
return;
|
2017-10-09 12:21:38 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
CD.IPBin? segaCd = CD.DecodeIPBin(ipbinSector);
|
|
|
|
|
|
Saturn.IPBin? saturn = Saturn.DecodeIPBin(ipbinSector);
|
|
|
|
|
|
Dreamcast.IPBin? dreamcast = Dreamcast.DecodeIPBin(ipbinSector);
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(highSierraInfo)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.High_Sierra_Format_file_system);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else if(cdiInfo)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.CD_i_file_system);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.ISO9660_file_system);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(xaExtensions)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.CD_ROM_XA_extensions_present);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(amiga)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.Amiga_extensions_present);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(apple)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.Apple_extensions_present);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(jolietvd != null)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.Joliet_extensions_present);
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(susp)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.System_Use_Sharing_Protocol_present);
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(rrip)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.Rock_Ridge_Interchange_Protocol_present);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(aaip)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.Arbitrary_Attribute_Interchange_Protocol_present);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(ziso)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.zisofs_compression_present);
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(evd)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.Contains_Enhanced_Volume_Descriptor);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(vpd)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.Contains_Volume_Partition_Descriptor);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(bvd != null)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Disc_bootable_following_0_specifications, bootSpec).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(segaCd != null)
|
|
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.This_is_a_SegaCD_MegaCD_disc);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
isoMetadata.AppendLine(CD.Prettify(segaCd));
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(saturn != null)
|
|
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.This_is_a_Sega_Saturn_disc);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
isoMetadata.AppendLine(Saturn.Prettify(saturn));
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(dreamcast != null)
|
|
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.This_is_a_Sega_Dreamcast_disc);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
isoMetadata.AppendLine(Dreamcast.Prettify(dreamcast));
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
if(cdiInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.FILE_STRUCTURE_VOLUME_DESCRIPTOR_INFORMATION_border);
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.FILE_STRUCTURE_VOLUME_DESCRIPTOR_INFORMATION);
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.FILE_STRUCTURE_VOLUME_DESCRIPTOR_INFORMATION_border);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.VOLUME_DESCRIPTOR_INFORMATION_border);
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.VOLUME_DESCRIPTOR_INFORMATION);
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.VOLUME_DESCRIPTOR_INFORMATION_border);
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
isoMetadata.AppendFormat(Localization.System_identifier_0, decodedVd.SystemIdentifier).AppendLine();
|
|
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_identifier_0, decodedVd.VolumeIdentifier).AppendLine();
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_set_identifier_0, decodedVd.VolumeSetIdentifier).AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Publisher_identifier_0, decodedVd.PublisherIdentifier).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Data_preparer_identifier_0, decodedVd.DataPreparerIdentifier).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Application_identifier_0, decodedVd.ApplicationIdentifier).AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_creation_date_0, decodedVd.CreationTime).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedVd.HasModificationTime)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_modification_date_0, decodedVd.ModificationTime).AppendLine();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_has_not_been_modified).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedVd.HasExpirationTime)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_expiration_date_0, decodedVd.ExpirationTime).AppendLine();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_does_not_expire).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedVd.HasEffectiveTime)
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_effective_date_0, decodedVd.EffectiveTime).AppendLine();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_has_always_been_effective).AppendLine();
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.
|
|
|
|
|
|
AppendFormat(Localization.Volume_has_0_blocks_of_1_bytes_each, decodedVd.Blocks, decodedVd.BlockSize).
|
|
|
|
|
|
AppendLine();
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(jolietvd != null)
|
|
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.JOLIET_VOLUME_DESCRIPTOR_INFORMATION_border);
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.JOLIET_VOLUME_DESCRIPTOR_INFORMATION);
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.JOLIET_VOLUME_DESCRIPTOR_INFORMATION_border);
|
|
|
|
|
|
isoMetadata.AppendFormat(Localization.System_identifier_0, decodedJolietVd.SystemIdentifier).AppendLine();
|
|
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_identifier_0, decodedJolietVd.VolumeIdentifier).AppendLine();
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_set_identifier_0, decodedJolietVd.VolumeSetIdentifier).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Publisher_identifier_0, decodedJolietVd.PublisherIdentifier).
|
|
|
|
|
|
AppendLine();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Data_preparer_identifier_0, decodedJolietVd.DataPreparerIdentifier).
|
2020-02-29 18:03:35 +00:00
|
|
|
|
AppendLine();
|
|
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Application_identifier_0, decodedJolietVd.ApplicationIdentifier).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_creation_date_0, decodedJolietVd.CreationTime).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedJolietVd.HasModificationTime)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_modification_date_0, decodedJolietVd.ModificationTime).
|
2022-03-06 13:29:38 +00:00
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_has_not_been_modified).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedJolietVd.HasExpirationTime)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_expiration_date_0, decodedJolietVd.ExpirationTime).
|
|
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_does_not_expire).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedJolietVd.HasEffectiveTime)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_effective_date_0, decodedJolietVd.EffectiveTime).
|
|
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Volume_has_always_been_effective).AppendLine();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(torito != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
errno = imagePlugin.ReadSector(torito.Value.catalog_sector + partition.Start, out vdSector);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(errno != ErrorNumber.NoError)
|
|
|
|
|
|
return;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
var toritoOff = 0;
|
2012-08-03 05:43:58 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(vdSector[toritoOff] != 1)
|
|
|
|
|
|
goto exit_torito;
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ElToritoValidationEntry valentry =
|
|
|
|
|
|
Marshal.ByteArrayToStructureLittleEndian<ElToritoValidationEntry>(vdSector, toritoOff,
|
|
|
|
|
|
EL_TORITO_ENTRY_SIZE);
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(valentry.signature != EL_TORITO_MAGIC)
|
|
|
|
|
|
goto exit_torito;
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
toritoOff = EL_TORITO_ENTRY_SIZE;
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ElToritoInitialEntry initialEntry =
|
|
|
|
|
|
Marshal.ByteArrayToStructureLittleEndian<ElToritoInitialEntry>(vdSector, toritoOff,
|
|
|
|
|
|
EL_TORITO_ENTRY_SIZE);
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
initialEntry.boot_type = (ElToritoEmulation)((byte)initialEntry.boot_type & 0xF);
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2023-10-03 17:47:32 +01:00
|
|
|
|
AaruConsole.DebugWriteLine(MODULE_NAME, "initialEntry.load_rba = {0}", initialEntry.load_rba);
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2023-10-04 17:34:40 +01:00
|
|
|
|
AaruConsole.DebugWriteLine(MODULE_NAME, "initialEntry.sector_count = {0}", initialEntry.sector_count);
|
2019-03-01 00:28:55 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
byte[] bootImage = null;
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(initialEntry.load_rba + partition.Start + initialEntry.sector_count - 1 <= partition.End)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
imagePlugin.ReadSectors(initialEntry.load_rba + partition.Start, initialEntry.sector_count,
|
|
|
|
|
|
out bootImage);
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine(Localization.EL_TORITO_INFORMATION_border);
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.EL_TORITO_INFORMATION);
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.EL_TORITO_INFORMATION_border);
|
|
|
|
|
|
|
|
|
|
|
|
isoMetadata.AppendLine(Localization.Initial_entry);
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-12-17 23:17:18 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t" + Localization.Developer_ID_0, encoding.GetString(valentry.developer_id)).
|
2022-11-28 02:59:53 +00:00
|
|
|
|
AppendLine();
|
2021-09-19 21:16:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(initialEntry.bootable == ElToritoIndicator.Bootable)
|
|
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t" + Localization.Bootable_on_0, valentry.platform_id).AppendLine();
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t" + Localization.Bootable_image_starts_at_sector_0_and_runs_for_1_sectors,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
initialEntry.load_rba, initialEntry.sector_count).
|
|
|
|
|
|
AppendLine();
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(valentry.platform_id == ElToritoPlatform.x86)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t" + Localization.Bootable_image_will_be_loaded_at_segment_0,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
initialEntry.load_seg == 0 ? 0x7C0 : initialEntry.load_seg).
|
|
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t" + Localization.Bootable_image_will_be_loaded_at_0,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
(uint)initialEntry.load_seg * 10).
|
|
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
switch(initialEntry.boot_type)
|
2017-10-09 00:32:17 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
case ElToritoEmulation.None:
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t" + Localization.Image_uses_no_emulation);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case ElToritoEmulation.Md2Hd:
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t" + Localization.Image_emulates_a_high_density_MD2HD_floppy);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case ElToritoEmulation.Mf2Hd:
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t" + Localization.Image_emulates_a_high_density_MF2HD_floppy);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case ElToritoEmulation.Mf2Ed:
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t" + Localization.Image_emulates_a_extra_density_MF2ED_floppy);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t" + Localization.Image_uses_unknown_emulation_type_0,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
(byte)initialEntry.boot_type).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t" + Localization.System_type_0, initialEntry.system_type).AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(bootImage != null)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.
|
|
|
|
|
|
AppendFormat("\t" + Localization.Bootable_image_SHA1_0, Sha1Context.Data(bootImage, out _)).
|
|
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t" + Localization.Not_bootable);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
toritoOff += EL_TORITO_ENTRY_SIZE;
|
2017-12-19 20:33:03 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
const int sectionCounter = 2;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
while(toritoOff < vdSector.Length &&
|
|
|
|
|
|
(vdSector[toritoOff] == (byte)ElToritoIndicator.Header ||
|
|
|
|
|
|
vdSector[toritoOff] == (byte)ElToritoIndicator.LastHeader))
|
|
|
|
|
|
{
|
|
|
|
|
|
ElToritoSectionHeaderEntry sectionHeader =
|
|
|
|
|
|
Marshal.ByteArrayToStructureLittleEndian<ElToritoSectionHeaderEntry>(vdSector, toritoOff,
|
|
|
|
|
|
EL_TORITO_ENTRY_SIZE);
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2017-12-22 07:28:54 +00:00
|
|
|
|
toritoOff += EL_TORITO_ENTRY_SIZE;
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat(Localization.Boot_section_0, sectionCounter);
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.
|
2022-12-17 23:17:18 +00:00
|
|
|
|
AppendFormat("\t" + Localization.Section_ID_0, encoding.GetString(sectionHeader.identifier)).
|
2022-11-28 02:59:53 +00:00
|
|
|
|
AppendLine();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
for(var entryCounter = 1;
|
|
|
|
|
|
entryCounter <= sectionHeader.entries && toritoOff < vdSector.Length;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
entryCounter++)
|
2017-10-09 00:32:17 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ElToritoSectionEntry sectionEntry =
|
|
|
|
|
|
Marshal.ByteArrayToStructureLittleEndian<ElToritoSectionEntry>(vdSector, toritoOff,
|
2020-11-11 04:19:18 +00:00
|
|
|
|
EL_TORITO_ENTRY_SIZE);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2017-12-22 07:28:54 +00:00
|
|
|
|
toritoOff += EL_TORITO_ENTRY_SIZE;
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t" + Localization.Entry_0, entryCounter);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(sectionEntry.bootable == ElToritoIndicator.Bootable)
|
2017-10-09 00:32:17 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
bootImage = null;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(sectionEntry.load_rba + partition.Start + sectionEntry.sector_count - 1 <= partition.End)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-03-07 07:36:44 +00:00
|
|
|
|
imagePlugin.ReadSectors(sectionEntry.load_rba + partition.Start, sectionEntry.sector_count,
|
|
|
|
|
|
out bootImage);
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t\t" + Localization.Bootable_on_0, sectionHeader.platform_id).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.
|
|
|
|
|
|
AppendFormat("\t\t" + Localization.Bootable_image_starts_at_sector_0_and_runs_for_1_sectors,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
sectionEntry.load_rba, sectionEntry.sector_count).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(valentry.platform_id == ElToritoPlatform.x86)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t\t" + Localization.Bootable_image_will_be_loaded_at_segment_0,
|
2022-03-06 13:29:38 +00:00
|
|
|
|
sectionEntry.load_seg == 0 ? 0x7C0 : sectionEntry.load_seg).
|
|
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t\t" + Localization.Bootable_image_will_be_loaded_at_0,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
(uint)sectionEntry.load_seg * 10).
|
|
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
switch((ElToritoEmulation)((byte)sectionEntry.boot_type & 0xF))
|
|
|
|
|
|
{
|
|
|
|
|
|
case ElToritoEmulation.None:
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t\t" + Localization.Image_uses_no_emulation);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case ElToritoEmulation.Md2Hd:
|
2023-10-04 17:34:40 +01:00
|
|
|
|
isoMetadata.AppendLine("\t\t" +
|
|
|
|
|
|
Localization.Image_emulates_a_high_density_MD2HD_floppy);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case ElToritoEmulation.Mf2Hd:
|
2023-10-04 17:34:40 +01:00
|
|
|
|
isoMetadata.AppendLine("\t\t" +
|
|
|
|
|
|
Localization.Image_emulates_a_high_density_MF2HD_floppy);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
case ElToritoEmulation.Mf2Ed:
|
2023-10-04 17:34:40 +01:00
|
|
|
|
isoMetadata.AppendLine("\t\t" +
|
|
|
|
|
|
Localization.Image_emulates_a_extra_density_MF2ED_floppy);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t\t" + Localization.Image_uses_unknown_emulation_type_0,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
(byte)initialEntry.boot_type).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t\t" + Localization.Selection_criteria_type_0,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
sectionEntry.selection_criteria_type).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t\t" + Localization.System_type_0, sectionEntry.system_type).
|
|
|
|
|
|
AppendLine();
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(bootImage != null)
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendFormat("\t\t" + Localization.Bootable_image_SHA1_0,
|
2023-10-04 17:34:40 +01:00
|
|
|
|
Sha1Context.Data(bootImage, out _)).
|
|
|
|
|
|
AppendLine();
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t\t" + Localization.Not_bootable);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
var flags = (ElToritoFlags)((byte)sectionEntry.boot_type & 0xF0);
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(flags.HasFlag(ElToritoFlags.ATAPI))
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t\t" + Localization.Image_contains_ATAPI_drivers);
|
2017-10-09 00:32:17 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(flags.HasFlag(ElToritoFlags.SCSI))
|
2022-11-28 02:59:53 +00:00
|
|
|
|
isoMetadata.AppendLine("\t\t" + Localization.Image_contains_SCSI_drivers);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(!flags.HasFlag(ElToritoFlags.Continued))
|
|
|
|
|
|
continue;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
while(toritoOff < vdSector.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
ElToritoSectionEntryExtension sectionExtension =
|
2022-03-07 07:36:44 +00:00
|
|
|
|
Marshal.ByteArrayToStructureLittleEndian<ElToritoSectionEntryExtension>(vdSector, toritoOff,
|
|
|
|
|
|
EL_TORITO_ENTRY_SIZE);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
toritoOff += EL_TORITO_ENTRY_SIZE;
|
2017-12-21 06:06:19 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(!sectionExtension.extension_flags.HasFlag(ElToritoFlags.Continued))
|
|
|
|
|
|
break;
|
2017-10-09 00:32:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(sectionHeader.header_id == ElToritoIndicator.LastHeader)
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2023-10-03 23:22:08 +01:00
|
|
|
|
exit_torito:
|
2017-10-09 11:25:47 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(refareas.Count > 0)
|
|
|
|
|
|
isoMetadata.Append(suspInformation);
|
2015-12-23 23:46:31 +00:00
|
|
|
|
|
2022-12-11 22:19:38 +00:00
|
|
|
|
if(highSierraInfo)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.Type = FS_TYPE_HSF;
|
2022-12-11 22:19:38 +00:00
|
|
|
|
else if(cdiInfo)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.Type = FS_TYPE_CDI;
|
2022-11-28 02:59:53 +00:00
|
|
|
|
else
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.Type = FS_TYPE_ISO;
|
2017-12-22 07:28:54 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(jolietvd != null)
|
|
|
|
|
|
{
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.VolumeName = decodedJolietVd.VolumeIdentifier;
|
2017-12-22 07:28:54 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(string.IsNullOrEmpty(decodedJolietVd.SystemIdentifier) ||
|
|
|
|
|
|
decodedVd.SystemIdentifier.Length > decodedJolietVd.SystemIdentifier.Length)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.SystemIdentifier = decodedVd.SystemIdentifier;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
|
|
|
|
|
metadata.SystemIdentifier = string.IsNullOrEmpty(decodedJolietVd.SystemIdentifier)
|
|
|
|
|
|
? null
|
2022-12-15 22:21:07 +00:00
|
|
|
|
: decodedJolietVd.SystemIdentifier;
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2017-12-22 07:28:54 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(string.IsNullOrEmpty(decodedJolietVd.VolumeSetIdentifier) ||
|
|
|
|
|
|
decodedVd.VolumeSetIdentifier.Length > decodedJolietVd.VolumeSetIdentifier.Length)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.VolumeSetIdentifier = decodedVd.VolumeSetIdentifier;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
|
|
|
|
|
metadata.VolumeSetIdentifier = string.IsNullOrEmpty(decodedJolietVd.VolumeSetIdentifier)
|
|
|
|
|
|
? null
|
2022-12-15 22:21:07 +00:00
|
|
|
|
: decodedJolietVd.VolumeSetIdentifier;
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2019-02-12 18:57:20 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(string.IsNullOrEmpty(decodedJolietVd.PublisherIdentifier) ||
|
|
|
|
|
|
decodedVd.PublisherIdentifier.Length > decodedJolietVd.PublisherIdentifier.Length)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.PublisherIdentifier = decodedVd.PublisherIdentifier;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
|
|
|
|
|
metadata.PublisherIdentifier = string.IsNullOrEmpty(decodedJolietVd.PublisherIdentifier)
|
|
|
|
|
|
? null
|
2022-12-15 22:21:07 +00:00
|
|
|
|
: decodedJolietVd.PublisherIdentifier;
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2019-02-12 18:57:20 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(string.IsNullOrEmpty(decodedJolietVd.DataPreparerIdentifier) ||
|
|
|
|
|
|
decodedVd.DataPreparerIdentifier.Length > decodedJolietVd.DataPreparerIdentifier.Length)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.DataPreparerIdentifier = decodedVd.DataPreparerIdentifier;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
|
|
|
|
|
metadata.DataPreparerIdentifier = string.IsNullOrEmpty(decodedJolietVd.DataPreparerIdentifier)
|
|
|
|
|
|
? null
|
2022-12-15 22:21:07 +00:00
|
|
|
|
: decodedJolietVd.DataPreparerIdentifier;
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2017-12-22 07:28:54 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(string.IsNullOrEmpty(decodedJolietVd.ApplicationIdentifier) ||
|
|
|
|
|
|
decodedVd.ApplicationIdentifier.Length > decodedJolietVd.ApplicationIdentifier.Length)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.ApplicationIdentifier = decodedVd.ApplicationIdentifier;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2023-10-03 23:22:08 +01:00
|
|
|
|
{
|
|
|
|
|
|
metadata.ApplicationIdentifier = string.IsNullOrEmpty(decodedJolietVd.ApplicationIdentifier)
|
|
|
|
|
|
? null
|
2022-12-15 22:21:07 +00:00
|
|
|
|
: decodedJolietVd.ApplicationIdentifier;
|
2023-10-03 23:22:08 +01:00
|
|
|
|
}
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.CreationDate = decodedJolietVd.CreationTime;
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedJolietVd.HasModificationTime)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.ModificationDate = decodedJolietVd.ModificationTime;
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedJolietVd.HasExpirationTime)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.ExpirationDate = decodedJolietVd.ExpirationTime;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
if(decodedJolietVd.HasEffectiveTime)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.EffectiveDate = decodedJolietVd.EffectiveTime;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.SystemIdentifier = decodedVd.SystemIdentifier;
|
|
|
|
|
|
metadata.VolumeName = decodedVd.VolumeIdentifier;
|
|
|
|
|
|
metadata.VolumeSetIdentifier = decodedVd.VolumeSetIdentifier;
|
|
|
|
|
|
metadata.PublisherIdentifier = decodedVd.PublisherIdentifier;
|
|
|
|
|
|
metadata.DataPreparerIdentifier = decodedVd.DataPreparerIdentifier;
|
|
|
|
|
|
metadata.ApplicationIdentifier = decodedVd.ApplicationIdentifier;
|
|
|
|
|
|
metadata.CreationDate = decodedVd.CreationTime;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedVd.HasModificationTime)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.ModificationDate = decodedVd.ModificationTime;
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedVd.HasExpirationTime)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.ExpirationDate = decodedVd.ExpirationTime;
|
2017-12-30 01:22:23 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(decodedVd.HasEffectiveTime)
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.EffectiveDate = decodedVd.EffectiveTime;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
2015-12-05 17:10:27 +00:00
|
|
|
|
|
2022-12-17 22:41:56 +00:00
|
|
|
|
metadata.Bootable |= bvd != null || segaCd != null || saturn != null || dreamcast != null;
|
|
|
|
|
|
metadata.Clusters = decodedVd.Blocks;
|
|
|
|
|
|
metadata.ClusterSize = decodedVd.BlockSize;
|
2015-12-06 05:09:31 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
information = isoMetadata.ToString();
|
2011-03-03 18:34:33 +00:00
|
|
|
|
}
|
2023-10-03 23:22:08 +01:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
2017-12-19 20:33:03 +00:00
|
|
|
|
}
|