From 7fa4c3fbebbf58926096c8141d0d33bd61e7d5c9 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Wed, 7 Oct 2015 02:15:31 +0100 Subject: [PATCH] Added ATA IOCTLs. --- DiscImageChef.Devices/ChangeLog | 10 ++++++ DiscImageChef.Devices/Linux/Enums.cs | 6 ++++ DiscImageChef.Devices/Linux/Extern.cs | 6 ++++ DiscImageChef.Devices/Linux/Structs.cs | 34 ++++++++++++++++++++ DiscImageChef.Devices/Windows/Enums.cs | 32 +++++++++++++++++- DiscImageChef.Devices/Windows/Extern.cs | 16 +++++++-- DiscImageChef.Devices/Windows/Structs.cs | 41 ++++++++++++++++++++++-- 7 files changed, 140 insertions(+), 5 deletions(-) diff --git a/DiscImageChef.Devices/ChangeLog b/DiscImageChef.Devices/ChangeLog index bbd27297..a96cfbb2 100644 --- a/DiscImageChef.Devices/ChangeLog +++ b/DiscImageChef.Devices/ChangeLog @@ -1,3 +1,13 @@ +2015-10-07 Natalia Portillo + + * Linux/Enums.cs: + * Linux/Extern.cs: + * Linux/Structs.cs: + * Windows/Enums.cs: + * Windows/Extern.cs: + * Windows/Structs.cs: + Added ATA IOCTLs. + 2015-10-06 Natalia Portillo * Linux/Enums.cs: diff --git a/DiscImageChef.Devices/Linux/Enums.cs b/DiscImageChef.Devices/Linux/Enums.cs index 31b7f895..1bf0a2cf 100644 --- a/DiscImageChef.Devices/Linux/Enums.cs +++ b/DiscImageChef.Devices/Linux/Enums.cs @@ -109,10 +109,16 @@ namespace DiscImageChef.Devices.Linux enum LinuxIoctl : ulong { + // SCSI IOCtls SG_EMULATED_HOST = 0x2203, SG_GET_VERSION_NUM = 0x2282, SG_IO = 0x2285, SG_GET_SCSI_ID = 0x2276, + + // ATA IOCtls + HDIO_DRIVE_CMD = 0x031F, + HDIO_DRIVE_TASK = 0x031E, + HDIO_DRIVE_TASKFILE = 0x031D } [Flags] diff --git a/DiscImageChef.Devices/Linux/Extern.cs b/DiscImageChef.Devices/Linux/Extern.cs index 19f21f6e..aef712ac 100644 --- a/DiscImageChef.Devices/Linux/Extern.cs +++ b/DiscImageChef.Devices/Linux/Extern.cs @@ -18,6 +18,12 @@ namespace DiscImageChef.Devices.Linux [DllImport("libc", EntryPoint="ioctl", SetLastError = true)] internal static extern int ioctlSg(int fd, ulong request, ref sg_io_hdr_t value); + + [DllImport("libc", EntryPoint="ioctl", SetLastError = true)] + internal static extern int ioctlHdTaskfile(int fd, ulong request, ref hd_drive_task_hdr value); + + [DllImport("libc", EntryPoint="ioctl", SetLastError = true)] + internal static extern int ioctlHdTask(int fd, ulong request, ref byte[] value); } } diff --git a/DiscImageChef.Devices/Linux/Structs.cs b/DiscImageChef.Devices/Linux/Structs.cs index bc9d223a..27083b99 100644 --- a/DiscImageChef.Devices/Linux/Structs.cs +++ b/DiscImageChef.Devices/Linux/Structs.cs @@ -32,5 +32,39 @@ namespace DiscImageChef.Devices.Linux public uint duration; /* [o] */ public SgInfo info; /* [o] */ } + + [StructLayout(LayoutKind.Sequential)] + struct hd_drive_task_hdr + { + public byte data; + public byte feature; + public byte sector_count; + public byte sector_number; + public byte low_cylinder; + public byte high_cylinder; + public byte device_head; + public byte command; + } + + [StructLayout(LayoutKind.Sequential)] + struct hd_drive_task_array + { + public byte command; + public byte features; + public byte sector_count; + public byte sector_number; + public byte low_cylinder; + public byte high_cylinder; + public byte device_head; + } + + [StructLayout(LayoutKind.Sequential)] + struct hd_drive_cmd + { + public byte command; + public byte sector; + public byte feature; + public byte nsector; + } } diff --git a/DiscImageChef.Devices/Windows/Enums.cs b/DiscImageChef.Devices/Windows/Enums.cs index 00e1f09f..a99b6a19 100644 --- a/DiscImageChef.Devices/Windows/Enums.cs +++ b/DiscImageChef.Devices/Windows/Enums.cs @@ -223,6 +223,8 @@ namespace DiscImageChef.Devices.Windows enum WindowsIoctl : uint { + IOCTL_ATA_PASS_THROUGH = 0x4D02C, + IOCTL_ATA_PASS_THROUGH_DIRECT = 0x4D030, /// /// ScsiPassThrough /// @@ -236,5 +238,33 @@ namespace DiscImageChef.Devices.Windows /// IOCTL_SCSI_GET_ADDRESS = 0x41018 } -} + [Flags] + enum AtaFlags : ushort + { + /// + /// ATA_FLAGS_DRDY_REQUIRED + /// + DrdyRequired = 0x01, + /// + /// ATA_FLAGS_DATA_IN + /// + DataIn = 0x02, + /// + /// ATA_FLAGS_DATA_OUT + /// + DataOut = 0x04, + /// + /// ATA_FLAGS_48BIT_COMMAND + /// + ExtendedCommand = 0x08, + /// + /// ATA_FLAGS_USE_DMA + /// + DMA = 0x10, + /// + /// ATA_FLAGS_NO_MULTIPLE + /// + NoMultiple = 0x20 + } +} diff --git a/DiscImageChef.Devices/Windows/Extern.cs b/DiscImageChef.Devices/Windows/Extern.cs index ed17d07f..e736b78a 100644 --- a/DiscImageChef.Devices/Windows/Extern.cs +++ b/DiscImageChef.Devices/Windows/Extern.cs @@ -16,8 +16,8 @@ namespace DiscImageChef.Devices.Windows [MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes, IntPtr templateFile); - [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] - public static extern bool DeviceIoControl( + [DllImport("Kernel32.dll", SetLastError = true, EntryPoint="ioctl", CharSet = CharSet.Auto)] + public static extern bool DeviceIoControlScsi( SafeFileHandle hDevice, uint IoControlCode, ref ScsiPassThroughDirectAndSenseBuffer InBuffer, @@ -28,6 +28,18 @@ namespace DiscImageChef.Devices.Windows IntPtr Overlapped ); + [DllImport("Kernel32.dll", SetLastError = true, EntryPoint="ioctl", CharSet = CharSet.Auto)] + public static extern bool DeviceIoControlAta( + SafeFileHandle hDevice, + uint IoControlCode, + ref AtaPassThroughDirect InBuffer, + uint nInBufferSize, + ref AtaPassThroughDirect OutBuffer, + uint nOutBufferSize, + ref uint pBytesReturned, + IntPtr Overlapped + ); + [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool CloseHandle(SafeFileHandle hDevice); } diff --git a/DiscImageChef.Devices/Windows/Structs.cs b/DiscImageChef.Devices/Windows/Structs.cs index 4db116f3..11ba5734 100644 --- a/DiscImageChef.Devices/Windows/Structs.cs +++ b/DiscImageChef.Devices/Windows/Structs.cs @@ -20,14 +20,51 @@ namespace DiscImageChef.Devices.Windows public IntPtr DataBuffer; public uint SenseInfoOffset; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - public byte[] Cdb; + public byte[] Cdb; }; [StructLayout(LayoutKind.Sequential)] - struct ScsiPassThroughDirectAndSenseBuffer { + struct ScsiPassThroughDirectAndSenseBuffer + { public ScsiPassThroughDirect sptd; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] SenseBuf; } + + struct AtaPassThroughDirect + { + public ushort Length; + public AtaFlags AtaFlags; + public byte PathId; + public byte TargetId; + public byte Lun; + public byte ReservedAsUchar; + public uint DataTransferLength; + public uint TimeOutValue; + public uint ReservedAsUlong; + public IntPtr DataBuffer; + public AtaTaskFile PreviousTaskFile; + public AtaTaskFile CurrentTaskFile; + } + + [StructLayout(LayoutKind.Explicit)] + struct AtaTaskFile + { + // Fields for commands sent + [FieldOffset(0)] public byte Features; + [FieldOffset(6)] public byte Command; + + // Fields on command return + [FieldOffset(0)] public byte Error; + [FieldOffset(6)] public byte Status; + + // Common fields + [FieldOffset(1)] public byte SectorCount; + [FieldOffset(2)] public byte SectorNumber; + [FieldOffset(3)] public byte CylinderLow; + [FieldOffset(4)] public byte CylinderHigh; + [FieldOffset(5)] public byte DeviceHead; + [FieldOffset(7)] public byte Reserved; + } }