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); } }
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); }