Do not allocate a CDB buffer in each command call, use a single preallocated

This commit is contained in:
2025-08-22 15:56:59 +01:00
parent 6b5e5322e5
commit 8e2fdd91a6
32 changed files with 510 additions and 334 deletions

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
using Aaru.Decoders.ATA;
@@ -50,7 +51,7 @@ public partial class Device
/// <c>True</c> if SCSI command returned non-OK status and <paramref name="senseBuffer" /> contains
/// SCSI sense
/// </param>
public virtual int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
public virtual int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
{
duration = 0;

View File

@@ -33,6 +33,7 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Structs.Devices.ATA;
using Aaru.CommonTypes.Structs.Devices.SCSI;
@@ -48,9 +49,35 @@ namespace Aaru.Devices;
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
[SuppressMessage("ReSharper", "UnusedMember.Global")]
[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
public partial class Device
public partial class Device : IDisposable
{
protected Device() {}
// Pointer to send CDB to device
protected unsafe void* CdbPtr;
protected Device()
{
unsafe
{
CdbPtr = NativeMemory.AlignedAlloc(16, 64);
NativeMemory.Clear(CdbPtr, 16);
}
}
// Span to make pointer usable as data. Fixed size CDB is maximum 16 bytes. Variable size CDB is another problem.
public unsafe Span<byte> CdbBuffer => new(CdbPtr, 16);
#region IDisposable Members
/// <inheritdoc />
public unsafe void Dispose()
{
void* p = CdbPtr;
CdbPtr = null;
if(p != null) NativeMemory.AlignedFree(p);
GC.SuppressFinalize(this);
}
#endregion
/// <summary>Opens the device for sending direct commands</summary>
/// <param name="devicePath">Device path</param>
@@ -184,8 +211,9 @@ public partial class Device
if(string.IsNullOrEmpty(dev.Serial))
dev.Serial = dev.UsbSerialString;
else
foreach(char c in dev.Serial.Where(c => !char.IsControl(c)))
dev.Serial = $"{dev.Serial}{c:X2}";
{
foreach(char c in dev.Serial.Where(c => !char.IsControl(c))) dev.Serial = $"{dev.Serial}{c:X2}";
}
}
if(dev.IsFireWire)
@@ -197,8 +225,9 @@ public partial class Device
if(string.IsNullOrEmpty(dev.Serial))
dev.Serial = $"{dev.FirewireGuid:X16}";
else
foreach(char c in dev.Serial.Where(c => !char.IsControl(c)))
dev.Serial = $"{dev.Serial}{c:X2}";
{
foreach(char c in dev.Serial.Where(c => !char.IsControl(c))) dev.Serial = $"{dev.Serial}{c:X2}";
}
}
// Some optical drives are not getting the correct serial, and IDENTIFY PACKET DEVICE is blocked without

View File

@@ -30,6 +30,8 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System.Runtime.InteropServices;
namespace Aaru.Devices;
public partial class Device
@@ -38,7 +40,12 @@ public partial class Device
/// Releases unmanaged resources and performs other cleanup operations before the <see cref="Device" /> is
/// reclaimed by garbage collection.
/// </summary>
~Device() => Close();
unsafe ~Device()
{
if(CdbPtr != null) NativeMemory.AlignedFree(CdbPtr);
Close();
}
/// <summary>Closes a device</summary>
public virtual void Close() {}

View File

@@ -61,7 +61,8 @@ public partial class Device
out double duration)
{
buffer = new byte[8];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.AdaptecTranslate;
@@ -107,7 +108,8 @@ public partial class Device
{
byte[] buffer = new byte[1];
buffer[0] = threshold;
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.AdaptecSetErrorThreshold;
@@ -149,7 +151,8 @@ public partial class Device
out double duration)
{
buffer = new byte[9];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.AdaptecTranslate;
@@ -183,7 +186,8 @@ public partial class Device
byte[] oneKBuffer = new byte[1024];
Array.Copy(buffer, 0, oneKBuffer, 0, buffer.Length < 1024 ? buffer.Length : 1024);
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.AdaptecWriteBuffer;
@@ -211,7 +215,8 @@ public partial class Device
public bool AdaptecReadBuffer(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[1024];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.AdaptecReadBuffer;

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Logging;
// ReSharper disable UnusedMember.Global
@@ -48,7 +49,8 @@ public partial class Device
out double duration)
{
buffer = new byte[3];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.ArchiveRequestBlockAddress;
@@ -67,9 +69,7 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization.ARCHIVE_CORP_REQUEST_BLOCK_ADDRESS_took_0_ms,
duration);
AaruLogging.Debug(SCSI_MODULE_NAME, Localization.ARCHIVE_CORP_REQUEST_BLOCK_ADDRESS_took_0_ms, duration);
return sense;
}
@@ -91,8 +91,9 @@ public partial class Device
public bool ArchiveCorpSeekBlock(out byte[] senseBuffer, bool immediate, uint lba, uint timeout,
out double duration)
{
byte[] buffer = [];
byte[] cdb = new byte[6];
byte[] buffer = [];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.ArchiveSeekBlock;

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
using Aaru.Logging;
@@ -59,8 +60,9 @@ public partial class Device
/// <param name="duration">Duration.</param>
public bool CertanceParkUnpark(out byte[] senseBuffer, bool park, uint timeout, out double duration)
{
byte[] buffer = [];
byte[] cdb = new byte[6];
byte[] buffer = [];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.CertanceParkUnpark;

View File

@@ -51,13 +51,14 @@ public partial class Device
public bool FujitsuDisplay(out byte[] senseBuffer, bool flash, FujitsuDisplayModes mode, string firstHalf,
string secondHalf, uint timeout, out double duration)
{
byte[] tmp;
byte[] firstHalfBytes = new byte[8];
byte[] secondHalfBytes = new byte[8];
byte[] buffer = new byte[17];
bool displayLen = false;
bool halfMsg = false;
byte[] cdb = new byte[10];
byte[] tmp;
byte[] firstHalfBytes = new byte[8];
byte[] secondHalfBytes = new byte[8];
byte[] buffer = new byte[17];
bool displayLen = false;
bool halfMsg = false;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
if(!string.IsNullOrWhiteSpace(firstHalf))
{

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using Aaru.CommonTypes.Enums;
using Aaru.Decoders.DVD;
@@ -60,7 +61,8 @@ public partial class Device
Read12(out _, out _, 0, false, false, false, false, lba, 2048, 0, 16, false, timeout, out duration);
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
buffer = new byte[2064 * transferLength];
uint cacheDataOffset = 0x80000000 + lba % 96 * 2064;

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Logging;
// ReSharper disable UnusedMember.Global
@@ -71,7 +72,8 @@ public partial class Device
ushort blockBytes, bool pba, bool sectorCount, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ReadLong;

View File

@@ -45,7 +45,8 @@ public partial class Device
public bool KreonDeprecatedUnlock(out byte[] senseBuffer, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.KreonCommand;
@@ -101,7 +102,8 @@ public partial class Device
public bool KreonSetLockState(out byte[] senseBuffer, KreonLockStates state, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.KreonCommand;
@@ -135,7 +137,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = new byte[26];
features = 0;
@@ -225,7 +228,8 @@ public partial class Device
byte requestNumber = 0x00)
{
buffer = new byte[2048];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.KreonSsCommand;

View File

@@ -115,7 +115,8 @@ public partial class Device
Read12(out _, out _, 0, false, false, false, false, lba, 2048, 0, 16, false, timeout, out duration);
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[transferLength];

View File

@@ -79,7 +79,8 @@ public partial class Device
MmcGetConfigurationRt rt, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[8];
cdb[0] = (byte)ScsiCommands.GetConfiguration;
@@ -119,13 +120,13 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.GET_CONFIGURATION_Starting_Feature_Number_1_Return_Type_2_Sense_3_Last_Error_4_took_0_ms,
duration,
startingFeatureNumber,
rt,
sense,
LastError);
Localization
.GET_CONFIGURATION_Starting_Feature_Number_1_Return_Type_2_Sense_3_Last_Error_4_took_0_ms,
duration,
startingFeatureNumber,
rt,
sense,
LastError);
return sense;
}
@@ -146,7 +147,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
buffer = new byte[8];
cdb[0] = (byte)ScsiCommands.ReadDiscStructure;
@@ -206,16 +208,16 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.READ_DISC_STRUCTURE_Media_Type_1_Address_2_Layer_Number_3_Format_4_AGID_5_Sense_6_Last_Error_7_took_0_ms,
duration,
mediaType,
address,
layerNumber,
format,
agid,
sense,
LastError);
Localization
.READ_DISC_STRUCTURE_Media_Type_1_Address_2_Layer_Number_3_Format_4_AGID_5_Sense_6_Last_Error_7_took_0_ms,
duration,
mediaType,
address,
layerNumber,
format,
agid,
sense,
LastError);
return sense;
}
@@ -313,7 +315,8 @@ public partial class Device
byte trackSessionNumber, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] tmpBuffer = (format & 0x0F) == 5 ? new byte[32768] : new byte[1536];
@@ -344,14 +347,14 @@ public partial class Device
Array.Copy(tmpBuffer, 0, buffer, 0, buffer.Length);
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.READ_TOC_PMA_ATIP_took_MSF_1_Format_2_Track_Session_Number_3_Sense_4_LastError_5_0_ms,
duration,
msf,
format,
trackSessionNumber,
sense,
LastError);
Localization
.READ_TOC_PMA_ATIP_took_MSF_1_Format_2_Track_Session_Number_3_Sense_4_LastError_5_0_ms,
duration,
msf,
format,
trackSessionNumber,
sense,
LastError);
return sense;
}
@@ -371,14 +374,14 @@ public partial class Device
duration += tmpDuration;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.READ_TOC_PMA_ATIP_took_MSF_1_Format_2_Track_Session_Number_3_Sense_4_LastError_5_0_ms,
duration,
msf,
format,
trackSessionNumber,
sense,
LastError);
Localization
.READ_TOC_PMA_ATIP_took_MSF_1_Format_2_Track_Session_Number_3_Sense_4_LastError_5_0_ms,
duration,
msf,
format,
trackSessionNumber,
sense,
LastError);
return sense;
}
@@ -407,7 +410,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] tmpBuffer = new byte[804];
cdb[0] = (byte)ScsiCommands.ReadDiscInformation;
@@ -433,11 +437,11 @@ public partial class Device
Array.Copy(tmpBuffer, 0, buffer, 0, buffer.Length);
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization.READ_DISC_INFORMATION_Data_Type_1_Sense_2_Last_Error_3_took_0_ms,
duration,
dataType,
sense,
LastError);
Localization.READ_DISC_INFORMATION_Data_Type_1_Sense_2_Last_Error_3_took_0_ms,
duration,
dataType,
sense,
LastError);
return sense;
}
@@ -466,7 +470,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ReadCd;
cdb[1] = (byte)((byte)expectedSectorType << 2);
@@ -506,23 +511,23 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.READ_CD_LBA_1_Block_Size_2_Transfer_Length_3_Expected_Sector_Type_4_DAP_5_Relative_Address_6_Sync_7_Headers_8_User_Data_9_ECC_EDC_10_C2_11_Subchannel_12_Sense_13_Last_Error_14_took_0_ms,
duration,
lba,
blockSize,
transferLength,
expectedSectorType,
dap,
relAddr,
sync,
headerCodes,
userData,
edcEcc,
c2Error,
subchannel,
sense,
LastError);
Localization
.READ_CD_LBA_1_Block_Size_2_Transfer_Length_3_Expected_Sector_Type_4_DAP_5_Relative_Address_6_Sync_7_Headers_8_User_Data_9_ECC_EDC_10_C2_11_Subchannel_12_Sense_13_Last_Error_14_took_0_ms,
duration,
lba,
blockSize,
transferLength,
expectedSectorType,
dap,
relAddr,
sync,
headerCodes,
userData,
edcEcc,
c2Error,
subchannel,
sense,
LastError);
return sense;
}
@@ -550,7 +555,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ReadCdMsf;
cdb[1] = (byte)((byte)expectedSectorType << 2);
@@ -589,22 +595,22 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.READ_CD_MSF_Start_MSF_1_End_MSF_2_Block_Size_3_Expected_Sector_Type_4_DAP_5_Sync_6_Headers_7_User_Data_8_ECC_EDC_9_C2_10_Subchannel_11_Sense_12_LastError_13_took_0_ms,
duration,
startMsf,
endMsf,
blockSize,
expectedSectorType,
dap,
sync,
headerCodes,
userData,
edcEcc,
c2Error,
subchannel,
sense,
LastError);
Localization
.READ_CD_MSF_Start_MSF_1_End_MSF_2_Block_Size_3_Expected_Sector_Type_4_DAP_5_Sync_6_Headers_7_User_Data_8_ECC_EDC_9_C2_10_Subchannel_11_Sense_12_LastError_13_took_0_ms,
duration,
startMsf,
endMsf,
blockSize,
expectedSectorType,
dap,
sync,
headerCodes,
userData,
edcEcc,
c2Error,
subchannel,
sense,
LastError);
return sense;
}
@@ -636,7 +642,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
@@ -656,13 +663,13 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.PREVENT_ALLOW_MEDIUM_REMOVAL_Persistent_1_Prevent_2_Sense_3_LastError_4_took_0_ms,
duration,
persistent,
prevent,
sense,
LastError);
Localization
.PREVENT_ALLOW_MEDIUM_REMOVAL_Persistent_1_Prevent_2_Sense_3_LastError_4_took_0_ms,
duration,
persistent,
prevent,
sense,
LastError);
return sense;
}
@@ -714,7 +721,8 @@ public partial class Device
bool changeFormatLayer, bool loadEject, bool start, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.StartStopUnit;
@@ -746,17 +754,17 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.START_STOP_UNIT_Immediate_1_FormatLayer_2_Power_Conditions_3_Change_Format_Layer_4_Load_Eject_5_Start_6_Sense_7_Last_Error_8_took_0_ms,
duration,
immediate,
formatLayer,
powerConditions,
changeFormatLayer,
loadEject,
start,
sense,
LastError);
Localization
.START_STOP_UNIT_Immediate_1_FormatLayer_2_Power_Conditions_3_Change_Format_Layer_4_Load_Eject_5_Start_6_Sense_7_Last_Error_8_took_0_ms,
duration,
immediate,
formatLayer,
powerConditions,
changeFormatLayer,
loadEject,
start,
sense,
LastError);
return sense;
}
@@ -772,7 +780,8 @@ public partial class Device
public bool ReadMcn(out string mcn, out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
mcn = null;
cdb[0] = (byte)ScsiCommands.ReadSubChannel;
@@ -795,10 +804,10 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization.READ_READ_SUB_CHANNEL_MCN_Sense_1_Last_Error_2_took_0_ms,
duration,
sense,
LastError);
Localization.READ_READ_SUB_CHANNEL_MCN_Sense_1_Last_Error_2_took_0_ms,
duration,
sense,
LastError);
if(!sense && (buffer[8] & 0x80) == 0x80) mcn = Encoding.ASCII.GetString(buffer, 9, 13);
@@ -818,7 +827,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
isrc = null;
cdb[0] = (byte)ScsiCommands.ReadSubChannel;
@@ -842,12 +852,11 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.READ_READ_SUB_CHANNEL_ISRC_Track_Number_1_Sense_2_Last_Error_3_took_0_ms,
duration,
trackNumber,
sense,
LastError);
Localization.READ_READ_SUB_CHANNEL_ISRC_Track_Number_1_Sense_2_Last_Error_3_took_0_ms,
duration,
trackNumber,
sense,
LastError);
if(!sense && (buffer[8] & 0x80) == 0x80) isrc = Encoding.ASCII.GetString(buffer, 9, 12);
@@ -866,7 +875,8 @@ public partial class Device
ushort writeSpeed, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.SetCdRomSpeed;
@@ -887,14 +897,14 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.SET_CD_SPEED_Rotational_Control_1_Read_Speed_2_Write_Speed_3_Sense_4_Last_Error_5_took_0_ms,
duration,
rotationalControl,
readSpeed,
writeSpeed,
sense,
LastError);
Localization
.SET_CD_SPEED_Rotational_Control_1_Read_Speed_2_Write_Speed_3_Sense_4_Last_Error_5_took_0_ms,
duration,
rotationalControl,
readSpeed,
writeSpeed,
sense,
LastError);
return sense;
}
@@ -912,7 +922,8 @@ public partial class Device
uint address, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[48];
cdb[0] = (byte)ScsiCommands.ReadTrackInformation;
@@ -937,11 +948,11 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization.READ_TRACK_INFORMATION_Data_Type_1_Sense_2_Last_Error_3_took_0_ms,
duration,
type,
sense,
LastError);
Localization.READ_TRACK_INFORMATION_Data_Type_1_Sense_2_Last_Error_3_took_0_ms,
duration,
type,
sense,
LastError);
return sense;
}

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Logging;
namespace Aaru.Devices;
@@ -48,7 +49,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[length];
cdb[0] = (byte)ScsiCommands.MediaTekVendorCommand;

