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(); } } }
public void Eject() { string driveName = "\\\\.\\" + drive.ToString().Substring(0, 2); SafeFileHandle hDrive = ApiFunctions.CreateFile(driveName, AccessMask.GENERIC_READ, System.IO.FileShare.ReadWrite, 0, System.IO.FileMode.Open, 0, IntPtr.Zero); if (hDrive.IsInvalid) { throw new DeviceException(host, "Failed to eject device, could not open drive"); } int retByte; NativeOverlapped nativeOverlap = new NativeOverlapped(); bool status = ApiFunctions.DeviceIoControl(hDrive, DeviceIOControlCode.StorageEjectMedia, IntPtr.Zero, 0, IntPtr.Zero, 0, out retByte, ref nativeOverlap); if (!status) { throw new DeviceException(host, "Failed to eject device, DeviceIoControl returned false"); } }
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(); } } }