Files
Aaru/Aaru.Core/ImageInfo.cs

996 lines
42 KiB
C#
Raw Normal View History

2018-01-28 16:05:54 +00:00
// /***************************************************************************
2020-02-27 12:31:25 +00:00
// Aaru Data Preservation Suite
2018-01-28 16:05:54 +00:00
// ----------------------------------------------------------------------------
//
// Filename : ImageInfo.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Core algorithms.
//
// --[ Description ] ----------------------------------------------------------
//
// Prints image information to console.
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 General public License for more details.
//
// You should have received a copy of the GNU General public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
2024-12-19 10:45:18 +00:00
// Copyright © 2011-2025 Natalia Portillo
2018-01-28 16:05:54 +00:00
// ****************************************************************************/
using System;
2020-06-17 20:34:35 +01:00
using System.Collections.Generic;
2018-01-28 16:05:54 +00:00
using System.Linq;
using System.Text;
2021-11-21 20:39:19 +00:00
using System.Text.Json;
using System.Text.Json.Serialization;
using Aaru.CommonTypes.AaruMetadata;
2020-02-27 00:33:26 +00:00
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Decoders.ATA;
using Aaru.Decoders.Bluray;
using Aaru.Decoders.CD;
using Aaru.Decoders.DVD;
using Aaru.Decoders.PCMCIA;
using Aaru.Decoders.SCSI;
using Aaru.Decoders.Xbox;
2020-07-20 15:43:52 +01:00
using Aaru.Helpers;
using Aaru.Logging;
2024-04-26 03:18:47 +01:00
using Humanizer;
2025-08-20 18:51:05 +01:00
using Sentry;
using Spectre.Console;
2025-08-18 02:34:48 +01:00
using Spectre.Console.Json;
2020-02-27 00:33:26 +00:00
using DDS = Aaru.Decoders.DVD.DDS;
using DMI = Aaru.Decoders.Xbox.DMI;
using Inquiry = Aaru.Decoders.SCSI.Inquiry;
using Session = Aaru.CommonTypes.Structs.Session;
using Track = Aaru.CommonTypes.Structs.Track;
2020-02-27 00:33:26 +00:00
using Tuple = Aaru.Decoders.PCMCIA.Tuple;
2018-01-28 16:05:54 +00:00
namespace Aaru.Core;
/// <summary>Image information operations</summary>
public static class ImageInfo
2018-01-28 16:05:54 +00:00
{
const string MODULE_NAME = "Image information";
/// <summary>Prints image information to console</summary>
/// <param name="imageFormat">Media image</param>
public static void PrintImageInfo(IBaseImage imageFormat)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Image_information_WithMarkup);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Version))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Format_0_version_1_WithMarkup,
2024-05-01 04:05:22 +01:00
Markup.Escape(imageFormat.Format),
Markup.Escape(imageFormat.Info.Version));
2023-10-03 22:57:50 +01:00
}
else
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Format_0_WithMarkup, Markup.Escape(imageFormat.Format));
2022-11-13 19:38:03 +00:00
switch(string.IsNullOrWhiteSpace(imageFormat.Info.Application))
{
case false when !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion):
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Was_created_with_0_version_1_WithMarkup,
2022-11-13 19:38:03 +00:00
Markup.Escape(imageFormat.Info.Application),
Markup.Escape(imageFormat.Info.ApplicationVersion));
break;
case false:
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Was_created_with_0_WithMarkup,
Markup.Escape(imageFormat.Info.Application));
2022-11-13 19:38:03 +00:00
break;
}
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Image_without_headers_is_0_bytes_long, imageFormat.Info.ImageSize);
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Contains_a_media_of_0_sectors_with_a_maximum_sector_size_of_1_bytes_etc,
2024-05-01 04:05:22 +01:00
imageFormat.Info.Sectors,
imageFormat.Info.SectorSize,
2024-04-26 03:18:47 +01:00
ByteSize.FromBytes(imageFormat.Info.Sectors * imageFormat.Info.SectorSize).Humanize());
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator))
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Created_by_0_WithMarkup, Markup.Escape(imageFormat.Info.Creator));
if(imageFormat.Info.CreationTime != DateTime.MinValue)
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Created_on_0, imageFormat.Info.CreationTime);
if(imageFormat.Info.LastModificationTime != DateTime.MinValue)
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Last_modified_on_0, imageFormat.Info.LastModificationTime);
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Contains_a_media_of_type_0_and_XML_type_1_WithMarkup,
2025-10-18 10:24:03 +01:00
imageFormat.Info.MediaType.Humanize(),
2024-05-01 04:05:22 +01:00
imageFormat.Info.MetadataMediaType);
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(imageFormat.Info.HasPartitions
2023-10-03 22:57:50 +01:00
? Localization.Core.Has_partitions
: Localization.Core.Doesnt_have_partitions);
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(imageFormat.Info.HasSessions
2023-10-03 22:57:50 +01:00
? Localization.Core.Has_sessions
: Localization.Core.Doesnt_have_sessions);
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Comments))
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Comments_0_WithMarkup, Markup.Escape(imageFormat.Info.Comments));
if(imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0)
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Media_is_number_0_on_a_set_of_1_medias,
2024-05-01 04:05:22 +01:00
imageFormat.Info.MediaSequence,
imageFormat.Info.LastMediaSequence);
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Media_title_0_WithMarkup,
Markup.Escape(imageFormat.Info.MediaTitle));
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Media_manufacturer_0_WithMarkup,
Markup.Escape(imageFormat.Info.MediaManufacturer));
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Media_model_0_WithMarkup,
Markup.Escape(imageFormat.Info.MediaModel));
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Media_serial_number_0_WithMarkup,
Markup.Escape(imageFormat.Info.MediaSerialNumber));
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Media_barcode_0_WithMarkup,
Markup.Escape(imageFormat.Info.MediaBarcode));
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Media_part_number_0_WithMarkup,
Markup.Escape(imageFormat.Info.MediaPartNumber));
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Drive_manufacturer_0_WithMarkup,
Markup.Escape(imageFormat.Info.DriveManufacturer));
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Drive_model_0_WithMarkup,
Markup.Escape(imageFormat.Info.DriveModel));
2023-10-03 22:57:50 +01:00
}
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Drive_serial_number_0_WithMarkup,
Markup.Escape(imageFormat.Info.DriveSerialNumber));
2023-10-03 22:57:50 +01:00
}
2018-01-28 16:05:54 +00:00
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision))
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Drive_firmware_info_0_WithMarkup,
Markup.Escape(imageFormat.Info.DriveFirmwareRevision));
2023-10-03 22:57:50 +01:00
}
if(imageFormat.Info.Cylinders > 0 &&
imageFormat.Info is { Heads: > 0, SectorsPerTrack: > 0 } &&
imageFormat.Info.MetadataMediaType != MetadataMediaType.OpticalDisc &&
2022-11-14 01:20:28 +00:00
imageFormat is not ITapeImage { IsTape: true })
2023-10-03 22:57:50 +01:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Media_geometry_0_cylinders_1_heads_2_sectors_per_track_WithMarkup,
2024-05-01 04:05:22 +01:00
imageFormat.Info.Cylinders,
imageFormat.Info.Heads,
imageFormat.Info.SectorsPerTrack);
2023-10-03 22:57:50 +01:00
}
if(imageFormat.Info.ReadableMediaTags is { Count: > 0 })
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Contains_0_readable_media_tags_WithMarkup,
imageFormat.Info.ReadableMediaTags.Count);
2018-01-28 16:05:54 +00:00
2025-11-08 14:05:30 +00:00
foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.OrderBy(static t => t.Humanize()))
AaruLogging.WriteLine("[italic][rosybrown]{0}[/][/]", Markup.Escape(tag.Humanize()));
}
if(imageFormat.Info.ReadableSectorTags is { Count: > 0 })
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Contains_0_readable_sector_tags_WithMarkup,
imageFormat.Info.ReadableSectorTags.Count);
2025-11-08 14:05:30 +00:00
foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.OrderBy(static t => t.Humanize()))
AaruLogging.WriteLine("[italic][rosybrown]{0}[/][/]", Markup.Escape(tag.Humanize()));
}
2018-01-28 16:05:54 +00:00
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.MetadataMediaType == MetadataMediaType.LinearMedia)
PrintByteAddressableImageInfo(imageFormat as IByteAddressableImage);
else
PrintBlockImageInfo(imageFormat as IMediaImage);
2018-01-28 16:05:54 +00:00
2024-05-01 04:05:22 +01:00
if(imageFormat.DumpHardware == null) return;
int manufacturerLen = Localization.Core.Title_Manufacturer.Length;
int modelLen = Localization.Core.Title_Model.Length;
int serialLen = Localization.Core.Title_Serial.Length;
int softwareLen = Localization.Core.Title_Software.Length;
int versionLen = Localization.Core.Title_Version.Length;
int osLen = Localization.Core.Title_Operating_system.Length;
int sectorLen = Localization.Core.Title_Start.Length;
2018-01-28 16:05:54 +00:00
foreach(DumpHardware dump in imageFormat.DumpHardware)
{
2024-05-01 04:05:22 +01:00
if(dump.Manufacturer?.Length > manufacturerLen) manufacturerLen = dump.Manufacturer.Length;
2018-01-28 16:05:54 +00:00
2024-05-01 04:05:22 +01:00
if(dump.Model?.Length > modelLen) modelLen = dump.Model.Length;
2024-05-01 04:05:22 +01:00
if(dump.Serial?.Length > serialLen) serialLen = dump.Serial.Length;
2018-01-28 16:05:54 +00:00
2024-05-01 04:05:22 +01:00
if(dump.Software?.Name?.Length > softwareLen) softwareLen = dump.Software.Name.Length;
2018-01-28 16:05:54 +00:00
2024-05-01 04:05:22 +01:00
if(dump.Software?.Version?.Length > versionLen) versionLen = dump.Software.Version.Length;
2024-05-01 04:05:22 +01:00
if(dump.Software?.OperatingSystem?.Length > osLen) osLen = dump.Software.OperatingSystem.Length;
2018-01-28 16:05:54 +00:00
foreach(Extent extent in dump.Extents)
2018-01-28 16:05:54 +00:00
{
2024-05-01 04:05:22 +01:00
if($"{extent.Start}".Length > sectorLen) sectorLen = $"{extent.Start}".Length;
2018-01-28 16:05:54 +00:00
2024-05-01 04:05:22 +01:00
if($"{extent.End}".Length > sectorLen) sectorLen = $"{extent.End}".Length;
2018-01-28 16:05:54 +00:00
}
}
2018-01-28 16:05:54 +00:00
var table = new Table
{
Title = new TableTitle(Localization.Core.Title_Dump_hardware_information)
};
2025-08-18 02:34:48 +01:00
AaruLogging.Information(Localization.Core.Title_Dump_hardware_information);
table.AddColumn(Localization.Core.Title_Manufacturer);
table.AddColumn(Localization.Core.Title_Model);
table.AddColumn(Localization.Core.Title_Serial);
table.AddColumn(Localization.Core.Title_Software);
table.AddColumn(Localization.Core.Title_Version);
table.AddColumn(Localization.Core.Title_Operating_system);
table.AddColumn(Localization.Core.Title_Start);
table.AddColumn(Localization.Core.Title_End);
2025-08-18 02:34:48 +01:00
table.Border(TableBorder.Rounded);
table.BorderColor(Color.Yellow);
table.Columns[6].RightAligned();
table.Columns[7].RightAligned();
foreach(DumpHardware dump in imageFormat.DumpHardware)
{
foreach(Extent extent in dump.Extents)
2023-10-03 22:57:50 +01:00
{
2025-08-18 02:34:48 +01:00
table.AddRow($"[navy]{Markup.Escape(dump.Manufacturer ?? "")}[/]",
$"[navy]{Markup.Escape(dump.Model ?? "")}[/]",
$"[fuchsia]{Markup.Escape(dump.Serial ?? "")}[/]",
$"[red3]{Markup.Escape(dump.Software.Name ?? "")}[/]",
$"[red3]{Markup.Escape(dump.Software.Version ?? "")}[/]",
$"[red3]{Markup.Escape(dump.Software.OperatingSystem ?? "")}[/]",
$"[lime]{extent.Start}[/]",
$"[lime]{extent.End}[/]");
// Write each row to AaruLogging.Information as a line
AaruLogging
.Information($"Manufacturer {dump.Manufacturer ?? ""}, model {dump.Model ?? ""}, serial {dump.Serial ?? ""}, software {dump.Software?.Name ?? ""}, version {dump.Software?.Version ?? ""}, operating system {dump.Software?.OperatingSystem ?? ""}, start {extent.Start}, end {extent.End}");
2023-10-03 22:57:50 +01:00
}
}
2025-08-18 02:34:48 +01:00
AnsiConsole.Write(table);
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
2018-01-28 16:05:54 +00:00
static void PrintByteAddressableImageInfo(IByteAddressableImage imageFormat)
{
2021-11-21 20:39:19 +00:00
ErrorNumber errno = imageFormat.GetMappings(out LinearMemoryMap mappings);
2018-01-28 16:05:54 +00:00
2024-05-01 04:05:22 +01:00
if(errno != ErrorNumber.NoError) return;
2018-01-28 16:05:54 +00:00
2025-08-18 02:34:48 +01:00
string jsonString = JsonSerializer.Serialize(mappings,
new JsonSerializerOptions
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters =
{
new JsonStringEnumConverter()
}
});
AaruLogging.Information(Localization.Core.Mapping_WithMarkup);
AaruLogging.Information(jsonString);
AnsiConsole.Write(new Panel(new JsonText(jsonString)).Header(Localization.Core.Mapping_WithMarkup)
.Collapse()
.RoundedBorder()
.BorderColor(Color.Yellow));
}
static void PrintBlockImageInfo(IMediaImage imageFormat)
{
PeripheralDeviceTypes scsiDeviceType = PeripheralDeviceTypes.DirectAccess;
byte[] scsiVendorId = null;
ErrorNumber errno;
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.SCSI_INQUIRY) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.SCSI_INQUIRY, out byte[] inquiry);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
scsiDeviceType = (PeripheralDeviceTypes)(inquiry[0] & 0x1F);
2018-01-28 16:05:54 +00:00
if(inquiry.Length >= 16)
{
scsiVendorId = new byte[8];
Array.Copy(inquiry, 8, scsiVendorId, 0, 8);
}
2018-01-28 16:05:54 +00:00
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.SCSI_INQUIRY_contained_in_image_WithMarkup);
AaruLogging.Write(Inquiry.Prettify(inquiry));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.ATA_IDENTIFY) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.ATA_IDENTIFY, out byte[] identify);
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.ATA_IDENTIFY_contained_in_image_WithMarkup);
AaruLogging.Write(Identify.Prettify(identify));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.ATAPI_IDENTIFY) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.ATAPI_IDENTIFY, out byte[] identify);
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.ATAPI_IDENTIFY_contained_in_image_WithMarkup);
AaruLogging.Write(Identify.Prettify(identify));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.SCSI_MODESENSE_10) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.SCSI_MODESENSE_10, out byte[] modeSense10);
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
2021-07-08 10:50:37 +01:00
{
Modes.DecodedMode? decMode = Modes.DecodeMode10(modeSense10, scsiDeviceType);
2021-07-08 10:50:37 +01:00
if(decMode.HasValue)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.SCSI_MODE_SENSE_10_contained_in_image_WithMarkup);
PrintScsiModePages.Print(decMode.Value, scsiDeviceType, scsiVendorId);
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
2021-07-08 10:50:37 +01:00
}
}
else if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.SCSI_MODESENSE_6) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.SCSI_MODESENSE_6, out byte[] modeSense6);
2021-07-08 10:50:37 +01:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
Modes.DecodedMode? decMode = Modes.DecodeMode6(modeSense6, scsiDeviceType);
2018-01-28 16:05:54 +00:00
if(decMode.HasValue)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.SCSI_MODE_SENSE_6_contained_in_image_WithMarkup);
PrintScsiModePages.Print(decMode.Value, scsiDeviceType, scsiVendorId);
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
2018-01-28 16:05:54 +00:00
}
}
else if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.SCSI_MODEPAGE_2A) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.SCSI_MODEPAGE_2A, out byte[] mode2A);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
AaruLogging.Write(Modes.PrettifyModePage_2A(mode2A));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.CD_FullTOC) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.CD_FullTOC, out byte[] toc);
if(errno == ErrorNumber.NoError && toc.Length > 0)
2018-01-28 16:05:54 +00:00
{
ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(toc, 0));
2018-01-28 16:05:54 +00:00
if(dataLen + 2 != toc.Length)
{
2025-10-18 10:24:03 +01:00
var tmp = new byte[toc.Length + 2];
Array.Copy(toc, 0, tmp, 2, toc.Length);
tmp[0] = (byte)((toc.Length & 0xFF00) >> 8);
tmp[1] = (byte)(toc.Length & 0xFF);
toc = tmp;
}
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.CompactDisc_Table_of_Contents_contained_in_image_WithMarkup);
AaruLogging.Write(FullTOC.Prettify(toc));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.CD_PMA) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.CD_PMA, out byte[] pma);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError && pma.Length > 0)
2018-01-28 16:05:54 +00:00
{
ushort dataLen = Swapping.Swap(BitConverter.ToUInt16(pma, 0));
2018-01-28 16:05:54 +00:00
if(dataLen + 2 != pma.Length)
{
2025-10-18 10:24:03 +01:00
var tmp = new byte[pma.Length + 2];
Array.Copy(pma, 0, tmp, 2, pma.Length);
tmp[0] = (byte)((pma.Length & 0xFF00) >> 8);
tmp[1] = (byte)(pma.Length & 0xFF);
pma = tmp;
}
2025-11-08 13:50:59 +00:00
AaruLogging.WriteLine(Localization.Core.CompactDisc_Program_Memory_Area_contained_in_image_WithMarkup);
AaruLogging.Write(PMA.Prettify(pma));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.CD_ATIP) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.CD_ATIP, out byte[] atip);
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
uint dataLen = Swapping.Swap(BitConverter.ToUInt32(atip, 0));
2018-01-28 16:05:54 +00:00
if(dataLen + 4 != atip.Length)
{
2025-10-18 10:24:03 +01:00
var tmp = new byte[atip.Length + 4];
Array.Copy(atip, 0, tmp, 4, atip.Length);
tmp[0] = (byte)((atip.Length & 0xFF000000) >> 24);
tmp[1] = (byte)((atip.Length & 0xFF0000) >> 16);
tmp[2] = (byte)((atip.Length & 0xFF00) >> 8);
tmp[3] = (byte)(atip.Length & 0xFF);
atip = tmp;
}
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core
2024-05-01 04:05:22 +01:00
.CompactDisc_Absolute_Time_In_Pregroove_ATIP_contained_in_image_WithMarkup);
AaruLogging.Write(ATIP.Prettify(atip));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.CD_TEXT) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.CD_TEXT, out byte[] cdtext);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
uint dataLen = Swapping.Swap(BitConverter.ToUInt32(cdtext, 0));
if(dataLen + 4 != cdtext.Length)
{
2025-10-18 10:24:03 +01:00
var tmp = new byte[cdtext.Length + 4];
Array.Copy(cdtext, 0, tmp, 4, cdtext.Length);
tmp[0] = (byte)((cdtext.Length & 0xFF000000) >> 24);
tmp[1] = (byte)((cdtext.Length & 0xFF0000) >> 16);
tmp[2] = (byte)((cdtext.Length & 0xFF00) >> 8);
tmp[3] = (byte)(cdtext.Length & 0xFF);
cdtext = tmp;
}
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.CompactDisc_Lead_in_CD_Text_contained_in_image_WithMarkup);
AaruLogging.Write(CDTextOnLeadIn.Prettify(cdtext));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.CD_MCN) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.CD_MCN, out byte[] mcn);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core
2024-05-01 04:05:22 +01:00
.CompactDisc_Media_Catalogue_Number_contained_in_image_0_WithMarkup,
Encoding.UTF8.GetString(mcn));
2018-01-28 16:05:54 +00:00
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.DVDR_PreRecordedInfo) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.DVDR_PreRecordedInfo, out byte[] pri);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.DVD_RW_Pre_Recorded_Information_WithMarkup);
AaruLogging.Write(PRI.Prettify(pri));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.DVD_PFI) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.DVD_PFI, out byte[] pfi);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.DVD_Physical_Format_Information_contained_in_image_WithMarkup);
AaruLogging.Write(PFI.Prettify(pfi, imageFormat.Info.MediaType));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.DVDRAM_DDS) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.DVDRAM_DDS, out byte[] dds);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core
2024-05-01 04:05:22 +01:00
.DVD_RAM_Disc_Definition_Structure_contained_in_image_WithMarkup);
AaruLogging.Write(DDS.Prettify(dds));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.DVDR_PFI) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.DVDR_PFI, out byte[] pfi);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core
2024-05-01 04:05:22 +01:00
.DVD_R_Physical_Format_Information_contained_in_image_WithMarkup);
AaruLogging.Write(PFI.Prettify(pfi, imageFormat.Info.MediaType));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.BD_DI) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.BD_DI, out byte[] di);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Bluray_Disc_Information_contained_in_image_WithMarkup);
AaruLogging.Write(DI.Prettify(di));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.BD_DDS) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.BD_DDS, out byte[] dds);
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Bluray_Disc_Definition_Structure_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.Bluray.DDS.Prettify(dds));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.PCMCIA_CIS) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.PCMCIA_CIS, out byte[] cis);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.PCMCIA_CIS_WithMarkup);
Tuple[] tuples = CIS.GetTuples(cis);
2018-01-28 16:05:54 +00:00
if(tuples != null)
2023-10-03 22:57:50 +01:00
{
foreach(Tuple tuple in tuples)
2023-10-03 22:57:50 +01:00
{
switch(tuple.Code)
{
case TupleCodes.CISTPL_NULL:
2023-10-03 22:57:50 +01:00
case TupleCodes.CISTPL_END:
break;
case TupleCodes.CISTPL_DEVICEGEO:
case TupleCodes.CISTPL_DEVICEGEO_A:
AaruLogging.WriteLine(CIS.PrettifyDeviceGeometryTuple(tuple));
break;
case TupleCodes.CISTPL_MANFID:
AaruLogging.WriteLine(CIS.PrettifyManufacturerIdentificationTuple(tuple));
break;
case TupleCodes.CISTPL_VERS_1:
AaruLogging.WriteLine(CIS.PrettifyLevel1VersionTuple(tuple));
break;
case TupleCodes.CISTPL_ALTSTR:
case TupleCodes.CISTPL_BAR:
case TupleCodes.CISTPL_BATTERY:
case TupleCodes.CISTPL_BYTEORDER:
case TupleCodes.CISTPL_CFTABLE_ENTRY:
case TupleCodes.CISTPL_CFTABLE_ENTRY_CB:
case TupleCodes.CISTPL_CHECKSUM:
case TupleCodes.CISTPL_CONFIG:
case TupleCodes.CISTPL_CONFIG_CB:
case TupleCodes.CISTPL_DATE:
case TupleCodes.CISTPL_DEVICE:
case TupleCodes.CISTPL_DEVICE_A:
case TupleCodes.CISTPL_DEVICE_OA:
case TupleCodes.CISTPL_DEVICE_OC:
case TupleCodes.CISTPL_EXTDEVIC:
case TupleCodes.CISTPL_FORMAT:
case TupleCodes.CISTPL_FORMAT_A:
case TupleCodes.CISTPL_FUNCE:
case TupleCodes.CISTPL_FUNCID:
case TupleCodes.CISTPL_GEOMETRY:
case TupleCodes.CISTPL_INDIRECT:
case TupleCodes.CISTPL_JEDEC_A:
case TupleCodes.CISTPL_JEDEC_C:
case TupleCodes.CISTPL_LINKTARGET:
case TupleCodes.CISTPL_LONGLINK_A:
case TupleCodes.CISTPL_LONGLINK_C:
case TupleCodes.CISTPL_LONGLINK_CB:
case TupleCodes.CISTPL_LONGLINK_MFC:
case TupleCodes.CISTPL_NO_LINK:
case TupleCodes.CISTPL_ORG:
case TupleCodes.CISTPL_PWR_MGMNT:
case TupleCodes.CISTPL_SPCL:
case TupleCodes.CISTPL_SWIL:
case TupleCodes.CISTPL_VERS_2:
2025-08-17 06:11:22 +01:00
AaruLogging.Debug(MODULE_NAME,
2025-08-18 02:34:48 +01:00
Localization.Core.Invoke_Found_undecoded_tuple_ID_0,
tuple.Code);
break;
default:
2025-08-17 06:11:22 +01:00
AaruLogging.Debug(MODULE_NAME,
2025-08-18 02:34:48 +01:00
Localization.Core.Found_unknown_tuple_ID_0,
(byte)tuple.Code);
break;
}
2023-10-03 22:57:50 +01:00
}
}
else
2025-08-17 06:11:22 +01:00
AaruLogging.Debug(MODULE_NAME, Localization.Core.Could_not_get_tuples);
2018-01-28 16:05:54 +00:00
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.SD_CID) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.SD_CID, out byte[] cid);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.SecureDigital_CID_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.SecureDigital.Decoders.PrettifyCID(cid));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.SD_CSD) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.SD_CSD, out byte[] csd);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.SecureDigital_CSD_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.SecureDigital.Decoders.PrettifyCSD(csd));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.SD_SCR) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.SD_SCR, out byte[] scr);
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.SecureDigital_SCR_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.SecureDigital.Decoders.PrettifySCR(scr));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.SD_OCR) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.SD_OCR, out byte[] ocr);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.SecureDigital_OCR_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.SecureDigital.Decoders.PrettifyOCR(ocr));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.MMC_CID) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.MMC_CID, out byte[] cid);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.MultiMediaCard_CID_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.MMC.Decoders.PrettifyCID(cid));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.MMC_CSD) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.MMC_CSD, out byte[] csd);
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.MultiMediaCard_CSD_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.MMC.Decoders.PrettifyCSD(csd));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.MMC_ExtendedCSD) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.MMC_ExtendedCSD, out byte[] ecsd);
2018-01-28 16:05:54 +00:00
if(errno == ErrorNumber.NoError)
2018-01-28 16:05:54 +00:00
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.MultiMediaCard_Extended_CSD_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.MMC.Decoders.PrettifyExtendedCSD(ecsd));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
2018-01-28 16:05:54 +00:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.MMC_OCR) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.MMC_OCR, out byte[] ocr);
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.MultiMediaCard_OCR_contained_in_image_WithMarkup);
AaruLogging.Write(Decoders.MMC.Decoders.PrettifyOCR(ocr));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.Xbox_PFI) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.Xbox_PFI, out byte[] xpfi);
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Xbox_Physical_Format_Information_contained_in_image_WithMarkup);
AaruLogging.Write(PFI.Prettify(xpfi, imageFormat.Info.MediaType));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.Xbox_DMI) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.Xbox_DMI, out byte[] xdmi);
if(errno == ErrorNumber.NoError)
{
if(DMI.IsXbox(xdmi))
{
DMI.XboxDMI? xmi = DMI.DecodeXbox(xdmi);
if(xmi.HasValue)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Xbox_DMI_contained_in_image_WithMarkup);
AaruLogging.Write(DMI.PrettifyXbox(xmi));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
if(DMI.IsXbox360(xdmi))
{
DMI.Xbox360DMI? xmi = DMI.DecodeXbox360(xdmi);
if(xmi.HasValue)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Xbox_360_DMI_contained_in_image_WithMarkup);
AaruLogging.Write(DMI.PrettifyXbox360(xmi));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
}
}
2020-06-17 20:34:35 +01:00
if(imageFormat.Info.ReadableMediaTags?.Contains(MediaTagType.Xbox_SecuritySector) == true)
{
errno = imageFormat.ReadMediaTag(MediaTagType.Xbox_SecuritySector, out byte[] toc);
2020-06-17 20:34:35 +01:00
if(errno == ErrorNumber.NoError)
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine(Localization.Core.Xbox_Security_Sectors_contained_in_image_WithMarkup);
AaruLogging.Write(SS.Prettify(toc));
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
2020-06-17 20:34:35 +01:00
2025-08-17 06:11:22 +01:00
if(imageFormat is IFluxImage) AaruLogging.WriteLine(Localization.Core.Image_flux_captures);
2023-04-13 21:06:57 +02:00
2024-05-01 04:05:22 +01:00
if(imageFormat is not IOpticalMediaImage opticalImage) return;
2021-09-14 00:56:06 +01:00
try
{
if(opticalImage.Sessions is { Count: > 0 })
{
var table = new Table
2020-06-17 20:34:35 +01:00
{
Title = new TableTitle(Localization.Core.Title_Image_sessions)
};
2025-08-18 02:34:48 +01:00
AaruLogging.Information(Localization.Core.Title_Image_sessions);
table.Border(TableBorder.Rounded);
table.BorderColor(Color.Yellow);
table.AddColumn(Localization.Core.Title_Session);
table.AddColumn(Localization.Core.Title_First_track);
table.AddColumn(Localization.Core.Title_Last_track);
table.AddColumn(Localization.Core.Title_Start);
table.AddColumn(Localization.Core.Title_End);
2025-08-18 02:34:48 +01:00
table.Columns[0].RightAligned();
table.Columns[1].RightAligned();
table.Columns[2].RightAligned();
table.Columns[3].RightAligned();
table.Columns[4].RightAligned();
foreach(Session session in opticalImage.Sessions)
2023-10-03 22:57:50 +01:00
{
2025-08-18 02:34:48 +01:00
table.AddRow($"[navy]{session.Sequence}[/]",
$"[purple]{session.StartTrack}[/]",
$"[purple]{session.EndTrack}[/]",
$"[lime]{session.StartSector}[/]",
$"[lime]{session.EndSector}[/]");
// Write all the session infomation to AaruLogging.Information in a single line
AaruLogging
.Information($"Session {session.Sequence}: first track {session.StartTrack}, last track {session.EndTrack}, start sector {session.StartSector}, end sector {session.EndSector}");
2023-10-03 22:57:50 +01:00
}
AnsiConsole.Write(table);
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
}
}
2025-08-20 18:51:05 +01:00
catch(Exception ex)
{
2025-08-20 18:51:05 +01:00
SentrySdk.CaptureException(ex);
}
try
{
2024-05-01 04:05:22 +01:00
if(opticalImage.Tracks is not { Count: > 0 }) return;
var table = new Table
{
Title = new TableTitle(Localization.Core.Title_Image_tracks)
};
2025-08-18 02:34:48 +01:00
table.Border(TableBorder.Rounded);
table.BorderColor(Color.Yellow);
table.AddColumn(Localization.Core.Title_Track);
table.AddColumn(Localization.Core.Title_Type_for_media);
table.AddColumn(Localization.Core.Title_Bps);
table.AddColumn(Localization.Core.Title_Raw_bps);
table.AddColumn(Localization.Core.Title_Subchannel);
table.AddColumn(Localization.Core.Title_Pregap);
table.AddColumn(Localization.Core.Title_Start);
table.AddColumn(Localization.Core.Title_End);
2025-08-18 02:34:48 +01:00
table.Columns[0].RightAligned();
table.Columns[2].RightAligned();
table.Columns[3].RightAligned();
table.Columns[5].RightAligned();
table.Columns[6].RightAligned();
table.Columns[7].RightAligned();
foreach(Track track in opticalImage.Tracks)
2023-10-03 22:57:50 +01:00
{
2025-08-18 02:34:48 +01:00
table.AddRow($"[teal]{track.Sequence}[/]",
2025-08-23 00:13:52 +01:00
$"[orange3]{track.Type.Humanize()}[/]",
2025-08-18 02:34:48 +01:00
$"[aqua]{track.BytesPerSector}[/]",
$"[aqua]{track.RawBytesPerSector}[/]",
$"[fuchsia]{track.SubchannelType}[/]",
$"[darkgreen]{track.Pregap}[/]",
$"[lime]{track.StartSector}[/]",
$"[lime]{track.EndSector}[/]");
// Write all the track information to AaruLogging.Information in a single line
AaruLogging
2025-08-23 00:13:52 +01:00
.Information($"Track {track.Sequence}: type {track.Type.Humanize()}, bytes per sector {track.BytesPerSector}, raw bytes per sector {track.RawBytesPerSector}, subchannel type {track.SubchannelType}, pregap {track.Pregap}, start sector {track.StartSector}, end sector {track.EndSector}");
2023-10-03 22:57:50 +01:00
}
AnsiConsole.Write(table);
if(!opticalImage.Tracks.Any(static t => t.Indexes.Any())) return;
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2021-09-14 00:56:06 +01:00
table = new Table
{
Title = new TableTitle(Localization.Core.Title_Image_indexes)
2021-09-14 00:56:06 +01:00
};
2025-08-18 02:34:48 +01:00
AaruLogging.Information(Localization.Core.Title_Image_indexes);
table.Border(TableBorder.Rounded);
table.BorderColor(Color.Yellow);
table.AddColumn(Localization.Core.Title_Track);
table.AddColumn(Localization.Core.Title_Index);
table.AddColumn(Localization.Core.Title_Start);
2025-08-18 02:34:48 +01:00
table.Columns[0].RightAligned();
table.Columns[1].RightAligned();
table.Columns[2].RightAligned();
foreach(Track track in opticalImage.Tracks)
2024-05-01 04:05:22 +01:00
{
foreach(KeyValuePair<ushort, int> index in track.Indexes)
2025-08-18 02:34:48 +01:00
{
table.AddRow($"[teal]{track.Sequence}[/]", $"[darkgreen]{index.Key}[/]", $"[lime]{index.Value}[/]");
// Write all the index information to AaruLogging.Information in a single line
AaruLogging.Information($"Track {track.Sequence}, index {index.Key}: start sector {index.Value}");
}
2024-05-01 04:05:22 +01:00
}
AnsiConsole.Write(table);
}
2025-08-20 18:51:05 +01:00
catch(Exception ex)
{
2025-08-20 18:51:05 +01:00
SentrySdk.CaptureException(ex);
}
finally
{
2025-08-17 06:11:22 +01:00
AaruLogging.WriteLine();
2018-01-28 16:05:54 +00:00
}
}
}