示例#1
0
        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();
                }
            }
        }
示例#2
0
        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");
            }
        }
示例#3
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();
                }
            }
        }