public bool GetSMARTBuffer(IntPtr handle, ref byte[] buffer)
        {
            IntPtr result = IntPtr.Zero;
            IntPtr buff1  = IntPtr.Zero;

            ATA_PASS_THROUGH_DIRECT input = new ATA_PASS_THROUGH_DIRECT();

            input.Length       = (UInt16)Marshal.SizeOf(input);
            input.AtaFlags     = ATA_FLAGS_DATA_IN;
            input.TimeOutValue = 2;

            TaskFile currentTaskFile = new TaskFile();
            TaskFile preTaskFile     = new TaskFile();

            currentTaskFile.Devic_Register         = 0xA0;
            currentTaskFile.Feature                = 0xD0;
            currentTaskFile.Command                = 0xB0;
            currentTaskFile.Cylinder_Low_Register  = 0x4F;
            currentTaskFile.Cylinder_High_Register = 0xC2;

            return(ATACommand(handle, ref currentTaskFile, ref preTaskFile, 512, ref buffer, true, false, false, false));
        }
        private bool ATACommand(IntPtr handle, ref TaskFile currentTaskFile, ref TaskFile preTaskFile, int dataTransferSzie, ref byte[] buffer, bool isRead, bool isDMA, bool isExCmd, bool isnodata)
        {
            //If parameter isRead is true, the command is a read command.
            //Otherwise it's a write command.
            ATA_PASS_THROUGH_DIRECT input;
            bool   status;
            Int32  nBytesReturned;
            IntPtr result = IntPtr.Zero;
            IntPtr buff1  = IntPtr.Zero;
            int    errorMessage;

            input        = new ATA_PASS_THROUGH_DIRECT();
            input.Length = (UInt16)Marshal.SizeOf(input);
            if (!isRead)
            {
                input.AtaFlags = ATA_FLAGS_DATA_OUT;    //For write command
            }
            else
            {
                input.AtaFlags = ATA_FLAGS_DATA_IN;     //For read command
            }
            if (isnodata)
            {
                input.AtaFlags = ATA_FLAGS_DRDY_REQUIRED;     //For no data
            }

            if (isDMA)
            {
                input.AtaFlags |= ATA_FLAGS_USE_DMA;    //For direct memory access
            }
            if (isExCmd)
            {
                input.AtaFlags |= ATA_FLAGS_48BIT_COMMAND;  //For 48 bit command
            }
            input.TimeOutValue       = 60;
            input.DataTransferLength = (uint)(dataTransferSzie);    //The buffer size that you want to read or write

            input.CurrentTaskFile  = currentTaskFile;
            input.PreviousTaskFile = preTaskFile;

            buff1 = Marshal.AllocHGlobal((int)(dataTransferSzie));
            Marshal.Copy(buffer, 0, buff1, (int)(dataTransferSzie));
            input.offset = buff1;
            result       = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ATA_PASS_THROUGH_DIRECT)));
            Marshal.StructureToPtr(input, result, false);


            status = DeviceIoControl(handle,
                                     IOCTL_ATA_PASS_THROUGH_DIRECT,
                                     result,
                                     Marshal.SizeOf(input),
                                     result,
                                     Marshal.SizeOf(input),
                                     out nBytesReturned,
                                     IntPtr.Zero);

            if (status == false)
            {
                errorMessage = Marshal.GetLastWin32Error();
            }

            input           = (ATA_PASS_THROUGH_DIRECT)Marshal.PtrToStructure(result, typeof(ATA_PASS_THROUGH_DIRECT));
            currentTaskFile = input.CurrentTaskFile;
            preTaskFile     = input.PreviousTaskFile;

            Marshal.Copy(buff1, buffer, 0, dataTransferSzie);

            Marshal.FreeHGlobal(buff1);
            Marshal.FreeHGlobal(result);

            if (status == false)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Beispiel #3
