Changeset 2187


Ignore:
Timestamp:
6/18/2010 11:33:59 AM (4 years ago)
Author:
lowjoel
Message:

Allow us to query the size of non-ready partitions and disks (for more informative UIs)

Location:
trunk/eraser/Eraser.Util
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.Util/NativeMethods/Kernel.cs

    r2179 r2187  
    675675        } 
    676676 
     677        [DllImport("Kernel32.dll", SetLastError = true)] 
     678        [return: MarshalAs(UnmanagedType.Bool)] 
     679        private extern static bool DeviceIoControl(SafeFileHandle hDevice, 
     680            uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, 
     681            out long lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, 
     682            IntPtr lpOverlapped); 
     683 
     684        public static bool DeviceIoControl(SafeFileHandle hDevice, 
     685            uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, 
     686            out long lpOutBuffer, out uint lpBytesReturned, IntPtr lpOverlapped) 
     687        { 
     688            return DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, 
     689                out lpOutBuffer, sizeof(long), out lpBytesReturned, lpOverlapped); 
     690        } 
     691 
     692        /// <summary> 
     693        /// Retrieves the length of the specified disk, volume, or partition. 
     694        /// </summary> 
     695        public const int IOCTL_DISK_GET_LENGTH_INFO = 
     696            (0x00000007 << 16) | (0x0001 << 14) | (0x0017 << 2); 
     697 
    677698        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
    678699        [return: MarshalAs(UnmanagedType.Bool)] 
  • trunk/eraser/Eraser.Util/PhysicalDriveInfo.cs

    r2186 r2187  
    6565                for (int i = 0; ; ++i) 
    6666                { 
    67                     using (SafeFileHandle handle = OpenWin32Device(GetDiskPath(i))) 
     67                    using (SafeFileHandle handle = OpenWin32Device(GetDiskPath(i), 
     68                        NativeMethods.FILE_READ_ATTRIBUTES)) 
    6869                    { 
    6970                        if (handle.IsInvalid) 
     
    8283        /// </summary> 
    8384        /// <param name="deviceName">The name of the device to open.</param> 
     85        /// <param name="access">The access needed for the handle.</param> 
    8486        /// <returns>A <see cref="SafeFileHandle"/> to the device.</returns> 
    85         private static SafeFileHandle OpenWin32Device(string deviceName) 
     87        private static SafeFileHandle OpenWin32Device(string deviceName, uint access) 
    8688        { 
    8789            //Define the DOS device name for access 
     
    100102                //Open the device handle. 
    101103                return NativeMethods.CreateFile(string.Format(CultureInfo.InvariantCulture, 
    102                     "\\\\.\\{0}", dosDeviceName), NativeMethods.FILE_READ_ATTRIBUTES, 
     104                    "\\\\.\\{0}", dosDeviceName), access, 
    103105                    NativeMethods.FILE_SHARE_READ | NativeMethods.FILE_SHARE_WRITE, IntPtr.Zero, 
    104106                    (int)FileMode.Open, (uint)FileAttributes.ReadOnly, IntPtr.Zero); 
     
    131133                { 
    132134                    string path = GetPartitionPath(i); 
    133                     using (SafeFileHandle handle = OpenWin32Device(path)) 
     135                    using (SafeFileHandle handle = OpenWin32Device(path, 
     136                        NativeMethods.FILE_READ_ATTRIBUTES)) 
    134137                    { 
    135138                        if (handle.IsInvalid) 
     
    161164 
    162165        /// <summary> 
     166        /// Gets the size of the disk, in bytes. 
     167        /// </summary> 
     168        public long Size 
     169        { 
     170            get 
     171            { 
     172                using (SafeFileHandle handle = OpenWin32Device(GetDiskPath(), 
     173                    NativeMethods.GENERIC_READ)) 
     174                { 
     175                    if (handle.IsInvalid) 
     176                        throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 
     177 
     178                    long result = 0; 
     179                    uint returned = 0; 
     180                    if (NativeMethods.DeviceIoControl(handle, NativeMethods.IOCTL_DISK_GET_LENGTH_INFO, 
     181                        IntPtr.Zero, 0, out result, out returned, IntPtr.Zero)) 
     182                    { 
     183                        return result; 
     184                    } 
     185 
     186                    throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 
     187                } 
     188            } 
     189        } 
     190 
     191        /// <summary> 
    163192        /// The format string for accessing partitions. 
    164193        /// </summary> 
  • trunk/eraser/Eraser.Util/VolumeInfo.cs

    r2185 r2187  
    463463            get 
    464464            { 
    465                 if (!IsReady) 
    466                     throw new InvalidOperationException("The volume has not been mounted or is not " + 
    467                         "currently ready."); 
    468  
    469465                ulong result, dummy; 
    470466                if (NativeMethods.GetDiskFreeSpaceEx(VolumeId, out dummy, out result, out dummy)) 
     
    473469                } 
    474470 
     471                //Try the alternative method 
     472                using (SafeFileHandle handle = OpenHandle(NativeMethods.GENERIC_READ, 
     473                    FileShare.ReadWrite, FileOptions.None)) 
     474                { 
     475                    if (handle.IsInvalid) 
     476                        throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 
     477 
     478                    long result2; 
     479                    uint returned = 0; 
     480                    if (NativeMethods.DeviceIoControl(handle, 
     481                        NativeMethods.IOCTL_DISK_GET_LENGTH_INFO, IntPtr.Zero, 0, out result2, 
     482                        out returned, IntPtr.Zero)) 
     483                    { 
     484                        return result2; 
     485                    } 
     486                } 
     487 
     488                //Otherwise, throw 
    475489                throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 
    476490            } 
Note: See TracChangeset for help on using the changeset viewer.