Remove deprecated FreeBSD code.

This commit is contained in:
2021-09-14 20:44:06 +01:00
parent 7237bbb4e8
commit 9dc57c2bd8
15 changed files with 122 additions and 2378 deletions

View File

@@ -197,7 +197,6 @@ namespace Aaru.Core.Devices.Dumping
if(cdiReadyReadAsAudio) if(cdiReadyReadAsAudio)
{ {
// TODO: FreeBSD bug
if(offsetBytes < 0) if(offsetBytes < 0)
{ {
if(i == 0) if(i == 0)

View File

@@ -221,7 +221,6 @@ namespace Aaru.Core.Devices.Dumping
if(_fixOffset && !inData) if(_fixOffset && !inData)
{ {
// TODO: FreeBSD bug
if(offsetBytes < 0) if(offsetBytes < 0)
{ {
if(i == 0) if(i == 0)

View File

@@ -46,7 +46,6 @@ using Aaru.Database.Models;
using Aaru.Decoders.CD; using Aaru.Decoders.CD;
using Aaru.Devices; using Aaru.Devices;
using Schemas; using Schemas;
using PlatformID = Aaru.CommonTypes.Interop.PlatformID;
using TrackType = Aaru.CommonTypes.Enums.TrackType; using TrackType = Aaru.CommonTypes.Enums.TrackType;
using Version = Aaru.CommonTypes.Interop.Version; using Version = Aaru.CommonTypes.Interop.Version;
@@ -80,7 +79,7 @@ namespace Aaru.Core.Devices.Dumping
double imageWriteDuration = 0; // Duration of image write double imageWriteDuration = 0; // Duration of image write
long lastSector; // Last sector number long lastSector; // Last sector number
var leadOutExtents = new ExtentsULong(); // Lead-out extents var leadOutExtents = new ExtentsULong(); // Lead-out extents
Dictionary<int, long> leadOutStarts = new Dictionary<int, long>(); // Lead-out starts Dictionary<int, long> leadOutStarts = new(); // Lead-out starts
double maxSpeed = double.MinValue; // Maximum speed double maxSpeed = double.MinValue; // Maximum speed
MhddLog mhddLog; // MHDD log MhddLog mhddLog; // MHDD log
double minSpeed = double.MaxValue; // Minimum speed double minSpeed = double.MaxValue; // Minimum speed
@@ -106,21 +105,21 @@ namespace Aaru.Core.Devices.Dumping
byte[] tmpBuf; // Temporary buffer byte[] tmpBuf; // Temporary buffer
FullTOC.CDFullTOC? toc; // Full CD TOC FullTOC.CDFullTOC? toc; // Full CD TOC
double totalDuration = 0; // Total commands duration double totalDuration = 0; // Total commands duration
Dictionary<byte, byte> trackFlags = new Dictionary<byte, byte>(); // Track flags Dictionary<byte, byte> trackFlags = new(); // Track flags
Track[] tracks; // Tracks in disc Track[] tracks; // Tracks in disc
int firstTrackLastSession; // Number of first track in last session int firstTrackLastSession; // Number of first track in last session
bool hiddenTrack; // Disc has a hidden track before track 1 bool hiddenTrack; // Disc has a hidden track before track 1
MmcSubchannel supportedSubchannel; // Drive's maximum supported subchannel MmcSubchannel supportedSubchannel; // Drive's maximum supported subchannel
MmcSubchannel desiredSubchannel; // User requested subchannel MmcSubchannel desiredSubchannel; // User requested subchannel
bool bcdSubchannel = false; // Subchannel positioning is in BCD bool bcdSubchannel = false; // Subchannel positioning is in BCD
Dictionary<byte, string> isrcs = new Dictionary<byte, string>(); Dictionary<byte, string> isrcs = new();
string mcn = null; string mcn = null;
HashSet<int> subchannelExtents = new HashSet<int>(); HashSet<int> subchannelExtents = new();
bool cdiReadyReadAsAudio = false; bool cdiReadyReadAsAudio = false;
uint firstLba; uint firstLba;
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags Dictionary<MediaTagType, byte[]> mediaTags = new(); // Media tags
Dictionary<byte, int> smallestPregapLbaPerTrack = new Dictionary<byte, int>(); Dictionary<byte, int> smallestPregapLbaPerTrack = new();
MediaType dskType = MediaType.CD; MediaType dskType = MediaType.CD;
@@ -565,7 +564,7 @@ namespace Aaru.Core.Devices.Dumping
_dumpLog.WriteLine("Disc contains a hidden track..."); _dumpLog.WriteLine("Disc contains a hidden track...");
UpdateStatus?.Invoke("Disc contains a hidden track..."); UpdateStatus?.Invoke("Disc contains a hidden track...");
List<Track> trkList = new List<Track> List<Track> trkList = new()
{ {
new Track new Track
{ {
@@ -721,31 +720,6 @@ namespace Aaru.Core.Devices.Dumping
// Check if something prevents from dumping the first track pregap // Check if something prevents from dumping the first track pregap
if(_dumpFirstTrackPregap && readcd) if(_dumpFirstTrackPregap && readcd)
{ {
if(_dev.PlatformId == PlatformID.FreeBSD &&
!_dev.IsRemote)
{
if(_force)
{
_dumpLog.
WriteLine("FreeBSD panics when reading CD first track pregap, see upstream bug #224253. continuing");
ErrorMessage?.
Invoke("FreeBSD panics when reading CD first track pregap, see upstream bug #224253. continuing");
}
else
{
_dumpLog.
WriteLine("FreeBSD panics when reading CD first track pregap, see upstream bug #224253. Not continuing");
StoppingErrorMessage?.
Invoke("FreeBSD panics when reading CD first track pregap, see upstream bug #224253. Not continuing");
return;
}
_dumpFirstTrackPregap = false;
}
if(!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.CD_FirstTrackPregap)) if(!_outputPlugin.SupportedMediaTags.Contains(MediaTagType.CD_FirstTrackPregap))
{ {
if(_force) if(_force)

View File

@@ -64,7 +64,6 @@
<Compile Include="Device\ScsiCommands\MediaTek.cs"/> <Compile Include="Device\ScsiCommands\MediaTek.cs"/>
<Compile Include="Device\ScsiCommands\MiniDisc.cs"/> <Compile Include="Device\ScsiCommands\MiniDisc.cs"/>
<Compile Include="Device\ScsiCommands\Optical.cs"/> <Compile Include="Device\ScsiCommands\Optical.cs"/>
<Compile Include="FreeBSD\ListDevices.cs" />
<Compile Include="Linux\Extern.cs"/> <Compile Include="Linux\Extern.cs"/>
<Compile Include="Linux\Structs.cs"/> <Compile Include="Linux\Structs.cs"/>
<Compile Include="Linux\Enums.cs"/> <Compile Include="Linux\Enums.cs"/>
@@ -107,10 +106,6 @@
<Compile Include="Device\AtaCommands\Smart.cs"/> <Compile Include="Device\AtaCommands\Smart.cs"/>
<Compile Include="Device\AtaCommands\Cfa.cs"/> <Compile Include="Device\AtaCommands\Cfa.cs"/>
<Compile Include="Device\AtaCommands\MCPT.cs"/> <Compile Include="Device\AtaCommands\MCPT.cs"/>
<Compile Include="FreeBSD\Command.cs" />
<Compile Include="FreeBSD\Enums.cs" />
<Compile Include="FreeBSD\Extern.cs" />
<Compile Include="FreeBSD\Structs.cs" />
<Compile Include="Device\MmcCommands\MMC.cs"/> <Compile Include="Device\MmcCommands\MMC.cs"/>
<Compile Include="Device\MmcCommands\SecureDigital.cs"/> <Compile Include="Device\MmcCommands\SecureDigital.cs"/>
<Compile Include="Device\ScsiCommands\Kreon.cs"/> <Compile Include="Device\ScsiCommands\Kreon.cs"/>

View File

@@ -33,7 +33,6 @@
using System; using System;
using Aaru.CommonTypes.Interop; using Aaru.CommonTypes.Interop;
using Aaru.Decoders.ATA; using Aaru.Decoders.ATA;
using Aaru.Devices.FreeBSD;
using Aaru.Devices.Windows; using Aaru.Devices.Windows;
using Microsoft.Win32.SafeHandles; using Microsoft.Win32.SafeHandles;
using PlatformID = Aaru.CommonTypes.Interop.PlatformID; using PlatformID = Aaru.CommonTypes.Interop.PlatformID;
@@ -142,36 +141,6 @@ namespace Aaru.Devices
return Linux.Command.SendScsiCommand((int)fd, cdb, ref buffer, out senseBuffer, timeout, dir, return Linux.Command.SendScsiCommand((int)fd, cdb, ref buffer, out senseBuffer, timeout, dir,
out duration, out sense); out duration, out sense);
} }
case PlatformID.FreeBSD:
{
CcbFlags flags = 0;
switch(direction)
{
case ScsiDirection.In:
flags = CcbFlags.CamDirIn;
break;
case ScsiDirection.Out:
flags = CcbFlags.CamDirOut;
break;
case ScsiDirection.Bidirectional:
flags = CcbFlags.CamDirBoth;
break;
case ScsiDirection.None:
flags = CcbFlags.CamDirNone;
break;
}
return IntPtr.Size == 8
? FreeBSD.Command.SendScsiCommand64((IntPtr)fd, cdb, ref buffer, out senseBuffer,
timeout, flags, out duration, out sense)
: FreeBSD.Command.SendScsiCommand((IntPtr)fd, cdb, ref buffer, out senseBuffer, timeout,
flags, out duration, out sense);
}
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }
} }
@@ -242,11 +211,6 @@ namespace Aaru.Devices
transferRegister, ref buffer, timeout, transferBlocks, transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense); out duration, out sense);
} }
case PlatformID.FreeBSD:
{
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
}
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }
} }
@@ -317,11 +281,6 @@ namespace Aaru.Devices
transferRegister, ref buffer, timeout, transferBlocks, transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense); out duration, out sense);
} }
case PlatformID.FreeBSD:
{
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
}
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }
} }
@@ -379,9 +338,6 @@ namespace Aaru.Devices
return Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol, return Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol,
transferRegister, ref buffer, timeout, transferBlocks, transferRegister, ref buffer, timeout, transferBlocks,
out duration, out sense); out duration, out sense);
case PlatformID.FreeBSD:
return FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
ref buffer, timeout, out duration, out sense);
default: throw new InvalidOperationException($"Platform {ptId} not yet supported."); default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
} }
} }

