2017-07-19 16:31:08 +01:00
|
|
|
|
// /***************************************************************************
|
2016-07-28 18:13:49 +01:00
|
|
|
|
// The Disc Image Chef
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
//
|
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-10-08 20:41:54 +01:00
|
|
|
|
// Component : Component
|
2016-07-28 18:13:49 +01:00
|
|
|
|
//
|
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
|
//
|
2017-10-08 20:41:54 +01:00
|
|
|
|
// Description
|
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/>.
|
|
|
|
|
|
//
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2017-05-19 20:28:49 +01:00
|
|
|
|
// Copyright © 2011-2017 Natalia Portillo
|
2016-07-28 18:13:49 +01:00
|
|
|
|
// ****************************************************************************/
|
2011-03-03 18:34:33 +00:00
|
|
|
|
using System;
|
2017-10-08 20:28:56 +01:00
|
|
|
|
using System.Runtime.InteropServices;
|
2014-04-14 02:29:13 +00:00
|
|
|
|
using System.Text;
|
2017-07-19 16:31:08 +01:00
|
|
|
|
using DiscImageChef.CommonTypes;
|
2015-10-18 22:04:03 +01:00
|
|
|
|
using DiscImageChef.Console;
|
|
|
|
|
|
|
2017-10-08 20:41:54 +01:00
|
|
|
|
namespace DiscImageChef.Filesystems.ISO9660
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2017-10-08 20:41:54 +01:00
|
|
|
|
public partial class ISO9660 : Filesystem
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2017-07-19 16:31:08 +01:00
|
|
|
|
public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, Partition partition)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2014-04-14 02:29:13 +00:00
|
|
|
|
byte VDType;
|
2012-08-03 05:43:58 +00:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
// ISO9660 is designed for 2048 bytes/sector devices
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(imagePlugin.GetSectorSize() < 2048)
|
2014-04-14 01:14:20 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
// ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size.
|
2017-07-19 16:37:11 +01:00
|
|
|
|
if(partition.End <= (16 + partition.Start))
|
2011-03-03 18:34:33 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
// Read to Volume Descriptor
|
2017-07-19 16:37:11 +01:00
|
|
|
|
byte[] vd_sector = imagePlugin.ReadSector(16 + partition.Start);
|
2014-04-14 01:14:20 +00:00
|
|
|
|
|
2015-12-06 07:51:46 +00:00
|
|
|
|
int xa_off = 0;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(vd_sector.Length == 2336)
|
2015-12-06 07:51:46 +00:00
|
|
|
|
xa_off = 8;
|
|
|
|
|
|
|
|
|
|
|
|
VDType = vd_sector[0 + xa_off];
|
2014-04-14 02:29:13 +00:00
|
|
|
|
byte[] VDMagic = new byte[5];
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2014-04-14 02:29:13 +00:00
|
|
|
|
// Wrong, VDs can be any order!
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(VDType == 255) // Supposedly we are in the PVD.
|
|
|
|
|
|
return false;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2015-12-06 07:51:46 +00:00
|
|
|
|
Array.Copy(vd_sector, 0x001 + xa_off, VDMagic, 0, 5);
|
|
|
|
|
|
|
2017-06-06 21:23:20 +01:00
|
|
|
|
DicConsole.DebugWriteLine("ISO9660 plugin", "VDMagic = {0}", CurrentEncoding.GetString(VDMagic));
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2017-06-06 21:23:20 +01:00
|
|
|
|
return CurrentEncoding.GetString(VDMagic) == "CD001";
|
2014-04-14 02:29:13 +00:00
|
|
|
|
}
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2017-07-19 16:31:08 +01:00
|
|
|
|
public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, Partition partition, out string information)
|
2016-04-19 02:11:47 +01:00
|
|
|
|
{
|
2011-03-03 18:34:33 +00:00
|
|
|
|
information = "";
|
|
|
|
|
|
StringBuilder ISOMetadata = new StringBuilder();
|
|
|
|
|
|
bool RockRidge = false;
|
|
|
|
|
|
byte VDType; // Volume Descriptor Type, should be 1 or 2.
|
|
|
|
|
|
byte[] VDMagic = new byte[5]; // Volume Descriptor magic "CD001"
|
2017-10-08 20:28:56 +01:00
|
|
|
|
|
2011-03-03 18:34:33 +00:00
|
|
|
|
string BootSpec = "";
|
|
|
|
|
|
|
|
|
|
|
|
byte[] VDPathTableStart = new byte[4];
|
|
|
|
|
|
byte[] RootDirectoryLocation = new byte[4];
|
|
|
|
|
|
|
2017-10-08 20:28:56 +01:00
|
|
|
|
PrimaryVolumeDescriptor? pvd = null;
|
|
|
|
|
|
PrimaryVolumeDescriptor? jolietvd = null;
|
|
|
|
|
|
BootRecord? bvd = null;
|
|
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
// ISO9660 is designed for 2048 bytes/sector devices
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(imagePlugin.GetSectorSize() < 2048)
|
2014-04-14 01:14:20 +00:00
|
|
|
|
return;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
// ISO9660 Primary Volume Descriptor starts at sector 16, so that's minimal size.
|
2017-07-19 16:37:11 +01:00
|
|
|
|
if(partition.End < 16)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
ulong counter = 0;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2016-04-19 02:11:47 +01:00
|
|
|
|
while(true)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2015-10-18 22:04:03 +01:00
|
|
|
|
DicConsole.DebugWriteLine("ISO9660 plugin", "Processing VD loop no. {0}", counter);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
// Seek to Volume Descriptor
|
2017-07-19 16:37:11 +01:00
|
|
|
|
DicConsole.DebugWriteLine("ISO9660 plugin", "Reading sector {0}", 16 + counter + partition.Start);
|
|
|
|
|
|
byte[] vd_sector_tmp = imagePlugin.ReadSector(16 + counter + partition.Start);
|
2015-12-06 07:51:46 +00:00
|
|
|
|
byte[] vd_sector;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(vd_sector_tmp.Length == 2336)
|
2015-12-06 07:51:46 +00:00
|
|
|
|
{
|
|
|
|
|
|
vd_sector = new byte[2336 - 8];
|
|
|
|
|
|
Array.Copy(vd_sector_tmp, 8, vd_sector, 0, 2336 - 8);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
vd_sector = vd_sector_tmp;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
VDType = vd_sector[0];
|
2015-10-18 22:04:03 +01:00
|
|
|
|
DicConsole.DebugWriteLine("ISO9660 plugin", "VDType = {0}", VDType);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(VDType == 255) // Supposedly we are in the PVD.
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(counter == 0)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
return;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
Array.Copy(vd_sector, 0x001, VDMagic, 0, 5);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2017-06-06 21:23:20 +01:00
|
|
|
|
if(CurrentEncoding.GetString(VDMagic) != "CD001") // Recognized, it is an ISO9660, now check for rest of data.
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(counter == 0)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
return;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch(VDType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0: // TODO
|
|
|
|
|
|
{
|
2017-10-08 20:28:56 +01:00
|
|
|
|
bvd = new BootRecord();
|
|
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(2048);
|
|
|
|
|
|
Marshal.Copy(vd_sector, 0, ptr, 2048);
|
|
|
|
|
|
bvd = (BootRecord)Marshal.PtrToStructure(ptr, typeof(BootRecord));
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2017-10-08 20:28:56 +01:00
|
|
|
|
BootSpec = "Unknown";
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2017-10-08 20:28:56 +01:00
|
|
|
|
if(CurrentEncoding.GetString(bvd.Value.system_id).Substring(0, 23) == "EL TORITO SPECIFICATION")
|
2011-03-03 18:34:33 +00:00
|
|
|
|
BootSpec = "El Torito";
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
{
|
2017-10-08 20:28:56 +01:00
|
|
|
|
pvd = new PrimaryVolumeDescriptor();
|
|
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(2048);
|
|
|
|
|
|
Marshal.Copy(vd_sector, 0, ptr, 2048);
|
|
|
|
|
|
pvd = (PrimaryVolumeDescriptor)Marshal.PtrToStructure(ptr, typeof(PrimaryVolumeDescriptor));
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
{
|
2017-10-08 20:28:56 +01:00
|
|
|
|
PrimaryVolumeDescriptor svd = new PrimaryVolumeDescriptor();
|
|
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(2048);
|
|
|
|
|
|
Marshal.Copy(vd_sector, 0, ptr, 2048);
|
|
|
|
|
|
svd = (PrimaryVolumeDescriptor)Marshal.PtrToStructure(ptr, typeof(PrimaryVolumeDescriptor));
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
2011-03-03 18:34:33 +00:00
|
|
|
|
// Check if this is Joliet
|
2017-10-08 20:28:56 +01:00
|
|
|
|
if(svd.escape_sequences[0] == '%' && svd.escape_sequences[1] == '/')
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2017-10-08 20:28:56 +01:00
|
|
|
|
if(svd.escape_sequences[2] == '@' || svd.escape_sequences[2] == 'C' || svd.escape_sequences[2] == 'E')
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
2017-10-08 20:28:56 +01:00
|
|
|
|
jolietvd = svd;
|
2011-03-03 18:34:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2017-10-08 20:28:56 +01:00
|
|
|
|
DicConsole.WriteLine("ISO9660 plugin", "Found unknown supplementary volume descriptor");
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
counter++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-04-19 02:11:47 +01:00
|
|
|
|
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
|
|
|
|
|
DecodedVolumeDescriptor decodedJolietVD = new DecodedVolumeDescriptor();
|
2012-08-03 05:43:58 +00:00
|
|
|
|
|
2017-10-08 20:28:56 +01:00
|
|
|
|
xmlFSType = new Schemas.FileSystemType();
|
|
|
|
|
|
|
|
|
|
|
|
if(pvd == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
information = "ERROR: Could not find primary volume descriptor";
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
decodedVD = DecodeVolumeDescriptor(pvd.Value);
|
|
|
|
|
|
if(jolietvd != null)
|
|
|
|
|
|
decodedJolietVD = DecodeJolietDescriptor(jolietvd.Value);
|
2012-08-03 05:43:58 +00:00
|
|
|
|
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2014-04-14 01:14:20 +00:00
|
|
|
|
ulong i = (ulong)BitConverter.ToInt32(VDPathTableStart, 0);
|
2017-07-19 16:37:11 +01:00
|
|
|
|
DicConsole.DebugWriteLine("ISO9660 plugin", "VDPathTableStart = {0} + {1} = {2}", i, partition.Start, i + partition.Start);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2014-07-09 19:50:16 +01:00
|
|
|
|
// TODO: Check this
|
2017-07-25 15:00:12 +01:00
|
|
|
|
/*
|
2017-07-19 16:37:11 +01:00
|
|
|
|
if((i + partition.Start) < partition.End)
|
2014-07-09 19:50:16 +01:00
|
|
|
|
{
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2017-07-19 16:37:11 +01:00
|
|
|
|
byte[] path_table = imagePlugin.ReadSector(i + partition.Start);
|
2014-07-09 19:50:16 +01:00
|
|
|
|
Array.Copy(path_table, 2, RootDirectoryLocation, 0, 4);
|
|
|
|
|
|
// Check for Rock Ridge
|
2017-07-19 16:37:11 +01:00
|
|
|
|
byte[] root_dir = imagePlugin.ReadSector((ulong)BitConverter.ToInt32(RootDirectoryLocation, 0) + partition.Start);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2014-07-09 19:50:16 +01:00
|
|
|
|
byte[] SUSPMagic = new byte[2];
|
|
|
|
|
|
byte[] RRMagic = new byte[2];
|
|
|
|
|
|
|
|
|
|
|
|
Array.Copy(root_dir, 0x22, SUSPMagic, 0, 2);
|
2017-06-06 21:23:20 +01:00
|
|
|
|
if(CurrentEncoding.GetString(SUSPMagic) == "SP")
|
2014-07-09 19:50:16 +01:00
|
|
|
|
{
|
|
|
|
|
|
Array.Copy(root_dir, 0x29, RRMagic, 0, 2);
|
2017-06-06 21:23:20 +01:00
|
|
|
|
RockRidge |= CurrentEncoding.GetString(RRMagic) == "RR";
|
2014-07-09 19:50:16 +01:00
|
|
|
|
}
|
2017-07-25 15:00:12 +01:00
|
|
|
|
}*/
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2017-07-19 16:37:11 +01:00
|
|
|
|
byte[] ipbin_sector = imagePlugin.ReadSector(0 + partition.Start);
|
2017-10-08 17:50:29 +01:00
|
|
|
|
Decoders.Sega.CD.IPBin? SegaCD = Decoders.Sega.CD.DecodeIPBin(ipbin_sector);
|
|
|
|
|
|
Decoders.Sega.Saturn.IPBin? Saturn = Decoders.Sega.Saturn.DecodeIPBin(ipbin_sector);
|
|
|
|
|
|
Decoders.Sega.Dreamcast.IPBin? Dreamcast = Decoders.Sega.Dreamcast.DecodeIPBin(ipbin_sector);
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
|
|
|
|
|
ISOMetadata.AppendFormat("ISO9660 file system").AppendLine();
|
2017-10-08 20:28:56 +01:00
|
|
|
|
if(jolietvd != null)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
ISOMetadata.AppendFormat("Joliet extensions present.").AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(RockRidge)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
ISOMetadata.AppendFormat("Rock Ridge Interchange Protocol present.").AppendLine();
|
2017-10-08 20:28:56 +01:00
|
|
|
|
if(bvd != null)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
ISOMetadata.AppendFormat("Disc bootable following {0} specifications.", BootSpec).AppendLine();
|
2017-10-08 17:50:29 +01:00
|
|
|
|
if(SegaCD != null)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
|
|
|
|
|
ISOMetadata.AppendLine("This is a SegaCD / MegaCD disc.");
|
2017-10-08 17:50:29 +01:00
|
|
|
|
ISOMetadata.AppendLine(Decoders.Sega.CD.Prettify(SegaCD));
|
2011-03-03 18:34:33 +00:00
|
|
|
|
}
|
2017-10-08 17:50:29 +01:00
|
|
|
|
if(Saturn != null)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
|
|
|
|
|
ISOMetadata.AppendLine("This is a Sega Saturn disc.");
|
2017-10-08 17:50:29 +01:00
|
|
|
|
ISOMetadata.AppendLine(Decoders.Sega.Saturn.Prettify(Saturn));
|
2011-03-03 18:34:33 +00:00
|
|
|
|
}
|
2017-10-08 17:50:29 +01:00
|
|
|
|
if(Dreamcast != null)
|
2011-03-03 18:34:33 +00:00
|
|
|
|
{
|
|
|
|
|
|
ISOMetadata.AppendLine("This is a Sega Dreamcast disc.");
|
2017-10-08 17:50:29 +01:00
|
|
|
|
ISOMetadata.AppendLine(Decoders.Sega.Dreamcast.Prettify(Dreamcast));
|
2011-03-03 18:34:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
ISOMetadata.AppendLine("--------------------------------");
|
|
|
|
|
|
ISOMetadata.AppendLine("VOLUME DESCRIPTOR INFORMATION:");
|
|
|
|
|
|
ISOMetadata.AppendLine("--------------------------------");
|
|
|
|
|
|
ISOMetadata.AppendFormat("System identifier: {0}", decodedVD.SystemIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume identifier: {0}", decodedVD.VolumeIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume set identifier: {0}", decodedVD.VolumeSetIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Publisher identifier: {0}", decodedVD.PublisherIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Data preparer identifier: {0}", decodedVD.DataPreparerIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Application identifier: {0}", decodedVD.ApplicationIdentifier).AppendLine();
|
2014-04-14 02:29:13 +00:00
|
|
|
|
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedVD.CreationTime).AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedVD.HasModificationTime)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedVD.ModificationTime).AppendLine();
|
2011-03-03 18:34:33 +00:00
|
|
|
|
else
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume has not been modified.").AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedVD.HasExpirationTime)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedVD.ExpirationTime).AppendLine();
|
2011-03-03 18:34:33 +00:00
|
|
|
|
else
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume does not expire.").AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedVD.HasEffectiveTime)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
ISOMetadata.AppendFormat("Volume effective date: {0}", decodedVD.EffectiveTime).AppendLine();
|
2011-03-03 18:34:33 +00:00
|
|
|
|
else
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
2017-10-08 21:54:56 +01:00
|
|
|
|
ISOMetadata.AppendFormat("Volume has {0} blocks of {1} bytes each", decodedVD.Blocks, decodedVD.BlockSize).AppendLine();
|
2011-03-03 18:34:33 +00:00
|
|
|
|
|
2017-10-08 20:28:56 +01:00
|
|
|
|
if(jolietvd != null)
|
2016-04-19 02:11:47 +01:00
|
|
|
|
{
|
|
|
|
|
|
ISOMetadata.AppendLine("---------------------------------------");
|
|
|
|
|
|
ISOMetadata.AppendLine("JOLIET VOLUME DESCRIPTOR INFORMATION:");
|
|
|
|
|
|
ISOMetadata.AppendLine("---------------------------------------");
|
|
|
|
|
|
ISOMetadata.AppendFormat("System identifier: {0}", decodedJolietVD.SystemIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume identifier: {0}", decodedJolietVD.VolumeIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume set identifier: {0}", decodedJolietVD.VolumeSetIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Publisher identifier: {0}", decodedJolietVD.PublisherIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Data preparer identifier: {0}", decodedJolietVD.DataPreparerIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Application identifier: {0}", decodedJolietVD.ApplicationIdentifier).AppendLine();
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume creation date: {0}", decodedJolietVD.CreationTime).AppendLine();
|
|
|
|
|
|
if(decodedJolietVD.HasModificationTime)
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume modification date: {0}", decodedJolietVD.ModificationTime).AppendLine();
|
|
|
|
|
|
else
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume has not been modified.").AppendLine();
|
|
|
|
|
|
if(decodedJolietVD.HasExpirationTime)
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume expiration date: {0}", decodedJolietVD.ExpirationTime).AppendLine();
|
|
|
|
|
|
else
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume does not expire.").AppendLine();
|
|
|
|
|
|
if(decodedJolietVD.HasEffectiveTime)
|
2014-04-14 02:29:13 +00:00
|
|
|
|
ISOMetadata.AppendFormat("Volume effective date: {0}", decodedJolietVD.EffectiveTime).AppendLine();
|
2016-04-19 02:11:47 +01:00
|
|
|
|
else
|
|
|
|
|
|
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
|
|
|
|
|
}
|
2012-08-03 05:43:58 +00:00
|
|
|
|
|
2015-12-05 17:10:27 +00:00
|
|
|
|
xmlFSType.Type = "ISO9660";
|
2015-12-23 23:46:31 +00:00
|
|
|
|
|
2017-10-08 20:28:56 +01:00
|
|
|
|
if(jolietvd != null)
|
2015-12-05 17:10:27 +00:00
|
|
|
|
{
|
2015-12-06 05:09:31 +00:00
|
|
|
|
xmlFSType.VolumeName = decodedJolietVD.VolumeIdentifier;
|
2015-12-23 23:46:31 +00:00
|
|
|
|
|
|
|
|
|
|
if(decodedJolietVD.SystemIdentifier == null || decodedVD.SystemIdentifier.Length > decodedJolietVD.SystemIdentifier.Length)
|
|
|
|
|
|
xmlFSType.SystemIdentifier = decodedVD.SystemIdentifier;
|
|
|
|
|
|
else
|
|
|
|
|
|
xmlFSType.SystemIdentifier = decodedJolietVD.SystemIdentifier;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2015-12-23 23:46:31 +00:00
|
|
|
|
if(decodedJolietVD.VolumeSetIdentifier == null || decodedVD.VolumeSetIdentifier.Length > decodedJolietVD.VolumeSetIdentifier.Length)
|
|
|
|
|
|
xmlFSType.VolumeSetIdentifier = decodedVD.VolumeSetIdentifier;
|
|
|
|
|
|
else
|
|
|
|
|
|
xmlFSType.VolumeSetIdentifier = decodedJolietVD.VolumeSetIdentifier;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2015-12-23 23:46:31 +00:00
|
|
|
|
if(decodedJolietVD.PublisherIdentifier == null || decodedVD.PublisherIdentifier.Length > decodedJolietVD.PublisherIdentifier.Length)
|
|
|
|
|
|
xmlFSType.PublisherIdentifier = decodedVD.PublisherIdentifier;
|
|
|
|
|
|
else
|
|
|
|
|
|
xmlFSType.PublisherIdentifier = decodedJolietVD.PublisherIdentifier;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2015-12-23 23:46:31 +00:00
|
|
|
|
if(decodedJolietVD.DataPreparerIdentifier == null || decodedVD.DataPreparerIdentifier.Length > decodedJolietVD.DataPreparerIdentifier.Length)
|
|
|
|
|
|
xmlFSType.DataPreparerIdentifier = decodedVD.DataPreparerIdentifier;
|
|
|
|
|
|
else
|
|
|
|
|
|
xmlFSType.DataPreparerIdentifier = decodedJolietVD.SystemIdentifier;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
|
2015-12-23 23:46:31 +00:00
|
|
|
|
if(decodedJolietVD.ApplicationIdentifier == null || decodedVD.ApplicationIdentifier.Length > decodedJolietVD.ApplicationIdentifier.Length)
|
|
|
|
|
|
xmlFSType.ApplicationIdentifier = decodedVD.ApplicationIdentifier;
|
|
|
|
|
|
else
|
|
|
|
|
|
xmlFSType.ApplicationIdentifier = decodedJolietVD.SystemIdentifier;
|
|
|
|
|
|
|
2015-12-06 05:09:31 +00:00
|
|
|
|
xmlFSType.CreationDate = decodedJolietVD.CreationTime;
|
|
|
|
|
|
xmlFSType.CreationDateSpecified = true;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedJolietVD.HasModificationTime)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
|
|
|
|
|
xmlFSType.ModificationDate = decodedJolietVD.ModificationTime;
|
|
|
|
|
|
xmlFSType.ModificationDateSpecified = true;
|
|
|
|
|
|
}
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedJolietVD.HasExpirationTime)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
|
|
|
|
|
xmlFSType.ExpirationDate = decodedJolietVD.ExpirationTime;
|
|
|
|
|
|
xmlFSType.ExpirationDateSpecified = true;
|
|
|
|
|
|
}
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedJolietVD.HasEffectiveTime)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
|
|
|
|
|
xmlFSType.EffectiveDate = decodedJolietVD.EffectiveTime;
|
|
|
|
|
|
xmlFSType.EffectiveDateSpecified = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
xmlFSType.SystemIdentifier = decodedVD.SystemIdentifier;
|
|
|
|
|
|
xmlFSType.VolumeName = decodedVD.VolumeIdentifier;
|
|
|
|
|
|
xmlFSType.VolumeSetIdentifier = decodedVD.VolumeSetIdentifier;
|
|
|
|
|
|
xmlFSType.PublisherIdentifier = decodedVD.PublisherIdentifier;
|
|
|
|
|
|
xmlFSType.DataPreparerIdentifier = decodedVD.DataPreparerIdentifier;
|
|
|
|
|
|
xmlFSType.ApplicationIdentifier = decodedVD.ApplicationIdentifier;
|
|
|
|
|
|
xmlFSType.CreationDate = decodedVD.CreationTime;
|
|
|
|
|
|
xmlFSType.CreationDateSpecified = true;
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedVD.HasModificationTime)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
|
|
|
|
|
xmlFSType.ModificationDate = decodedVD.ModificationTime;
|
|
|
|
|
|
xmlFSType.ModificationDateSpecified = true;
|
|
|
|
|
|
}
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedVD.HasExpirationTime)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
|
|
|
|
|
xmlFSType.ExpirationDate = decodedVD.ExpirationTime;
|
|
|
|
|
|
xmlFSType.ExpirationDateSpecified = true;
|
|
|
|
|
|
}
|
2016-04-19 02:11:47 +01:00
|
|
|
|
if(decodedVD.HasEffectiveTime)
|
2015-12-06 05:09:31 +00:00
|
|
|
|
{
|
|
|
|
|
|
xmlFSType.EffectiveDate = decodedVD.EffectiveTime;
|
|
|
|
|
|
xmlFSType.EffectiveDateSpecified = true;
|
|
|
|
|
|
}
|
2015-12-05 17:10:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-08 20:28:56 +01:00
|
|
|
|
xmlFSType.Bootable |= bvd != null || SegaCD != null || Saturn != null || Dreamcast != null;
|
2017-10-08 21:54:56 +01:00
|
|
|
|
xmlFSType.Clusters = decodedVD.Blocks;
|
|
|
|
|
|
xmlFSType.ClusterSize = decodedVD.BlockSize;
|
2015-12-06 05:09:31 +00:00
|
|
|
|
|
2011-03-03 18:34:33 +00:00
|
|
|
|
information = ISOMetadata.ToString();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-10-08 20:41:54 +01:00
|
|
|
|
}
|