View File

@@ -32,6 +32,7 @@
// ReSharper disable InconsistentNaming
using System;
using Aaru.Logging;
// ReSharper disable UnusedMember.Global
@@ -50,7 +51,8 @@ public partial class Device
{
const ushort transferLength = 2336;
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.MiniDiscReadDTOC;
@@ -86,7 +88,8 @@ public partial class Device
{
const ushort transferLength = 2336;
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.MiniDiscReadUTOC;
@@ -124,7 +127,8 @@ public partial class Device
{
const ushort transferLength = 4;
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.MiniDiscD5;
@@ -157,7 +161,8 @@ public partial class Device
public bool MiniDiscStopPlaying(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.MiniDiscStopPlay;
@@ -188,7 +193,8 @@ public partial class Device
{
const ushort transferLength = 4;
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.MiniDiscReadPosition;
@@ -222,7 +228,8 @@ public partial class Device
{
const ushort transferLength = 8;
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.MiniDiscGetType;

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Logging;
namespace Aaru.Devices;
@@ -48,7 +49,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.NecReadCdDa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Decoders.SCSI;
using Aaru.Logging;
@@ -62,7 +63,8 @@ public partial class Device
out uint foundBlocks, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
foundLba = 0;
foundBlocks = 0;

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Logging;
namespace Aaru.Devices;
@@ -50,7 +51,8 @@ public partial class Device
uint transferLength, PioneerSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ReadCdDa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
@@ -93,7 +95,8 @@ public partial class Device
uint blockSize, PioneerSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ReadCdDaMsf;
cdb[3] = (byte)((startMsf & 0xFF0000) >> 16);
@@ -139,7 +142,8 @@ public partial class Device
bool errorFlags, bool wholeSector, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ReadCdXa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Logging;
// ReSharper disable UnusedMember.Global
@@ -92,7 +93,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlasmonReadSectorLocation;
cdb[2] = (byte)((address & 0xFF000000) >> 24);

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Helpers;
using Aaru.Logging;
@@ -51,7 +52,8 @@ public partial class Device
uint transferLength, PlextorSubchannel subchannel, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ReadCdDa;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);
@@ -77,15 +79,15 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization
.Plextor_READ_CD_DA_LBA_1_Block_Size_2_Transfer_Length_3_Subchannel_4_Sense_5_Last_Error_6_took_0_ms,
duration,
lba,
blockSize,
transferLength,
subchannel,
sense,
LastError);
Localization
.Plextor_READ_CD_DA_LBA_1_Block_Size_2_Transfer_Length_3_Subchannel_4_Sense_5_Last_Error_6_took_0_ms,
duration,
lba,
blockSize,
transferLength,
subchannel,
sense,
LastError);
return sense;
}
@@ -102,7 +104,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[2064 * transferLength];
cdb[0] = (byte)ScsiCommands.ReadBuffer;
@@ -139,7 +142,8 @@ public partial class Device
{
buffer = new byte[256];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorReadEeprom;
cdb[8] = 1;
@@ -169,7 +173,8 @@ public partial class Device
{
buffer = new byte[512];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorReadEeprom;
cdb[8] = 2;
@@ -202,7 +207,8 @@ public partial class Device
{
buffer = new byte[blockSize];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorReadEeprom;
cdb[1] = 1;
@@ -238,7 +244,8 @@ public partial class Device
{
byte[] buf = new byte[10];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
selected = 0;
max = 0;
@@ -280,7 +287,8 @@ public partial class Device
{
byte[] buf = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
enabled = false;
speed = 0;
@@ -319,7 +327,8 @@ public partial class Device
{
buffer = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
@@ -352,7 +361,8 @@ public partial class Device
{
buffer = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
@@ -386,7 +396,8 @@ public partial class Device
{
buffer = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
@@ -423,7 +434,8 @@ public partial class Device
{
buffer = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[2] = (byte)PlextorSubCommands.SecuRec;
@@ -454,7 +466,8 @@ public partial class Device
{
buffer = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
@@ -486,7 +499,8 @@ public partial class Device
{
buffer = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
@@ -503,9 +517,7 @@ public partial class Device
Error = LastError != 0;
AaruLogging.Debug(SCSI_MODULE_NAME,
Localization.PLEXTOR_GET_SINGLE_SESSION_HIDE_CD_R_took_0_ms,
duration);
AaruLogging.Debug(SCSI_MODULE_NAME, Localization.PLEXTOR_GET_SINGLE_SESSION_HIDE_CD_R_took_0_ms, duration);
return sense;
}
@@ -522,7 +534,8 @@ public partial class Device
{
buffer = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;
@@ -559,7 +572,8 @@ public partial class Device
{
buffer = new byte[8];
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.PlextorExtend;
cdb[1] = (byte)PlextorSubCommands.GetMode;

View File

@@ -62,7 +62,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.Read6;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
@@ -113,7 +114,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.Read10;
cdb[1] = (byte)((rdprotect & 0x07) << 5);
@@ -178,7 +180,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.Read12;
cdb[1] = (byte)((rdprotect & 0x07) << 5);
@@ -246,7 +249,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[16];
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
byte[] lbaBytes = BitConverter.GetBytes(lba);
cdb[0] = (byte)ScsiCommands.Read16;
@@ -308,7 +312,8 @@ public partial class Device
ushort transferBytes, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ReadLong;
@@ -356,7 +361,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[16];
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
byte[] lbaBytes = BitConverter.GetBytes(lba);
cdb[0] = (byte)ScsiCommands.ServiceActionIn;
@@ -399,7 +405,8 @@ public partial class Device
public bool Seek6(out byte[] senseBuffer, uint lba, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.Seek6;
@@ -430,7 +437,8 @@ public partial class Device
public bool Seek10(out byte[] senseBuffer, uint lba, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.Seek10;

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Logging;
namespace Aaru.Devices;
@@ -53,7 +54,8 @@ public partial class Device
uint timeout, out double duration)
{
buffer = new byte[256];
byte[] cdb = new byte[16];
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.ReadAttribute;

View File

@@ -77,7 +77,15 @@ public partial class Device
buffer = new byte[36];
senseBuffer = new byte[64];
byte[] cdb = [(byte)ScsiCommands.Inquiry, 0, 0, 0, 36, 0];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.Inquiry;
cdb[1] = 0;
cdb[2] = 0;
cdb[3] = 0;
cdb[4] = 36;
cdb[5] = 0;
LastError = SendScsiCommand(cdb,
ref buffer,
@@ -93,7 +101,12 @@ public partial class Device
byte pagesLength = (byte)(buffer[4] + 5);
cdb = [(byte)ScsiCommands.Inquiry, 0, 0, 0, pagesLength, 0];
cdb[0] = (byte)ScsiCommands.Inquiry;
cdb[1] = 0;
cdb[2] = 0;
cdb[3] = 0;
cdb[4] = pagesLength;
cdb[5] = 0;
buffer = new byte[pagesLength];
senseBuffer = new byte[64];
@@ -157,7 +170,14 @@ public partial class Device
buffer = new byte[36];
senseBuffer = new byte[64];
byte[] cdb = [(byte)ScsiCommands.Inquiry, 1, page, 0, 36, 0];
Span<byte> cdb = CdbBuffer[..6];
cdb[0] = (byte)ScsiCommands.Inquiry;
cdb[1] = 1;
cdb[2] = page;
cdb[3] = 0;
cdb[4] = 36;
cdb[5] = 0;
LastError = SendScsiCommand(cdb,
ref buffer,
@@ -176,7 +196,12 @@ public partial class Device
byte pagesLength = (byte)(buffer[3] + 4);
cdb = [(byte)ScsiCommands.Inquiry, 1, page, 0, pagesLength, 0];
cdb[0] = (byte)ScsiCommands.Inquiry;
cdb[1] = 1;
cdb[2] = page;
cdb[3] = 0;
cdb[4] = pagesLength;
cdb[5] = 0;
buffer = new byte[pagesLength];
senseBuffer = new byte[64];
@@ -205,7 +230,10 @@ public partial class Device
{
senseBuffer = new byte[64];
byte[] cdb = [(byte)ScsiCommands.TestUnitReady, 0, 0, 0, 0, 0];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.TestUnitReady;
byte[] buffer = [];
@@ -260,9 +288,11 @@ public partial class Device
byte pageCode, byte subPageCode, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
buffer = new byte[254];
cdb[0] = (byte)ScsiCommands.ModeSense;
if(dbd) cdb[1] = 0x08;
@@ -350,7 +380,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[4096];
cdb[0] = (byte)ScsiCommands.ModeSense10;
@@ -438,7 +469,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.PreventAllowMediumRemoval;
@@ -481,7 +513,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
buffer = new byte[8];
cdb[0] = (byte)ScsiCommands.ReadCapacity;
@@ -534,7 +567,8 @@ public partial class Device
out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[16];
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
buffer = new byte[32];
cdb[0] = (byte)ScsiCommands.ServiceActionIn;
@@ -583,7 +617,8 @@ public partial class Device
public bool ReadMediaSerialNumber(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[12];
Span<byte> cdb = CdbBuffer[..12];
cdb.Clear();
buffer = new byte[4];
cdb[0] = (byte)ScsiCommands.ReadSerialNumber;
@@ -775,7 +810,8 @@ public partial class Device
return true;
}
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
cdb[0] = (byte)ScsiCommands.ModeSelect;
@@ -832,9 +868,8 @@ public partial class Device
return true;
}
byte[] cdb = new byte[10];
cdb[0] = (byte)ScsiCommands.ModeSelect10;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
if(pageFormat) cdb[1] += 0x10;
@@ -874,7 +909,8 @@ public partial class Device
/// <returns><c>true</c> if the command failed.</returns>
public bool RequestSense(bool descriptor, out byte[] buffer, uint timeout, out double duration)
{
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
buffer = new byte[252];
cdb[0] = (byte)ScsiCommands.RequestSense;

View File

@@ -74,7 +74,8 @@ public partial class Device
uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.LoadUnload;
@@ -160,7 +161,8 @@ public partial class Device
uint objectId, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.Locate;
@@ -258,7 +260,8 @@ public partial class Device
bool bam, byte partition, ulong identifier, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[16];
Span<byte> cdb = CdbBuffer[..16];
cdb.Clear();
byte[] buffer = [];
byte[] idBytes = BitConverter.GetBytes(identifier);
@@ -348,7 +351,8 @@ public partial class Device
uint blockSize, uint timeout, out double duration)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.Read6;
@@ -457,7 +461,8 @@ public partial class Device
ulong objectId, uint transferLen, uint objectSize, uint timeout, out double duration)
{
buffer = fixedLen ? new byte[objectSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
byte[] idBytes = BitConverter.GetBytes(objectId);
@@ -503,7 +508,8 @@ public partial class Device
public bool ReadBlockLimits(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration)
{
buffer = new byte[6];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.ReadBlockLimits;
@@ -584,7 +590,8 @@ public partial class Device
_ => new byte[32]
};
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.ReadPosition;
@@ -661,7 +668,8 @@ public partial class Device
uint transferLen, uint blockSize, uint timeout, out double duration)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.ReadReverse;
@@ -806,7 +814,8 @@ public partial class Device
out double duration)
{
buffer = fixedLen ? new byte[objectSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
byte[] idBytes = BitConverter.GetBytes(objectId);
@@ -888,7 +897,8 @@ public partial class Device
uint transferLen, uint blockSize, uint timeout, out double duration)
{
buffer = fixedLen ? new byte[blockSize * transferLen] : new byte[transferLen];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.RecoverBufferedData;
@@ -945,7 +955,8 @@ public partial class Device
uint timeout, out double duration)
{
buffer = new byte[256];
byte[] cdb = new byte[10];
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
senseBuffer = new byte[64];
cdb[0] = (byte)ScsiCommands.ReportDensitySupport;
@@ -1005,7 +1016,8 @@ public partial class Device
public bool Rewind(out byte[] senseBuffer, bool immediate, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.Rewind;
@@ -1036,7 +1048,8 @@ public partial class Device
public bool TrackSelect(out byte[] senseBuffer, byte track, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
cdb[0] = (byte)ScsiCommands.TrackSelect;
@@ -1067,7 +1080,8 @@ public partial class Device
public bool Space(out byte[] senseBuffer, SscSpaceCodes code, int count, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
byte[] buffer = [];
byte[] countB = BitConverter.GetBytes(count);

View File

@@ -30,6 +30,7 @@
// Copyright © 2011-2025 Natalia Portillo
// ****************************************************************************/
using System;
using Aaru.Logging;
// ReSharper disable UnusedMember.Global
@@ -84,8 +85,9 @@ public partial class Device
bool inhibitDma, bool readLong, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[6];
bool sense;
Span<byte> cdb = CdbBuffer[..6];
cdb.Clear();
bool sense;
cdb[0] = (byte)ScsiCommands.Read6;
cdb[1] = (byte)((lba & 0x1F0000) >> 16);
@@ -170,8 +172,9 @@ public partial class Device
ushort transferLength, bool inhibitDma, bool readLong, uint timeout, out double duration)
{
senseBuffer = new byte[64];
byte[] cdb = new byte[10];
bool sense;
Span<byte> cdb = CdbBuffer[..10];
cdb.Clear();
bool sense;
cdb[0] = (byte)ScsiCommands.Read10;
cdb[2] = (byte)((lba & 0xFF000000) >> 24);

View File

@@ -43,8 +43,8 @@ namespace Aaru.Devices.Linux;
partial class Device
{
/// <inheritdoc />
public override int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
public override unsafe int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
{
// We need a timeout
if(timeout == 0) timeout = Timeout > 0 ? Timeout : 15;
@@ -74,13 +74,12 @@ partial class Device
ioHdr.dxfer_direction = dir;
ioHdr.dxfer_len = (uint)buffer.Length;
ioHdr.dxferp = Marshal.AllocHGlobal(buffer.Length);
ioHdr.cmdp = Marshal.AllocHGlobal(cdb.Length);
ioHdr.cmdp = (IntPtr)CdbPtr;
ioHdr.sbp = Marshal.AllocHGlobal(senseBuffer.Length);
ioHdr.timeout = timeout * 1000;
ioHdr.flags = (uint)SgFlags.DirectIo;
Marshal.Copy(buffer, 0, ioHdr.dxferp, buffer.Length);
Marshal.Copy(cdb, 0, ioHdr.cmdp, cdb.Length);
Marshal.Copy(senseBuffer, 0, ioHdr.sbp, senseBuffer.Length);
var cmdStopWatch = new Stopwatch();
@@ -91,7 +90,6 @@ partial class Device
if(error < 0) error = Marshal.GetLastWin32Error();
Marshal.Copy(ioHdr.dxferp, buffer, 0, buffer.Length);
Marshal.Copy(ioHdr.cmdp, cdb, 0, cdb.Length);
Marshal.Copy(ioHdr.sbp, senseBuffer, 0, senseBuffer.Length);
sense |= (ioHdr.info & SgInfo.OkMask) != SgInfo.Ok;
@@ -99,12 +97,12 @@ partial class Device
duration = ioHdr.duration > 0 ? ioHdr.duration : cmdStopWatch.Elapsed.TotalMilliseconds;
Marshal.FreeHGlobal(ioHdr.dxferp);
Marshal.FreeHGlobal(ioHdr.cmdp);
Marshal.FreeHGlobal(ioHdr.sbp);
return error;
}
/// <summary>Converts ATA protocol to SG_IO direction</summary>
/// <param name="protocol">ATA protocol</param>
/// <returns>SG_IO direction</returns>
@@ -138,7 +136,7 @@ partial class Device
if(buffer == null) return -1;
var cdb = new byte[16];
byte[] cdb = new byte[16];
cdb[0] = (byte)ScsiCommands.AtaPassThrough16;
cdb[1] = (byte)((byte)protocol << 1 & 0x1E);
@@ -203,7 +201,7 @@ partial class Device
if(buffer == null) return -1;
var cdb = new byte[16];
byte[] cdb = new byte[16];
cdb[0] = (byte)ScsiCommands.AtaPassThrough16;
cdb[1] = (byte)((byte)protocol << 1 & 0x1E);
@@ -268,7 +266,7 @@ partial class Device
if(buffer == null) return -1;
var cdb = new byte[16];
byte[] cdb = new byte[16];
cdb[0] = (byte)ScsiCommands.AtaPassThrough16;
cdb[1] = (byte)((byte)protocol << 1 & 0x1E);
cdb[1] |= 0x01;
@@ -451,17 +449,17 @@ partial class Device
sense = false;
// Create array for buffers
var bufferPointers = new nint[commands.Length];
IntPtr[] bufferPointers = new nint[commands.Length];
// Allocate memory for the array for commands
var ioMultiCmd = new byte[sizeof(ulong) + Marshal.SizeOf<MmcIocCmd>() * commands.Length];
byte[] ioMultiCmd = new byte[sizeof(ulong) + Marshal.SizeOf<MmcIocCmd>() * commands.Length];
// First value of array is uint64 with count of commands
Array.Copy(BitConverter.GetBytes((ulong)commands.Length), 0, ioMultiCmd, 0, sizeof(ulong));
int off = sizeof(ulong);
for(var i = 0; i < commands.Length; i++)
for(int i = 0; i < commands.Length; i++)
{
// Create command
var ioCmd = new MmcIocCmd();
@@ -521,9 +519,9 @@ partial class Device
Marshal.Copy(ioMultiCmdPtr, ioMultiCmd, 0, ioMultiCmd.Length);
// TODO: Use real pointers this is too slow
for(var i = 0; i < commands.Length; i++)
for(int i = 0; i < commands.Length; i++)
{
var tmp = new byte[Marshal.SizeOf<MmcIocCmd>()];
byte[] tmp = new byte[Marshal.SizeOf<MmcIocCmd>()];
// Copy command to managed space
Array.Copy(ioMultiCmd, off, tmp, 0, tmp.Length);
@@ -623,7 +621,7 @@ partial class Device
resultSize = result;
}
var resultString = new byte[resultSize];
byte[] resultString = new byte[resultSize];
Marshal.Copy(buf, resultString, 0, resultSize);
Marshal.FreeHGlobal(buf);

View File

@@ -219,8 +219,8 @@ partial class Device : Devices.Device
var usbFs = new FileStream(resolvedLink + "/descriptors", FileMode.Open, FileAccess.Read);
var usbBuf = new byte[65536];
int usbCount = usbFs.EnsureRead(usbBuf, 0, 65536);
byte[] usbBuf = new byte[65536];
int usbCount = usbFs.EnsureRead(usbBuf, 0, 65536);
dev.UsbDescriptors = new byte[usbCount];
Array.Copy(usbBuf, 0, dev.UsbDescriptors, 0, usbCount);
usbFs.Close();
@@ -388,8 +388,8 @@ partial class Device : Devices.Device
var cisFs = new FileStream(possibleDir + "/cis", FileMode.Open, FileAccess.Read);
var cisBuf = new byte[65536];
int cisCount = cisFs.EnsureRead(cisBuf, 0, 65536);
byte[] cisBuf = new byte[65536];
int cisCount = cisFs.EnsureRead(cisBuf, 0, 65536);
dev.Cis = new byte[cisCount];
Array.Copy(cisBuf, 0, dev.Cis, 0, cisCount);
cisFs.Close();

View File

@@ -41,7 +41,7 @@ namespace Aaru.Devices.Remote;
public partial class Device
{
/// <inheritdoc />
public override int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
public override int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
{
// We need a timeout
@@ -194,7 +194,7 @@ public partial class Device
if(_remote.ServerProtocolVersion >= 2)
return _remote.SendMultipleMmcCommands(commands, out duration, out sense, timeout);
var error = 0;
int error = 0;
duration = 0;
sense = false;

View File

@@ -522,7 +522,7 @@ public class Remote : IDisposable
/// <c>True</c> if SCSI command returned non-OK status and <paramref name="senseBuffer" /> contains
/// SCSI sense
/// </param>
public int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
public int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
{
senseBuffer = null;
@@ -553,7 +553,11 @@ public class Remote : IDisposable
Array.Copy(pktBuf, 0, buf, 0, Marshal.SizeOf<AaruPacketCmdScsi>());
if(cdb != null) Array.Copy(cdb, 0, buf, Marshal.SizeOf<AaruPacketCmdScsi>(), cmdPkt.cdb_len);
if(cdb != null)
{
byte[] cdbArray = cdb.ToArray();
Array.Copy(cdbArray, 0, buf, Marshal.SizeOf<AaruPacketCmdScsi>(), cmdPkt.cdb_len);
}
if(buffer != null)
Array.Copy(buffer, 0, buf, Marshal.SizeOf<AaruPacketCmdScsi>() + cmdPkt.cdb_len, cmdPkt.buf_len);

View File

@@ -44,7 +44,7 @@ namespace Aaru.Devices.Windows;
partial class Device
{
/// <inheritdoc />
public override int SendScsiCommand(byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
public override int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
ScsiDirection direction, out double duration, out bool sense)
{
// We need a timeout
@@ -80,10 +80,10 @@ partial class Device
sptdSb.sptd.Length = (ushort)Marshal.SizeOf(sptdSb.sptd);
sptdSb.sptd.SenseInfoOffset = (uint)Marshal.SizeOf(sptdSb.sptd);
Array.Copy(cdb, sptdSb.sptd.Cdb, cdb.Length);
cdb.CopyTo(sptdSb.sptd.Cdb);
uint k = 0;
var error = 0;
int error = 0;
Marshal.Copy(buffer, 0, sptdSb.sptd.DataBuffer, buffer.Length);
@@ -173,7 +173,7 @@ partial class Device
aptd.AtaFlags |= AtaFlags.DrdyRequired;
uint k = 0;
var error = 0;
int error = 0;
Marshal.Copy(buffer, 0, aptd.DataBuffer, buffer.Length);
@@ -268,7 +268,7 @@ partial class Device
aptd.AtaFlags |= AtaFlags.DrdyRequired;
uint k = 0;
var error = 0;
int error = 0;
Marshal.Copy(buffer, 0, aptd.DataBuffer, buffer.Length);
@@ -372,7 +372,7 @@ partial class Device
aptd.AtaFlags |= AtaFlags.DrdyRequired;
uint k = 0;
var error = 0;
int error = 0;
Marshal.Copy(buffer, 0, aptd.DataBuffer, buffer.Length);
@@ -535,17 +535,18 @@ partial class Device
if(flags.HasFlag(MmcFlags.ResponseR6)) commandDescriptor.responseType = SdResponseType.R6;
var commandB = new byte[commandData.size + commandData.protocolArgumentSize + commandData.deviceDataBufferSize];
byte[] commandB =
new byte[commandData.size + commandData.protocolArgumentSize + commandData.deviceDataBufferSize];
Array.Copy(buffer, 0, commandB, commandData.size + commandData.protocolArgumentSize, buffer.Length);
IntPtr hBuf = Marshal.AllocHGlobal(commandB.Length);
Marshal.StructureToPtr(commandData, hBuf, true);
var descriptorOffset = IntPtr.Add(hBuf, commandData.size);
IntPtr descriptorOffset = IntPtr.Add(hBuf, commandData.size);
Marshal.StructureToPtr(commandDescriptor, descriptorOffset, true);
Marshal.Copy(hBuf, commandB, 0, commandB.Length);
Marshal.FreeHGlobal(hBuf);
var error = 0;
int error = 0;
cmdStopwatch.Restart();
sense = !Extern.DeviceIoControl(_fileHandle,
@@ -577,7 +578,7 @@ partial class Device
// We need a timeout
if(timeout == 0) timeout = Timeout > 0 ? Timeout : 15;
var error = 0;
int error = 0;
duration = 0;
sense = false;