Ejemplo n.º 1
0
        /// <summary>
        /// <see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa365194(v=vs.85).aspx" />
        /// </summary>
        public VOLUME_DISK_EXTENTS VolumeGetVolumeDiskExtents()
        {
            // Fetch in increments of 32 bytes, as one extent (the most common case) is one extent pr. volume.
            byte[] data = DeviceIoControlHelper.InvokeIoControlUnknownSize(Handle, IOControlCode.VolumeGetVolumeDiskExtents, 32);

            // Build the VOLUME_DISK_EXTENTS structure
            VOLUME_DISK_EXTENTS res = new VOLUME_DISK_EXTENTS();

            res.NumberOfDiskExtents = BitConverter.ToUInt32(data, 0);
            res.Extents             = new DISK_EXTENT[res.NumberOfDiskExtents];

            using (UnmanagedMemory dataPtr = new UnmanagedMemory(data))
            {
                // TODO: This code needs to be tested for volumes with more than one extent.
                for (int i = 0; i < res.NumberOfDiskExtents; i++)
                {
                    IntPtr      currentDataPtr = new IntPtr(dataPtr.Handle.ToInt64() + 8 + i * MarshalHelper.SizeOf <DISK_EXTENT>());
                    DISK_EXTENT extent         = currentDataPtr.ToStructure <DISK_EXTENT>();

                    res.Extents[i] = extent;
                }
            }

            return(res);
        }
Ejemplo n.º 2
0
        //method for disk extents
        private static uint?GetPhysicalDriveNumber(string driveLetter)
        {
            var sDrive = "\\\\.\\" + driveLetter + ":";

            var hDrive = CreateFileW(sDrive, 0, // No access to drive
                                     FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);

            if (hDrive == null || hDrive.IsInvalid)
            {
                var message = GetErrorMessage(Marshal.GetLastWin32Error());
                log.Warn("CreateFile failed. " + message);
                return(uint.MinValue);
            }

            uint IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS); // From winioctl.h

            VOLUME_DISK_EXTENTS query_disk_extents = new VOLUME_DISK_EXTENTS();

            uint returned_query_disk_extents_size;

            bool query_disk_extents_result = DeviceIoControl(hDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, ref query_disk_extents, (uint)Marshal.SizeOf(query_disk_extents), out returned_query_disk_extents_size, IntPtr.Zero);

            hDrive.Close();

            if (query_disk_extents_result == false || query_disk_extents.Extents.Length != 1)
            {
                var message = GetErrorMessage(Marshal.GetLastWin32Error());
                log.Warn("DeviceIoControl failed. " + message);
                return(null);
            }

            return(query_disk_extents.Extents[0].DiskNumber);
        }
Ejemplo n.º 3
0
 public static extern bool DeviceIoControl(
     SafeFileHandle hDevice,
     uint dwIoControlCode,
     IntPtr lpInBuffer,
     uint nInBufferSize,
     ref VOLUME_DISK_EXTENTS lpOutBuffer,
     uint nOutBufferSize,
     out uint lpBytesReturned,
     IntPtr lpOverlapped
     );
