mirror of
https://github.com/aaru-dps/Aaru.git
synced 2026-07-08 18:16:24 +00:00
Initial OmniDrive DVD read
This commit is contained in:
@@ -324,6 +324,7 @@ partial class Dump
|
||||
scsiReader.otp = decodedPfi is { Layers: 1, TrackPath: false };
|
||||
|
||||
if(scsiReader.HldtstReadRaw) blocksToRead = 1;
|
||||
if(scsiReader.OmniDriveReadRaw) blocksToRead = 31;
|
||||
|
||||
UpdateStatus?.Invoke(string.Format(Localization.Core.Reading_0_raw_bytes_1_cooked_bytes_per_sector,
|
||||
longBlockSize,
|
||||
@@ -804,9 +805,9 @@ partial class Dump
|
||||
{
|
||||
mediaTags.TryGetValue(MediaTagType.DVD_DiscKey_Decrypted, out byte[] discKey);
|
||||
|
||||
if(scsiReader.HldtstReadRaw || scsiReader.ReadBuffer3CReadRaw)
|
||||
if(scsiReader.HldtstReadRaw || scsiReader.ReadBuffer3CReadRaw || scsiReader.OmniDriveReadRaw)
|
||||
{
|
||||
ReadCacheData(blocks,
|
||||
ReadRawDvdData(blocks,
|
||||
blocksToRead,
|
||||
blockSize,
|
||||
currentTry,
|
||||
@@ -905,6 +906,7 @@ partial class Dump
|
||||
|
||||
// Unnecessary since keys are already in raw data
|
||||
!scsiReader.ReadBuffer3CReadRaw &&
|
||||
!scsiReader.OmniDriveReadRaw &&
|
||||
!scsiReader.HldtstReadRaw &&
|
||||
mediaTag is not null)
|
||||
RetryTitleKeys(dvdDecrypt, mediaTag, ref totalDuration);
|
||||
|
||||
@@ -306,7 +306,7 @@ partial class Dump
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
|
||||
if(scsiReader.ReadBuffer3CReadRaw || scsiReader.HldtstReadRaw)
|
||||
if(scsiReader.ReadBuffer3CReadRaw || scsiReader.OmniDriveReadRaw || scsiReader.HldtstReadRaw)
|
||||
{
|
||||
var cmi = new byte[1];
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : Cache.cs
|
||||
// Filename : RawDvd.cs
|
||||
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// --[ License ] --------------------------------------------------------------
|
||||
@@ -44,8 +44,8 @@ namespace Aaru.Core.Devices.Dumping;
|
||||
partial class Dump
|
||||
{
|
||||
/// <summary>
|
||||
/// Dumps data when dumping from a SCSI Block Commands compliant device,
|
||||
/// and reads the data from the device cache
|
||||
/// Dumps raw DVD sectors (2064-byte frames) when dumping from a SCSI Block Commands compliant device.
|
||||
/// Supports HL-DT-ST, ReadBuffer 3C, and OmniDrive raw reading methods.
|
||||
/// </summary>
|
||||
/// <param name="blocks">Media blocks</param>
|
||||
/// <param name="maxBlocksToRead">Maximum number of blocks to read in a single command</param>
|
||||
@@ -62,7 +62,7 @@ partial class Dump
|
||||
/// <param name="imageWriteDuration">Total time spent writing to image</param>
|
||||
/// <param name="newTrim">Set if we need to start a trim</param>
|
||||
/// <param name="discKey">The DVD disc key</param>
|
||||
void ReadCacheData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, DumpHardware currentTry,
|
||||
void ReadRawDvdData(in ulong blocks, in uint maxBlocksToRead, in uint blockSize, DumpHardware currentTry,
|
||||
ExtentsULong extents, ref double currentSpeed, ref double minSpeed, ref double maxSpeed,
|
||||
ref double totalDuration, Reader scsiReader, MhddLog mhddLog, IbgLog ibgLog,
|
||||
ref double imageWriteDuration, ref bool newTrim, byte[] discKey)
|
||||
@@ -216,4 +216,4 @@ partial class Dump
|
||||
|
||||
EndProgress?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ partial class Dump
|
||||
_resume.BadBlocks.Remove(badSector);
|
||||
extents.Add(badSector);
|
||||
|
||||
if(scsiReader.ReadBuffer3CReadRaw || scsiReader.HldtstReadRaw)
|
||||
if(scsiReader.ReadBuffer3CReadRaw || scsiReader.OmniDriveReadRaw || scsiReader.HldtstReadRaw)
|
||||
{
|
||||
var cmi = new byte[1];
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ sealed partial class Reader
|
||||
// TODO: Raw reading
|
||||
public bool HldtstReadRaw;
|
||||
public uint layerbreak;
|
||||
public bool OmniDriveReadRaw;
|
||||
public bool ReadBuffer3CReadRaw;
|
||||
public bool otp;
|
||||
|
||||
@@ -587,7 +588,14 @@ sealed partial class Reader
|
||||
ReadBuffer3CReadRaw =
|
||||
!_dev.ReadBuffer3CRawDvd(out _, out senseBuf, 0, 1, _timeout, out _, layerbreak, otp);
|
||||
|
||||
if(HldtstReadRaw || _plextorReadRaw || ReadBuffer3CReadRaw)
|
||||
// Try OmniDrive on drives with OmniDrive firmware
|
||||
if(_dev.IsOmniDriveFirmware())
|
||||
{
|
||||
OmniDriveReadRaw =
|
||||
!_dev.OmniDriveReadRawDvd(out _, out senseBuf, 0, 1, _timeout, out _);
|
||||
}
|
||||
|
||||
if(HldtstReadRaw || _plextorReadRaw || ReadBuffer3CReadRaw || OmniDriveReadRaw)
|
||||
{
|
||||
CanReadRaw = true;
|
||||
LongBlockSize = 2064;
|
||||
@@ -622,6 +630,8 @@ sealed partial class Reader
|
||||
AaruLogging.WriteLine($"[slateblue1]{Localization.Core.Using_HL_DT_ST_raw_DVD_reading}[/]");
|
||||
else if(_plextorReadRaw)
|
||||
AaruLogging.WriteLine($"[slateblue1]{Localization.Core.Using_Plextor_raw_DVD_reading}[/]");
|
||||
else if(OmniDriveReadRaw)
|
||||
AaruLogging.WriteLine($"[slateblue1]{Localization.Core.Using_OmniDrive_raw_DVD_reading}[/]");
|
||||
else if(ReadBuffer3CReadRaw)
|
||||
AaruLogging.WriteLine($"[slateblue1]{Localization.Core.Using_ReadBuffer_3C_raw_DVD_reading}[/]");
|
||||
}
|
||||
@@ -687,6 +697,8 @@ sealed partial class Reader
|
||||
{
|
||||
if(HldtstReadRaw || ReadBuffer3CReadRaw)
|
||||
BlocksToRead = 1;
|
||||
else if(OmniDriveReadRaw)
|
||||
BlocksToRead = (uint)Math.Min(31, startWithBlocks);
|
||||
else if(_read6)
|
||||
{
|
||||
_dev.Read6(out _, out _, 0, LogicalBlockSize, (byte)BlocksToRead, _timeout, out _);
|
||||
@@ -833,6 +845,15 @@ sealed partial class Reader
|
||||
_timeout,
|
||||
out duration);
|
||||
}
|
||||
else if(OmniDriveReadRaw)
|
||||
{
|
||||
sense = _dev.OmniDriveReadRawDvd(out buffer,
|
||||
out senseBuf,
|
||||
(uint)block,
|
||||
count,
|
||||
_timeout,
|
||||
out duration);
|
||||
}
|
||||
else if(ReadBuffer3CReadRaw)
|
||||
{
|
||||
sense = _dev.ReadBuffer3CRawDvd(out buffer,
|
||||
|
||||
109
Aaru.Devices/Device/ScsiCommands/OmniDrive.cs
Normal file
109
Aaru.Devices/Device/ScsiCommands/OmniDrive.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
// /***************************************************************************
|
||||
// Aaru Data Preservation Suite
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Filename : OmniDrive.cs
|
||||
// Author(s) : Rebecca Wallander <sakcheen@gmail.com>
|
||||
//
|
||||
// Component : OmniDrive firmware vendor commands.
|
||||
//
|
||||
// --[ Description ] ----------------------------------------------------------
|
||||
//
|
||||
// Contains vendor commands for OmniDrive firmware. OmniDrive is custom
|
||||
// firmware that adds SCSI command 0xC0 to read raw DVD sectors (2064 bytes)
|
||||
// directly by LBA.
|
||||
//
|
||||
// --[ 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-2026 Rebecca Wallander
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using Aaru.CommonTypes.Structs.Devices.SCSI;
|
||||
using Aaru.Logging;
|
||||
|
||||
namespace Aaru.Devices;
|
||||
|
||||
public partial class Device
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the drive has OmniDrive firmware by inspecting INQUIRY Reserved5 (bytes 74+) for "OmniDrive",
|
||||
/// matching redumper's is_omnidrive_firmware behaviour.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if Reserved5 starts with "OmniDrive" and has at least 11 bytes (8 + 3 for version).</returns>
|
||||
public bool IsOmniDriveFirmware()
|
||||
{
|
||||
bool sense = ScsiInquiry(out byte[] buffer, out _, Timeout, out _);
|
||||
|
||||
if(sense || buffer == null) return false;
|
||||
|
||||
Inquiry? inquiry = Inquiry.Decode(buffer);
|
||||
|
||||
if(!inquiry.HasValue || inquiry.Value.Reserved5 == null || inquiry.Value.Reserved5.Length < 11)
|
||||
return false;
|
||||
|
||||
byte[] reserved5 = inquiry.Value.Reserved5;
|
||||
byte[] omnidrive = [0x4F, 0x6D, 0x6E, 0x69, 0x44, 0x72, 0x69, 0x76, 0x65]; // "OmniDrive"
|
||||
|
||||
if(reserved5.Length < omnidrive.Length) return false;
|
||||
|
||||
for(int i = 0; i < omnidrive.Length; i++)
|
||||
if(reserved5[i] != omnidrive[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Reads raw DVD sectors (2064 bytes) directly by LBA on OmniDrive firmware.</summary>
|
||||
/// <returns><c>true</c> if the command failed and <paramref name="senseBuffer" /> contains the sense buffer.</returns>
|
||||
/// <param name="buffer">Buffer where the raw DataFrame response will be stored</param>
|
||||
/// <param name="senseBuffer">Sense buffer.</param>
|
||||
/// <param name="lba">Start block address (LBA).</param>
|
||||
/// <param name="transferLength">Number of 2064-byte sectors to read.</param>
|
||||
/// <param name="timeout">Timeout in seconds.</param>
|
||||
/// <param name="duration">Duration in milliseconds it took for the device to execute the command.</param>
|
||||
public bool OmniDriveReadRawDvd(out byte[] buffer, out ReadOnlySpan<byte> senseBuffer, uint lba, uint transferLength,
|
||||
uint timeout, out double duration)
|
||||
{
|
||||
senseBuffer = SenseBuffer;
|
||||
Span<byte> cdb = CdbBuffer[..12];
|
||||
cdb.Clear();
|
||||
|
||||
buffer = new byte[2064 * transferLength];
|
||||
|
||||
cdb[0] = (byte)ScsiCommands.ReadOmniDrive;
|
||||
cdb[1] = 0x11; // disc_type=1 (DVD), raw_addressing=0 (LBA), fua=0, descramble=1
|
||||
cdb[2] = (byte)((lba >> 24) & 0xFF);
|
||||
cdb[3] = (byte)((lba >> 16) & 0xFF);
|
||||
cdb[4] = (byte)((lba >> 8) & 0xFF);
|
||||
cdb[5] = (byte)(lba & 0xFF);
|
||||
cdb[6] = (byte)((transferLength >> 24) & 0xFF);
|
||||
cdb[7] = (byte)((transferLength >> 16) & 0xFF);
|
||||
cdb[8] = (byte)((transferLength >> 8) & 0xFF);
|
||||
cdb[9] = (byte)(transferLength & 0xFF);
|
||||
cdb[10] = 0; // subchannels=NONE, c2=0
|
||||
cdb[11] = 0; // control
|
||||
|
||||
LastError = SendScsiCommand(cdb, ref buffer, timeout, ScsiDirection.In, out duration, out bool sense);
|
||||
|
||||
Error = LastError != 0;
|
||||
|
||||
AaruLogging.Debug(SCSI_MODULE_NAME, "OmniDrive READ RAW DVD took {0} ms", duration);
|
||||
|
||||
return sense;
|
||||
}
|
||||
}
|
||||
@@ -1885,6 +1885,13 @@ public enum ScsiCommands : byte
|
||||
|
||||
#endregion HL-DT-ST vendor commands
|
||||
|
||||
#region OmniDrive vendor commands
|
||||
|
||||
/// <summary>Reads raw DVD sectors directly by LBA/PSN (OmniDrive firmware)</summary>
|
||||
ReadOmniDrive = 0xC0,
|
||||
|
||||
#endregion OmniDrive vendor commands
|
||||
|
||||
#region NEC vendor commands
|
||||
|
||||
/// <summary>Reads CD-DA data</summary>
|
||||
|
||||
8
Aaru.Localization/Core.Designer.cs
generated
8
Aaru.Localization/Core.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
@@ -6839,6 +6839,12 @@ namespace Aaru.Localization {
|
||||
}
|
||||
}
|
||||
|
||||
public static string Using_OmniDrive_raw_DVD_reading {
|
||||
get {
|
||||
return ResourceManager.GetString("Using_OmniDrive_raw_DVD_reading", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Using_ReadBuffer_3C_raw_DVD_reading {
|
||||
get {
|
||||
return ResourceManager.GetString("Using_ReadBuffer_3C_raw_DVD_reading", resourceCulture);
|
||||
|
||||
@@ -3271,6 +3271,9 @@ No tiene sentido hacerlo y supondría demasiado esfuerzo para la cinta.</value>
|
||||
<data name="Using_MMC_READ_CD_command" xml:space="preserve">
|
||||
<value>[slateblue1]Usando comando [fuchsia]MMC READ CD[/].[/]</value>
|
||||
</data>
|
||||
<data name="Using_OmniDrive_raw_DVD_reading" xml:space="preserve">
|
||||
<value>[slateblue1]Usando lectura de [fuchsia]DVD sin procesar de OmniDrive[/].[/]</value>
|
||||
</data>
|
||||
<data name="Using_Plextor_raw_DVD_reading" xml:space="preserve">
|
||||
<value>[slateblue1]Usando lectura de [fuchsia]DVD sin procesar de Plextor[/].[/]</value>
|
||||
</data>
|
||||
|
||||
@@ -3490,6 +3490,9 @@ It has no sense to do it, and it will put too much strain on the tape.</value>
|
||||
<data name="Using_Lite-On_raw_DVD_reading" xml:space="preserve">
|
||||
<value>[slateblue1]Using [fuchsia]Lite-On raw DVD[/] reading[/]</value>
|
||||
</data>
|
||||
<data name="Using_OmniDrive_raw_DVD_reading" xml:space="preserve">
|
||||
<value>[slateblue1]Using [fuchsia]OmniDrive[/] raw DVD reading[/]</value>
|
||||
</data>
|
||||
<data name="Using_ReadBuffer_3C_raw_DVD_reading" xml:space="preserve">
|
||||
<value>[slateblue1]Using [fuchsia]ReadBuffer 3C raw DVD[/] reading[/]</value>
|
||||
</data>
|
||||
|
||||
Reference in New Issue
Block a user