예제 #1
0
 internal static extern bool DeviceIoControlIde(SafeFileHandle hDevice,
                                                WindowsIoctl ioControlCode,
                                                ref IdePassThroughDirect inBuffer,
                                                uint nInBufferSize,
                                                ref IdePassThroughDirect outBuffer,
                                                uint nOutBufferSize,
                                                ref uint pBytesReturned,
                                                IntPtr overlapped);
예제 #2
0
        /// <summary>
        ///     Sends an ATA command in 28-bit LBA mode using undocumented Windows XP ioctl
        /// </summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <param name="fd">File handle</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>
        internal static int SendIdeCommand(SafeFileHandle fd, 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);
            }

            IdePassThroughDirect iptd = new IdePassThroughDirect
            {
                CurrentTaskFile = new AtaTaskFile
                {
                    Command      = registers.Command,
                    CylinderHigh = registers.LbaHigh,
                    CylinderLow  = registers.LbaMid,
                    DeviceHead   = registers.DeviceHead,
                    Features     = registers.Feature,
                    SectorCount  = registers.SectorCount,
                    SectorNumber = registers.LbaLow
                },
                DataBufferSize = 512,
                DataBuffer     = new byte[512]
            };

            uint k     = 0;
            int  error = 0;

            Array.Copy(buffer, 0, iptd.DataBuffer, 0, buffer.Length);

            DateTime start = DateTime.Now;

            sense = !Extern.DeviceIoControlIde(fd, WindowsIoctl.IoctlIdePassThrough, ref iptd,
                                               (uint)Marshal.SizeOf(iptd), ref iptd, (uint)Marshal.SizeOf(iptd), ref k,
                                               IntPtr.Zero);
            DateTime end = DateTime.Now;

            if (sense)
            {
                error = Marshal.GetLastWin32Error();
            }

            buffer = new byte[k - 12];
            Array.Copy(iptd.DataBuffer, 0, buffer, 0, buffer.Length);

            duration = (end - start).TotalMilliseconds;

            errorRegisters.LbaHigh     = iptd.CurrentTaskFile.CylinderHigh;
            errorRegisters.LbaMid      = iptd.CurrentTaskFile.CylinderLow;
            errorRegisters.DeviceHead  = iptd.CurrentTaskFile.DeviceHead;
            errorRegisters.Error       = iptd.CurrentTaskFile.Error;
            errorRegisters.LbaLow      = iptd.CurrentTaskFile.SectorNumber;
            errorRegisters.SectorCount = iptd.CurrentTaskFile.SectorCount;
            errorRegisters.Status      = iptd.CurrentTaskFile.Status;

            sense = errorRegisters.Error != 0 || (errorRegisters.Status & 0xA5) != 0;

            return(error);
        }