Ignore:
Timestamp:
6/19/2010 10:14:24 AM (2 years ago)
Author:
lowjoel
Message:
  • Don't define a shortcut function for DeviceIoControl? since that's a rather low-level API and we don't want to confuse things further.
  • Properly implement the querying of the Physical drive a volume belongs to using the IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS Control Code
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.Util/VolumeInfo.cs

    r2189 r2206  
    480480                    if (NativeMethods.DeviceIoControl(handle, 
    481481                        NativeMethods.IOCTL_DISK_GET_LENGTH_INFO, IntPtr.Zero, 0, out result2, 
    482                         out returned, IntPtr.Zero)) 
     482                        sizeof(long), out returned, IntPtr.Zero)) 
    483483                    { 
    484484                        return result2; 
     
    582582            get 
    583583            { 
    584                 foreach (PhysicalDriveInfo info in PhysicalDriveInfo.Drives) 
    585                 { 
    586                     if (info.Volumes.IndexOf(this) != -1) 
    587                         return info; 
    588                 } 
    589  
     584                IntPtr buffer = IntPtr.Zero; 
     585                List<NativeMethods.DISK_EXTENT> extents = new List<NativeMethods.DISK_EXTENT>(); 
     586                SafeFileHandle handle = OpenHandle(FileAccess.Read, FileShare.ReadWrite, 
     587                    FileOptions.None); 
     588 
     589                try 
     590                { 
     591                    uint returnSize = 0; 
     592                    int bufferSize = Marshal.SizeOf(typeof(NativeMethods.VOLUME_DISK_EXTENTS)); 
     593                    buffer = Marshal.AllocHGlobal(bufferSize); 
     594                    NativeMethods.VOLUME_DISK_EXTENTS header; 
     595 
     596                    if (!NativeMethods.DeviceIoControl(handle, 
     597                        NativeMethods.IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, 
     598                        buffer, (uint)bufferSize, out returnSize, IntPtr.Zero)) 
     599                    { 
     600                        int error = Marshal.GetLastWin32Error(); 
     601                        if (error != Win32ErrorCode.InsufficientBuffer) 
     602                            throw Win32ErrorCode.GetExceptionForWin32Error(error); 
     603 
     604                        //Calculate the size of the buffer required 
     605                        header = (NativeMethods.VOLUME_DISK_EXTENTS) 
     606                            Marshal.PtrToStructure(buffer, 
     607                                typeof(NativeMethods.VOLUME_DISK_EXTENTS)); 
     608                        Marshal.FreeHGlobal(buffer); 
     609                        bufferSize += (int)(header.NumberOfDiskExtents - 1) * 
     610                            Marshal.SizeOf(typeof(NativeMethods.DISK_EXTENT)); 
     611                        buffer = Marshal.AllocHGlobal(bufferSize); 
     612 
     613                        if (!NativeMethods.DeviceIoControl(handle, 
     614                            NativeMethods.IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, IntPtr.Zero, 0, 
     615                            buffer, (uint)bufferSize, out returnSize, IntPtr.Zero)) 
     616                        { 
     617                            throw Win32ErrorCode.GetExceptionForWin32Error( 
     618                                Marshal.GetLastWin32Error()); 
     619                        } 
     620                    } 
     621 
     622                    //Parse the structure. 
     623                    header = (NativeMethods.VOLUME_DISK_EXTENTS)Marshal.PtrToStructure(buffer, 
     624                        typeof(NativeMethods.VOLUME_DISK_EXTENTS)); 
     625                    extents.Add(header.Extent); 
     626 
     627                    for (long i = 1, offset = (uint)Marshal.SizeOf(typeof( 
     628                        NativeMethods.VOLUME_DISK_EXTENTS)); i < header.NumberOfDiskExtents; 
     629                        ++i, offset += Marshal.SizeOf(typeof(NativeMethods.DISK_EXTENT))) 
     630                    { 
     631                        NativeMethods.DISK_EXTENT extent = new NativeMethods.DISK_EXTENT(); 
     632                        Marshal.PtrToStructure(new IntPtr(buffer.ToInt64() + offset), extent); 
     633                        extents.Add(extent); 
     634                    } 
     635                } 
     636                finally 
     637                { 
     638                    handle.Close(); 
     639                    Marshal.FreeHGlobal(buffer); 
     640                } 
     641 
     642                if (extents.Count == 1) 
     643                    return new PhysicalDriveInfo((int)extents[0].DiskNumber); 
    590644                return null; 
    591645            } 
Note: See TracChangeset for help on using the changeset viewer.