Add tested media to device report view.

This commit is contained in:
2024-05-09 19:56:24 +01:00
parent d43b3f6ec3
commit f039686d2e
6 changed files with 610 additions and 60 deletions

View File

@@ -35,7 +35,7 @@
<div class="stats-section">
<h3 style="font-weight: bold;">
@lblDeviceType<br/>
@DeviceType<br/>
</h3>
<Accordion>
@if(UsbItem is not null)
@@ -835,4 +835,45 @@
</AccordionItem>
}
</Accordion>
</div>
</div>
@if(MediaInformation?.Count > 0)
{
<div class="stats-section">
<h3 style="font-weight: bold;">
Tested media information<br/>
</h3>
<Accordion>
@foreach(KeyValuePair<string, (Dictionary<string, string> Table, List<string> List)> mediaInfo in MediaInformation)
{
<AccordionItem>
<AccordionHeader>
<Heading Size="HeadingSize.Is5">
<AccordionToggle>@mediaInfo.Key</AccordionToggle>
</Heading>
</AccordionHeader>
<AccordionBody>
<Table class="table-borderless table-dark" FullWidth>
<TableBody>
@foreach(KeyValuePair<string, string> kvp in mediaInfo.Value.Table)
{
<TableRow>
<TableRowHeader>@kvp.Key</TableRowHeader>
<TableRowCell>@kvp.Value</TableRowCell>
</TableRow>
}
</TableBody>
</Table>
<ListGroup>
@foreach(string cap in mediaInfo.Value.List)
{
<ListGroupItem>@cap</ListGroupItem>
}
</ListGroup>
</AccordionBody>
</AccordionItem>
}
</Accordion>
</div>
}

View File