View File

@@ -42,14 +42,13 @@ using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Decoders.SCSI; using Aaru.Decoders.SCSI;
using Aaru.Decoders.SCSI.MMC; using Aaru.Decoders.SCSI.MMC;
using Aaru.Decoders.SecureDigital; using Aaru.Decoders.SecureDigital;
using Aaru.Devices.FreeBSD; using Aaru.Devices.Linux;
using Aaru.Devices.Windows; using Aaru.Devices.Windows;
using Aaru.Helpers; using Aaru.Helpers;
using Microsoft.Win32.SafeHandles; using Microsoft.Win32.SafeHandles;
using Extern = Aaru.Devices.Windows.Extern; using Extern = Aaru.Devices.Windows.Extern;
using FileAccess = Aaru.Devices.Windows.FileAccess; using FileAccess = Aaru.Devices.Windows.FileAccess;
using FileAttributes = Aaru.Devices.Windows.FileAttributes; using FileAttributes = Aaru.Devices.Windows.FileAttributes;
using FileFlags = Aaru.Devices.Linux.FileFlags;
using FileMode = Aaru.Devices.Windows.FileMode; using FileMode = Aaru.Devices.Windows.FileMode;
using FileShare = Aaru.Devices.Windows.FileShare; using FileShare = Aaru.Devices.Windows.FileShare;
using Inquiry = Aaru.CommonTypes.Structs.Devices.SCSI.Inquiry; using Inquiry = Aaru.CommonTypes.Structs.Devices.SCSI.Inquiry;
@@ -151,25 +150,7 @@ namespace Aaru.Devices
break; break;
} }
case PlatformID.FreeBSD: default: throw new DeviceException($"Platform {PlatformId} not supported.");
{
FileHandle = FreeBSD.Extern.cam_open_device(devicePath, FreeBSD.FileFlags.ReadWrite);
if(((IntPtr)FileHandle).ToInt64() == 0)
{
Error = true;
LastError = Marshal.GetLastWin32Error();
}
var camDevice = (CamDevice)Marshal.PtrToStructure((IntPtr)FileHandle, typeof(CamDevice));
if(StringHandlers.CToString(camDevice.SimName) == "ata")
throw new
DeviceException("Parallel ATA devices are not supported on FreeBSD due to upstream bug #224250.");
break;
}
default: throw new DeviceException($"Platform {PlatformId} not yet supported.");
} }
} }

View File

@@ -30,10 +30,9 @@
// Copyright © 2011-2021 Natalia Portillo // Copyright © 2011-2021 Natalia Portillo
// ****************************************************************************/ // ****************************************************************************/
using System; using Aaru.CommonTypes.Interop;
using Aaru.Devices.Linux; using Aaru.Devices.Linux;
using Microsoft.Win32.SafeHandles; using Microsoft.Win32.SafeHandles;
using PlatformID = Aaru.CommonTypes.Interop.PlatformID;
namespace Aaru.Devices namespace Aaru.Devices
{ {
@@ -68,10 +67,6 @@ namespace Aaru.Devices
case PlatformID.Linux: case PlatformID.Linux:
Extern.close((int)FileHandle); Extern.close((int)FileHandle);
break;
case PlatformID.FreeBSD:
FreeBSD.Extern.cam_close_device((IntPtr)FileHandle);
break; break;
} }

View File