Ejemplo n.º 4
0
        /// <summary>
        /// Get volume disk extents for volumes that may or may not span more than one physical drive.
        /// </summary>
        /// <param name="devicePath">The device path of the volume.</param>
        /// <returns>An array of DiskExtent structures.</returns>
        /// <remarks></remarks>
        public static DiskExtent[] GetDiskExtentsFor(string devicePath)
        {
            DiskExtent[] deOut  = null;
            MemPtr       inBuff = new MemPtr();
            int          inSize;
            IntPtr       file;
            int          h  = 0;
            var          de = new DISK_EXTENT();
            var          ve = new VOLUME_DISK_EXTENTS();
            bool         r;

            file = IO.CreateFile(devicePath, IO.GENERIC_READ, IO.FILE_SHARE_READ | IO.FILE_SHARE_WRITE, IntPtr.Zero, IO.OPEN_EXISTING, IO.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
            if (file == DevProp.INVALID_HANDLE_VALUE)
            {
                return(null);
            }

            uint arb = 0;

            inSize        = Marshal.SizeOf(de) + Marshal.SizeOf(ve);
            inBuff.Length = inSize;
            r             = DeviceIoControl(file, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, inBuff, (uint)inSize, ref arb, IntPtr.Zero);

            if (!r && User32.GetLastError() == ERROR_MORE_DATA)
            {
                inBuff.Length = inSize * inBuff.IntAt(0L);
                r             = DeviceIoControl(file, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, inBuff, (uint)inSize, ref arb, IntPtr.Zero);
            }

            if (!r)
            {
                inBuff.Free();
                User32.CloseHandle(file);
                return(null);
            }

            User32.CloseHandle(file);
            ve = VOLUME_DISK_EXTENTS.FromPtr(inBuff);
            inBuff.Free();
            h     = 0;
            deOut = new DiskExtent[ve.Extents.Length];
            foreach (var currentDe in ve.Extents)
            {
                de = currentDe;
                deOut[h].PhysicalDevice = de.DiskNumber;
                deOut[h].Space          = de.Space;
                deOut[h].Size           = de.ExtentLength;
                deOut[h].Offset         = de.StartingOffset;
                h += 1;
            }

            return(deOut);
        }
Ejemplo n.º 5
0
        //method for disk extents
        public static uint?GetPhysicalDriveNumber(string driveLetter)
        {
            var sDrive = "\\\\.\\" + driveLetter + ":";

            var hDrive = CreateFileW(sDrive, 0, // No access to drive
                                     FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);

            VOLUME_DISK_EXTENTS query_disk_extents;
            bool query_disk_extents_result;

            try
            {
                if (hDrive == INVALID_HANDLE_VALUE)
                {
                    var message = GetErrorMessage(Marshal.GetLastWin32Error());
                    if (Log.IsInfoEnabled)
                    {
                        Log.Info("CreateFile failed. " + message);
                    }
                    return(uint.MinValue);
                }

                uint IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS); // From winioctl.h

                query_disk_extents = new VOLUME_DISK_EXTENTS();

                uint returned_query_disk_extents_size;

                query_disk_extents_result = DeviceIoControl(hDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, ref query_disk_extents,
                                                            (uint)Marshal.SizeOf(query_disk_extents), out returned_query_disk_extents_size, IntPtr.Zero);
            }
            finally
            {
                Win32ThreadsMethods.CloseHandle(hDrive);
            }

            if (query_disk_extents_result == false || query_disk_extents.Extents.Length != 1)
            {
                var message = GetErrorMessage(Marshal.GetLastWin32Error());
                if (Log.IsInfoEnabled)
                {
                    Log.Info("DeviceIoControl failed. " + message);
                }
                return(null);
            }

            return(query_disk_extents.Extents[0].DiskNumber);
        }
        private int GetDiskForVolume(string volume)
        {
            int disk = -1;

            // CreateFile method accepts "\\\\.\\Volume{4b3d5e28-4b1a-11e9-b640-54bf64435496}"
            SafeFileHandle hndl = CreateFile(string.Format("\\\\.\\{0}", volume),
                                             GENERIC_READ | GENERIC_WRITE,
                                             FILE_SHARE_READ | FILE_SHARE_WRITE,
                                             IntPtr.Zero,
                                             OPEN_EXISTING,
                                             FILE_ATTRIBUTE_READONLY,
                                             IntPtr.Zero);

            if (hndl.IsInvalid)
            {
                LogHelper.Log("EFIFirmwareService:GetDiskForVolume: Invalid handle:");
            }
            else
            {
                VOLUME_DISK_EXTENTS vde = new VOLUME_DISK_EXTENTS();
                UInt32 outBufferSize    = (UInt32)Marshal.SizeOf(vde);
                IntPtr outBuffer        = Marshal.AllocHGlobal((int)outBufferSize);
                UInt32 bytesReturned    = 0;

                if (DeviceIoControl(hndl,
                                    IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
                                    IntPtr.Zero,
                                    0,
                                    outBuffer,
                                    outBufferSize,
                                    out bytesReturned,
                                    IntPtr.Zero))
                {
                    Marshal.PtrToStructure(outBuffer, vde);
                    disk = Convert.ToInt32(vde.Extents.DiskNumber);
                }

                Marshal.FreeHGlobal(outBuffer);
            }

            hndl.Close();
            return(disk);
        }
