diff --git a/DiscImageChef.Devices/FreeBSD/Command.cs b/DiscImageChef.Devices/FreeBSD/Command.cs index 82b18f3ed..bf2aa8001 100644 --- a/DiscImageChef.Devices/FreeBSD/Command.cs +++ b/DiscImageChef.Devices/FreeBSD/Command.cs @@ -42,7 +42,7 @@ namespace DiscImageChef.Devices.FreeBSD static class Command { const int CAM_MAX_CDBLEN = 16; - + /// /// Sends a SCSI command (64-bit arch) /// @@ -65,6 +65,7 @@ namespace DiscImageChef.Devices.FreeBSD return -1; IntPtr ccbPtr = cam_getccb(dev); + IntPtr cdbPtr = IntPtr.Zero; if(ccbPtr.ToInt64() == 0) { @@ -85,17 +86,18 @@ namespace DiscImageChef.Devices.FreeBSD csio.cdb_len = (byte)cdb.Length; // TODO: Create enum? csio.tag_action = 0x20; - csio.cdb_io = new cdb_t64(); + csio.cdb_bytes = new byte[CAM_MAX_CDBLEN]; if(cdb.Length <= CAM_MAX_CDBLEN) - { - csio.cdb_io.cdb_bytes = new byte[CAM_MAX_CDBLEN]; - Array.Copy(cdb, 0, csio.cdb_io.cdb_bytes, 0, cdb.Length); - } + Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length); else { - csio.cdb_io.cdb_ptr = Marshal.AllocHGlobal(cdb.Length).ToInt64(); + 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 |= ccb_flags.CAM_CDB_POINTER; } + csio.ccb_h.flags |= ccb_flags.CAM_DEV_QFRZDIS; + Marshal.Copy(buffer, 0, csio.data_ptr, buffer.Length); Marshal.StructureToPtr(csio, ccbPtr, false); @@ -139,11 +141,13 @@ namespace DiscImageChef.Devices.FreeBSD Marshal.Copy(csio.data_ptr, buffer, 0, buffer.Length); if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER)) - Marshal.Copy(new IntPtr(csio.cdb_io.cdb_ptr), cdb, 0, cdb.Length); + Marshal.Copy(new IntPtr(BitConverter.ToInt64(csio.cdb_bytes, 0)), cdb, 0, cdb.Length); else - Array.Copy(csio.cdb_io.cdb_bytes, 0, cdb, 0, cdb.Length); + Array.Copy(csio.cdb_bytes, 0, cdb, 0, cdb.Length); duration = (end - start).TotalMilliseconds; + if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER)) + Marshal.FreeHGlobal(cdbPtr); Marshal.FreeHGlobal(csio.data_ptr); cam_freeccb(ccbPtr); @@ -172,6 +176,7 @@ namespace DiscImageChef.Devices.FreeBSD return -1; IntPtr ccbPtr = cam_getccb(dev); + IntPtr cdbPtr = IntPtr.Zero; if(ccbPtr.ToInt32() == 0) { @@ -192,17 +197,18 @@ namespace DiscImageChef.Devices.FreeBSD csio.cdb_len = (byte)cdb.Length; // TODO: Create enum? csio.tag_action = 0x20; - csio.cdb_io = new cdb_t(); + csio.cdb_bytes = new byte[CAM_MAX_CDBLEN]; if(cdb.Length <= CAM_MAX_CDBLEN) - { - csio.cdb_io.cdb_bytes = new byte[CAM_MAX_CDBLEN]; - Array.Copy(cdb, 0, csio.cdb_io.cdb_bytes, 0, cdb.Length); - } + Array.Copy(cdb, 0, csio.cdb_bytes, 0, cdb.Length); else { - csio.cdb_io.cdb_ptr = Marshal.AllocHGlobal(cdb.Length).ToInt32(); + 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 |= ccb_flags.CAM_CDB_POINTER; } + csio.ccb_h.flags |= ccb_flags.CAM_DEV_QFRZDIS; + Marshal.Copy(buffer, 0, csio.data_ptr, buffer.Length); Marshal.StructureToPtr(csio, ccbPtr, false); @@ -246,11 +252,13 @@ namespace DiscImageChef.Devices.FreeBSD Marshal.Copy(csio.data_ptr, buffer, 0, buffer.Length); if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER)) - Marshal.Copy(new IntPtr(csio.cdb_io.cdb_ptr), cdb, 0, cdb.Length); + Marshal.Copy(new IntPtr(BitConverter.ToInt32(csio.cdb_bytes, 0)), cdb, 0, cdb.Length); else - Array.Copy(csio.cdb_io.cdb_bytes, 0, cdb, 0, cdb.Length); + Array.Copy(csio.cdb_bytes, 0, cdb, 0, cdb.Length); duration = (end - start).TotalMilliseconds; + if(csio.ccb_h.flags.HasFlag(ccb_flags.CAM_CDB_POINTER)) + Marshal.FreeHGlobal(cdbPtr); Marshal.FreeHGlobal(csio.data_ptr); cam_freeccb(ccbPtr); diff --git a/DiscImageChef.Devices/FreeBSD/Structs.cs b/DiscImageChef.Devices/FreeBSD/Structs.cs index c83dc9a6a..da6d5e10a 100644 --- a/DiscImageChef.Devices/FreeBSD/Structs.cs +++ b/DiscImageChef.Devices/FreeBSD/Structs.cs @@ -182,19 +182,6 @@ namespace DiscImageChef.Devices.FreeBSD [MarshalAs(UnmanagedType.ByValArray, SizeConst = SSD_FULL_SIZE - 1)] public byte[] sense_buf; } - struct cdb_t - { - /// - /// Pointer to the CDB bytes to send - /// - public int cdb_ptr; - /// - /// Area for the CDB send - /// - const int IOCDBLEN = 16; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)] public byte[] cdb_bytes; - } - /// /// SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO function codes. /// @@ -224,8 +211,11 @@ namespace DiscImageChef.Devices.FreeBSD public sbyte sense_resid; /// Transfer residual length: 2's comp public int resid; - /// Union for CDB bytes/pointer - public cdb_t cdb_io; + /// + /// Area for the CDB send, or pointer to the CDB bytes to send + /// + const int IOCDBLEN = 16; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)] public byte[] cdb_bytes; /// Pointer to the message buffer public IntPtr msg_ptr; /// Number of bytes for the Message @@ -238,19 +228,6 @@ namespace DiscImageChef.Devices.FreeBSD public uint init_id; } - struct cdb_t64 - { - /// - /// Pointer to the CDB bytes to send - /// - public long cdb_ptr; - /// - /// Area for the CDB send - /// - const int IOCDBLEN = 16; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)] public byte[] cdb_bytes; - } - /// /// SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO function codes. /// @@ -280,8 +257,12 @@ namespace DiscImageChef.Devices.FreeBSD public sbyte sense_resid; /// Transfer residual length: 2's comp public int resid; - /// Union for CDB bytes/pointer - public cdb_t64 cdb_io; + public uint alignment; + /// + /// Area for the CDB send, or pointer to the CDB bytes to send + /// + const int IOCDBLEN = 16; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = IOCDBLEN)] public byte[] cdb_bytes; /// Pointer to the message buffer public IntPtr msg_ptr; /// Number of bytes for the Message