0
        public static bool ReadPhysicalDriveInNtUsingSmart2(int drive)
        {
            using (var hDisk = OpenDisk(drive))
            {
                ATA_PASS_THROUGH_EX apex = new ATA_PASS_THROUGH_EX();
                apex.Length             = (ushort)Marshal.SizeOf(apex);
                apex.AtaFlags           = AtaFlags.ReceiveData;                     // 2 ATA_FLAGS_DATA_IN
                apex.DataTransferLength = 512;                                      // The command returns a 512 byte package of info.
                apex.TimeOutValue       = 10;                                       // 10 second timeout.

                apex.DataBufferOffset = Marshal.OffsetOf(typeof(ATA_PASS_THROUGH_EX_WITH_BUFFER), "Data");
                apex.CurrentTaskFile  = new ATA_TASK_FILE();                          // This contains the command we are requesting.
                apex.CurrentTaskFile  = new ATA_TASK_FILE(AtaCommand.IdentifyDevice); // &HEC <-- the command "IDENTIFY DEVICE"
                                                                                      //uint inBufferSize = (uint)Marshal.SizeOf(typeof(ATA_PASS_THROUGH_EX)) + apex.DataTransferLength;

                var apexb = new ATA_PASS_THROUGH_EX_WITH_BUFFER {
                    Apt = apex
                };
                uint inBufferSize = (uint)Marshal.SizeOf(typeof(ATA_PASS_THROUGH_EX_WITH_BUFFER));

                //var sciPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SENDCMDINPARAMS)));

                var apexHandle = Marshal.AllocHGlobal((int)inBufferSize);
                Marshal.StructureToPtr(apexb, apexHandle, true);

                uint bytesReturned = 0;
                var  result        = DeviceManagement.NativeMethods.DeviceIoControl(hDisk, IdeIoControlCode.IOCTL_ATA_PASS_THROUGH, apexHandle, inBufferSize, apexHandle, inBufferSize, ref bytesReturned, IntPtr.Zero);
                var  apexValue     = (ATA_PASS_THROUGH_EX_WITH_BUFFER)Marshal.PtrToStructure(apexHandle, typeof(ATA_PASS_THROUGH_EX_WITH_BUFFER));
                var  sddd          = result;
                var  i             = 0;
                i++;


                IDENTIFY_DEVICE_DATA idd = new IDENTIFY_DEVICE_DATA();
                var iddHandle            = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IDENTIFY_DEVICE_DATA)));
                //Marshal.StructureToPtr(idd, iddHandle, true);

                ATA_PASS_THROUGH_DIRECT aptd = new ATA_PASS_THROUGH_DIRECT();
                aptd.Length             = (ushort)Marshal.SizeOf(typeof(ATA_PASS_THROUGH_DIRECT)); //(ushort)Marshal.SizeOf(aptd);
                aptd.AtaFlags           = AtaFlags.ReceiveData;                                    // 2 ATA_FLAGS_DATA_IN
                aptd.DataTransferLength = 512;                                                     // The command returns a 512 byte package of info.
                aptd.TimeOutValue       = 10;                                                      // 10 second timeout.
                aptd.CurrentTaskFile    = new ATA_TASK_FILE();                                     // This contains the command we are requesting.
                aptd.CurrentTaskFile    = new ATA_TASK_FILE(AtaCommand.IdentifyDevice);            // &HEC <-- the command "IDENTIFY DEVICE"
                aptd.DataBuffer         = iddHandle;


                var apedHandle = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ATA_PASS_THROUGH_DIRECT)));
                Marshal.StructureToPtr(aptd, apedHandle, true);

                uint bytesReturned2 = 0;
                var  result2        = DeviceManagement.NativeMethods.DeviceIoControl(hDisk, IdeIoControlCode.IOCTL_ATA_PASS_THROUGH_DIRECT, apedHandle, aptd.Length, apedHandle, aptd.Length, ref bytesReturned2, IntPtr.Zero);

                var jkjk      = aptd.DataBuffer;
                var apedValue = (IDENTIFY_DEVICE_DATA)Marshal.PtrToStructure(jkjk, typeof(IDENTIFY_DEVICE_DATA));
                var ddd       = apedValue.ModelNumber;

                var jhh = new byte[512];
                Marshal.Copy(aptd.DataBuffer, jhh, 0, 511);
                //var apedValue = (IDENTIFY_DEVICE_DATA)Marshal..PtrToStructure(aptd.DataBuffer, typeof(IDENTIFY_DEVICE_DATA));
                var jj = result2;
                i++;
            }

            return(true);
        }