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