Ejemplo n.º 7
0
            public static VOLUME_DISK_EXTENTS FromPtr(IntPtr ptr)
            {
                VOLUME_DISK_EXTENTS FromPtrRet = default;
                var    ve = new VOLUME_DISK_EXTENTS();
                int    cb = Marshal.SizeOf <DISK_EXTENT>();
                MemPtr m  = ptr;
                int    i;

                ve.NumberOfExtents = m.IntAt(0L);
                ve.Space           = m.IntAt(1L);
                ve.Extents         = new DISK_EXTENT[ve.NumberOfExtents];
                m = m + 8;
                var c = ve.NumberOfExtents;

                for (i = 0; i < c; i++)
                {
                    ve.Extents[i] = m.ToStruct <DISK_EXTENT>();
                    m             = m + cb;
                }

                FromPtrRet = ve;
                return(FromPtrRet);
            }
Ejemplo n.º 8
0
 public static extern bool DeviceIoControl([InAttribute()] VolumeSafeHandle hDevice, UInt32 dwIoControlCode, [InAttribute()] IntPtr lpInBuffer, Int32 nInBufferSize, ref VOLUME_DISK_EXTENTS lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
Ejemplo n.º 9
0
            public Extents(string name)
            {
                // Remove trailing '/' character from path
                string newname = name.Substring(0, name.Length - 1);

                IntPtr volhandle = CreateFile(newname, EFileAccess.Any, EFileShare.Read | EFileShare.Write, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.Normal, 0);

                if (volhandle.ToInt32() == INVALID_HANDLE_VALUE)
                {
                    return;
                }

                try
                {
                    VOLUME_DISK_EXTENTS vextents = new VOLUME_DISK_EXTENTS();
                    DISK_EXTENT         dextent  = new DISK_EXTENT();
                    uint   numextents            = 1;
                    int    allocsize             = (int)Marshal.SizeOf(vextents) + (int)numextents * (int)Marshal.SizeOf(dextent);
                    IntPtr memblock = IntPtr.Zero;
                    IntPtr alloced;
                    memblock = Marshal.AllocHGlobal((int)allocsize);
                    alloced  = memblock;
                    try {
                        int returned = 0;

                        VOLUME_DISK_EXTENTS diskExtents = new VOLUME_DISK_EXTENTS();
                        while (true)
                        {
                            if (!DeviceIoControl(volhandle, IoctlControlCodes.IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, memblock, allocsize, out returned, 0))
                            {
                                int err = Marshal.GetLastWin32Error();
                                if ((err == ERROR_INSUFFICIENT_BUFFER) || (err == ERROR_MORE_DATA))
                                {
                                    Marshal.PtrToStructure(memblock, diskExtents);
                                    numextents = diskExtents.NumberOfDiskExtents;
                                    allocsize  = (int)Marshal.SizeOf(vextents) + (int)numextents * (int)Marshal.SizeOf(dextent);
                                    memblock   = Marshal.ReAllocHGlobal(memblock, new IntPtr(allocsize));
                                    alloced    = memblock;
                                    continue;
                                }
                                else
                                {
                                    return;
                                }
                            }
                            break;
                        }
                        Marshal.PtrToStructure(memblock, diskExtents);
                        memblock = new IntPtr(memblock.ToInt64() + Marshal.SizeOf(diskExtents));
                        for (int i = 0; i < diskExtents.NumberOfDiskExtents; i++)
                        {
                            Marshal.PtrToStructure(memblock, dextent);
                            Extent extent = new Extent {
                                DiskNumber = dextent.DiskNumber, ExtentLength = dextent.ExtentLength, StartingOffset = dextent.StartingOffset
                            };
                            this.Add(extent);
                            memblock = new IntPtr(memblock.ToInt64() + Marshal.SizeOf(dextent));
                        }
                    }
                    finally {
                        Marshal.FreeHGlobal(alloced);
                    }
                }
                catch (Exception e)
                {
                    WmiBase.Singleton.DebugMsg("Extent listing exception : " + e.ToString());
                    throw;
                }
                finally
                {
                    CloseHandle(volhandle);
                }
            }
Ejemplo n.º 10
0
 public static extern bool DeviceIoControl([InAttribute()] VolumeSafeHandle hDevice, UInt32 dwIoControlCode, [InAttribute()] IntPtr lpInBuffer, Int32 nInBufferSize, ref VOLUME_DISK_EXTENTS lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
Ejemplo n.º 11
0
Archivo: Form1.cs Proyecto: taitung/lba
        private void dumpDiskInfo()
        {
            if (cbDriveInfos.SelectedIndex <=0 )
                return;

            MyDrive myDrive = (MyDrive)this.cbDriveInfos.SelectedItem;

            rtxtExtends.Clear();

            SafeFileHandle volume = CreateFile(
                "\\\\.\\" + myDrive.DriveLetter,
                0,
                FileShare.ReadWrite,
                IntPtr.Zero,
                FileMode.Open,
                0,
                IntPtr.Zero);

            if (volume.IsInvalid)
            {
                string message = GetSystemMessage(Marshal.GetHRForLastWin32Error());
                MessageBox.Show(message);
            }
            else
            {

                uint IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS);
                VOLUME_DISK_EXTENTS query_disk_extents = new VOLUME_DISK_EXTENTS();
                uint returned_query_disk_extents_size;
                try
                {
                    bool query_disk_extents_result = DeviceIoControl(
                        volume,
                        IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
                        IntPtr.Zero,
                        0,
                        ref query_disk_extents,
                        (uint)Marshal.SizeOf(query_disk_extents),
                        out returned_query_disk_extents_size,
                        IntPtr.Zero);

                    if (query_disk_extents_result == false ||
                        query_disk_extents.Extents.Length != 1)
                    {
                        string message = GetSystemMessage(Marshal.GetLastWin32Error());
                        MessageBox.Show(message);
                    }
                    else
                    {
                        this.lblNumbersOfDiskExtends.Text = String.Format("{0}", query_disk_extents.NumberOfDiskExtents);
                        foreach (DISK_EXTENT ext in query_disk_extents.Extents)
                        {
                            rtxtExtends.AppendText(String.Format("Disk number:{0}\n", ext.DiskNumber));
                            rtxtExtends.AppendText(String.Format("Extend length:{0}\n", ext.ExtentLength));
                            rtxtExtends.AppendText(String.Format("Starting offset:{0}\n", ext.StartingOffset));
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                finally
                {
                    if (!volume.IsInvalid && !volume.IsClosed)
                    {
                        volume.Close();
                    }
                }
            }
        }
Ejemplo n.º 12
0
Archivo: Form1.cs Proyecto: taitung/lba
 private static extern bool DeviceIoControl(
     SafeFileHandle hDevice,
     uint dwIoControlCode,
     IntPtr lpInBuffer,
     uint nInBufferSize,
     ref VOLUME_DISK_EXTENTS lpOutBuffer,
     uint nOutBufferSize,
     out uint lpBytesReturned,
     IntPtr lpOverlapped);