public static string GetDeviceFromDrive(System.IO.DriveInfo driveInfo) { IntPtr pStorageDeviceNumber = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (STORAGE_DEVICE_NUMBER))); SafeFileHandle hDrive = null; try { string driveName = "\\\\.\\" + driveInfo.ToString ().Substring (0, 2); hDrive = ApiFunctions.CreateFile (driveName, AccessMask.GENERIC_READ, System.IO.FileShare.ReadWrite, 0, System.IO.FileMode.Open, 0, IntPtr.Zero); if (hDrive.IsInvalid) throw new FileLoadException ("Drive handle invalid"); bool status; int retByte; System.Threading.NativeOverlapped nativeOverlap = new System.Threading.NativeOverlapped (); status = ApiFunctions.DeviceIoControl (hDrive, DeviceIOControlCode.StorageGetDeviceNumber, IntPtr.Zero, 0, pStorageDeviceNumber, Marshal.SizeOf (typeof (STORAGE_DEVICE_NUMBER)), out retByte, ref nativeOverlap); if (!status) throw new FileLoadException ("DeviceIoControl error"); STORAGE_DEVICE_NUMBER storDevNum = (STORAGE_DEVICE_NUMBER)Marshal.PtrToStructure (pStorageDeviceNumber, typeof (STORAGE_DEVICE_NUMBER)); return "\\\\.\\PhysicalDrive" + storDevNum.DeviceNumber; } finally { Marshal.FreeHGlobal (pStorageDeviceNumber); if (hDrive != null) hDrive.Close (); } }
static internal extern bool GetOverlappedResult(IntPtr hFile, [In] ref System.Threading.NativeOverlapped lpOverlapped, out uint lpNumberOfBytesTransferred, bool bWait);
public static extern Boolean ReadFile(IntPtr hFile, [Out] Byte[] lpBuffer, Int32 nNumberOfBytesToRead, IntPtr lpNumberOfBytesRead, [In] ref System.Threading.NativeOverlapped lpOverlapped);
static extern bool ReadFileEx(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, [In] ref System.Threading.NativeOverlapped lpOverlapped, ReadFileCompletionDelegate lpCompletionRoutine);
public static extern bool SFileReadFile(MpqFileSafeHandle hFile, IntPtr lpBuffer, uint dwToRead, out uint pdwRead, ref System.Threading.NativeOverlapped lpOverlapped);
static internal extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, [In] ref System.Threading.NativeOverlapped lpOverlapped);
internal static extern int WriteFile( IntPtr hFile, byte[] lpBuffer, UInt32 bytesToWrite, out UInt32 bytesWritten, ref System.Threading.NativeOverlapped lpOverlapped);
public static extern Boolean GetOverlappedResult( IntPtr hFile, [In] ref System.Threading.NativeOverlapped lpOverlapped, out Int32 lpNumberOfBytesTransferred, Boolean bWait );
internal static extern bool ReadFileEx( IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, [In] ref System.Threading.NativeOverlapped lpOverlapped, System.Threading.IOCompletionCallback lpCompletionRoutine);
private byte[] GetWin32XML(IDevice Ipod) { IntPtr pSptwb = IntPtr.Zero; SafeFileHandle driveHandle = null; try { ScsiPassThroughWithBuffers sptwb; int returned, length; string device = GetDeviceFromDrive (((Win32.Device)Ipod).Drive); bool status; byte [] buffer = new byte [102400]; int bufferIdx = 0; byte page_code, page_start, page_end = 0; driveHandle = ApiFunctions.CreateFile (device, AccessMask.GENERIC_ALL, System.IO.FileShare.ReadWrite, 0, System.IO.FileMode.Open, 0, IntPtr.Zero); if (driveHandle.IsInvalid) throw new FileLoadException ("Device invalid"); sptwb = new ScsiPassThroughWithBuffers (); sptwb.spt.Length = (ushort)Marshal.SizeOf (typeof (SCSI_PASS_THROUGH)); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = 6; sptwb.spt.SenseInfoLength = 32; sptwb.spt.DataIn = 1; //SCSI_IOCTL_DATA_IN sptwb.spt.DataTransferLength = 255; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = Marshal.OffsetOf (typeof (ScsiPassThroughWithBuffers), "ucDataBuf"); sptwb.spt.SenseInfoOffset = Marshal.OffsetOf (typeof (ScsiPassThroughWithBuffers), "ucSenseBuf"); sptwb.spt.Cdb = new byte [16]; sptwb.spt.Cdb [0] = 0x12; //SCSI_INQUIRY sptwb.spt.Cdb [1] |= 1; sptwb.spt.Cdb [2] = 0xC0; sptwb.spt.Cdb [4] = 255; length = Marshal.OffsetOf (typeof (ScsiPassThroughWithBuffers), "ucDataBuf").ToInt32 () + (int)sptwb.spt.DataTransferLength; pSptwb = Marshal.AllocHGlobal (Marshal.SizeOf (sptwb)); Marshal.StructureToPtr (sptwb, pSptwb, true); System.Threading.NativeOverlapped nativeOverlapped = new System.Threading.NativeOverlapped (); status = ApiFunctions.DeviceIoControl (driveHandle, DeviceIOControlCode.ScsiPassThrough, pSptwb, Marshal.SizeOf (typeof (SCSI_PASS_THROUGH)), pSptwb, length, out returned, ref nativeOverlapped); if (!status) throw new FileLoadException("DeviceIoControl Error", Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error())); sptwb = (ScsiPassThroughWithBuffers)Marshal.PtrToStructure (pSptwb, typeof (ScsiPassThroughWithBuffers)); page_start = sptwb.ucDataBuf [4]; page_end = sptwb.ucDataBuf [3 + sptwb.ucDataBuf [3]]; for (page_code = page_start; page_code <= page_end; page_code++) { sptwb.spt.Length = (ushort)Marshal.SizeOf (typeof (SCSI_PASS_THROUGH)); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = 6; sptwb.spt.SenseInfoLength = 32; sptwb.spt.DataIn = 1; //SCSI_IOCTL_DATA_IN sptwb.spt.DataTransferLength = 255; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = Marshal.OffsetOf (typeof (ScsiPassThroughWithBuffers), "ucDataBuf"); sptwb.spt.SenseInfoOffset = Marshal.OffsetOf (typeof (ScsiPassThroughWithBuffers), "ucSenseBuf"); sptwb.spt.Cdb = new byte [16]; sptwb.spt.Cdb [0] = 0x12; //SCSI_INQUIRY sptwb.spt.Cdb [1] |= 1; sptwb.spt.Cdb [2] = page_code; sptwb.spt.Cdb [4] = 255; length = Marshal.OffsetOf (typeof (ScsiPassThroughWithBuffers), "ucDataBuf").ToInt32 () + (int)sptwb.spt.DataTransferLength; returned = 0; Marshal.StructureToPtr (sptwb, pSptwb, true); status = ApiFunctions.DeviceIoControl (driveHandle, DeviceIOControlCode.ScsiPassThrough, pSptwb, Marshal.SizeOf (typeof (SCSI_PASS_THROUGH)), pSptwb, length, out returned, ref nativeOverlapped); if (!status) throw new FileLoadException ("DeviceIoControl Error", Marshal.GetExceptionForHR(Marshal.GetLastWin32Error())); sptwb = (ScsiPassThroughWithBuffers)Marshal.PtrToStructure (pSptwb, typeof (ScsiPassThroughWithBuffers)); while (bufferIdx + sptwb.ucDataBuf [3] > buffer.Length) Array.Resize<byte> (ref buffer, buffer.Length * 2); Array.Copy (sptwb.ucDataBuf, 4, buffer, bufferIdx, sptwb.ucDataBuf [3]); bufferIdx += sptwb.ucDataBuf [3]; } if (bufferIdx == 0) return null; buffer [bufferIdx] = 0; Array.Resize<byte> (ref buffer, bufferIdx + 1); return buffer; } finally { if (pSptwb != IntPtr.Zero) Marshal.FreeHGlobal (pSptwb); if (driveHandle != null) driveHandle.Close (); } }
public static extern bool WriteFile( IntPtr hFile, System.Text.StringBuilder lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, [In] ref System.Threading.NativeOverlapped lpOverlapped);
public static extern bool UnlockFileEx(SafeFileHandle handle, uint reserved, uint countLow, uint countHigh, ref System.Threading.NativeOverlapped overlapped);
public static extern Boolean WriteFile(IntPtr hFile, Byte[] lpBuffer, Int32 nNumberOfBytesToWrite, IntPtr lpNumberOfBytesWritten, [In] ref System.Threading.NativeOverlapped lpOverlapped);
static extern bool ConnectNamedPipe(IntPtr hNamedPipe, [In] ref System.Threading.NativeOverlapped lpOverlapped);
public static extern bool WriteFile(SafeFileHandle hFile, // Handle to file byte[] lpBuffer, // Data buffer uint nNumberOfBytesToWrite, // Number of bytes to write out uint lpNumberOfBytesWritten, // Number of bytes written [In] ref System.Threading.NativeOverlapped lpOverlapped); // Overlapped buffer
public static bool _ConnectNamedPipe(IntPtr hNamedPipe, [In] ref System.Threading.NativeOverlapped lpOverlapped) { return(ConnectNamedPipe(hNamedPipe, ref lpOverlapped)); }
public static extern bool ReadFile(SafeFileHandle hFile, [Out] IntPtr lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, [In] ref System.Threading.NativeOverlapped lpOverlapped);
/// <summary> /// 驱动通信的IO控制器方法 /// </summary> /// <param name="hDriver">驱动句柄</param> /// <param name="nIoCode">IO控制码</param> /// <param name="InBuffer">传入缓冲区</param> /// <param name="nInBufferSize">传入缓冲区大小</param> /// <param name="OutBuffer">输出缓冲区</param> /// <param name="nOutBufferSize">输出缓冲区大小</param> /// <param name="pBytesReturned">返回字节数</param> /// <param name="Overlapped">输入输出的信息的结构体</param> /// <returns>bool</returns> public static bool IoControl(SafeFileHandle hDriver, uint nIoCode, object InBuffer, uint nInBufferSize, object OutBuffer, uint nOutBufferSize, ref uint pBytesReturned, ref System.Threading.NativeOverlapped Overlapped) { const uint FILE_ANY_ACCESS = 0; const uint METHOD_BUFFERED = 0; bool bRet; nIoCode = ((int)NativeApiEx.DEVICE_TYPE.FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (nIoCode * 4) | METHOD_BUFFERED; bRet = NativeApi.DeviceIoControl(hDriver, nIoCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, ref pBytesReturned, ref Overlapped); return(bRet); }
public static extern bool GetOverlappedResult(SafeFileHandle hFile, [In] ref System.Threading.NativeOverlapped lpOverlapped, out uint lpNumberOfBytesTransferred, [MarshalAs(UnmanagedType.Bool)] bool bWait);
internal static extern int ReadFile( IntPtr hFile, byte[] lpBuffer, UInt32 bytesToRead, out UInt32 bytesRead, ref System.Threading.NativeOverlapped lpOverlapped);
public static extern bool WaitCommEvent(SafeFileHandle hFile, [MarshalAs(UnmanagedType.U4)] out NativeMethods.SerialEventMask lpEvtMask, ref System.Threading.NativeOverlapped lpOverlapped);
internal static extern bool WriteFile( SafeFileHandle hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, [In] ref System.Threading.NativeOverlapped lpOverlapped);
public static extern bool GetOverlappedResult(IntPtr hFile, ref System.Threading.NativeOverlapped lpOverlapped, ref uint lpNumberOfBytesTransferred, bool bWait);
static internal extern bool WriteFile(IntPtr hFile, IntPtr lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, [In] ref System.Threading.NativeOverlapped lpOverlapped);
public static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, [In] byte[] lpInBuffer, uint nInBufferSize, byte[] lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, ref System.Threading.NativeOverlapped lpOverlapped);
static void Main(string[] args) { ManagementScope scope = new ManagementScope(@"\\.\root\CIMv2"); SelectQuery query = new SelectQuery("SELECT * FROM Win32_DiskDrive"); List<WritablePhysicalDevice> allDevices = new List<WritablePhysicalDevice>(); WritablePhysicalDevice myDevice = null; bool force = false; bool listOnly = false; int devNum = -1; byte[] imageBytes = null; string imageFile = string.Empty; UInt64 startingsector = UInt64.MaxValue; uint bytesWritten = 0; string helpText = HelpText.Print(); if (helpText.Length < 1) { Environment.ExitCode = (int)WinErrorCodes.ERROR_RESOURCE_NOT_PRESENT; return; } if (args.Length < 1) { Console.WriteLine(helpText); Environment.ExitCode = (int)WinErrorCodes.ERROR_BAD_ARGUMENTS; return; } foreach (string arg in args) { string formattedArg = arg.ToLower().Trim(); if (formattedArg == "force") { force = true; continue; } if (formattedArg == "list") { listOnly = true; break; } if (!formattedArg.Contains("=") || formattedArg.Split('=').Length != 2) { Console.WriteLine(helpText); Environment.ExitCode = (int)WinErrorCodes.ERROR_BAD_ARGUMENTS; return; } if (formattedArg.Split('=')[0] == "image") { imageFile = formattedArg.Split('=')[1]; if (!File.Exists(imageFile)) { Environment.ExitCode = (int)WinErrorCodes.ERROR_INVALID_NAME; Console.WriteLine("Error: The supplied image path does not exist."); return; } } else if (formattedArg.Split('=')[0] == "device") { if (!int.TryParse(formattedArg.Split('=')[1], out devNum)) { Environment.ExitCode = (int)WinErrorCodes.ERROR_BAD_ARGUMENTS; Console.WriteLine("Error: Could not validate device number argument."); return; } } else if (formattedArg.Split('=')[0] == "startingsector") { if (!UInt64.TryParse(formattedArg.Split('=')[1], out startingsector)) { Environment.ExitCode = (int)WinErrorCodes.ERROR_BAD_ARGUMENTS; Console.WriteLine("Error: Could not validate startingsector argument."); return; } } else { Console.WriteLine(helpText); Environment.ExitCode = (int)WinErrorCodes.ERROR_BAD_ARGUMENTS; Console.WriteLine("Error: Invalid argument."); return; } } if ((devNum < 0 || imageFile.Length < 1) & !listOnly) { Console.WriteLine(helpText); Environment.ExitCode = (int)WinErrorCodes.ERROR_BAD_ARGUMENTS; return; } try { scope.Connect(); } catch (Exception ex) { Environment.ExitCode = (int)WinErrorCodes.ERROR_WMI_DP_FAILED; Console.WriteLine("Error: " + ex.Message); return; } try { using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query)) using (ManagementObjectCollection queryCollection = searcher.Get()) { foreach (ManagementObject mObject in queryCollection) { // 4 = Supports Writing - Win32_DiskDrive: msdn.microsoft.com/en-us/library/aa394132(v=vs.85).aspx UInt16[] capabilities = (UInt16[])mObject["Capabilities"]; if (capabilities.Contains((UInt16)4) & mObject["DeviceID"].ToString().Contains("PHYSICALDRIVE")) allDevices.Add(new WritablePhysicalDevice((string)mObject["DeviceID"], (UInt32)mObject["BytesPerSector"], (UInt64)mObject["TotalSectors"], (UInt64)mObject["Size"])); } } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); Environment.ExitCode = (int)WinErrorCodes.ERROR_WMI_DP_FAILED; return; } if (listOnly) { foreach (WritablePhysicalDevice dev in allDevices) { Console.WriteLine("\n DeviceID: " + dev.deviceID); Console.WriteLine(" Bytes/Sector: " + dev.bytesPerSector); Console.WriteLine("Total Sectors: " + dev.totalSectors); Console.WriteLine(" Total Size: " + dev.size); } return; } foreach (WritablePhysicalDevice dev in allDevices) if (dev.deviceNum == devNum) myDevice = dev; if (myDevice == null) { Environment.ExitCode = (int)WinErrorCodes.ERROR_DEV_NOT_EXIST; Console.WriteLine("Error: Device number " + devNum + " does not exist!"); return; } if (startingsector > myDevice.totalSectors) { Environment.ExitCode = (int)WinErrorCodes.ERROR_INVALID_BLOCK; Console.WriteLine("Error: Starting sector was greater than drive's total sectors!"); return; } if (!force) { Console.WriteLine("\nPress Y if you are sure you want to write the data in"); Console.WriteLine(imageFile); Console.Write("to " + myDevice.deviceID + " starting at sector " + startingsector + ": "); if (Console.ReadKey().Key != ConsoleKey.Y) return; Console.WriteLine(); } try { imageBytes = File.ReadAllBytes(imageFile); Console.WriteLine("Read " + imageBytes.Length + " bytes from source image."); } catch (Exception ex) { Console.WriteLine("Error reading source file: " + ex.Message); Environment.ExitCode = (int)WinErrorCodes.ERROR_READ_FAULT; return; } if (imageBytes.Length % myDevice.bytesPerSector != 0) { Console.WriteLine("The image provided is not a multiple of " + myDevice.bytesPerSector + " bytes."); Console.WriteLine("Data will be padded with zeroes to the nearest sector..."); do { byte[] newArray = new byte[imageBytes.Length + 1]; imageBytes.CopyTo(newArray, 0); newArray[newArray.Length - 1] = 0; imageBytes = newArray; } while (imageBytes.Length % myDevice.bytesPerSector != 0); Console.WriteLine("Adjusted image size is " + imageBytes.Length + " bytes."); } if ((ulong)imageBytes.Length > (myDevice.size - (startingsector * myDevice.bytesPerSector))) { Console.WriteLine("Error: Image is larger than the space available on the drive!"); Environment.ExitCode = (int)WinErrorCodes.ERROR_FILE_TOO_LARGE; return; } Console.WriteLine("Opening handle to " + myDevice.deviceID + "..."); try { using (SafeFileHandle safeHandle = NativeMethods.CreateFile(myDevice.deviceID, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero)) { if (safeHandle.IsClosed || safeHandle.IsInvalid) throw new Exception("Device handle could not be opened! (Check Administrator privileges.)"); Console.WriteLine("Seeking to sector " + startingsector + " (byte " + startingsector * myDevice.bytesPerSector + ")..."); unsafe { UInt64 n = 0; IntPtr ptr = new IntPtr(&n); int ret = 0; NativeMethods.SetFilePointerEx(safeHandle, (long)(startingsector * myDevice.bytesPerSector), ptr, NativeMethods.EMoveMethod.Begin); ret = Marshal.GetLastWin32Error(); if (ret != 0) throw new Exception("Error during file seek! Win32 code: " + ret); var nativeOverlap = new System.Threading.NativeOverlapped(); NativeMethods.WriteFile(safeHandle, imageBytes, (uint)imageBytes.Length, out bytesWritten, ref nativeOverlap); ret = Marshal.GetLastWin32Error(); if (ret != 0) throw new Exception("Error during file write! Win32 code: " + ret); Console.WriteLine(bytesWritten + " bytes were written to " + myDevice.deviceID + "."); } } } catch (Exception ex) { Environment.ExitCode = (int)WinErrorCodes.ERROR_WRITE_FAULT; Console.WriteLine("Error: " + ex.Message); } }
private byte [] GetWin32XML(IDevice Ipod) { IntPtr pSptwb = IntPtr.Zero; SafeFileHandle driveHandle = null; try { ScsiPassThroughWithBuffers sptwb; int returned, length; string device = GetDeviceFromDrive(((Win32.Device)Ipod).Drive); bool status; byte [] buffer = new byte [102400]; int bufferIdx = 0; byte page_code, page_start, page_end = 0; driveHandle = ApiFunctions.CreateFile(device, AccessMask.GENERIC_ALL, System.IO.FileShare.ReadWrite, 0, System.IO.FileMode.Open, 0, IntPtr.Zero); if (driveHandle.IsInvalid) { throw new FileLoadException("Device invalid"); } sptwb = new ScsiPassThroughWithBuffers(); sptwb.spt.Length = (ushort)Marshal.SizeOf(typeof(SCSI_PASS_THROUGH)); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = 6; sptwb.spt.SenseInfoLength = 32; sptwb.spt.DataIn = 1; //SCSI_IOCTL_DATA_IN sptwb.spt.DataTransferLength = 255; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = Marshal.OffsetOf(typeof(ScsiPassThroughWithBuffers), "ucDataBuf"); sptwb.spt.SenseInfoOffset = Marshal.OffsetOf(typeof(ScsiPassThroughWithBuffers), "ucSenseBuf"); sptwb.spt.Cdb = new byte [16]; sptwb.spt.Cdb [0] = 0x12; //SCSI_INQUIRY sptwb.spt.Cdb [1] |= 1; sptwb.spt.Cdb [2] = 0xC0; sptwb.spt.Cdb [4] = 255; length = Marshal.OffsetOf(typeof(ScsiPassThroughWithBuffers), "ucDataBuf").ToInt32() + (int)sptwb.spt.DataTransferLength; pSptwb = Marshal.AllocHGlobal(Marshal.SizeOf(sptwb)); Marshal.StructureToPtr(sptwb, pSptwb, true); System.Threading.NativeOverlapped nativeOverlapped = new System.Threading.NativeOverlapped(); status = ApiFunctions.DeviceIoControl(driveHandle, DeviceIOControlCode.ScsiPassThrough, pSptwb, Marshal.SizeOf(typeof(SCSI_PASS_THROUGH)), pSptwb, length, out returned, ref nativeOverlapped); if (!status) { throw new FileLoadException("DeviceIoControl Error", Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error())); } sptwb = (ScsiPassThroughWithBuffers)Marshal.PtrToStructure(pSptwb, typeof(ScsiPassThroughWithBuffers)); page_start = sptwb.ucDataBuf [4]; page_end = sptwb.ucDataBuf [3 + sptwb.ucDataBuf [3]]; for (page_code = page_start; page_code <= page_end; page_code++) { sptwb.spt.Length = (ushort)Marshal.SizeOf(typeof(SCSI_PASS_THROUGH)); sptwb.spt.PathId = 0; sptwb.spt.TargetId = 1; sptwb.spt.Lun = 0; sptwb.spt.CdbLength = 6; sptwb.spt.SenseInfoLength = 32; sptwb.spt.DataIn = 1; //SCSI_IOCTL_DATA_IN sptwb.spt.DataTransferLength = 255; sptwb.spt.TimeOutValue = 2; sptwb.spt.DataBufferOffset = Marshal.OffsetOf(typeof(ScsiPassThroughWithBuffers), "ucDataBuf"); sptwb.spt.SenseInfoOffset = Marshal.OffsetOf(typeof(ScsiPassThroughWithBuffers), "ucSenseBuf"); sptwb.spt.Cdb = new byte [16]; sptwb.spt.Cdb [0] = 0x12; //SCSI_INQUIRY sptwb.spt.Cdb [1] |= 1; sptwb.spt.Cdb [2] = page_code; sptwb.spt.Cdb [4] = 255; length = Marshal.OffsetOf(typeof(ScsiPassThroughWithBuffers), "ucDataBuf").ToInt32() + (int)sptwb.spt.DataTransferLength; returned = 0; Marshal.StructureToPtr(sptwb, pSptwb, true); status = ApiFunctions.DeviceIoControl(driveHandle, DeviceIOControlCode.ScsiPassThrough, pSptwb, Marshal.SizeOf(typeof(SCSI_PASS_THROUGH)), pSptwb, length, out returned, ref nativeOverlapped); if (!status) { throw new FileLoadException("DeviceIoControl Error", Marshal.GetExceptionForHR(Marshal.GetLastWin32Error())); } sptwb = (ScsiPassThroughWithBuffers)Marshal.PtrToStructure(pSptwb, typeof(ScsiPassThroughWithBuffers)); while (bufferIdx + sptwb.ucDataBuf [3] > buffer.Length) { Array.Resize <byte> (ref buffer, buffer.Length * 2); } Array.Copy(sptwb.ucDataBuf, 4, buffer, bufferIdx, sptwb.ucDataBuf [3]); bufferIdx += sptwb.ucDataBuf [3]; } if (bufferIdx == 0) { return(null); } buffer [bufferIdx] = 0; Array.Resize <byte> (ref buffer, bufferIdx + 1); return(buffer); } finally { if (pSptwb != IntPtr.Zero) { Marshal.FreeHGlobal(pSptwb); } if (driveHandle != null) { driveHandle.Close(); } } }