mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Use structures and marshalling in ISO9660.
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscImageChef.CommonTypes;
|
using DiscImageChef.CommonTypes;
|
||||||
using DiscImageChef.Console;
|
using DiscImageChef.Console;
|
||||||
@@ -62,6 +63,79 @@ namespace DiscImageChef.Filesystems
|
|||||||
CurrentEncoding = Encoding.ASCII;
|
CurrentEncoding = Encoding.ASCII;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct PrimaryVolumeDescriptor
|
||||||
|
{
|
||||||
|
public byte type;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||||
|
public byte[] id;
|
||||||
|
public byte version;
|
||||||
|
// Only used in SVDs
|
||||||
|
public byte flags;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] system_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] volume_id;
|
||||||
|
public ulong reserved2;
|
||||||
|
public ulong volume_space_size;
|
||||||
|
// Only used in SVDs
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] escape_sequences;
|
||||||
|
public uint volume_set_size;
|
||||||
|
public uint volume_sequence_number;
|
||||||
|
public uint logical_block_size;
|
||||||
|
public ulong path_table_size;
|
||||||
|
public uint type_1_path_table;
|
||||||
|
public uint opt_type_1_path_table;
|
||||||
|
public uint type_m_path_table;
|
||||||
|
public uint opt_type_m_path_table;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 34)]
|
||||||
|
public byte[] root_directory_record;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
|
||||||
|
public byte[] volume_set_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
|
||||||
|
public byte[] publisher_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
|
||||||
|
public byte[] preparer_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
|
||||||
|
public byte[] application_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
|
||||||
|
public byte[] copyright_file_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
|
||||||
|
public byte[] abstract_file_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
|
||||||
|
public byte[] bibliographic_file_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
|
||||||
|
public byte[] creation_date;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
|
||||||
|
public byte[] modification_date;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
|
||||||
|
public byte[] expiration_date;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
|
||||||
|
public byte[] effective_date;
|
||||||
|
public byte file_structure_version;
|
||||||
|
public byte reserved4;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
|
||||||
|
public byte[] application_data;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 653)]
|
||||||
|
public byte[] reserved5;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct BootRecord
|
||||||
|
{
|
||||||
|
public byte type;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||||
|
public byte[] id;
|
||||||
|
public byte version;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] system_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] boot_id;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1977)]
|
||||||
|
public byte[] boot_use;
|
||||||
|
}
|
||||||
|
|
||||||
struct DecodedVolumeDescriptor
|
struct DecodedVolumeDescriptor
|
||||||
{
|
{
|
||||||
public string SystemIdentifier;
|
public string SystemIdentifier;
|
||||||
@@ -120,40 +194,19 @@ namespace DiscImageChef.Filesystems
|
|||||||
{
|
{
|
||||||
information = "";
|
information = "";
|
||||||
StringBuilder ISOMetadata = new StringBuilder();
|
StringBuilder ISOMetadata = new StringBuilder();
|
||||||
bool Joliet = false;
|
|
||||||
bool Bootable = false;
|
|
||||||
bool RockRidge = false;
|
bool RockRidge = false;
|
||||||
byte VDType; // Volume Descriptor Type, should be 1 or 2.
|
byte VDType; // Volume Descriptor Type, should be 1 or 2.
|
||||||
byte[] VDMagic = new byte[5]; // Volume Descriptor magic "CD001"
|
byte[] VDMagic = new byte[5]; // Volume Descriptor magic "CD001"
|
||||||
byte[] VDSysId = new byte[32]; // System Identifier
|
|
||||||
byte[] VDVolId = new byte[32]; // Volume Identifier
|
|
||||||
byte[] VDVolSetId = new byte[128]; // Volume Set Identifier
|
|
||||||
byte[] VDPubId = new byte[128]; // Publisher Identifier
|
|
||||||
byte[] VDDataPrepId = new byte[128]; // Data Preparer Identifier
|
|
||||||
byte[] VDAppId = new byte[128]; // Application Identifier
|
|
||||||
byte[] VCTime = new byte[17]; // Volume Creation Date and Time
|
|
||||||
byte[] VMTime = new byte[17]; // Volume Modification Date and Time
|
|
||||||
byte[] VXTime = new byte[17]; // Volume Expiration Date and Time
|
|
||||||
byte[] VETime = new byte[17]; // Volume Effective Date and Time
|
|
||||||
|
|
||||||
byte[] JolietMagic = new byte[3];
|
|
||||||
byte[] JolietSysId = new byte[32]; // System Identifier
|
|
||||||
byte[] JolietVolId = new byte[32]; // Volume Identifier
|
|
||||||
byte[] JolietVolSetId = new byte[128]; // Volume Set Identifier
|
|
||||||
byte[] JolietPubId = new byte[128]; // Publisher Identifier
|
|
||||||
byte[] JolietDataPrepId = new byte[128]; // Data Preparer Identifier
|
|
||||||
byte[] JolietAppId = new byte[128]; // Application Identifier
|
|
||||||
byte[] JolietCTime = new byte[17]; // Volume Creation Date and Time
|
|
||||||
byte[] JolietMTime = new byte[17]; // Volume Modification Date and Time
|
|
||||||
byte[] JolietXTime = new byte[17]; // Volume Expiration Date and Time
|
|
||||||
byte[] JolietETime = new byte[17]; // Volume Effective Date and Time
|
|
||||||
|
|
||||||
byte[] BootSysId = new byte[32];
|
|
||||||
string BootSpec = "";
|
string BootSpec = "";
|
||||||
|
|
||||||
byte[] VDPathTableStart = new byte[4];
|
byte[] VDPathTableStart = new byte[4];
|
||||||
byte[] RootDirectoryLocation = new byte[4];
|
byte[] RootDirectoryLocation = new byte[4];
|
||||||
|
|
||||||
|
PrimaryVolumeDescriptor? pvd = null;
|
||||||
|
PrimaryVolumeDescriptor? jolietvd = null;
|
||||||
|
BootRecord? bvd = null;
|
||||||
|
|
||||||
// ISO9660 is designed for 2048 bytes/sector devices
|
// ISO9660 is designed for 2048 bytes/sector devices
|
||||||
if(imagePlugin.GetSectorSize() < 2048)
|
if(imagePlugin.GetSectorSize() < 2048)
|
||||||
return;
|
return;
|
||||||
@@ -202,49 +255,42 @@ namespace DiscImageChef.Filesystems
|
|||||||
{
|
{
|
||||||
case 0: // TODO
|
case 0: // TODO
|
||||||
{
|
{
|
||||||
Bootable = true;
|
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);
|
||||||
|
|
||||||
BootSpec = "Unknown";
|
BootSpec = "Unknown";
|
||||||
|
|
||||||
// Read to boot system identifier
|
if(CurrentEncoding.GetString(bvd.Value.system_id).Substring(0, 23) == "EL TORITO SPECIFICATION")
|
||||||
Array.Copy(vd_sector, 0x007, BootSysId, 0, 32);
|
|
||||||
|
|
||||||
if(CurrentEncoding.GetString(BootSysId).Substring(0, 23) == "EL TORITO SPECIFICATION")
|
|
||||||
BootSpec = "El Torito";
|
BootSpec = "El Torito";
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
// Read first identifiers
|
pvd = new PrimaryVolumeDescriptor();
|
||||||
Array.Copy(vd_sector, 0x008, VDSysId, 0, 32);
|
IntPtr ptr = Marshal.AllocHGlobal(2048);
|
||||||
Array.Copy(vd_sector, 0x028, VDVolId, 0, 32);
|
Marshal.Copy(vd_sector, 0, ptr, 2048);
|
||||||
|
pvd = (PrimaryVolumeDescriptor)Marshal.PtrToStructure(ptr, typeof(PrimaryVolumeDescriptor));
|
||||||
// Get path table start
|
Marshal.FreeHGlobal(ptr);
|
||||||
Array.Copy(vd_sector, 0x08C, VDPathTableStart, 0, 4);
|
|
||||||
|
|
||||||
// Read next identifiers
|
|
||||||
Array.Copy(vd_sector, 0x0BE, VDVolSetId, 0, 128);
|
|
||||||
Array.Copy(vd_sector, 0x13E, VDPubId, 0, 128);
|
|
||||||
Array.Copy(vd_sector, 0x1BE, VDDataPrepId, 0, 128);
|
|
||||||
Array.Copy(vd_sector, 0x23E, VDAppId, 0, 128);
|
|
||||||
|
|
||||||
// Read dates
|
|
||||||
Array.Copy(vd_sector, 0x32D, VCTime, 0, 17);
|
|
||||||
Array.Copy(vd_sector, 0x33E, VMTime, 0, 17);
|
|
||||||
Array.Copy(vd_sector, 0x34F, VXTime, 0, 17);
|
|
||||||
Array.Copy(vd_sector, 0x360, VETime, 0, 17);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
// Check if this is Joliet
|
// Check if this is Joliet
|
||||||
Array.Copy(vd_sector, 0x058, JolietMagic, 0, 3);
|
if(svd.escape_sequences[0] == '%' && svd.escape_sequences[1] == '/')
|
||||||
if(JolietMagic[0] == '%' && JolietMagic[1] == '/')
|
|
||||||
{
|
{
|
||||||
if(JolietMagic[2] == '@' || JolietMagic[2] == 'C' || JolietMagic[2] == 'E')
|
if(svd.escape_sequences[2] == '@' || svd.escape_sequences[2] == 'C' || svd.escape_sequences[2] == 'E')
|
||||||
{
|
{
|
||||||
Joliet = true;
|
jolietvd = svd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -252,23 +298,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
DicConsole.WriteLine("ISO9660 plugin", "Found unknown supplementary volume descriptor");
|
||||||
|
|
||||||
// Read first identifiers
|
|
||||||
Array.Copy(vd_sector, 0x008, JolietSysId, 0, 32);
|
|
||||||
Array.Copy(vd_sector, 0x028, JolietVolId, 0, 32);
|
|
||||||
|
|
||||||
// Read next identifiers
|
|
||||||
Array.Copy(vd_sector, 0x0BE, JolietVolSetId, 0, 128);
|
|
||||||
Array.Copy(vd_sector, 0x13E, JolietPubId, 0, 128);
|
|
||||||
Array.Copy(vd_sector, 0x13E, JolietDataPrepId, 0, 128);
|
|
||||||
Array.Copy(vd_sector, 0x13E, JolietAppId, 0, 128);
|
|
||||||
|
|
||||||
// Read dates
|
|
||||||
Array.Copy(vd_sector, 0x32D, JolietCTime, 0, 17);
|
|
||||||
Array.Copy(vd_sector, 0x33E, JolietMTime, 0, 17);
|
|
||||||
Array.Copy(vd_sector, 0x34F, JolietXTime, 0, 17);
|
|
||||||
Array.Copy(vd_sector, 0x360, JolietETime, 0, 17);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -280,9 +310,17 @@ namespace DiscImageChef.Filesystems
|
|||||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||||
DecodedVolumeDescriptor decodedJolietVD = new DecodedVolumeDescriptor();
|
DecodedVolumeDescriptor decodedJolietVD = new DecodedVolumeDescriptor();
|
||||||
|
|
||||||
decodedVD = DecodeVolumeDescriptor(VDSysId, VDVolId, VDVolSetId, VDPubId, VDDataPrepId, VDAppId, VCTime, VMTime, VXTime, VETime);
|
xmlFSType = new Schemas.FileSystemType();
|
||||||
if(Joliet)
|
|
||||||
decodedJolietVD = DecodeJolietDescriptor(JolietSysId, JolietVolId, JolietVolSetId, JolietPubId, JolietDataPrepId, JolietAppId, JolietCTime, JolietMTime, JolietXTime, JolietETime);
|
if(pvd == null)
|
||||||
|
{
|
||||||
|
information = "ERROR: Could not find primary volume descriptor";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
decodedVD = DecodeVolumeDescriptor(pvd.Value);
|
||||||
|
if(jolietvd != null)
|
||||||
|
decodedJolietVD = DecodeJolietDescriptor(jolietvd.Value);
|
||||||
|
|
||||||
|
|
||||||
ulong i = (ulong)BitConverter.ToInt32(VDPathTableStart, 0);
|
ulong i = (ulong)BitConverter.ToInt32(VDPathTableStart, 0);
|
||||||
@@ -315,11 +353,11 @@ namespace DiscImageChef.Filesystems
|
|||||||
Decoders.Sega.Dreamcast.IPBin? Dreamcast = Decoders.Sega.Dreamcast.DecodeIPBin(ipbin_sector);
|
Decoders.Sega.Dreamcast.IPBin? Dreamcast = Decoders.Sega.Dreamcast.DecodeIPBin(ipbin_sector);
|
||||||
|
|
||||||
ISOMetadata.AppendFormat("ISO9660 file system").AppendLine();
|
ISOMetadata.AppendFormat("ISO9660 file system").AppendLine();
|
||||||
if(Joliet)
|
if(jolietvd != null)
|
||||||
ISOMetadata.AppendFormat("Joliet extensions present.").AppendLine();
|
ISOMetadata.AppendFormat("Joliet extensions present.").AppendLine();
|
||||||
if(RockRidge)
|
if(RockRidge)
|
||||||
ISOMetadata.AppendFormat("Rock Ridge Interchange Protocol present.").AppendLine();
|
ISOMetadata.AppendFormat("Rock Ridge Interchange Protocol present.").AppendLine();
|
||||||
if(Bootable)
|
if(bvd != null)
|
||||||
ISOMetadata.AppendFormat("Disc bootable following {0} specifications.", BootSpec).AppendLine();
|
ISOMetadata.AppendFormat("Disc bootable following {0} specifications.", BootSpec).AppendLine();
|
||||||
if(SegaCD != null)
|
if(SegaCD != null)
|
||||||
{
|
{
|
||||||
@@ -359,7 +397,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
else
|
else
|
||||||
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
||||||
|
|
||||||
if(Joliet)
|
if(jolietvd != null)
|
||||||
{
|
{
|
||||||
ISOMetadata.AppendLine("---------------------------------------");
|
ISOMetadata.AppendLine("---------------------------------------");
|
||||||
ISOMetadata.AppendLine("JOLIET VOLUME DESCRIPTOR INFORMATION:");
|
ISOMetadata.AppendLine("JOLIET VOLUME DESCRIPTOR INFORMATION:");
|
||||||
@@ -385,10 +423,9 @@ namespace DiscImageChef.Filesystems
|
|||||||
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
ISOMetadata.AppendFormat("Volume has always been effective.").AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlFSType = new Schemas.FileSystemType();
|
|
||||||
xmlFSType.Type = "ISO9660";
|
xmlFSType.Type = "ISO9660";
|
||||||
|
|
||||||
if(Joliet)
|
if(jolietvd != null)
|
||||||
{
|
{
|
||||||
xmlFSType.VolumeName = decodedJolietVD.VolumeIdentifier;
|
xmlFSType.VolumeName = decodedJolietVD.VolumeIdentifier;
|
||||||
|
|
||||||
@@ -462,104 +499,104 @@ namespace DiscImageChef.Filesystems
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlFSType.Bootable |= Bootable || SegaCD != null || Saturn != null || Dreamcast != null;
|
xmlFSType.Bootable |= bvd != null || SegaCD != null || Saturn != null || Dreamcast != null;
|
||||||
xmlFSType.Clusters = (long)(partition.End - partition.Start + 1);
|
xmlFSType.Clusters = (long)(partition.End - partition.Start + 1);
|
||||||
xmlFSType.ClusterSize = 2048;
|
xmlFSType.ClusterSize = 2048;
|
||||||
|
|
||||||
information = ISOMetadata.ToString();
|
information = ISOMetadata.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static DecodedVolumeDescriptor DecodeJolietDescriptor(byte[] VDSysId, byte[] VDVolId, byte[] VDVolSetId, byte[] VDPubId, byte[] VDDataPrepId, byte[] VDAppId, byte[] VCTime, byte[] VMTime, byte[] VXTime, byte[] VETime)
|
static DecodedVolumeDescriptor DecodeJolietDescriptor(PrimaryVolumeDescriptor jolietvd)
|
||||||
{
|
{
|
||||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||||
|
|
||||||
decodedVD.SystemIdentifier = Encoding.BigEndianUnicode.GetString(VDSysId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.SystemIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.system_id).TrimEnd().Trim(new[] { '\u0000' });
|
||||||
decodedVD.VolumeIdentifier = Encoding.BigEndianUnicode.GetString(VDVolId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.VolumeIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.volume_id).TrimEnd().Trim(new[] { '\u0000' });
|
||||||
decodedVD.VolumeSetIdentifier = Encoding.BigEndianUnicode.GetString(VDVolSetId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.VolumeSetIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.volume_set_id).TrimEnd().Trim(new[] { '\u0000' });
|
||||||
decodedVD.PublisherIdentifier = Encoding.BigEndianUnicode.GetString(VDPubId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.PublisherIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.publisher_id).TrimEnd().Trim(new[] { '\u0000' });
|
||||||
decodedVD.DataPreparerIdentifier = Encoding.BigEndianUnicode.GetString(VDDataPrepId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.DataPreparerIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.preparer_id).TrimEnd().Trim(new[] { '\u0000' });
|
||||||
decodedVD.ApplicationIdentifier = Encoding.BigEndianUnicode.GetString(VDAppId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.ApplicationIdentifier = Encoding.BigEndianUnicode.GetString(jolietvd.application_id).TrimEnd().Trim(new[] { '\u0000' });
|
||||||
if(VCTime[0] < 0x31 || VCTime[0] > 0x39)
|
if(jolietvd.creation_date[0] < 0x31 || jolietvd.creation_date[0] > 0x39)
|
||||||
decodedVD.CreationTime = DateTime.MinValue;
|
decodedVD.CreationTime = DateTime.MinValue;
|
||||||
else
|
else
|
||||||
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(VCTime);
|
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(jolietvd.creation_date);
|
||||||
|
|
||||||
if(VMTime[0] < 0x31 || VMTime[0] > 0x39)
|
if(jolietvd.modification_date[0] < 0x31 || jolietvd.modification_date[0] > 0x39)
|
||||||
{
|
{
|
||||||
decodedVD.HasModificationTime = false;
|
decodedVD.HasModificationTime = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
decodedVD.HasModificationTime = true;
|
decodedVD.HasModificationTime = true;
|
||||||
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(VMTime);
|
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(jolietvd.modification_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VXTime[0] < 0x31 || VXTime[0] > 0x39)
|
if(jolietvd.expiration_date[0] < 0x31 || jolietvd.expiration_date[0] > 0x39)
|
||||||
{
|
{
|
||||||
decodedVD.HasExpirationTime = false;
|
decodedVD.HasExpirationTime = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
decodedVD.HasExpirationTime = true;
|
decodedVD.HasExpirationTime = true;
|
||||||
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(VXTime);
|
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(jolietvd.expiration_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VETime[0] < 0x31 || VETime[0] > 0x39)
|
if(jolietvd.effective_date[0] < 0x31 || jolietvd.effective_date[0] > 0x39)
|
||||||
{
|
{
|
||||||
decodedVD.HasEffectiveTime = false;
|
decodedVD.HasEffectiveTime = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
decodedVD.HasEffectiveTime = true;
|
decodedVD.HasEffectiveTime = true;
|
||||||
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(VETime);
|
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(jolietvd.effective_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
return decodedVD;
|
return decodedVD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DecodedVolumeDescriptor DecodeVolumeDescriptor(byte[] VDSysId, byte[] VDVolId, byte[] VDVolSetId, byte[] VDPubId, byte[] VDDataPrepId, byte[] VDAppId, byte[] VCTime, byte[] VMTime, byte[] VXTime, byte[] VETime)
|
static DecodedVolumeDescriptor DecodeVolumeDescriptor(PrimaryVolumeDescriptor pvd)
|
||||||
{
|
{
|
||||||
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor();
|
||||||
|
|
||||||
decodedVD.SystemIdentifier = Encoding.ASCII.GetString(VDSysId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.SystemIdentifier = Encoding.ASCII.GetString(pvd.system_id).TrimEnd().Trim(new[] { '\0' });
|
||||||
decodedVD.VolumeIdentifier = Encoding.ASCII.GetString(VDVolId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.VolumeIdentifier = Encoding.ASCII.GetString(pvd.volume_id).TrimEnd().Trim(new[] { '\0' });
|
||||||
decodedVD.VolumeSetIdentifier = Encoding.ASCII.GetString(VDVolSetId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.VolumeSetIdentifier = Encoding.ASCII.GetString(pvd.volume_set_id).TrimEnd().Trim(new[] { '\0' });
|
||||||
decodedVD.PublisherIdentifier = Encoding.ASCII.GetString(VDPubId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.PublisherIdentifier = Encoding.ASCII.GetString(pvd.publisher_id).TrimEnd().Trim(new[] { '\0' });
|
||||||
decodedVD.DataPreparerIdentifier = Encoding.ASCII.GetString(VDDataPrepId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.DataPreparerIdentifier = Encoding.ASCII.GetString(pvd.preparer_id).TrimEnd().Trim(new[] { '\0' });
|
||||||
decodedVD.ApplicationIdentifier = Encoding.ASCII.GetString(VDAppId).TrimEnd().Trim(new[] { '\u0000' });
|
decodedVD.ApplicationIdentifier = Encoding.ASCII.GetString(pvd.application_data).TrimEnd().Trim(new[] { '\0' });
|
||||||
if(VCTime[0] == '0' || VCTime[0] == 0x00)
|
if(pvd.creation_date[0] == '0' || pvd.creation_date[0] == 0x00)
|
||||||
decodedVD.CreationTime = DateTime.MinValue;
|
decodedVD.CreationTime = DateTime.MinValue;
|
||||||
else
|
else
|
||||||
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(VCTime);
|
decodedVD.CreationTime = DateHandlers.ISO9660ToDateTime(pvd.creation_date);
|
||||||
|
|
||||||
if(VMTime[0] == '0' || VMTime[0] == 0x00)
|
if(pvd.modification_date[0] == '0' || pvd.modification_date[0] == 0x00)
|
||||||
{
|
{
|
||||||
decodedVD.HasModificationTime = false;
|
decodedVD.HasModificationTime = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
decodedVD.HasModificationTime = true;
|
decodedVD.HasModificationTime = true;
|
||||||
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(VMTime);
|
decodedVD.ModificationTime = DateHandlers.ISO9660ToDateTime(pvd.modification_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VXTime[0] == '0' || VXTime[0] == 0x00)
|
if(pvd.expiration_date[0] == '0' || pvd.expiration_date[0] == 0x00)
|
||||||
{
|
{
|
||||||
decodedVD.HasExpirationTime = false;
|
decodedVD.HasExpirationTime = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
decodedVD.HasExpirationTime = true;
|
decodedVD.HasExpirationTime = true;
|
||||||
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(VXTime);
|
decodedVD.ExpirationTime = DateHandlers.ISO9660ToDateTime(pvd.expiration_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(VETime[0] == '0' || VETime[0] == 0x00)
|
if(pvd.effective_date[0] == '0' || pvd.effective_date[0] == 0x00)
|
||||||
{
|
{
|
||||||
decodedVD.HasEffectiveTime = false;
|
decodedVD.HasEffectiveTime = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
decodedVD.HasEffectiveTime = true;
|
decodedVD.HasEffectiveTime = true;
|
||||||
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(VETime);
|
decodedVD.EffectiveTime = DateHandlers.ISO9660ToDateTime(pvd.effective_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
return decodedVD;
|
return decodedVD;
|
||||||
|
|||||||
Reference in New Issue
Block a user