Ejemplo n.º 1
0
        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 ();
            }
        }
Ejemplo n.º 2
0
        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();
                }
            }
        }