diff --git a/DiscImageChef.Devices/Windows/Command.cs b/DiscImageChef.Devices/Windows/Command.cs index eceb0d90e..a696ba70e 100644 --- a/DiscImageChef.Devices/Windows/Command.cs +++ b/DiscImageChef.Devices/Windows/Command.cs @@ -40,7 +40,7 @@ using Microsoft.Win32.SafeHandles; namespace DiscImageChef.Devices.Windows { [SuppressMessage("ReSharper", "UnusedParameter.Global")] - static class Command + internal static class Command { /// /// Sends a SCSI command @@ -58,46 +58,46 @@ namespace DiscImageChef.Devices.Windows /// sense /// internal static int SendScsiCommand(SafeFileHandle fd, byte[] cdb, ref byte[] buffer, - out byte[] senseBuffer, - uint timeout, ScsiIoctlDirection direction, out double duration, - out bool sense) + out byte[] senseBuffer, + uint timeout, ScsiIoctlDirection direction, out double duration, + out bool sense) { senseBuffer = null; - duration = 0; - sense = false; + duration = 0; + sense = false; - if(buffer == null) return -1; + if (buffer == null) return -1; - ScsiPassThroughDirectAndSenseBuffer sptdSb = new ScsiPassThroughDirectAndSenseBuffer + var sptdSb = new ScsiPassThroughDirectAndSenseBuffer { SenseBuf = new byte[32], sptd = new ScsiPassThroughDirect { - Cdb = new byte[16], - CdbLength = (byte)cdb.Length, - SenseInfoLength = 32, - DataIn = direction, - DataTransferLength = (uint)buffer.Length, - TimeOutValue = timeout, - DataBuffer = Marshal.AllocHGlobal(buffer.Length) + Cdb = new byte[16], + CdbLength = (byte) cdb.Length, + SenseInfoLength = 32, + DataIn = direction, + DataTransferLength = (uint) buffer.Length, + TimeOutValue = timeout, + DataBuffer = Marshal.AllocHGlobal(buffer.Length) } }; - sptdSb.sptd.Length = (ushort)Marshal.SizeOf(sptdSb.sptd); - sptdSb.sptd.SenseInfoOffset = (uint)Marshal.SizeOf(sptdSb.sptd); + sptdSb.sptd.Length = (ushort) Marshal.SizeOf(sptdSb.sptd); + sptdSb.sptd.SenseInfoOffset = (uint) Marshal.SizeOf(sptdSb.sptd); Array.Copy(cdb, sptdSb.sptd.Cdb, cdb.Length); - uint k = 0; - int error = 0; + uint k = 0; + var error = 0; Marshal.Copy(buffer, 0, sptdSb.sptd.DataBuffer, buffer.Length); - DateTime start = DateTime.Now; - bool hasError = !Extern.DeviceIoControlScsi(fd, WindowsIoctl.IoctlScsiPassThroughDirect, ref sptdSb, - (uint)Marshal.SizeOf(sptdSb), ref sptdSb, - (uint)Marshal.SizeOf(sptdSb), ref k, IntPtr.Zero); - DateTime end = DateTime.Now; + var start = DateTime.Now; + var hasError = !Extern.DeviceIoControlScsi(fd, WindowsIoctl.IoctlScsiPassThroughDirect, ref sptdSb, + (uint) Marshal.SizeOf(sptdSb), ref sptdSb, + (uint) Marshal.SizeOf(sptdSb), ref k, IntPtr.Zero); + var end = DateTime.Now; - if(hasError) error = Marshal.GetLastWin32Error(); + if (hasError) error = Marshal.GetLastWin32Error(); Marshal.Copy(sptdSb.sptd.DataBuffer, buffer, 0, buffer.Length); @@ -125,43 +125,43 @@ namespace DiscImageChef.Devices.Windows /// Registers to send to drive /// Registers returned by drive /// ATA protocol to use - internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersChs registers, - out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol, - ref byte[] buffer, uint timeout, - out double duration, out bool sense) + internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersChs registers, + out AtaErrorRegistersChs errorRegisters, AtaProtocol protocol, + ref byte[] buffer, uint timeout, + out double duration, out bool sense) { - duration = 0; - sense = false; + duration = 0; + sense = false; errorRegisters = new AtaErrorRegistersChs(); - if(buffer == null) return -1; + if (buffer == null) return -1; - uint offsetForBuffer = (uint)(Marshal.SizeOf(typeof(AtaPassThroughDirect)) + Marshal.SizeOf(typeof(uint))); + var offsetForBuffer = (uint) (Marshal.SizeOf(typeof(AtaPassThroughEx)) + Marshal.SizeOf(typeof(uint))); - AtaPassThroughDirectWithBuffer aptdBuf = new AtaPassThroughDirectWithBuffer + var aptdBuf = new AtaPassThroughExBuffer { - aptd = new AtaPassThroughDirect + aptd = new AtaPassThroughEx { - TimeOutValue = timeout, - DataBuffer = (IntPtr)offsetForBuffer, - Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)), - DataTransferLength = (uint)buffer.Length, - PreviousTaskFile = new AtaTaskFile(), + TimeOutValue = timeout, + DataBufferOffset = (IntPtr) offsetForBuffer, + Length = (ushort) Marshal.SizeOf(typeof(AtaPassThroughEx)), + DataTransferLength = (uint) buffer.Length, + PreviousTaskFile = new AtaTaskFile(), CurrentTaskFile = new AtaTaskFile { - Command = registers.Command, + Command = registers.Command, CylinderHigh = registers.CylinderHigh, - CylinderLow = registers.CylinderLow, - DeviceHead = registers.DeviceHead, - Features = registers.Feature, - SectorCount = registers.SectorCount, + CylinderLow = registers.CylinderLow, + DeviceHead = registers.DeviceHead, + Features = registers.Feature, + SectorCount = registers.SectorCount, SectorNumber = registers.Sector } }, dataBuffer = new byte[64 * 512] }; - switch(protocol) + switch (protocol) { case AtaProtocol.PioIn: case AtaProtocol.UDmaIn: @@ -174,7 +174,7 @@ namespace DiscImageChef.Devices.Windows break; } - switch(protocol) + switch (protocol) { case AtaProtocol.Dma: case AtaProtocol.DmaQueued: @@ -188,30 +188,30 @@ namespace DiscImageChef.Devices.Windows // Unknown if needed aptdBuf.aptd.AtaFlags |= AtaFlags.DrdyRequired; - uint k = 0; - int error = 0; + uint k = 0; + var error = 0; Array.Copy(buffer, 0, aptdBuf.dataBuffer, 0, buffer.Length); - DateTime start = DateTime.Now; + var start = DateTime.Now; sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IoctlAtaPassThrough, ref aptdBuf, - (uint)Marshal.SizeOf(aptdBuf), ref aptdBuf, - (uint)Marshal.SizeOf(aptdBuf), ref k, IntPtr.Zero); - DateTime end = DateTime.Now; + (uint) Marshal.SizeOf(aptdBuf), ref aptdBuf, + (uint) Marshal.SizeOf(aptdBuf), ref k, IntPtr.Zero); + var end = DateTime.Now; - if(sense) error = Marshal.GetLastWin32Error(); + if (sense) error = Marshal.GetLastWin32Error(); Array.Copy(aptdBuf.dataBuffer, 0, buffer, 0, buffer.Length); duration = (end - start).TotalMilliseconds; errorRegisters.CylinderHigh = aptdBuf.aptd.CurrentTaskFile.CylinderHigh; - errorRegisters.CylinderLow = aptdBuf.aptd.CurrentTaskFile.CylinderLow; - errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead; - errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error; - errorRegisters.Sector = aptdBuf.aptd.CurrentTaskFile.SectorNumber; - errorRegisters.SectorCount = aptdBuf.aptd.CurrentTaskFile.SectorCount; - errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status; + errorRegisters.CylinderLow = aptdBuf.aptd.CurrentTaskFile.CylinderLow; + errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead; + errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error; + errorRegisters.Sector = aptdBuf.aptd.CurrentTaskFile.SectorNumber; + errorRegisters.SectorCount = aptdBuf.aptd.CurrentTaskFile.SectorCount; + errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status; sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0; @@ -230,43 +230,43 @@ namespace DiscImageChef.Devices.Windows /// Registers to send to drive /// Registers returned by drive /// ATA protocol to use - internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLba28 registers, - out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, - ref byte[] buffer, uint timeout, - out double duration, out bool sense) + internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLba28 registers, + out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol, + ref byte[] buffer, uint timeout, + out double duration, out bool sense) { - duration = 0; - sense = false; + duration = 0; + sense = false; errorRegisters = new AtaErrorRegistersLba28(); - if(buffer == null) return -1; + if (buffer == null) return -1; - uint offsetForBuffer = (uint)(Marshal.SizeOf(typeof(AtaPassThroughDirect)) + Marshal.SizeOf(typeof(uint))); + var offsetForBuffer = (uint) (Marshal.SizeOf(typeof(AtaPassThroughEx)) + Marshal.SizeOf(typeof(uint))); - AtaPassThroughDirectWithBuffer aptdBuf = new AtaPassThroughDirectWithBuffer + var aptdBuf = new AtaPassThroughExBuffer { - aptd = new AtaPassThroughDirect + aptd = new AtaPassThroughEx { - TimeOutValue = timeout, - DataBuffer = (IntPtr)offsetForBuffer, - Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)), - DataTransferLength = (uint)buffer.Length, - PreviousTaskFile = new AtaTaskFile(), + TimeOutValue = timeout, + DataBufferOffset = (IntPtr) offsetForBuffer, + Length = (ushort) Marshal.SizeOf(typeof(AtaPassThroughEx)), + DataTransferLength = (uint) buffer.Length, + PreviousTaskFile = new AtaTaskFile(), CurrentTaskFile = new AtaTaskFile { - Command = registers.Command, + Command = registers.Command, CylinderHigh = registers.LbaHigh, - CylinderLow = registers.LbaMid, - DeviceHead = registers.DeviceHead, - Features = registers.Feature, - SectorCount = registers.SectorCount, + CylinderLow = registers.LbaMid, + DeviceHead = registers.DeviceHead, + Features = registers.Feature, + SectorCount = registers.SectorCount, SectorNumber = registers.LbaLow } }, dataBuffer = new byte[64 * 512] }; - switch(protocol) + switch (protocol) { case AtaProtocol.PioIn: case AtaProtocol.UDmaIn: @@ -279,7 +279,7 @@ namespace DiscImageChef.Devices.Windows break; } - switch(protocol) + switch (protocol) { case AtaProtocol.Dma: case AtaProtocol.DmaQueued: @@ -293,30 +293,30 @@ namespace DiscImageChef.Devices.Windows // Unknown if needed aptdBuf.aptd.AtaFlags |= AtaFlags.DrdyRequired; - uint k = 0; - int error = 0; + uint k = 0; + var error = 0; Array.Copy(buffer, 0, aptdBuf.dataBuffer, 0, buffer.Length); - DateTime start = DateTime.Now; + var start = DateTime.Now; sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IoctlAtaPassThrough, ref aptdBuf, - (uint)Marshal.SizeOf(aptdBuf), ref aptdBuf, - (uint)Marshal.SizeOf(aptdBuf), ref k, IntPtr.Zero); - DateTime end = DateTime.Now; + (uint) Marshal.SizeOf(aptdBuf), ref aptdBuf, + (uint) Marshal.SizeOf(aptdBuf), ref k, IntPtr.Zero); + var end = DateTime.Now; - if(sense) error = Marshal.GetLastWin32Error(); + if (sense) error = Marshal.GetLastWin32Error(); Array.Copy(aptdBuf.dataBuffer, 0, buffer, 0, buffer.Length); duration = (end - start).TotalMilliseconds; - errorRegisters.LbaHigh = aptdBuf.aptd.CurrentTaskFile.CylinderHigh; - errorRegisters.LbaMid = aptdBuf.aptd.CurrentTaskFile.CylinderLow; - errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead; - errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error; - errorRegisters.LbaLow = aptdBuf.aptd.CurrentTaskFile.SectorNumber; + errorRegisters.LbaHigh = aptdBuf.aptd.CurrentTaskFile.CylinderHigh; + errorRegisters.LbaMid = aptdBuf.aptd.CurrentTaskFile.CylinderLow; + errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead; + errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error; + errorRegisters.LbaLow = aptdBuf.aptd.CurrentTaskFile.SectorNumber; errorRegisters.SectorCount = aptdBuf.aptd.CurrentTaskFile.SectorCount; - errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status; + errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status; sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0; @@ -335,51 +335,51 @@ namespace DiscImageChef.Devices.Windows /// Registers to send to drive /// Registers returned by drive /// ATA protocol to use - internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLba48 registers, - out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, - ref byte[] buffer, uint timeout, - out double duration, out bool sense) + internal static int SendAtaCommand(SafeFileHandle fd, AtaRegistersLba48 registers, + out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol, + ref byte[] buffer, uint timeout, + out double duration, out bool sense) { - duration = 0; - sense = false; + duration = 0; + sense = false; errorRegisters = new AtaErrorRegistersLba48(); - if(buffer == null) return -1; + if (buffer == null) return -1; - uint offsetForBuffer = (uint)(Marshal.SizeOf(typeof(AtaPassThroughDirect)) + Marshal.SizeOf(typeof(uint))); + var offsetForBuffer = (uint) (Marshal.SizeOf(typeof(AtaPassThroughEx)) + Marshal.SizeOf(typeof(uint))); - AtaPassThroughDirectWithBuffer aptdBuf = new AtaPassThroughDirectWithBuffer + var aptdBuf = new AtaPassThroughExBuffer { - aptd = new AtaPassThroughDirect + aptd = new AtaPassThroughEx { - TimeOutValue = timeout, - DataBuffer = (IntPtr)offsetForBuffer, - Length = (ushort)Marshal.SizeOf(typeof(AtaPassThroughDirect)), - DataTransferLength = (uint)buffer.Length, + TimeOutValue = timeout, + DataBufferOffset = (IntPtr) offsetForBuffer, + Length = (ushort) Marshal.SizeOf(typeof(AtaPassThroughEx)), + DataTransferLength = (uint) buffer.Length, PreviousTaskFile = new AtaTaskFile { - CylinderHigh = (byte)((registers.LbaHigh & 0xFF00) >> 8), - CylinderLow = (byte)((registers.LbaMid & 0xFF00) >> 8), - Features = (byte)((registers.Feature & 0xFF00) >> 8), - SectorCount = (byte)((registers.SectorCount & 0xFF00) >> 8), - SectorNumber = (byte)((registers.LbaLow & 0xFF00) >> 8) + CylinderHigh = (byte) ((registers.LbaHigh & 0xFF00) >> 8), + CylinderLow = (byte) ((registers.LbaMid & 0xFF00) >> 8), + Features = (byte) ((registers.Feature & 0xFF00) >> 8), + SectorCount = (byte) ((registers.SectorCount & 0xFF00) >> 8), + SectorNumber = (byte) ((registers.LbaLow & 0xFF00) >> 8) }, CurrentTaskFile = new AtaTaskFile { - Command = registers.Command, - CylinderHigh = (byte)(registers.LbaHigh & 0xFF), - CylinderLow = (byte)(registers.LbaMid & 0xFF), - DeviceHead = registers.DeviceHead, - Features = (byte)(registers.Feature & 0xFF), - SectorCount = (byte)(registers.SectorCount & 0xFF), - SectorNumber = (byte)(registers.LbaLow & 0xFF) + Command = registers.Command, + CylinderHigh = (byte) (registers.LbaHigh & 0xFF), + CylinderLow = (byte) (registers.LbaMid & 0xFF), + DeviceHead = registers.DeviceHead, + Features = (byte) (registers.Feature & 0xFF), + SectorCount = (byte) (registers.SectorCount & 0xFF), + SectorNumber = (byte) (registers.LbaLow & 0xFF) } }, dataBuffer = new byte[64 * 512] }; - switch(protocol) + switch (protocol) { case AtaProtocol.PioIn: case AtaProtocol.UDmaIn: @@ -392,7 +392,7 @@ namespace DiscImageChef.Devices.Windows break; } - switch(protocol) + switch (protocol) { case AtaProtocol.Dma: case AtaProtocol.DmaQueued: @@ -403,37 +403,39 @@ namespace DiscImageChef.Devices.Windows break; } + aptdBuf.aptd.AtaFlags |= AtaFlags.ExtendedCommand; + // Unknown if needed aptdBuf.aptd.AtaFlags |= AtaFlags.DrdyRequired; - uint k = 0; - int error = 0; + uint k = 0; + var error = 0; Array.Copy(buffer, 0, aptdBuf.dataBuffer, 0, buffer.Length); - DateTime start = DateTime.Now; + var start = DateTime.Now; sense = !Extern.DeviceIoControlAta(fd, WindowsIoctl.IoctlAtaPassThrough, ref aptdBuf, - (uint)Marshal.SizeOf(aptdBuf), ref aptdBuf, - (uint)Marshal.SizeOf(aptdBuf), ref k, IntPtr.Zero); - DateTime end = DateTime.Now; + (uint) Marshal.SizeOf(aptdBuf), ref aptdBuf, + (uint) Marshal.SizeOf(aptdBuf), ref k, IntPtr.Zero); + var end = DateTime.Now; - if(sense) error = Marshal.GetLastWin32Error(); + if (sense) error = Marshal.GetLastWin32Error(); Array.Copy(aptdBuf.dataBuffer, 0, buffer, 0, buffer.Length); duration = (end - start).TotalMilliseconds; - errorRegisters.SectorCount = (ushort)((aptdBuf.aptd.PreviousTaskFile.SectorCount << 8) + - aptdBuf.aptd.CurrentTaskFile.SectorCount); - errorRegisters.LbaLow = (ushort)((aptdBuf.aptd.PreviousTaskFile.SectorNumber << 8) + - aptdBuf.aptd.CurrentTaskFile.SectorNumber); - errorRegisters.LbaMid = (ushort)((aptdBuf.aptd.PreviousTaskFile.CylinderLow << 8) + - aptdBuf.aptd.CurrentTaskFile.CylinderLow); - errorRegisters.LbaHigh = (ushort)((aptdBuf.aptd.PreviousTaskFile.CylinderHigh << 8) + - aptdBuf.aptd.CurrentTaskFile.CylinderHigh); + errorRegisters.SectorCount = (ushort) ((aptdBuf.aptd.PreviousTaskFile.SectorCount << 8) + + aptdBuf.aptd.CurrentTaskFile.SectorCount); + errorRegisters.LbaLow = (ushort) ((aptdBuf.aptd.PreviousTaskFile.SectorNumber << 8) + + aptdBuf.aptd.CurrentTaskFile.SectorNumber); + errorRegisters.LbaMid = (ushort) ((aptdBuf.aptd.PreviousTaskFile.CylinderLow << 8) + + aptdBuf.aptd.CurrentTaskFile.CylinderLow); + errorRegisters.LbaHigh = (ushort) ((aptdBuf.aptd.PreviousTaskFile.CylinderHigh << 8) + + aptdBuf.aptd.CurrentTaskFile.CylinderHigh); errorRegisters.DeviceHead = aptdBuf.aptd.CurrentTaskFile.DeviceHead; - errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error; - errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status; + errorRegisters.Error = aptdBuf.aptd.CurrentTaskFile.Error; + errorRegisters.Status = aptdBuf.aptd.CurrentTaskFile.Status; sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0; @@ -445,15 +447,15 @@ namespace DiscImageChef.Devices.Windows /// /// Device handle /// Device number - static uint GetDeviceNumber(SafeFileHandle deviceHandle) + private static uint GetDeviceNumber(SafeFileHandle deviceHandle) { - StorageDeviceNumber sdn = new StorageDeviceNumber {deviceNumber = -1}; - uint k = 0; - if(!Extern.DeviceIoControlGetDeviceNumber(deviceHandle, WindowsIoctl.IoctlStorageGetDeviceNumber, - IntPtr.Zero, 0, ref sdn, (uint)Marshal.SizeOf(sdn), ref k, - IntPtr.Zero)) return uint.MaxValue; + var sdn = new StorageDeviceNumber {deviceNumber = -1}; + uint k = 0; + if (!Extern.DeviceIoControlGetDeviceNumber(deviceHandle, WindowsIoctl.IoctlStorageGetDeviceNumber, + IntPtr.Zero, 0, ref sdn, (uint) Marshal.SizeOf(sdn), ref k, + IntPtr.Zero)) return uint.MaxValue; - return (uint)sdn.deviceNumber; + return (uint) sdn.deviceNumber; } /// @@ -463,11 +465,12 @@ namespace DiscImageChef.Devices.Windows /// true if SDHCI, false otherwise internal static bool IsSdhci(SafeFileHandle fd) { - SffdiskQueryDeviceProtocolData queryData1 = new SffdiskQueryDeviceProtocolData(); - queryData1.size = (ushort)Marshal.SizeOf(queryData1); + var queryData1 = new SffdiskQueryDeviceProtocolData(); + queryData1.size = (ushort) Marshal.SizeOf(queryData1); Extern.DeviceIoControl(fd, WindowsIoctl.IoctlSffdiskQueryDeviceProtocol, IntPtr.Zero, 0, ref queryData1, - queryData1.size, out _, IntPtr.Zero); - return queryData1.protocolGuid.Equals(Consts.GuidSffProtocolSd); + queryData1.size, out _, IntPtr.Zero); + return queryData1.protocolGuid.Equals(Consts.GuidSffProtocolSd) || + queryData1.protocolGuid.Equals(Consts.GuidSffProtocolMmc); } /// @@ -488,57 +491,60 @@ namespace DiscImageChef.Devices.Windows /// Response registers /// Size of block in bytes internal static int SendMmcCommand(SafeFileHandle fd, MmcCommands command, bool write, - bool isApplication, - MmcFlags flags, uint argument, uint blockSize, - uint blocks, - ref byte[] buffer, out uint[] response, out double duration, - out bool sense, - uint timeout = 0) + bool isApplication, + MmcFlags flags, uint argument, uint blockSize, + uint blocks, + ref byte[] buffer, out uint[] response, out double duration, + out bool sense, + uint timeout = 0) { - SffdiskDeviceCommandData commandData = new SffdiskDeviceCommandData(); - SdCmdDescriptor commandDescriptor = new SdCmdDescriptor(); - commandData.size = (ushort)Marshal.SizeOf(commandData); - commandData.command = SffdiskDcmd.DeviceCommand; - commandData.protocolArgumentSize = (ushort)Marshal.SizeOf(commandDescriptor); - commandData.deviceDataBufferSize = blockSize * blocks; - commandDescriptor.commandCode = (byte)command; - commandDescriptor.cmdClass = isApplication ? SdCommandClass.AppCmd : SdCommandClass.Standard; + var commandData = new SffdiskDeviceCommandData(); + var commandDescriptor = new SdCmdDescriptor(); + commandData.size = (ushort) Marshal.SizeOf(commandData); + commandData.command = SffdiskDcmd.DeviceCommand; + commandData.protocolArgumentSize = (ushort) Marshal.SizeOf(commandDescriptor); + commandData.deviceDataBufferSize = blockSize * blocks; + commandDescriptor.commandCode = (byte) command; + commandDescriptor.cmdClass = isApplication ? SdCommandClass.AppCmd : SdCommandClass.Standard; commandDescriptor.transferDirection = write ? SdTransferDirection.Write : SdTransferDirection.Read; commandDescriptor.transferType = flags.HasFlag(MmcFlags.CommandAdtc) - ? SdTransferType.SingleBlock - : SdTransferType.CmdOnly; + ? SdTransferType.SingleBlock + : SdTransferType.CmdOnly; commandDescriptor.responseType = 0; - if(flags.HasFlag(MmcFlags.ResponseR1) || flags.HasFlag(MmcFlags.ResponseSpiR1)) + if (flags.HasFlag(MmcFlags.ResponseR1) || flags.HasFlag(MmcFlags.ResponseSpiR1)) commandDescriptor.responseType = SdResponseType.R1; - if(flags.HasFlag(MmcFlags.ResponseR1B) || flags.HasFlag(MmcFlags.ResponseSpiR1B)) + if (flags.HasFlag(MmcFlags.ResponseR1B) || flags.HasFlag(MmcFlags.ResponseSpiR1B)) commandDescriptor.responseType = SdResponseType.R1b; - if(flags.HasFlag(MmcFlags.ResponseR2) || flags.HasFlag(MmcFlags.ResponseSpiR2)) + if (flags.HasFlag(MmcFlags.ResponseR2) || flags.HasFlag(MmcFlags.ResponseSpiR2)) commandDescriptor.responseType = SdResponseType.R2; - if(flags.HasFlag(MmcFlags.ResponseR3) || flags.HasFlag(MmcFlags.ResponseSpiR3)) + if (flags.HasFlag(MmcFlags.ResponseR3) || flags.HasFlag(MmcFlags.ResponseSpiR3)) commandDescriptor.responseType = SdResponseType.R3; - if(flags.HasFlag(MmcFlags.ResponseR4) || flags.HasFlag(MmcFlags.ResponseSpiR4)) + if (flags.HasFlag(MmcFlags.ResponseR4) || flags.HasFlag(MmcFlags.ResponseSpiR4)) commandDescriptor.responseType = SdResponseType.R4; - if(flags.HasFlag(MmcFlags.ResponseR5) || flags.HasFlag(MmcFlags.ResponseSpiR5)) + if (flags.HasFlag(MmcFlags.ResponseR5) || flags.HasFlag(MmcFlags.ResponseSpiR5)) commandDescriptor.responseType = SdResponseType.R5; - if(flags.HasFlag(MmcFlags.ResponseR6)) commandDescriptor.responseType = SdResponseType.R6; + if (flags.HasFlag(MmcFlags.ResponseR6)) commandDescriptor.responseType = SdResponseType.R6; - byte[] commandB = new byte[commandData.size + commandData.protocolArgumentSize + - commandData.deviceDataBufferSize]; - IntPtr hBuf = Marshal.AllocHGlobal(commandB.Length); + var commandB = new byte[commandData.size + commandData.protocolArgumentSize + + commandData.deviceDataBufferSize]; + + Array.Copy(buffer, 0, commandB, commandData.size + commandData.protocolArgumentSize, buffer.Length); + var hBuf = Marshal.AllocHGlobal(commandB.Length); Marshal.StructureToPtr(commandData, hBuf, true); - IntPtr descriptorOffset = IntPtr.Add(hBuf, commandData.size); + var descriptorOffset = IntPtr.Add(hBuf, commandData.size); Marshal.StructureToPtr(commandDescriptor, descriptorOffset, true); Marshal.Copy(hBuf, commandB, 0, commandB.Length); Marshal.FreeHGlobal(hBuf); - int error = 0; - DateTime start = DateTime.Now; - sense = !Extern.DeviceIoControl(fd, WindowsIoctl.IoctlSffdiskDeviceCommand, commandB, (uint)commandB.Length, - commandB, (uint)commandB.Length, out _, IntPtr.Zero); - DateTime end = DateTime.Now; + var error = 0; + var start = DateTime.Now; + sense = !Extern.DeviceIoControl(fd, WindowsIoctl.IoctlSffdiskDeviceCommand, commandB, + (uint) commandB.Length, + commandB, (uint) commandB.Length, out _, IntPtr.Zero); + var end = DateTime.Now; - if(sense) error = Marshal.GetLastWin32Error(); + if (sense) error = Marshal.GetLastWin32Error(); buffer = new byte[blockSize * blocks]; Buffer.BlockCopy(commandB, commandB.Length - buffer.Length, buffer, 0, buffer.Length);