@@ -107,7 +107,6 @@ namespace Aaru.Devices
{ {
case PlatformID.Win32NT: return Windows.ListDevices.GetList(); case PlatformID.Win32NT: return Windows.ListDevices.GetList();
case PlatformID.Linux: return Linux.ListDevices.GetList(); case PlatformID.Linux: return Linux.ListDevices.GetList();
case PlatformID.FreeBSD: return FreeBSD.ListDevices.GetList();
default: default:
throw new throw new
InvalidOperationException($"Platform {DetectOS.GetRealPlatformID()} not yet supported."); InvalidOperationException($"Platform {DetectOS.GetRealPlatformID()} not yet supported.");

View File

@@ -1,630 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Command.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : FreeBSD direct device access.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains a high level representation of the FreeBSD syscalls used to
// directly interface devices.
//
// --[ 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-2021 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Aaru.Console;
using Aaru.Decoders.ATA;
using static Aaru.Devices.FreeBSD.Extern;
namespace Aaru.Devices.FreeBSD
{
[SuppressMessage("ReSharper", "BitwiseOperatorOnEnumWithoutFlags"), Obsolete]
internal static class Command
{
const int CAM_MAX_CDBLEN = 16;
/// <summary>Sends a SCSI command (64-bit arch)</summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="dev">CAM device</param>
/// <param name="cdb">SCSI CDB</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="senseBuffer">Buffer with the SCSI sense</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="direction">SCSI command transfer direction</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense">
/// <c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer" /> contains SCSI
/// sense
/// </param>
[Obsolete]
internal static int SendScsiCommand64(IntPtr dev, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
uint timeout, CcbFlags direction, out double duration, out bool sense)
{
senseBuffer = null;
duration = 0;
sense = false;
if(buffer == null)
return -1;
IntPtr ccbPtr = cam_getccb(dev);
IntPtr cdbPtr = IntPtr.Zero;
if(ccbPtr.ToInt64() == 0)
{
sense = true;
return Marshal.GetLastWin32Error();
}
var csio = (CcbScsiio64)Marshal.PtrToStructure(ccbPtr, typeof(CcbScsiio64));
csio.ccb_h.func_code = XptOpcode.XptScsiIo;
csio.ccb_h.flags = direction;
csio.ccb_h.xflags = 0;
csio.ccb_h.retry_count = 1;
csio.ccb_h.cbfcnp = IntPtr.Zero;
csio.ccb_h.timeout = timeout;
csio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
csio.dxfer_len = (uint)buffer.Length;
csio.sense_len = 32;
csio.cdb_len = (byte)cdb.Length;
// TODO: Create enum?
csio.tag_action = 0x20;
csio.cdb_bytes = new byte[CAM_MAX_CDBLEN];
if(cdb.Length <= CAM_MAX_CDBLEN)
Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length);
else
{
cdbPtr = Marshal.AllocHGlobal(cdb.Length);
byte[] cdbPtrBytes = BitConverter.GetBytes(cdbPtr.ToInt64());
Array.Copy(cdbPtrBytes, 0, csio.cdb_bytes, 0, IntPtr.Size);
csio.ccb_h.flags |= CcbFlags.CamCdbPointer;
}
csio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
Marshal.Copy(buffer, 0, csio.data_ptr, buffer.Length);
Marshal.StructureToPtr(csio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0)
error = Marshal.GetLastWin32Error();
csio = (CcbScsiio64)Marshal.PtrToStructure(ccbPtr, typeof(CcbScsiio64));
if((csio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamReqCmp &&
(csio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamScsiStatusError)
{
error = Marshal.GetLastWin32Error();
AaruConsole.DebugWriteLine("FreeBSD devices", "CAM status {0} error {1}", csio.ccb_h.status, error);
sense = true;
}
if((csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError)
{
sense = true;
senseBuffer = new byte[1];
senseBuffer[0] = csio.scsi_status;
}
if((csio.ccb_h.status & CamStatus.CamAutosnsValid) != 0)
if(csio.sense_len - csio.sense_resid > 0)
{
sense = (csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError;
senseBuffer = new byte[csio.sense_len - csio.sense_resid];
senseBuffer[0] = csio.sense_data.error_code;
Array.Copy(csio.sense_data.sense_buf, 0, senseBuffer, 1, senseBuffer.Length - 1);
}
buffer = new byte[csio.dxfer_len];
cdb = new byte[csio.cdb_len];
Marshal.Copy(csio.data_ptr, buffer, 0, buffer.Length);
if(csio.ccb_h.flags.HasFlag(CcbFlags.CamCdbPointer))
Marshal.Copy(new IntPtr(BitConverter.ToInt64(csio.cdb_bytes, 0)), cdb, 0, cdb.Length);
else
Array.Copy(csio.cdb_bytes, 0, cdb, 0, cdb.Length);
duration = (end - start).TotalMilliseconds;
if(csio.ccb_h.flags.HasFlag(CcbFlags.CamCdbPointer))
Marshal.FreeHGlobal(cdbPtr);
Marshal.FreeHGlobal(csio.data_ptr);
cam_freeccb(ccbPtr);
return error;
}
/// <summary>Sends a SCSI command (32-bit arch)</summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="dev">CAM device</param>
/// <param name="cdb">SCSI CDB</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="senseBuffer">Buffer with the SCSI sense</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="direction">SCSI command transfer direction</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense">
/// <c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer" /> contains SCSI
/// sense
/// </param>
[Obsolete]
internal static int SendScsiCommand(IntPtr dev, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer,
uint timeout, CcbFlags direction, out double duration, out bool sense)
{
senseBuffer = null;
duration = 0;
sense = false;
if(buffer == null)
return -1;
IntPtr ccbPtr = cam_getccb(dev);
IntPtr cdbPtr = IntPtr.Zero;
if(ccbPtr.ToInt32() == 0)
{
sense = true;
return Marshal.GetLastWin32Error();
}
var csio = (CcbScsiio)Marshal.PtrToStructure(ccbPtr, typeof(CcbScsiio));
csio.ccb_h.func_code = XptOpcode.XptScsiIo;
csio.ccb_h.flags = direction;
csio.ccb_h.xflags = 0;
csio.ccb_h.retry_count = 1;
csio.ccb_h.cbfcnp = IntPtr.Zero;
csio.ccb_h.timeout = timeout;
csio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
csio.dxfer_len = (uint)buffer.Length;
csio.sense_len = 32;
csio.cdb_len = (byte)cdb.Length;
// TODO: Create enum?
csio.tag_action = 0x20;
csio.cdb_bytes = new byte[CAM_MAX_CDBLEN];
if(cdb.Length <= CAM_MAX_CDBLEN)
Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length);
else
{
cdbPtr = Marshal.AllocHGlobal(cdb.Length);
byte[] cdbPtrBytes = BitConverter.GetBytes(cdbPtr.ToInt32());
Array.Copy(cdbPtrBytes, 0, csio.cdb_bytes, 0, IntPtr.Size);
csio.ccb_h.flags |= CcbFlags.CamCdbPointer;
}
csio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
Marshal.Copy(buffer, 0, csio.data_ptr, buffer.Length);
Marshal.StructureToPtr(csio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0)
error = Marshal.GetLastWin32Error();
csio = (CcbScsiio)Marshal.PtrToStructure(ccbPtr, typeof(CcbScsiio));
if((csio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamReqCmp &&
(csio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamScsiStatusError)
{
error = Marshal.GetLastWin32Error();
AaruConsole.DebugWriteLine("FreeBSD devices", "CAM status {0} error {1}", csio.ccb_h.status, error);
sense = true;
}
if((csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError)
{
sense = true;
senseBuffer = new byte[1];
senseBuffer[0] = csio.scsi_status;
}
if((csio.ccb_h.status & CamStatus.CamAutosnsValid) != 0)
if(csio.sense_len - csio.sense_resid > 0)
{
sense = (csio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamScsiStatusError;
senseBuffer = new byte[csio.sense_len - csio.sense_resid];
senseBuffer[0] = csio.sense_data.error_code;
Array.Copy(csio.sense_data.sense_buf, 0, senseBuffer, 1, senseBuffer.Length - 1);
}
buffer = new byte[csio.dxfer_len];
cdb = new byte[csio.cdb_len];
Marshal.Copy(csio.data_ptr, buffer, 0, buffer.Length);
if(csio.ccb_h.flags.HasFlag(CcbFlags.CamCdbPointer))
Marshal.Copy(new IntPtr(BitConverter.ToInt32(csio.cdb_bytes, 0)), cdb, 0, cdb.Length);
else
Array.Copy(csio.cdb_bytes, 0, cdb, 0, cdb.Length);
duration = (end - start).TotalMilliseconds;
if(csio.ccb_h.flags.HasFlag(CcbFlags.CamCdbPointer))
Marshal.FreeHGlobal(cdbPtr);
Marshal.FreeHGlobal(csio.data_ptr);
cam_freeccb(ccbPtr);
return error;
}
/// <summary>Converts ATA protocol to CAM flags</summary>
/// <param name="protocol">ATA protocol</param>
/// <returns>CAM flags</returns>
[Obsolete]
static CcbFlags AtaProtocolToCamFlags(AtaProtocol protocol)
{
switch(protocol)
{
case AtaProtocol.DeviceDiagnostic:
case AtaProtocol.DeviceReset:
case AtaProtocol.HardReset:
case AtaProtocol.NonData:
case AtaProtocol.SoftReset:
case AtaProtocol.ReturnResponse: return CcbFlags.CamDirNone;
case AtaProtocol.PioIn:
case AtaProtocol.UDmaIn: return CcbFlags.CamDirIn;
case AtaProtocol.PioOut:
case AtaProtocol.UDmaOut: return CcbFlags.CamDirOut;
default: return CcbFlags.CamDirNone;
}
}
/// <summary>Sends an ATA command in CHS mode</summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="dev">CAM device</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
[Obsolete]
internal static int SendAtaCommand(IntPtr dev, AtaRegistersChs registers,
out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense)
{
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersChs();
if(buffer == null)
return -1;
IntPtr ccbPtr = cam_getccb(dev);
var ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult;
switch(protocol)
{
case AtaProtocol.Dma:
case AtaProtocol.DmaQueued:
case AtaProtocol.UDmaIn:
case AtaProtocol.UDmaOut:
ataio.cmd.flags |= CamAtaIoFlags.Dma;
break;
case AtaProtocol.FpDma:
ataio.cmd.flags |= CamAtaIoFlags.Fpdma;
break;
}
ataio.cmd.command = registers.Command;
ataio.cmd.lba_high = registers.CylinderHigh;
ataio.cmd.lba_mid = registers.CylinderLow;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
ataio.cmd.features = registers.Feature;
ataio.cmd.sector_count = registers.SectorCount;
ataio.cmd.lba_low = registers.Sector;
Marshal.Copy(buffer, 0, ataio.data_ptr, buffer.Length);
Marshal.StructureToPtr(ataio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0)
error = Marshal.GetLastWin32Error();
ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
if((ataio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamReqCmp &&
(ataio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamAtaStatusError)
{
error = Marshal.GetLastWin32Error();
AaruConsole.DebugWriteLine("FreeBSD devices", "CAM status {0} error {1}", ataio.ccb_h.status, error);
sense = true;
}
if((ataio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamAtaStatusError)
sense = true;
errorRegisters.CylinderHigh = ataio.res.lba_high;
errorRegisters.CylinderLow = ataio.res.lba_mid;
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.Sector = ataio.res.lba_low;
errorRegisters.SectorCount = ataio.res.sector_count;
errorRegisters.Status = ataio.res.status;
buffer = new byte[ataio.dxfer_len];
Marshal.Copy(ataio.data_ptr, buffer, 0, buffer.Length);
duration = (end - start).TotalMilliseconds;
Marshal.FreeHGlobal(ataio.data_ptr);
cam_freeccb(ccbPtr);
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0 || error != 0;
return error;
}
/// <summary>Sends an ATA command in 28-bit LBA mode</summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="dev">CAM device</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
[Obsolete]
internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba28 registers,
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense)
{
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersLba28();
if(buffer == null)
return -1;
IntPtr ccbPtr = cam_getccb(dev);
var ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult;
switch(protocol)
{
case AtaProtocol.Dma:
case AtaProtocol.DmaQueued:
case AtaProtocol.UDmaIn:
case AtaProtocol.UDmaOut:
ataio.cmd.flags |= CamAtaIoFlags.Dma;
break;
case AtaProtocol.FpDma:
ataio.cmd.flags |= CamAtaIoFlags.Fpdma;
break;
}
ataio.cmd.command = registers.Command;
ataio.cmd.lba_high = registers.LbaHigh;
ataio.cmd.lba_mid = registers.LbaMid;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
ataio.cmd.features = registers.Feature;
ataio.cmd.sector_count = registers.SectorCount;
ataio.cmd.lba_low = registers.LbaLow;
Marshal.Copy(buffer, 0, ataio.data_ptr, buffer.Length);
Marshal.StructureToPtr(ataio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0)
error = Marshal.GetLastWin32Error();
ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
if((ataio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamReqCmp &&
(ataio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamAtaStatusError)
{
error = Marshal.GetLastWin32Error();
AaruConsole.DebugWriteLine("FreeBSD devices", "CAM status {0} error {1}", ataio.ccb_h.status, error);
sense = true;
}
if((ataio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamAtaStatusError)
sense = true;
errorRegisters.LbaHigh = ataio.res.lba_high;
errorRegisters.LbaMid = ataio.res.lba_mid;
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.LbaLow = ataio.res.lba_low;
errorRegisters.SectorCount = ataio.res.sector_count;
errorRegisters.Status = ataio.res.status;
buffer = new byte[ataio.dxfer_len];
Marshal.Copy(ataio.data_ptr, buffer, 0, buffer.Length);
duration = (end - start).TotalMilliseconds;
Marshal.FreeHGlobal(ataio.data_ptr);
cam_freeccb(ccbPtr);
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0 || error != 0;
return error;
}
/// <summary>Sends an ATA command in 48-bit mode</summary>
/// <returns>0 if no error occurred, otherwise, errno</returns>
/// <param name="dev">CAM device</param>
/// <param name="buffer">Buffer for SCSI command response</param>
/// <param name="timeout">Timeout in seconds</param>
/// <param name="duration">Time it took to execute the command in milliseconds</param>
/// <param name="sense"><c>True</c> if ATA error returned non-OK status</param>
/// <param name="registers">Registers to send to drive</param>
/// <param name="errorRegisters">Registers returned by drive</param>
/// <param name="protocol">ATA protocol to use</param>
[Obsolete]
internal static int SendAtaCommand(IntPtr dev, AtaRegistersLba48 registers,
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
ref byte[] buffer, uint timeout, out double duration, out bool sense)
{
duration = 0;
sense = false;
errorRegisters = new AtaErrorRegistersLba48();
// 48-bit ATA CAM commands can crash FreeBSD < 9.2-RELEASE
if((Environment.Version.Major == 9 && Environment.Version.Minor < 2) ||
Environment.Version.Major < 9)
return -1;
if(buffer == null)
return -1;
IntPtr ccbPtr = cam_getccb(dev);
var ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
ataio.ccb_h.func_code = XptOpcode.XptAtaIo;
ataio.ccb_h.flags = AtaProtocolToCamFlags(protocol);
ataio.ccb_h.xflags = 0;
ataio.ccb_h.retry_count = 1;
ataio.ccb_h.cbfcnp = IntPtr.Zero;
ataio.ccb_h.timeout = timeout;
ataio.data_ptr = Marshal.AllocHGlobal(buffer.Length);
ataio.dxfer_len = (uint)buffer.Length;
ataio.ccb_h.flags |= CcbFlags.CamDevQfrzdis;
ataio.cmd.flags = CamAtaIoFlags.NeedResult | CamAtaIoFlags.ExtendedCommand;
switch(protocol)
{
case AtaProtocol.Dma:
case AtaProtocol.DmaQueued:
case AtaProtocol.UDmaIn:
case AtaProtocol.UDmaOut:
ataio.cmd.flags |= CamAtaIoFlags.Dma;
break;
case AtaProtocol.FpDma:
ataio.cmd.flags |= CamAtaIoFlags.Fpdma;
break;
}
ataio.cmd.lba_high_exp = registers.LbaHighCurrent;
ataio.cmd.lba_mid_exp = registers.LbaMidCurrent;
ataio.cmd.features_exp = (byte)((registers.Feature & 0xFF00) >> 8);
ataio.cmd.sector_count_exp = (byte)((registers.SectorCount & 0xFF00) >> 8);
ataio.cmd.lba_low_exp = registers.LbaLowCurrent;
ataio.cmd.lba_high = registers.LbaHighPrevious;
ataio.cmd.lba_mid = registers.LbaMidPrevious;
ataio.cmd.features = (byte)(registers.Feature & 0xFF);
ataio.cmd.sector_count = (byte)(registers.SectorCount & 0xFF);
ataio.cmd.lba_low = registers.LbaLowPrevious;
ataio.cmd.command = registers.Command;
ataio.cmd.device = (byte)(0x40 | registers.DeviceHead);
Marshal.Copy(buffer, 0, ataio.data_ptr, buffer.Length);
Marshal.StructureToPtr(ataio, ccbPtr, false);
DateTime start = DateTime.UtcNow;
int error = cam_send_ccb(dev, ccbPtr);
DateTime end = DateTime.UtcNow;
if(error < 0)
error = Marshal.GetLastWin32Error();
ataio = (CcbAtaio)Marshal.PtrToStructure(ccbPtr, typeof(CcbAtaio));
if((ataio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamReqCmp &&
(ataio.ccb_h.status & CamStatus.CamStatusMask) != CamStatus.CamAtaStatusError)
{
error = Marshal.GetLastWin32Error();
AaruConsole.DebugWriteLine("FreeBSD devices", "CAM status {0} error {1}", ataio.ccb_h.status, error);
sense = true;
}
if((ataio.ccb_h.status & CamStatus.CamStatusMask) == CamStatus.CamAtaStatusError)
sense = true;
errorRegisters.SectorCount = (ushort)((ataio.res.sector_count_exp << 8) + ataio.res.sector_count);
errorRegisters.LbaLowCurrent = ataio.res.lba_low_exp;
errorRegisters.LbaMidCurrent = ataio.res.lba_mid_exp;
errorRegisters.LbaHighCurrent = ataio.res.lba_high_exp;
errorRegisters.LbaLowPrevious = ataio.res.lba_low;
errorRegisters.LbaMidPrevious = ataio.res.lba_mid;
errorRegisters.LbaHighPrevious = ataio.res.lba_high;
errorRegisters.DeviceHead = ataio.res.device;
errorRegisters.Error = ataio.res.error;
errorRegisters.Status = ataio.res.status;
buffer = new byte[ataio.dxfer_len];
Marshal.Copy(ataio.data_ptr, buffer, 0, buffer.Length);
duration = (end - start).TotalMilliseconds;
Marshal.FreeHGlobal(ataio.data_ptr);
cam_freeccb(ccbPtr);
sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0 || error != 0;
return error;
}
}
}

View File

@@ -1,572 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Enums.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : FreeBSD direct device access.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains enumerations necessary for directly interfacing devices under
// FreeBSD.
//
// --[ 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-2021 Natalia Portillo
// ****************************************************************************/
using System;
namespace Aaru.Devices.FreeBSD
{
[Flags, Obsolete]
internal enum FileFlags
{
/// <summary>O_RDONLY</summary>
ReadOnly = 0x00000000,
/// <summary>O_WRONLY</summary>
WriteOnly = 0x00000001,
/// <summary>O_RDWR</summary>
ReadWrite = 0x00000002,
/// <summary>O_NONBLOCK</summary>
NonBlocking = 0x00000004,
/// <summary>O_APPEND</summary>
Append = 0x00000008,
/// <summary>O_SHLOCK</summary>
SharedLock = 0x00000010,
/// <summary>O_EXLOCK</summary>
ExclusiveLock = 0x00000020,
/// <summary>O_ASYNC</summary>
Async = 0x00000040,
/// <summary>O_FSYNC</summary>
SyncWrites = 0x00000080,
/// <summary>O_NOFOLLOW</summary>
NoFollowSymlink = 0x00000100,
/// <summary>O_CREAT</summary>
OpenOrCreate = 0x00000200,
/// <summary>O_TRUNC</summary>
Truncate = 0x00000400,
/// <summary>O_EXCL</summary>
CreateNew = 0x00000800,
/// <summary>O_NOCTTY</summary>
NoControlTty = 0x00008000,
/// <summary>O_DIRECT</summary>
Direct = 0x00010000,
/// <summary>O_DIRECTORY</summary>
Directory = 0x00020000,
/// <summary>O_EXEC</summary>
Execute = 0x00040000,
/// <summary>O_TTY_INIT</summary>
InitializeTty = 0x00080000,
/// <summary>O_CLOEXEC</summary>
CloseOnExec = 0x00100000
}
[Flags, Obsolete]
internal enum CamAtaIoFlags : byte
{
/// <summary>48-bit command</summary>
ExtendedCommand = 0x01,
/// <summary>FPDMA command</summary>
Fpdma = 0x02,
/// <summary>Control, not a command</summary>
Control = 0x04,
/// <summary>Needs result</summary>
NeedResult = 0x08,
/// <summary>DMA command</summary>
Dma = 0x10
}
/// <summary>XPT Opcodes for xpt_action</summary>
[Flags, Obsolete]
internal enum XptOpcode
{
// Function code flags are bits greater than 0xff
/// <summary>Non-immediate function code</summary>
XptFcQueued = 0x100, XptFcUserCcb = 0x200,
/// <summary>Only for the transport layer device</summary>
XptFcXptOnly = 0x400,
/// <summary>Passes through the device queues</summary>
XptFcDevQueued = 0x800 | XptFcQueued,
// Common function commands: 0x00->0x0F
/// <summary>Execute Nothing</summary>
XptNoop = 0x00,
/// <summary>Execute the requested I/O operation</summary>
XptScsiIo = 0x01 | XptFcDevQueued,
/// <summary>Get type information for specified device</summary>
XptGdevType = 0x02,
/// <summary>Get a list of peripheral devices</summary>
XptGdevlist = 0x03,
/// <summary>Path routing inquiry</summary>
XptPathInq = 0x04,
/// <summary>Release a frozen device queue</summary>
XptRelSimq = 0x05,
/// <summary>Set Asynchronous Callback Parameters</summary>
XptSasyncCb = 0x06,
/// <summary>Set device type information</summary>
XptSdevType = 0x07,
/// <summary>(Re)Scan the SCSI Bus</summary>
XptScanBus = 0x08 | XptFcQueued | XptFcUserCcb | XptFcXptOnly,
/// <summary>Get EDT entries matching the given pattern</summary>
XptDevMatch = 0x09 | XptFcXptOnly,
/// <summary>Turn on debugging for a bus, target or lun</summary>
XptDebug = 0x0a,
/// <summary>Path statistics (error counts, etc.)</summary>
XptPathStats = 0x0b,
/// <summary>Device statistics (error counts, etc.)</summary>
XptGdevStats = 0x0c,
/// <summary>Get/Set Device advanced information</summary>
XptDevAdvinfo = 0x0e,
/// <summary>Asynchronous event</summary>
XptAsync = 0x0f | XptFcQueued | XptFcUserCcb | XptFcXptOnly,
/// <summary>SCSI Control Functions: 0x10->0x1F</summary>
/// <summary>Abort the specified CCB</summary>
XptAbort = 0x10,
/// <summary>Reset the specified SCSI bus</summary>
XptResetBus = 0x11 | XptFcXptOnly,
/// <summary>Bus Device Reset the specified SCSI device</summary>
XptResetDev = 0x12 | XptFcDevQueued,
/// <summary>Terminate the I/O process</summary>
XptTermIo = 0x13,
/// <summary>Scan Logical Unit</summary>
XptScanLun = 0x14 | XptFcQueued | XptFcUserCcb | XptFcXptOnly,
/// <summary>Get default/user transfer settings for the target</summary>
XptGetTranSettings = 0x15,
/// <summary>Set transfer rate/width negotiation settings</summary>
XptSetTranSettings = 0x16,
/// <summary>Calculate the geometry parameters for a device give the sector size and volume size.</summary>
XptCalcGeometry = 0x17,
/// <summary>Execute the requested ATA I/O operation</summary>
XptAtaIo = 0x18 | XptFcDevQueued,
/// <summary>Compat only</summary>
XptGetSimKnobOld = 0x18,
/// <summary>Set SIM specific knob values.</summary>
XptSetSimKnob = 0x19,
/// <summary>Get SIM specific knob values.</summary>
XptGetSimKnob = 0x1a,
/// <summary>Serial Management Protocol</summary>
XptSmpIo = 0x1b | XptFcDevQueued,
/// <summary>Scan Target</summary>
XptScanTgt = 0x1E | XptFcQueued | XptFcUserCcb | XptFcXptOnly,
// HBA engine commands 0x20->0x2F
/// <summary>HBA engine feature inquiry</summary>
XptEngInq = 0x20 | XptFcXptOnly,
/// <summary>HBA execute engine request</summary>
XptEngExec = 0x21 | XptFcDevQueued,
// Target mode commands: 0x30->0x3F
/// <summary>Enable LUN as a target</summary>
XptEnLun = 0x30,
/// <summary>Execute target I/O request</summary>
XptTargetIo = 0x31 | XptFcDevQueued,
/// <summary>Accept Host Target Mode CDB</summary>
XptAcceptTargetIo = 0x32 | XptFcQueued | XptFcUserCcb,
/// <summary>Continue Host Target I/O Connection</summary>
XptContTargetIo = 0x33 | XptFcDevQueued,
/// <summary>Notify Host Target driver of event (obsolete)</summary>
XptImmedNotify = 0x34 | XptFcQueued | XptFcUserCcb,
/// <summary>Acknowledgement of event (obsolete)</summary>
XptNotifyAck = 0x35,
/// <summary>Notify Host Target driver of event</summary>
XptImmediateNotify = 0x36 | XptFcQueued | XptFcUserCcb,
/// <summary>Acknowledgement of event</summary>
XptNotifyAcknowledge = 0x37 | XptFcQueued | XptFcUserCcb,
/// <summary>Vendor Unique codes: 0x80->0x8F</summary>
XptVunique = 0x80
}
[Obsolete]
internal enum CcbDevMatchStatus
{
CamDevMatchLast, CamDevMatchMore, CamDevMatchListChanged,
CamDevMatchSizeError, CamDevMatchError
}
[Obsolete]
internal enum DevMatchType
{
DevMatchPeriph = 0, DevMatchDevice, DevMatchBus
}
[Flags, Obsolete]
internal enum PeriphPatternFlags
{
PeriphMatchNone = 0x000, PeriphMatchPath = 0x001, PeriphMatchTarget = 0x002,
PeriphMatchLun = 0x004, PeriphMatchName = 0x008, PeriphMatchUnit = 0x010
// PERIPH_MATCH_ANY = 0x01f
}
[Flags, Obsolete]
internal enum DevPatternFlags
{
DevMatchNone = 0x000, DevMatchPath = 0x001, DevMatchTarget = 0x002,
DevMatchLun = 0x004, DevMatchInquiry = 0x008, DevMatchDevid = 0x010
// DEV_MATCH_ANY = 0x00f
}
[Flags, Obsolete]
internal enum BusPatternFlags
{
BusMatchNone = 0x000, BusMatchPath = 0x001, BusMatchName = 0x002,
BusMatchUnit = 0x004, BusMatchBusId = 0x008
// BUS_MATCH_ANY = 0x00f
}
[Flags, Obsolete]
internal enum DevResultFlags
{
DevResultNoflag = 0x00, DevResultUnconfigured = 0x01
}
[Obsolete]
internal enum CamProto
{
ProtoUnknown, ProtoUnspecified,
/// <summary>Small Computer System Interface</summary>
ProtoScsi,
/// <summary>AT Attachment</summary>
ProtoAta,
/// <summary>AT Attachment Packetized Interface</summary>
ProtoAtapi,
/// <summary>SATA Port Multiplier</summary>
ProtoSatapm,
/// <summary>SATA Enclosure Management Bridge</summary>
ProtoSemb,
/// <summary>NVMe</summary>
ProtoNvme,
/// <summary>MMC, SD, SDIO</summary>
ProtoMmcsd
}
[Flags, Obsolete]
internal enum MmcCardFeatures
{
CardFeatureMemory = 0x1, CardFeatureSdhc = 0x1 << 1, CardFeatureSdio = 0x1 << 2,
CardFeatureSd20 = 0x1 << 3, CardFeatureMmc = 0x1 << 4, CardFeature18V = 0x1 << 5
}
[Obsolete]
internal enum CamGenerations : uint
{
CamBusGeneration = 0x00, CamTargetGeneration = 0x01, CamDevGeneration = 0x02,
CamPeriphGeneration = 0x03
}
[Flags, Obsolete]
internal enum DevPosType
{
CamDevPosNone = 0x000, CamDevPosBus = 0x001, CamDevPosTarget = 0x002,
CamDevPosDevice = 0x004, CamDevPosPeriph = 0x008, CamDevPosPdptr = 0x010,
// CAM_DEV_POS_TYPEMASK = 0xf00,
CamDevPosEdt = 0x100, CamDevPosPdrv = 0x200
}
[Obsolete]
internal enum FreebsdIoctl : uint
{
Camiocommand = 0xC4D81802
}
[Flags, Obsolete]
internal enum CcbFlags : uint
{
/// <summary>The CDB field is a pointer</summary>
CamCdbPointer = 0x00000001,
/// <summary>SIM queue actions are enabled</summary>
CamQueueEnable = 0x00000002,
/// <summary>CCB contains a linked CDB</summary>
CamCdbLinked = 0x00000004,
/// <summary>Perform transport negotiation with this command.</summary>
CamNegotiate = 0x00000008,
/// <summary>Data type with physical addrs</summary>
CamDataIsphys = 0x00000010,
/// <summary>Disable autosense feature</summary>
CamDisAutosense = 0x00000020,
/// <summary>Data direction (00:IN/OUT)</summary>
CamDirBoth = 0x00000000,
/// <summary>Data direction (01:DATA IN)</summary>
CamDirIn = 0x00000040,
/// <summary>Data direction (10:DATA OUT)</summary>
CamDirOut = 0x00000080,
/// <summary>Data direction (11:no data)</summary>
CamDirNone = 0x000000C0,
/// <summary>Data type (000:Virtual)</summary>
CamDataVaddr = 0x00000000,
/// <summary>Data type (001:Physical)</summary>
CamDataPaddr = 0x00000010,
/// <summary>Data type (010:sglist)</summary>
CamDataSg = 0x00040000,
/// <summary>Data type (011:sglist phys)</summary>
CamDataSgPaddr = 0x00040010,
/// <summary>Data type (100:bio)</summary>
CamDataBio = 0x00200000,
/// <summary>Use Soft reset alternative</summary>
CamSoftRstOp = 0x00000100,
/// <summary>Flush resid bytes on complete</summary>
CamEngSync = 0x00000200,
/// <summary>Disable DEV Q freezing</summary>
CamDevQfrzdis = 0x00000400,
/// <summary>Freeze DEV Q on execution</summary>
CamDevQfreeze = 0x00000800,
/// <summary>Command takes a lot of power</summary>
CamHighPower = 0x00001000,
/// <summary>Sense data is a pointer</summary>
CamSensePtr = 0x00002000,
/// <summary>Sense pointer is physical addr</summary>
CamSensePhys = 0x00004000,
/// <summary>Use the tag action in this ccb</summary>
CamTagActionValid = 0x00008000,
/// <summary>Pass driver does err. recovery</summary>
CamPassErrRecover = 0x00010000,
/// <summary>Disable disconnect</summary>
CamDisDisconnect = 0x00020000,
/// <summary>Message buffer ptr is physical</summary>
CamMsgBufPhys = 0x00080000,
/// <summary>Autosense data ptr is physical</summary>
CamSnsBufPhys = 0x00100000,
/// <summary>CDB poiner is physical</summary>
CamCdbPhys = 0x00400000,
/// <summary>SG list is for the HBA engine</summary>
CamEngSglist = 0x00800000,
/* Phase cognizant mode flags */
/// <summary>Disable autosave/restore ptrs</summary>
CamDisAutosrp = 0x01000000,
/// <summary>Disable auto disconnect</summary>
CamDisAutodisc = 0x02000000,
/// <summary>Target CCB available</summary>
CamTgtCcbAvail = 0x04000000,
/// <summary>The SIM runs in phase mode</summary>
CamTgtPhaseMode = 0x08000000,
/// <summary>Message buffer valid</summary>
CamMsgbValid = 0x10000000,
/// <summary>Status buffer valid</summary>
CamStatusValid = 0x20000000,
/// <summary>Data buffer valid</summary>
CamDatabValid = 0x40000000,
/* Host target Mode flags */
/// <summary>Send sense data with status</summary>
CamSendSense = 0x08000000,
/// <summary>Terminate I/O Message sup.</summary>
CamTermIo = 0x10000000,
/// <summary>Disconnects are mandatory</summary>
CamDisconnect = 0x20000000,
/// <summary>Send status after data phase</summary>
CamSendStatus = 0x40000000,
/// <summary>Call callback without lock.</summary>
CamUnlocked = 0x80000000
}
[Obsolete]
internal enum CamStatus : uint
{
/// <summary>CCB request is in progress</summary>
CamReqInprog = 0x00,
/// <summary>CCB request completed without error</summary>
CamReqCmp = 0x01,
/// <summary>CCB request aborted by the host</summary>
CamReqAborted = 0x02,
/// <summary>Unable to abort CCB request</summary>
CamUaAbort = 0x03,
/// <summary>CCB request completed with an error</summary>
CamReqCmpErr = 0x04,
/// <summary>CAM subsystem is busy</summary>
CamBusy = 0x05,
/// <summary>CCB request was invalid</summary>
CamReqInvalid = 0x06,
/// <summary>Supplied Path ID is invalid</summary>
CamPathInvalid = 0x07,
/// <summary>SCSI Device Not Installed/there</summary>
CamDevNotThere = 0x08,
/// <summary>Unable to terminate I/O CCB request</summary>
CamUaTermio = 0x09,
/// <summary>Target Selection Timeout</summary>
CamSelTimeout = 0x0a,
/// <summary>Command timeout</summary>
CamCmdTimeout = 0x0b,
/// <summary>SCSI error, look at error code in CCB</summary>
CamScsiStatusError = 0x0c,
/// <summary>Message Reject Received</summary>
CamMsgRejectRec = 0x0d,
/// <summary>SCSI Bus Reset Sent/Received</summary>
CamScsiBusReset = 0x0e,
/// <summary>Uncorrectable parity error occurred</summary>
CamUncorParity = 0x0f,
/// <summary>Autosense: request sense cmd fail</summary>
CamAutosenseFail = 0x10,
/// <summary>No HBA Detected error</summary>
CamNoHba = 0x11,
/// <summary>Data Overrun error</summary>
CamDataRunErr = 0x12,
/// <summary>Unexpected Bus Free</summary>
CamUnexpBusfree = 0x13,
/// <summary>Target Bus Phase Sequence Failure</summary>
CamSequenceFail = 0x14,
/// <summary>CCB length supplied is inadequate</summary>
CamCcbLenErr = 0x15,
/// <summary>Unable to provide requested capability</summary>
CamProvideFail = 0x16,
/// <summary>A SCSI BDR msg was sent to target</summary>
CamBdrSent = 0x17,
/// <summary>CCB request terminated by the host</summary>
CamReqTermio = 0x18,
/// <summary>Unrecoverable Host Bus Adapter Error</summary>
CamUnrecHbaError = 0x19,
/// <summary>Request was too large for this host</summary>
CamReqTooBig = 0x1a,
/// <summary>
/// This request should be requeued to preserve transaction ordering. This typically occurs when the SIM
/// recognizes an error that should freeze the queue and must place additional requests for the target at the sim level
/// back into the XPT queue.
/// </summary>
CamRequeueReq = 0x1b,
/// <summary>ATA error, look at error code in CCB</summary>
CamAtaStatusError = 0x1c,
/// <summary>Initiator/Target Nexus lost.</summary>
CamScsiItNexusLost = 0x1d,
/// <summary>SMP error, look at error code in CCB</summary>
CamSmpStatusError = 0x1e,
/// <summary>Command completed without error but exceeded the soft timeout threshold.</summary>
CamReqSofttimeout = 0x1f,
/*
* 0x20 - 0x32 are unassigned
*/
/// <summary>Initiator Detected Error</summary>
CamIde = 0x33,
/// <summary>Resource Unavailable</summary>
CamResrcUnavail = 0x34,
/// <summary>Unacknowledged Event by Host</summary>
CamUnackedEvent = 0x35,
/// <summary>Message Received in Host Target Mode</summary>
CamMessageRecv = 0x36,
/// <summary>Invalid CDB received in Host Target Mode</summary>
CamInvalidCdb = 0x37,
/// <summary>Lun supplied is invalid</summary>
CamLunInvalid = 0x38,
/// <summary>Target ID supplied is invalid</summary>
CamTidInvalid = 0x39,
/// <summary>The requested function is not available</summary>
CamFuncNotavail = 0x3a,
/// <summary>Nexus is not established</summary>
CamNoNexus = 0x3b,
/// <summary>The initiator ID is invalid</summary>
CamIidInvalid = 0x3c,
/// <summary>The SCSI CDB has been received</summary>
CamCdbRecvd = 0x3d,
/// <summary>The LUN is already enabled for target mode</summary>
CamLunAlrdyEna = 0x3e,
/// <summary>SCSI Bus Busy</summary>
CamScsiBusy = 0x3f,
/*
* Flags
*/
/// <summary>The DEV queue is frozen w/this err</summary>
CamDevQfrzn = 0x40,
/// <summary>Autosense data valid for target</summary>
CamAutosnsValid = 0x80,
/// <summary>SIM ready to take more commands</summary>
CamReleaseSimq = 0x100,
/// <summary>SIM has this command in its queue</summary>
CamSimQueued = 0x200,
/// <summary>Quality of service data is valid</summary>
CamQosValid = 0x400,
/// <summary>Mask bits for just the status #</summary>
CamStatusMask = 0x3F,
/*
* Target Specific Adjunct Status
*/
/// <summary>sent sense with status</summary>
CamSentSense = 0x40000000
}
}

View File

@@ -1,66 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Extern.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : FreeBSD direct device access.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains the P/Invoke definitions of FreeBSD syscalls used to directly
// interface devices.
//
// --[ 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-2021 Natalia Portillo
// ****************************************************************************/
using System;
using System.Runtime.InteropServices;
namespace Aaru.Devices.FreeBSD
{
[Obsolete]
internal static class Extern
{
[DllImport("libc", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int open(string pathname, [MarshalAs(UnmanagedType.U4)] FileFlags flags);
[DllImport("libc")]
internal static extern int close(int fd);
[DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern IntPtr cam_open_device(string path, [MarshalAs(UnmanagedType.U4)] FileFlags flags);
[DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern void cam_close_device(IntPtr dev);
[DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern IntPtr cam_getccb(IntPtr dev);
[DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern void cam_freeccb(IntPtr ccb);
[DllImport("libcam", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int cam_send_ccb(IntPtr dev, IntPtr ccb);
[DllImport("libc")]
internal static extern int ioctl(int fd, FreebsdIoctl request, IntPtr argp);
}
}

View File

@@ -1,169 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : ListDevices.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : FreeBSD direct device access.
//
// --[ Description ] ----------------------------------------------------------
//
// Gets a list of known devices.
//
// --[ 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-2021 Natalia Portillo
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Aaru.CommonTypes.Structs.Devices.ATA;
using Aaru.CommonTypes.Structs.Devices.SCSI;
using Aaru.Helpers;
using static Aaru.Devices.FreeBSD.Extern;
using Marshal = System.Runtime.InteropServices.Marshal;
namespace Aaru.Devices.FreeBSD
{
[Obsolete]
internal static class ListDevices
{
/// <summary>Gets a list of all known storage devices on FreeBSD</summary>
/// <returns>List of devices</returns>
[Obsolete]
internal static DeviceInfo[] GetList()
{
string[] passDevices = Directory.GetFiles("/dev/", "pass*", SearchOption.TopDirectoryOnly);
List<DeviceInfo> listDevices = new List<DeviceInfo>();
foreach(string passDevice in passDevices)
{
var deviceInfo = new DeviceInfo();
IntPtr dev = cam_open_device(passDevice, FileFlags.ReadWrite);
var camDevice = (CamDevice)Marshal.PtrToStructure(dev, typeof(CamDevice));
IntPtr ccbPtr = cam_getccb(dev);
if(ccbPtr.ToInt64() == 0)
continue;
var cgd = (CcbGetdev)Marshal.PtrToStructure(ccbPtr, typeof(CcbGetdev));
cgd.ccb_h.func_code = XptOpcode.XptGdevType;
Marshal.StructureToPtr(cgd, ccbPtr, false);
int error = cam_send_ccb(dev, ccbPtr);
if(error < 0)
{
cam_freeccb(ccbPtr);
continue;
}
cgd = (CcbGetdev)Marshal.PtrToStructure(ccbPtr, typeof(CcbGetdev));
cam_freeccb(ccbPtr);
cam_close_device(dev);
string simName = StringHandlers.CToString(camDevice.SimName);
deviceInfo.Path = passDevice;
byte[] serialNumber = new byte[camDevice.SerialNumLen];
Array.Copy(camDevice.SerialNum, 0, serialNumber, 0, serialNumber.Length);
deviceInfo.Serial = StringHandlers.CToString(serialNumber);
switch(cgd.protocol)
{
case CamProto.ProtoAta:
case CamProto.ProtoAtapi:
case CamProto.ProtoSatapm:
{
// Little-endian FreeBSD gives it resorted
// Big-endian FreeBSD, no idea
byte[] atadTneid = new byte[512];
for(int aIndex = 0; aIndex < 512; aIndex += 2)
{
atadTneid[aIndex] = cgd.ident_data[aIndex + 1];
atadTneid[aIndex + 1] = cgd.ident_data[aIndex];
}
Identify.IdentifyDevice? idt = Identify.Decode(atadTneid);
if(idt.HasValue)
{
string[] separated = idt.Value.Model.Split(' ');
if(separated.Length == 1)
{
deviceInfo.Vendor = "ATA";
deviceInfo.Model = separated[0];
}
else
{
deviceInfo.Vendor = separated[0];
deviceInfo.Model = separated[^1];
}
deviceInfo.Serial = idt.Value.SerialNumber;
deviceInfo.Bus = simName == "ahcich" ? "SATA" : "ATA";
deviceInfo.Supported = simName != "ata";
}
if(cgd.protocol == CamProto.ProtoAtapi)
goto case CamProto.ProtoScsi;
break;
}
case CamProto.ProtoScsi:
{
Inquiry? inq = Inquiry.Decode(cgd.inq_data);
if(inq.HasValue)
{
deviceInfo.Vendor = StringHandlers.CToString(inq.Value.VendorIdentification).Trim();
deviceInfo.Model = StringHandlers.CToString(inq.Value.ProductIdentification).Trim();
deviceInfo.Bus = simName == "ata" || simName == "ahcich" ? "ATAPI" : "SCSI";
deviceInfo.Supported = simName != "ata";
}
break;
}
case CamProto.ProtoNvme:
deviceInfo.Bus = "NVMe";
deviceInfo.Supported = false;
break;
case CamProto.ProtoMmcsd:
deviceInfo.Model = "Unknown card";
deviceInfo.Bus = "MMC/SD";
deviceInfo.Supported = false;
break;
}
listDevices.Add(deviceInfo);
}
return listDevices.Count > 0 ? listDevices.OrderBy(t => t.Path).ToArray() : null;
}
}
}

View File

@@ -1,711 +0,0 @@
// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// Filename : Structs.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : FreeBSD direct device access.
//
// --[ Description ] ----------------------------------------------------------
//
// Contains structures necessary for directly interfacing devices under
// FreeBSD.
//
// --[ 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-2021 Natalia Portillo
// ****************************************************************************/
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using lun_id_t = System.UInt32;
using path_id_t = System.UInt32;
using target_id_t = System.UInt32;
// ReSharper disable BuiltInTypeReferenceStyle
#pragma warning disable 649
#pragma warning disable 169
namespace Aaru.Devices.FreeBSD
{
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct AtaCmd
{
public CamAtaIoFlags flags;
public byte command;
public byte features;
public byte lba_low;
public byte lba_mid;
public byte lba_high;
public byte device;
public byte lba_low_exp;
public byte lba_mid_exp;
public byte lba_high_exp;
public byte features_exp;
public byte sector_count;
public byte sector_count_exp;
public byte control;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct AtaRes
{
public CamAtaIoFlags flags;
public byte status;
public byte error;
public byte lba_low;
public byte lba_mid;
public byte lba_high;
public byte device;
public byte lba_low_exp;
public byte lba_mid_exp;
public byte lba_high_exp;
public byte sector_count;
public byte sector_count_exp;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CamPinfo
{
public uint priority;
public uint generation;
public int index;
}
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct ListEntry
{
/// <summary>LIST_ENTRY(ccb_hdr)=le->*le_next</summary>
public IntPtr LeNext;
/// <summary>LIST_ENTRY(ccb_hdr)=le->**le_prev</summary>
public IntPtr LePrev;
}
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct SlistEntry
{
/// <summary>SLIST_ENTRY(ccb_hdr)=sle->*sle_next</summary>
public IntPtr SleNext;
}
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct TailqEntry
{
/// <summary>TAILQ_ENTRY(ccb_hdr)=tqe->*tqe_next</summary>
public IntPtr TqeNext;
/// <summary>TAILQ_ENTRY(ccb_hdr)=tqe->**tqe_prev</summary>
public IntPtr TqePrev;
}
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct StailqEntry
{
/// <summary>STAILQ_ENTRY(ccb_hdr)=stqe->*stqe_next</summary>
public IntPtr StqeNext;
}
[StructLayout(LayoutKind.Explicit), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CamqEntry
{
[FieldOffset(0)]
public ListEntry le;
[FieldOffset(0)]
public SlistEntry sle;
[FieldOffset(0)]
public TailqEntry tqe;
[FieldOffset(0)]
public StailqEntry stqe;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct Timeval
{
public long tv_sec;
/// <summary>long</summary>
public IntPtr tv_usec;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbQosArea
{
public Timeval etime;
public UIntPtr sim_data;
public UIntPtr periph_data;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbHdr
{
public CamPinfo pinfo;
public CamqEntry xpt_links;
public CamqEntry sim_links;
public CamqEntry periph_links;
public uint retry_count;
public IntPtr cbfcnp;
public XptOpcode func_code;
public CamStatus status;
public IntPtr path;
public uint path_id;
public uint target_id;
public ulong target_lun;
public CcbFlags flags;
public uint xflags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] periph_priv;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] sim_priv;
public CcbQosArea qos;
public uint timeout;
public Timeval softtimeout;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct ScsiSenseData
{
const int SSD_FULL_SIZE = 252;
public byte error_code;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SSD_FULL_SIZE - 1)]
public byte[] sense_buf;
}
/// <summary>SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO function codes.</summary>
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbScsiio
{
public CcbHdr ccb_h;
/// <summary>Ptr for next CCB for action</summary>
public IntPtr next_ccb;
/// <summary>Ptr to mapping info</summary>
public IntPtr req_map;
/// <summary>Ptr to the data buf/SG list</summary>
public IntPtr data_ptr;
/// <summary>Data transfer length</summary>
public uint dxfer_len;
/// <summary>Autosense storage</summary>
public ScsiSenseData sense_data;
/// <summary>Number of bytes to autosense</summary>
public byte sense_len;
/// <summary>Number of bytes for the CDB</summary>
public byte cdb_len;
/// <summary>Number of SG list entries</summary>
public short sglist_cnt;
/// <summary>Returned SCSI status</summary>
public byte scsi_status;
/// <summary>Autosense resid length: 2's comp</summary>
public sbyte sense_resid;
/// <summary>Transfer residual length: 2's comp</summary>
public int resid;
/// <summary>Area for the CDB send, or pointer to the CDB bytes to send</summary>
const int IOCDBLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)]
public byte[] cdb_bytes;
/// <summary>Pointer to the message buffer</summary>
public IntPtr msg_ptr;
/// <summary>Number of bytes for the Message</summary>
public short msg_len;
/// <summary>
/// What to do for tag queueing. The tag action should be either the define below (to send a non-tagged
/// transaction) or one of the defined scsi tag messages from scsi_message.h.
/// </summary>
public byte tag_action;
/// <summary>tag id from initator (target mode)</summary>
public uint tag_id;
/// <summary>initiator id of who selected</summary>
public uint init_id;
}
/// <summary>SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO function codes.</summary>
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbScsiio64
{
public CcbHdr ccb_h;
/// <summary>Ptr for next CCB for action</summary>
public IntPtr next_ccb;
/// <summary>Ptr to mapping info</summary>
public IntPtr req_map;
/// <summary>Ptr to the data buf/SG list</summary>
public IntPtr data_ptr;
/// <summary>Data transfer length</summary>
public uint dxfer_len;
/// <summary>Autosense storage</summary>
public ScsiSenseData sense_data;
/// <summary>Number of bytes to autosense</summary>
public byte sense_len;
/// <summary>Number of bytes for the CDB</summary>
public byte cdb_len;
/// <summary>Number of SG list entries</summary>
public short sglist_cnt;
/// <summary>Returned SCSI status</summary>
public byte scsi_status;
/// <summary>Autosense resid length: 2's comp</summary>
public sbyte sense_resid;
/// <summary>Transfer residual length: 2's comp</summary>
public int resid;
public uint alignment;
/// <summary>Area for the CDB send, or pointer to the CDB bytes to send</summary>
const int IOCDBLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)]
public byte[] cdb_bytes;
/// <summary>Pointer to the message buffer</summary>
public IntPtr msg_ptr;
/// <summary>Number of bytes for the Message</summary>
public short msg_len;
/// <summary>
/// What to do for tag queueing. The tag action should be either the define below (to send a non-tagged
/// transaction) or one of the defined scsi tag messages from scsi_message.h.
/// </summary>
public byte tag_action;
/// <summary>tag id from initator (target mode)</summary>
public uint tag_id;
/// <summary>initiator id of who selected</summary>
public uint init_id;
}
/// <summary>ATA I/O Request CCB used for the XPT_ATA_IO function code.</summary>
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbAtaio
{
public CcbHdr ccb_h;
/// <summary>Ptr for next CCB for action</summary>
public IntPtr next_ccb;
/// <summary>ATA command register set</summary>
public AtaCmd cmd;
/// <summary>ATA result register set</summary>
public AtaRes res;
/// <summary>Ptr to the data buf/SG list</summary>
public IntPtr data_ptr;
/// <summary>Data transfer length</summary>
public uint dxfer_len;
/// <summary>Transfer residual length: 2's comp</summary>
public int resid;
/// <summary>Flags for the rest of the buffer</summary>
public byte ata_flags;
public uint aux;
public uint unused;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct NvmeCommand
{
readonly ushort opc_fuse_rsvd1;
/// <summary>command identifier</summary>
public ushort cid;
/// <summary>namespace identifier</summary>
public uint nsid;
/// <summary>reserved</summary>
public uint rsvd2;
/// <summary>reserved</summary>
public uint rsvd3;
/// <summary>metadata pointer</summary>
public ulong mptr;
/// <summary>prp entry 1</summary>
public ulong prp1;
/// <summary>prp entry 2</summary>
public ulong prp2;
/// <summary>command-specific</summary>
public uint cdw10;
/// <summary>command-specific</summary>
public uint cdw11;
/// <summary>command-specific</summary>
public uint cdw12;
/// <summary>command-specific</summary>
public uint cdw13;
/// <summary>command-specific</summary>
public uint cdw14;
/// <summary>command-specific</summary>
public uint cdw15;
/// <summary>opcode</summary>
public byte Opc => (byte)((opc_fuse_rsvd1 & 0xFF00) >> 8);
/// <summary>fused operation</summary>
public byte Fuse => (byte)((opc_fuse_rsvd1 & 0xC0) >> 6);
/// <summary>reserved</summary>
public byte Rsvd1 => (byte)(opc_fuse_rsvd1 & 0x3F);
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct NvmeStatus
{
readonly ushort status;
/// <summary>phase tag</summary>
public byte P => (byte)((status & 0x8000) >> 15);
/// <summary>status code</summary>
public byte Sc => (byte)((status & 0x7F80) >> 7);
/// <summary>status code type</summary>
public byte Sct => (byte)((status & 0x70) >> 4);
/// <summary>reserved</summary>
public byte Rsvd2 => (byte)((status & 0xC) >> 15);
/// <summary>more</summary>
public byte M => (byte)((status & 0x2) >> 1);
/// <summary>do not retry</summary>
public byte Dnr => (byte)(status & 0x1);
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct NvmeCompletion
{
/// <summary>command-specific</summary>
public uint cdw0;
/// <summary>reserved</summary>
public uint rsvd1;
/// <summary>submission queue head pointer</summary>
public ushort sqhd;
/// <summary>submission queue identifier</summary>
public ushort sqid;
/// <summary>command identifier</summary>
public ushort cid;
public NvmeStatus status;
}
/// <summary>NVMe I/O Request CCB used for the XPT_NVME_IO and XPT_NVME_ADMIN function codes.</summary>
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbNvmeio
{
public CcbHdr ccb_h;
/// <summary>Ptr for next CCB for action</summary>
public IntPtr next_ccb;
/// <summary>NVME command, per NVME standard</summary>
public NvmeCommand cmd;
/// <summary>NVME completion, per NVME standard</summary>
public NvmeCompletion cpl;
/// <summary>Ptr to the data buf/SG list</summary>
public IntPtr data_ptr;
/// <summary>Data transfer length</summary>
public uint dxfer_len;
/// <summary>Number of SG list entries</summary>
public ushort sglist_cnt;
/// <summary>padding for removed uint32_t</summary>
public ushort unused;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct PeriphMatchPattern
{
const int DEV_IDLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)]
public byte[] periph_name;
public uint unit_number;
public path_id_t path_id;
public target_id_t target_id;
public lun_id_t target_lun;
public PeriphPatternFlags flags;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct DeviceIdMatchPattern
{
public byte id_len;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] id;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct ScsiStaticInquiryPattern
{
const int SID_VENDOR_SIZE = 8;
const int SID_PRODUCT_SIZE = 16;
const int SID_REVISION_SIZE = 4;
public byte type;
public byte media_type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_VENDOR_SIZE + 1)]
public byte[] vendor;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_PRODUCT_SIZE + 1)]
public byte[] product;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SID_REVISION_SIZE + 1)]
public byte[] revision;
}
[StructLayout(LayoutKind.Explicit), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct DeviceMatchPatternData
{
[FieldOffset(0)]
public ScsiStaticInquiryPattern inq_pat;
[FieldOffset(0)]
public DeviceIdMatchPattern devid_pat;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct DeviceMatchPattern
{
public uint path_id;
public uint target_id;
public uint target_lun;
public DevPatternFlags flags;
public DeviceMatchPatternData data;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct BusMatchPattern
{
const int DEV_IDLEN = 16;
public path_id_t path_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)]
public byte[] dev_name;
public uint unit_number;
public uint bus_id;
readonly BusPatternFlags flags;
}
[StructLayout(LayoutKind.Explicit), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct MatchPattern
{
[FieldOffset(0)]
public PeriphMatchPattern periph_pattern;
[FieldOffset(0)]
public DeviceMatchPattern device_pattern;
[FieldOffset(0)]
public BusMatchPattern bus_pattern;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct DevMatchPattern
{
public DevMatchType type;
public MatchPattern pattern;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct PeriphMatchResult
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] periph_name;
public uint unit_number;
public path_id_t path_id;
public target_id_t target_id;
public lun_id_t target_lun;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct MmcCid
{
public uint mid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] pnm;
public uint psn;
public ushort oid;
public ushort mdt_year;
public byte mdt_month;
public byte prv;
public byte fwrev;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct MmcParams
{
/// <summary>Card model</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[] model;
/// <summary>Card OCR</summary>
public uint card_ocr;
/// <summary>OCR of the IO portion of the card</summary>
public uint io_ocr;
/// <summary>Card CID -- raw</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] card_cid;
/// <summary>Card CID -- parsed</summary>
public MmcCid cid;
/// <summary>Card CSD -- raw</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint[] card_csd;
/// <summary>Card RCA</summary>
public ushort card_rca;
/// <summary>What kind of card is it</summary>
public MmcCardFeatures card_features;
public byte sdio_func_count;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct DeviceMatchResult
{
public path_id_t path_id;
public target_id_t target_id;
public lun_id_t target_lun;
public CamProto protocol;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] inq_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] ident_data;
public DevResultFlags flags;
public MmcParams mmc_ident_data;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct BusMatchResult
{
public path_id_t path_id;
const int DEV_IDLEN = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN)]
public byte[] dev_name;
public uint unit_number;
public uint bus_id;
}
[StructLayout(LayoutKind.Explicit), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct MatchResult
{
[FieldOffset(0)]
public PeriphMatchResult periph_result;
[FieldOffset(0)]
public DeviceMatchResult device_result;
[FieldOffset(0)]
public BusMatchResult bus_result;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct DevMatchResult
{
public DevMatchType type;
public MatchResult result;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbDmCookie
{
public IntPtr bus;
public IntPtr target;
public IntPtr device;
public IntPtr periph;
public IntPtr pdrv;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbDevPosition
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public CamGenerations[] generations;
readonly DevPosType position_type;
public CcbDmCookie cookie;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbDevMatch
{
public CcbHdr ccb_h;
readonly CcbDevMatchStatus status;
public uint num_patterns;
public uint pattern_buf_len;
/// <summary>dev_match_pattern*</summary>
public IntPtr patterns;
public uint num_matches;
public uint match_buf_len;
/// <summary>dev_match_result*</summary>
public IntPtr matches;
public CcbDevPosition pos;
}
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CamDevice
{
const int MAXPATHLEN = 1024;
const int DEV_IDLEN = 16;
const int SIM_IDLEN = 16;
/// <summary>
/// Pathname of the device given by the user. This may be null if the user states the device name and unit number
/// separately.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXPATHLEN)]
public byte[] DevicePath;
/// <summary>Device name given by the user.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN + 1)]
public byte[] GivenDevName;
/// <summary>Unit number given by the user.</summary>
public uint GivenUnitNumber;
/// <summary>Name of the device, e.g. 'pass'</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = DEV_IDLEN + 1)]
public byte[] DeviceName;
/// <summary>Unit number of the passthrough device associated with this particular device.</summary>
public uint DevUnitNum;
/// <summary>Controller name, e.g. 'ahc'</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = SIM_IDLEN + 1)]
public byte[] SimName;
/// <summary>Controller unit number</summary>
public uint SimUnitNumber;
/// <summary>Controller bus number</summary>
public uint BusId;
/// <summary>Logical Unit Number</summary>
public lun_id_t TargetLun;
/// <summary>Target ID</summary>
public target_id_t TargetId;
/// <summary>System SCSI bus number</summary>
public path_id_t PathId;
/// <summary>type of peripheral device</summary>
public ushort PdType;
/// <summary>SCSI Inquiry data</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] InqData;
/// <summary>device serial number</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 252)]
public byte[] SerialNum;
/// <summary>length of the serial number</summary>
public byte SerialNumLen;
/// <summary>Negotiated sync period</summary>
public byte SyncPeriod;
/// <summary>Negotiated sync offset</summary>
public byte SyncOffset;
/// <summary>Negotiated bus width</summary>
public byte BusWidth;
/// <summary>file descriptor for device</summary>
public int Fd;
}
[StructLayout(LayoutKind.Sequential), SuppressMessage("ReSharper", "MemberCanBePrivate.Global"), Obsolete]
internal struct CcbGetdev
{
public CcbHdr ccb_h;
public CamProto protocol;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] inq_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] ident_data;
/// <summary>device serial number</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 252)]
public byte[] serial_num;
public byte inq_flags;
/// <summary>length of the serial number</summary>
public byte serial_num_len;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public IntPtr[] padding;
}
}

View File

@@ -153,15 +153,10 @@ Logo and art:
process.StartInfo.FileName = "cmd"; process.StartInfo.FileName = "cmd";
process.StartInfo.Arguments = $"/c start {process.StartInfo.Arguments.Replace("&", "^&")}"; process.StartInfo.Arguments = $"/c start {process.StartInfo.Arguments.Replace("&", "^&")}";
} }
else if(RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD) || else if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
process.StartInfo.FileName = "xdg-open"; process.StartInfo.FileName = "xdg-open";
}
else if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) else if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
process.StartInfo.FileName = "open"; process.StartInfo.FileName = "open";
}
else else
return; return;

View File

@@ -28,8 +28,8 @@ Stable releases in [Github](https://github.com/aaru-dps/Aaru/releases).
System requirements System requirements
=================== ===================
Aaru is created using .NET 6 and can be compiled with all the major IDEs. To run it you require to use one of the Aaru is created using .NET 6 and can be compiled with all the major IDEs. To run it you require to use one of the stable
stable releases, or build it yourself. releases, or build it yourself.
Usage Usage
===== =====
@@ -59,8 +59,7 @@ Features
* Can create standard open XML metadata from existing images. * Can create standard open XML metadata from existing images.
* Can measure readability and speed of media (same that can be dumped, MHDD style) * Can measure readability and speed of media (same that can be dumped, MHDD style)
* Has an online database with drive capabilities, and can report the capabilities of any drive. * Has an online database with drive capabilities, and can report the capabilities of any drive.
* Works on any operating system and architecture where .NET Core is supported (drive access requires Windows, Linux or * Works on any operating system and architecture where .NET Core is supported (drive access requires Windows or Linux).
FreeBSD).
* Has a graphical interface (work in progress) * Has a graphical interface (work in progress)
Supported disk image formats (read-only) Supported disk image formats (read-only)