@@ -10,6 +10,7 @@ using Microsoft.EntityFrameworkCore;
using Ata = Aaru.CommonTypes.Metadata.Ata;
using DbContext = Aaru.Server.Database.DbContext;
using Inquiry = Aaru.CommonTypes.Structs.Devices.SCSI.Inquiry;
using TestedMedia = Aaru.CommonTypes.Metadata.TestedMedia;
using Tuple = Aaru.Decoders.PCMCIA.Tuple;
namespace Aaru.Server.New.Components.Pages.Report;
@@ -18,7 +19,6 @@ public partial class View
{
bool _initialized;
bool _notFound;
bool accordionItem1Visible;
string _pageTitle { get; set; } = "Aaru Device Report";
[CascadingParameter]
HttpContext HttpContext { get; set; } = default!;
@@ -28,7 +28,7 @@ public partial class View
public Item? FireWireItem { get; set; }
public Dictionary<string, string>? PcmciaTuples { get; set; }
public PcmciaItem? PcmciaItem { get; set; }
public string? lblDeviceType { get; set; }
public string? DeviceType { get; set; }
public string? AtaItem { get; set; }
public string? MaximumAtaRevision { get; set; }
public List<string>? SupportedAtaVersions { get; set; }
@@ -58,16 +58,18 @@ public partial class View
public List<string>? InquiryCapabilities { get; set; }
public List<string>? ModeSenseCapabilities { get; set; }
public Dictionary<string, List<string>>? ModeSensePages { get; set; }
public List<string>? BlockDescriptors { get; set; }
public List<SscSupportedMedia>? ScsiSscMedias { get; set; }
public List<SupportedDensity>? ScsiSscDensities { get; set; }
public string? ScsiSscMinBlock { get; set; }
public string? ScsiSscMaxBlock { get; set; }
public string? ScsiSscGranularity { get; set; }
public bool ScsiSscVisible { get; set; }
public List<string>? MmcFeaturesList { get; set; }
public List<string>? MmcModeList { get; set; }
public Dictionary<string, List<string>>? EvpdPages { get; set; }
public List<string>? BlockDescriptors { get; set; }
public List<SscSupportedMedia>? ScsiSscMedias { get; set; }
public List<SupportedDensity>? ScsiSscDensities { get; set; }
public string? ScsiSscMinBlock { get; set; }
public string? ScsiSscMaxBlock { get; set; }
public string? ScsiSscGranularity { get; set; }
public bool ScsiSscVisible { get; set; }
public List<string>? MmcFeaturesList { get; set; }
public List<string>? MmcModeList { get; set; }
public Dictionary<string, List<string>>? EvpdPages { get; set; }
public Dictionary<string, (Dictionary<string, string> Table, List<string> List)>? MediaInformation { get; set; }
/// <inheritdoc />
protected override async Task OnInitializedAsync()
@@ -112,6 +114,14 @@ public partial class View
.ThenInclude(static ssc => ssc.SupportedMediaTypes)
.Include(static deviceReportV2 => deviceReportV2.SCSI)
.ThenInclude(static scsi => scsi.ReadCapabilities)
.Include(static deviceReportV2 => deviceReportV2.SCSI)
.ThenInclude(static scsi => scsi.SequentialDevice)
.ThenInclude(static ssc => ssc.TestedMedia)
.Include(static deviceReportV2 => deviceReportV2.SCSI)
.ThenInclude(static scsi => scsi.RemovableMedias)
.Include(static deviceReportV2 => deviceReportV2.SCSI)
.ThenInclude(static scsi => scsi.MultiMediaDevice)
.ThenInclude(static mmc => mmc.TestedMedia)
.FirstOrDefaultAsync(d => d.Id == Id);
if(report is null)
@@ -269,9 +279,10 @@ public partial class View
}
}
var removable = true;
List<TestedMedia>? testedMedia;
var atapi = false;
var removable = true;
List<TestedMedia>? testedMedia = null;
var atapi = false;
var sscMedia = false;
if(report.ATA != null || report.ATAPI != null)
{
@@ -291,12 +302,12 @@ public partial class View
bool cfa = report.CompactFlash;
lblDeviceType = atapi switch
{
true when !cfa => "ATAPI device",
false when cfa => "CompactFlash device",
_ => "ATA device"
};
DeviceType = atapi switch
{
true when !cfa => "ATAPI device",
false when cfa => "CompactFlash device",
_ => "ATA device"
};
Core.Ata.Report(ataReport!,
cfa,
@@ -346,7 +357,7 @@ public partial class View
if(report.MultiMediaCard != null)
{
lblDeviceType = "MultiMediaCard";
DeviceType = "MultiMediaCard";
if(report.MultiMediaCard.CID != null)
Cid = Decoders.MMC.Decoders.PrettifyCID(report.MultiMediaCard.CID).Replace("\n", "<br/>");
@@ -366,7 +377,7 @@ public partial class View
if(report.SecureDigital != null)
{
lblDeviceType = "SecureDigital";
DeviceType = "SecureDigital";
if(report.SecureDigital.CID != null)
Cid = Decoders.SecureDigital.Decoders.PrettifyCID(report.SecureDigital.CID).Replace("\n", "<br/>");
@@ -381,6 +392,7 @@ public partial class View
Ocr = Decoders.SecureDigital.Decoders.PrettifyCSD(report.SecureDigital.OCR).Replace("\n", "<br/>");
}
if(report.SCSI != null)
{
var vendorId = "";
@@ -388,16 +400,23 @@ public partial class View
if(report.SCSI.Inquiry != null)
{
Inquiry inq = report.SCSI.Inquiry.Value;
vendorId = StringHandlers.CToString(report.SCSI.Inquiry?.VendorIdentification);
DeviceInquiry = new Dictionary<string, string>();
vendorId = StringHandlers.CToString(report.SCSI.Inquiry?.VendorIdentification);
DeviceInquiry.Add("Vendor:",
VendorString.Prettify(vendorId) != vendorId
? $"{vendorId} ({VendorString.Prettify(vendorId)})"
: vendorId);
DeviceInquiry.Add("Product:", StringHandlers.CToString(inq.ProductIdentification));
DeviceInquiry.Add("Revision:", StringHandlers.CToString(inq.ProductRevisionLevel));
DeviceInquiry = new Dictionary<string, string>
{
{
"Vendor:",
VendorString.Prettify(vendorId) != vendorId
? $"{vendorId} ({VendorString.Prettify(vendorId)})"
: vendorId
},
{
"Product:", StringHandlers.CToString(inq.ProductIdentification)
},
{
"Revision:", StringHandlers.CToString(inq.ProductRevisionLevel)
}
};
}
List<string> inquiryCapabilities = ScsiInquiry.Report(report.SCSI.Inquiry);
@@ -439,7 +458,7 @@ public partial class View
if(modeSenseCapabilities is not null)
{
ModeSenseCapabilities ??= new List<string>();
ModeSenseCapabilities ??= [];
ModeSenseCapabilities.AddRange(modeSenseCapabilities);
}
@@ -455,7 +474,7 @@ public partial class View
if(report.SCSI.MultiMediaDevice is not null)
{
// testedMedia = report.SCSI.MultiMediaDevice.TestedMedia;
testedMedia = report.SCSI.MultiMediaDevice.TestedMedia;
if(report.SCSI.MultiMediaDevice.ModeSense2A != null)
{
@@ -487,20 +506,20 @@ public partial class View
if(report.SCSI.SequentialDevice.SupportedMediaTypes != null)
ScsiSscMedias = report.SCSI.SequentialDevice.SupportedMediaTypes;
/* if(report.SCSI.SequentialDevice.TestedMedia != null)
{
List<string> mediaOneValue = new();
SscTestedMedia.Report(report.SCSI.SequentialDevice.TestedMedia, ref mediaOneValue);
if(report.SCSI.SequentialDevice.TestedMedia != null)
{
sscMedia = true;
if(mediaOneValue.Count > 0)
{
sscMedia = true;
ViewBag.repTestedMedia = mediaOneValue;
}
}*/
SscTestedMedia.Report(report.SCSI.SequentialDevice.TestedMedia,
out Dictionary<string, (Dictionary<string, string> Table, List<string> List)>
mediaInformation);
if(mediaInformation.Count > 0) MediaInformation = mediaInformation;
}
}
else if(report.SCSI.ReadCapabilities != null)
{
removable = false;
List<string> readCapabilitiesList = [];
var readCapabilitiesDictionary = new Dictionary<string, string>();
@@ -530,8 +549,10 @@ public partial class View
}
if(report.SCSI.ReadCapabilities.MediumType.HasValue)
{
readCapabilitiesDictionary.Add("Medium type code",
$"{report.SCSI.ReadCapabilities.MediumType:X2}h");
}
if(report.SCSI.ReadCapabilities.Density.HasValue)
readCapabilitiesDictionary.Add("Density code", $"{report.SCSI.ReadCapabilities.Density:X2}h");
@@ -539,8 +560,10 @@ public partial class View
if((report.SCSI.ReadCapabilities.SupportsReadLong == true ||
report.SCSI.ReadCapabilities.SupportsReadLong16 == true) &&
report.SCSI.ReadCapabilities.LongBlockSize.HasValue)
{
readCapabilitiesDictionary.Add("Long block size",
$"{report.SCSI.ReadCapabilities.LongBlockSize} bytes");
}
if(report.SCSI.ReadCapabilities.SupportsReadCapacity == true)
readCapabilitiesList.Add("Device supports READ CAPACITY (10) command.");
@@ -569,9 +592,17 @@ public partial class View
if(readCapabilitiesList.Count > 0) ReadCapabilitiesList = readCapabilitiesList;
if(readCapabilitiesDictionary.Count > 0) ReadCapabilitiesDictionary = readCapabilitiesDictionary;
}
/* else
testedMedia = report.SCSI.RemovableMedias;
*/
else
testedMedia = report.SCSI.RemovableMedias;
}
if(removable && !sscMedia && testedMedia != null)
{
Core.TestedMedia.Report(testedMedia,
out Dictionary<string, (Dictionary<string, string> Table, List<string> List)>
mediaInformation);
if(mediaInformation.Count > 0) MediaInformation = mediaInformation;
}
_initialized = true;

View File

@@ -30,7 +30,6 @@
// Copyright © 2011-2024 Natalia Portillo
// ****************************************************************************/
using Aaru.CommonTypes.Metadata;
using Aaru.CommonTypes.Structs.Devices.ATA;
using Aaru.CommonTypes.Structs.Devices.SCSI;
@@ -68,7 +67,8 @@ public static class Ata
/// <param name="readCapabilitiesDictionary">Dictionary of read capabilities for non-removable media</param>
/// <param name="readCapabilitiesList">List of read capabilities for non-removable media</param>
public static void Report(CommonTypes.Metadata.Ata ataReport, bool cfa, bool atapi, ref bool removable,
out List<TestedMedia>? testedMedia, out Dictionary<string, string>? deviceIdentification,
out List<CommonTypes.Metadata.TestedMedia>? testedMedia,
out Dictionary<string, string>? deviceIdentification,
out List<string> supportedAtaVersions, out string? maximumAtaRevision,
out string? transport, out List<string>? transportVersions,
out List<string> generalConfiguration, out List<string>? specificConfiguration,
@@ -1672,12 +1672,14 @@ public static class Ata
!ataIdentify.CommandSet3.HasFlag(Identify.CommandSetBit3.MustBeClear) &&
ataIdentify.CommandSet3.HasFlag(Identify.CommandSetBit3.Streaming))
{
streaming = [];
streaming.Add($"Minimum request size is {ataIdentify.StreamMinReqSize}");
streaming.Add($"Streaming transfer time in PIO is {ataIdentify.StreamTransferTimePIO}");
streaming.Add($"Streaming transfer time in DMA is {ataIdentify.StreamTransferTimeDMA}");
streaming.Add($"Streaming access latency is {ataIdentify.StreamAccessLatency}");
streaming.Add($"Streaming performance granularity is {ataIdentify.StreamPerformanceGranularity}");
streaming =
[
$"Minimum request size is {ataIdentify.StreamMinReqSize}",
$"Streaming transfer time in PIO is {ataIdentify.StreamTransferTimePIO}",
$"Streaming transfer time in DMA is {ataIdentify.StreamTransferTimeDMA}",
$"Streaming access latency is {ataIdentify.StreamAccessLatency}",
$"Streaming performance granularity is {ataIdentify.StreamPerformanceGranularity}"
];
}
if(ataIdentify.SCTCommandTransport.HasFlag(Identify.SCTCommandTransportBit.Supported))
@@ -1702,8 +1704,7 @@ public static class Ata
if((ataIdentify.NVCacheCaps & 0x0010) == 0x0010)
{
nvCache = [];
nvCache.Add($"Version {(ataIdentify.NVCacheCaps & 0xF000) >> 12}");
nvCache = [$"Version {(ataIdentify.NVCacheCaps & 0xF000) >> 12}"];
if((ataIdentify.NVCacheCaps & 0x0001) == 0x0001)
{
@@ -1741,12 +1742,16 @@ public static class Ata
}
if(ataReport.ReadCapabilities.PhysicalBlockSize != null)
{
readCapabilitiesDictionary.Add("Physical sector size",
$"{ataReport.ReadCapabilities.PhysicalBlockSize} bytes");
}
if(ataReport.ReadCapabilities.LongBlockSize != null)
{
readCapabilitiesDictionary.Add("READ LONG sector size",
$"{ataReport.ReadCapabilities.LongBlockSize} bytes");
}
if(ataReport.ReadCapabilities.BlockSize != null &&
ataReport.ReadCapabilities.PhysicalBlockSize != null &&
@@ -1847,12 +1852,16 @@ public static class Ata
if(ata1 || cfa)
{
if(ataReport.ReadCapabilities.UnformattedBPT > 0)
{
readCapabilitiesDictionary.Add("Bytes per unformatted track",
$"{ataReport.ReadCapabilities.UnformattedBPT}");
}
if(ataReport.ReadCapabilities.UnformattedBPS > 0)
{
readCapabilitiesDictionary.Add("Bytes per unformatted sector",
$"{ataReport.ReadCapabilities.UnformattedBPS}");
}
}
}

View File

@@ -44,7 +44,7 @@ static class ScsiInquiry
/// <returns>List of values</returns>
internal static List<string> Report(Inquiry? inquiryNullable)
{
List<string> scsiOneValue = new();
List<string> scsiOneValue = [];
if(!inquiryNullable.HasValue) return scsiOneValue;

View File

@@ -0,0 +1,79 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : SscTestedMedia.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Aaru Server.
//
// --[ Description ] ----------------------------------------------------------
//
// Decodes SCSI Streaming media tests from reports.
//
// --[ 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/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2024 Natalia Portillo
// ****************************************************************************/
using Aaru.CommonTypes.Metadata;
namespace Aaru.Server.New.Core;
public static class SscTestedMedia
{
/// <summary>Takes the tested media from SCSI Streaming devices of a device report and prints it as a list of values</summary>
/// <param name="mediaOneValue">List to put values on</param>
/// <param name="testedMedia">List of tested media</param>
public static void Report(IEnumerable<TestedSequentialMedia> testedMedia,
out Dictionary<string, (Dictionary<string, string> Table, List<string> List)>
mediaInformation)
{
mediaInformation = new Dictionary<string, (Dictionary<string, string>, List<string>)>();
foreach(TestedSequentialMedia media in testedMedia)
{
Dictionary<string, string> table = new();
List<string> list = [];
string header;
if(!string.IsNullOrWhiteSpace(media.MediumTypeName))
{
header = $"Information for medium named \"{media.MediumTypeName}\"";
if(media.MediumType.HasValue) table.Add("Medium type code", $"{media.MediumType:X2}h");
}
else if(media.MediumType.HasValue)
header = $"Information for medium type {media.MediumType:X2}h";
else
header = "Information for unknown medium type";
if(!string.IsNullOrWhiteSpace(media.Manufacturer))
table.Add("Medium manufacturer", $"{media.Manufacturer}");
if(!string.IsNullOrWhiteSpace(media.Model)) table.Add("Medium model", $"{media.Model}");
if(media.Density.HasValue) list.Add($"Medium has density code {media.Density:X2}h");
if(media.CanReadMediaSerial == true) list.Add("Drive can read medium serial number.");
if(media.MediaIsRecognized) list.Add("Drive recognizes this medium.");
mediaInformation.Add(header, (table, list));
}
}
}

View File

@@ -0,0 +1,390 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : TestedMedia.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Aaru Server.
//
// --[ Description ] ----------------------------------------------------------
//
// Decodes media tests from reports.
//
// --[ 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/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2024 Natalia Portillo
// ****************************************************************************/
namespace Aaru.Server.New.Core;
public static class TestedMedia
{
/// <summary>Takes the tested media from a device report and prints it as a list of values</summary>
/// <param name="list">List to put values on</param>
/// <param name="testedMedias">List of tested media</param>
public static void Report(List<CommonTypes.Metadata.TestedMedia> testedMedias,
out Dictionary<string, (Dictionary<string, string>, List<string>)> mediaInformation)
{
mediaInformation = new Dictionary<string, (Dictionary<string, string>, List<string>)>();
foreach(CommonTypes.Metadata.TestedMedia testedMedia in testedMedias)
{
Dictionary<string, string> table = new();
List<string> list = [];
string header;
if(!string.IsNullOrWhiteSpace(testedMedia.MediumTypeName))
{
header = $"Information for medium named \"{testedMedia.MediumTypeName}\"";
if(testedMedia.MediumType != null) table.Add("Medium type code", $"{testedMedia.MediumType:X2}h");
}
else if(testedMedia.MediumType != null)
header = $"Information for medium type {testedMedia.MediumType:X2}h";
else
header = "Information for unknown medium type";
list.Add(testedMedia.MediaIsRecognized
? "Drive recognizes this medium."
: "Drive does not recognize this medium.");
if(!string.IsNullOrWhiteSpace(testedMedia.Manufacturer))
table.Add("Medium manufacturer", $"{testedMedia.Manufacturer}");
if(!string.IsNullOrWhiteSpace(testedMedia.Model)) table.Add("Medium model", $"{testedMedia.Model}");
if(testedMedia.Density != null) table.Add("Density code", $"{testedMedia.Density:X2}h");
if(testedMedia.BlockSize != null) table.Add("Logical sector size", $"{testedMedia.BlockSize} bytes");
if(testedMedia.PhysicalBlockSize != null)
table.Add("Physical sector size", $"{testedMedia.PhysicalBlockSize} bytes");
if(testedMedia.LongBlockSize != null)
table.Add("READ LONG sector size", $"{testedMedia.LongBlockSize} bytes");
if(testedMedia is { Blocks: not null, BlockSize: not null })
{
table.Add("Blocks", $"{testedMedia.Blocks}");
table.Add("Block size", $"{testedMedia.BlockSize} bytes per block");
if(testedMedia.Blocks * testedMedia.BlockSize / 1024 / 1024 > 1000000)
{
table.Add("Medium size",
$"{testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
}
else if(testedMedia.Blocks * testedMedia.BlockSize / 1024 / 1024 > 1000)
{
table.Add("Medium size",
$"{testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
}
else
{
table.Add("Medium size",
$"{testedMedia.Blocks * testedMedia.BlockSize} bytes, {testedMedia.Blocks * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)(testedMedia.Blocks * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
}
if(testedMedia is { CHS: not null, CurrentCHS: not null })
{
int currentSectors = testedMedia.CurrentCHS.Cylinders *
testedMedia.CurrentCHS.Heads *
testedMedia.CurrentCHS.Sectors;
table.Add("Cylinders", $"{testedMedia.CHS.Cylinders} max., {testedMedia.CurrentCHS.Cylinders} current");
table.Add("Heads", $"{testedMedia.CHS.Heads} max., {testedMedia.CurrentCHS.Heads} current");
table.Add("Sectors per track",
$"{testedMedia.CHS.Sectors} max., {testedMedia.CurrentCHS.Sectors} current");
table.Add("Sectors addressable in CHS mode",
$"{testedMedia.CHS.Cylinders * testedMedia.CHS.Heads * testedMedia.CHS.Sectors} max., {currentSectors} current");
table.Add("Medium size in CHS mode",
$"{(ulong)currentSectors * testedMedia.BlockSize} bytes, {(ulong)currentSectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)currentSectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
else if(testedMedia.CHS != null)
{
int currentSectors = testedMedia.CHS.Cylinders * testedMedia.CHS.Heads * testedMedia.CHS.Sectors;
table.Add("Cylinders", $"{testedMedia.CHS.Cylinders}");
table.Add("Heads", $"{testedMedia.CHS.Heads}");
table.Add("Sectors per track", $"{testedMedia.CHS.Sectors}");
table.Add("Sectors addressable in CHS mode", $"{currentSectors}");
table.Add("Medium size in CHS mode",
$"{(ulong)currentSectors * testedMedia.BlockSize} bytes, {(ulong)currentSectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)currentSectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
if(testedMedia.LBASectors != null)
{
table.Add("Sectors addressable in sectors in 28-bit LBA mode", $"{testedMedia.LBASectors}");
if((ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1024 / 1024 > 1000000)
{
table.Add("Medium size in 28-bit LBA mode",
$"{(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
}
else if((ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1024 / 1024 > 1000)
{
table.Add("Medium size in 28-bit LBA mode",
$"{(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
}
else
{
table.Add("Medium size in 28-bit LBA mode",
$"{(ulong)testedMedia.LBASectors * testedMedia.BlockSize} bytes, {(ulong)testedMedia.LBASectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)((ulong)testedMedia.LBASectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
}
if(testedMedia.LBA48Sectors != null)
{
table.Add("Sectors addressable in sectors in 48-bit LBA mode", $"{testedMedia.LBA48Sectors}");
if(testedMedia.LBA48Sectors * testedMedia.BlockSize / 1024 / 1024 > 1000000)
{
table.Add("Medium size in 48-bit LBA mode",
$"{testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000 / 1000 / 1000} Tb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024 / 1024 / 1024:F2} TiB");
}
else if(testedMedia.LBA48Sectors * testedMedia.BlockSize / 1024 / 1024 > 1000)
{
table.Add("Medium size in 48-bit LBA mode",
$"{testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000 / 1000} Gb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024 / 1024:F2} GiB");
}
else
{
table.Add("Medium size in 48-bit LBA mode",
$"{testedMedia.LBA48Sectors * testedMedia.BlockSize} bytes, {testedMedia.LBA48Sectors * testedMedia.BlockSize / 1000 / 1000} Mb, {(double)(testedMedia.LBA48Sectors * testedMedia.BlockSize) / 1024 / 1024:F2} MiB");
}
}
if(testedMedia.NominalRotationRate != null &&
testedMedia.NominalRotationRate != 0x0000 &&
testedMedia.NominalRotationRate != 0xFFFF)
{
list.Add(testedMedia.NominalRotationRate == 0x0001
? "Medium does not rotate."
: $"Medium rotates at {testedMedia.NominalRotationRate} rpm");
}
if(testedMedia.BlockSize != null &&
testedMedia.PhysicalBlockSize != null &&
testedMedia.BlockSize.Value != testedMedia.PhysicalBlockSize.Value &&
(testedMedia.LogicalAlignment & 0x8000) == 0x0000 &&
(testedMedia.LogicalAlignment & 0x4000) == 0x4000)
list.Add($"Logical sector starts at offset {testedMedia.LogicalAlignment & 0x3FFF} from physical sector");
if(testedMedia.SupportsReadSectors == true)
list.Add("Device can use the READ SECTOR(S) command in CHS mode with this medium");
if(testedMedia.SupportsReadRetry == true)
list.Add("Device can use the READ SECTOR(S) RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadDma == true)
list.Add("Device can use the READ DMA command in CHS mode with this medium");
if(testedMedia.SupportsReadDmaRetry == true)
list.Add("Device can use the READ DMA RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadLong == true)
list.Add("Device can use the READ LONG command in CHS mode with this medium");
if(testedMedia.SupportsReadLongRetry == true)
list.Add("Device can use the READ LONG RETRY command in CHS mode with this medium");
if(testedMedia.SupportsReadLba == true)
list.Add("Device can use the READ SECTOR(S) command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadRetryLba == true)
list.Add("Device can use the READ SECTOR(S) RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaLba == true)
list.Add("Device can use the READ DMA command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaRetryLba == true)
list.Add("Device can use the READ DMA RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLongLba == true)
list.Add("Device can use the READ LONG command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLongRetryLba == true)
list.Add("Device can use the READ LONG RETRY command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadLba48 == true)
list.Add("Device can use the READ SECTOR(S) command in 48-bit LBA mode with this medium");
if(testedMedia.SupportsReadDmaLba48 == true)
list.Add("Device can use the READ DMA command in 48-bit LBA mode with this medium");
if(testedMedia.SupportsSeek == true)
list.Add("Device can use the SEEK command in CHS mode with this medium");
if(testedMedia.SupportsSeekLba == true)
list.Add("Device can use the SEEK command in 28-bit LBA mode with this medium");
if(testedMedia.SupportsReadCapacity == true)
list.Add("Device can use the READ CAPACITY (10) command with this medium");
if(testedMedia.SupportsReadCapacity16 == true)
list.Add("Device can use the READ CAPACITY (16) command with this medium");
if(testedMedia.SupportsRead6 == true) list.Add("Device can use the READ (6) command with this medium");
if(testedMedia.SupportsRead10 == true) list.Add("Device can use the READ (10) command with this medium");
if(testedMedia.SupportsRead12 == true) list.Add("Device can use the READ (12) command with this medium");
if(testedMedia.SupportsRead16 == true) list.Add("Device can use the READ (16) command with this medium");
if(testedMedia.SupportsReadLong == true)
list.Add("Device can use the READ LONG (10) command with this medium");
if(testedMedia.SupportsReadLong16 == true)
list.Add("Device can use the READ LONG (16) command with this medium");
if(testedMedia.SupportsReadCd == true)
list.Add("Device can use the READ CD command with LBA addressing with this medium");
if(testedMedia.SupportsReadCdMsf == true)
list.Add("Device can use the READ CD command with MM:SS:FF addressing with this medium");
if(testedMedia.SupportsReadCdRaw == true)
list.Add("Device can use the READ CD command with LBA addressing with this medium to read raw sector");
if(testedMedia.SupportsReadCdMsfRaw == true)
list.Add("Device can use the READ CD command with MM:SS:FF addressing with this medium read raw sector");
if(testedMedia.SupportsHLDTSTReadRawDVD == true)
list.Add("Device can use the HL-DT-ST vendor READ DVD (RAW) command with this medium");
if(testedMedia.SupportsNECReadCDDA == true)
list.Add("Device can use the NEC vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPioneerReadCDDA == true)
list.Add("Device can use the PIONEER vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPioneerReadCDDAMSF == true)
list.Add("Device can use the PIONEER vendor READ CD-DA MSF command with this medium");
if(testedMedia.SupportsPlextorReadCDDA == true)
list.Add("Device can use the PLEXTOR vendor READ CD-DA command with this medium");
if(testedMedia.SupportsPlextorReadRawDVD == true)
list.Add("Device can use the PLEXTOR vendor READ DVD (RAW) command with this medium");
if(testedMedia.CanReadAACS == true)
list.Add("Device can read the Advanced Access Content System from this medium");
if(testedMedia.CanReadADIP == true)
list.Add("Device can read the DVD ADress-In-Pregroove from this medium");
if(testedMedia.CanReadATIP == true)
list.Add("Device can read the CD Absolute-Time-In-Pregroove from this medium");
if(testedMedia.CanReadBCA == true) list.Add("Device can read the Burst Cutting Area from this medium");
if(testedMedia.CanReadC2Pointers == true)
list.Add("Device can report the C2 pointers when reading from this medium");
if(testedMedia.CanReadCMI == true)
list.Add("Device can read the Copyright Management Information from this medium");
if(testedMedia.CanReadCorrectedSubchannel == true)
list.Add("Device can correct subchannels when reading from this medium");
if(testedMedia.CanReadCorrectedSubchannelWithC2 == true)
list.Add("Device can correct subchannels and report the C2 pointers when reading from this medium");
if(testedMedia.CanReadDCB == true) list.Add("Device can read the Disc Control Blocks from this medium");
if(testedMedia.CanReadDDS == true)
list.Add("Device can read the Disc Definition Structure from this medium");
if(testedMedia.CanReadDMI == true)
list.Add("Device can read the Disc Manufacturer Information from this medium");
if(testedMedia.CanReadDiscInformation == true)
list.Add("Device can read the Disc Information from this medium");
if(testedMedia.CanReadFullTOC == true)
list.Add("Device can read the Table of Contents from this medium, without processing it");
if(testedMedia.CanReadHDCMI == true)
list.Add("Device can read the HD DVD Copyright Management Information from this medium");
if(testedMedia.CanReadLayerCapacity == true)
list.Add("Device can read the layer capacity from this medium");
if(testedMedia.CanReadFirstTrackPreGap == true) list.Add("Device can read the first track's pregap data");
if(testedMedia.CanReadLeadIn == true) list.Add("Device can read the Lead-In from this medium");
if(testedMedia.CanReadLeadOut == true) list.Add("Device can read the Lead-Out from this medium");
if(testedMedia.CanReadMediaID == true) list.Add("Device can read the Media ID from this medium");
if(testedMedia.CanReadMediaSerial == true)
list.Add("Device can read the Media Serial Number from this medium");
if(testedMedia.CanReadPAC == true) list.Add("Device can read the PAC from this medium");
if(testedMedia.CanReadPFI == true)
list.Add("Device can read the Physical Format Information from this medium");
if(testedMedia.CanReadPMA == true) list.Add("Device can read the Power Management Area from this medium");
if(testedMedia.CanReadPQSubchannel == true)
list.Add("Device can read the P to Q subchannels from this medium");
if(testedMedia.CanReadPQSubchannelWithC2 == true)
list.Add("Device can read the P to Q subchannels from this medium reporting the C2 pointers");
if(testedMedia.CanReadPRI == true)
list.Add("Device can read the Pre-Recorded Information from this medium");
if(testedMedia.CanReadRWSubchannel == true)
list.Add("Device can read the R to W subchannels from this medium");
if(testedMedia.CanReadRWSubchannelWithC2 == true)
list.Add("Device can read the R to W subchannels from this medium reporting the C2 pointers");
if(testedMedia.CanReadRecordablePFI == true)
list.Add("Device can read the Physical Format Information from Lead-In from this medium");
if(testedMedia.CanReadSpareAreaInformation == true)
list.Add("Device can read the Spare Area Information from this medium");
if(testedMedia.CanReadTOC == true) list.Add("Device can read the Table of Contents from this medium");
if(testedMedia.CanReadingIntersessionLeadIn == true) list.Add("Device can read Lead-In between sessions");
if(testedMedia.CanReadingIntersessionLeadOut == true) list.Add("Device can read Lead-Out between sessions");
if(testedMedia.CanReadCdScrambled == true)
list.Add("Device can read scrambled sectors using standard READ CD command");
if(testedMedia.CanReadF1_06 == true)
list.Add("Device can read from cache using F1h command with subcommand 06h");
if(testedMedia.CanReadF1_06LeadOut == true)
list.Add("Device can read Lead-Out from cache using F1h command with subcommand 06h");
mediaInformation.Add(header, (table, list));
}
}
}