Exemplo n.º 1
0
        public static List <PhysicalDisk> GetPhysicalDisks()
        {
            List <PhysicalDisk> result        = new List <PhysicalDisk>();
            List <int>          diskIndexList = PhysicalDiskControl.GetPhysicalDiskIndexList();

            foreach (int diskIndex in diskIndexList)
            {
                PhysicalDisk disk;
                try
                {
                    disk = new PhysicalDisk(diskIndex); // will throw an exception if disk is not valid
                }
                catch (DriveNotFoundException)
                {
                    // The disk must have been removed from the system
                    continue;
                }
                catch (DeviceNotReadyException)
                {
                    continue;
                }
                catch (SharingViolationException) // skip this disk, it's probably being used
                {
                    continue;
                }
                result.Add(disk);
            }

            return(result);
        }
        /// <summary>
        /// Available on Windows Vista and newer
        /// </summary>
        /// <exception cref="System.IO.IOException"></exception>
        public bool GetOnlineStatus(out bool isReadOnly)
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.ReadWrite, ShareMode.Read, out releaseHandle);

            if (!handle.IsInvalid)
            {
                bool isOnline = PhysicalDiskControl.GetOnlineStatus(handle, out isReadOnly);
                if (releaseHandle)
                {
                    PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
                }
                return(isOnline);
            }
            else
            {
                // we always release invalid handle
                PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);

                // get error code and throw
                int    errorCode = Marshal.GetLastWin32Error();
                string message   = String.Format("Failed to get disk {0} online status, Win32 Error: {1}", m_physicalDiskIndex, errorCode);
                throw new IOException(message);
            }
        }
        /// <summary>
        /// Available on Windows Vista and newer
        /// </summary>
        /// <exception cref="System.IO.IOException"></exception>
        public bool SetOnlineStatus(bool online, bool persist)
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.ReadWrite, ShareMode.Read, out releaseHandle);

            if (!handle.IsInvalid)
            {
                bool success = PhysicalDiskControl.SetOnlineStatus(handle, online, persist);
                if (releaseHandle)
                {
                    PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
                }
                return(success);
            }
            else
            {
                // we always release invalid handle
                PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);

                int errorCode = Marshal.GetLastWin32Error();
                if (errorCode == (int)Win32Error.ERROR_SHARING_VIOLATION)
                {
                    return(false);
                }
                else
                {
                    string message = String.Format("Failed to take disk {0} offline, Win32 Error: {1}", m_physicalDiskIndex, errorCode);
                    throw new IOException(message);
                }
            }
        }
        private void PopulateDescription()
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.Read, ShareMode.ReadWrite, out releaseHandle);

            if (!handle.IsInvalid)
            {
                m_description  = PhysicalDiskControl.GetDeviceDescription(handle);
                m_serialNumber = PhysicalDiskControl.GetDeviceSerialNumber(handle);
                if (releaseHandle)
                {
                    PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
                }
            }
            else
            {
                // we always release invalid handle
                PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);

                // get error code and throw
                int    errorCode = Marshal.GetLastWin32Error();
                string message   = String.Format("Failed to access disk {0}.", m_physicalDiskIndex);
                if (errorCode == (int)Win32Error.ERROR_FILE_NOT_FOUND)
                {
                    throw new DriveNotFoundException(message);
                }
                else
                {
                    IOExceptionHelper.ThrowIOError(errorCode, message);
                }
            }
        }
Exemplo n.º 5
0
 // By locking the volume before you dismount it, you can ensure that the volume is dismounted cleanly
 // (because the system flushes all cached data to the volume before locking it)
 //
 // A locked volume remains locked until one of the following occurs:
 // * The application uses the FSCTL_UNLOCK_VOLUME control code to unlock the volume.
 // * The handle closes, either directly through CloseHandle, or indirectly when a process terminates.
 // http://msdn.microsoft.com/en-us/library/bb521494(v=winembedded.5).aspx
 // http://msdn.microsoft.com/en-us/library/Aa364575
 /// <param name="handle">
 /// The application must specify the FILE_SHARE_READ and FILE_SHARE_WRITE flags in the dwShareMode parameter of CreateFile.
 /// https://msdn.microsoft.com/en-us/library/Aa364575
 /// </param>
 public static bool LockVolume(SafeFileHandle handle)
 {
     if (!handle.IsInvalid)
     {
         uint dummy;
         bool success = PhysicalDiskControl.DeviceIoControl(handle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out dummy, IntPtr.Zero);
         return(success);
     }
     else
     {
         return(false);
     }
 }
Exemplo n.º 6
0
 /// <summary>
 /// Note: The NTFS file system treats a locked volume as a dismounted volume.
 /// </summary>
 /// <param name="handle">When opening a volume, the dwShareMode parameter must have the FILE_SHARE_WRITE flag.</param>
 public static bool IsVolumeMounted(SafeFileHandle handle)
 {
     if (!handle.IsInvalid)
     {
         uint dummy;
         bool mounted = PhysicalDiskControl.DeviceIoControl(handle, FSCTL_IS_VOLUME_MOUNTED, IntPtr.Zero, 0, IntPtr.Zero, 0, out dummy, IntPtr.Zero);
         handle.Close();
         return(mounted);
     }
     else
     {
         return(false);
     }
 }
        private void PopulateDiskInfo()
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.Read, ShareMode.ReadWrite, out releaseHandle);

            if (!handle.IsInvalid)
            {
                if (!PhysicalDiskControl.IsMediaAccesible(handle))
                {
                    throw new DeviceNotReadyException();
                }
                DISK_GEOMETRY diskGeometry = PhysicalDiskControl.GetDiskGeometryAndSize(handle, out m_size);
                if (releaseHandle)
                {
                    PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
                }
                m_bytesPerSector = (int)diskGeometry.BytesPerSector;

                // CHS:
                m_cylinders         = diskGeometry.Cylinders;
                m_tracksPerCylinder = (int)diskGeometry.TracksPerCylinder;
                m_sectorsPerTrack   = (int)diskGeometry.SectorsPerTrack;
            }
            else
            {
                // we always release invalid handle
                PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);

                // get error code and throw
                int    errorCode = Marshal.GetLastWin32Error();
                string message   = String.Format("Failed to access disk {0}.", m_physicalDiskIndex);
                if (errorCode == (int)Win32Error.ERROR_FILE_NOT_FOUND)
                {
                    throw new DriveNotFoundException(message);
                }
                else
                {
                    IOExceptionHelper.ThrowIOError(errorCode, message);
                }
            }
        }
Exemplo n.º 8
0
 public static bool AllowExtendedIO(SafeFileHandle handle)
 {
     if (!handle.IsInvalid)
     {
         uint dummy;
         bool success = PhysicalDiskControl.DeviceIoControl(handle, FSCTL_ALLOW_EXTENDED_DASD_IO, IntPtr.Zero, 0, IntPtr.Zero, 0, out dummy, IntPtr.Zero);
         if (!success)
         {
             int errorCode = Marshal.GetLastWin32Error();
             if (errorCode == (int)Win32Error.ERROR_ACCESS_DENIED)
             {
                 throw new UnauthorizedAccessException();
             }
         }
         return(success);
     }
     else
     {
         return(false);
     }
 }
Exemplo n.º 9
0
 // Forced dismount only does FSCTL_DISMOUNT_VOLUME (without locking the volume first),
 // and then does the formatting write/verify operations _from this very handle_.
 // Then the handle is just closed, and any next attempt to access the volume will automount it.
 /// <param name="handle">
 /// The application must specify the FILE_SHARE_READ and FILE_SHARE_WRITE flags in the dwShareMode parameter of CreateFile.
 /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364562%28v=vs.85%29.aspx
 /// </param>
 public static bool DismountVolume(SafeFileHandle handle)
 {
     if (!handle.IsInvalid)
     {
         uint dummy;
         bool success = PhysicalDiskControl.DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out dummy, IntPtr.Zero);
         if (!success)
         {
             int errorCode = Marshal.GetLastWin32Error();
             if (errorCode == (int)Win32Error.ERROR_ACCESS_DENIED)
             {
                 throw new UnauthorizedAccessException();
             }
         }
         return(success);
     }
     else
     {
         return(false);
     }
 }
        /// <summary>
        /// Invalidates the cached partition table and re-enumerates the device
        /// </summary>
        /// <exception cref="System.IO.IOException"></exception>
        public void UpdateProperties()
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.ReadWrite, ShareMode.Read, out releaseHandle);

            if (!handle.IsInvalid)
            {
                bool success = PhysicalDiskControl.UpdateDiskProperties(handle);
                if (!success)
                {
                    throw new IOException("Failed to update disk properties");
                }
                if (releaseHandle)
                {
                    PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
                }
            }
            else
            {
                // we always release invalid handle
                PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
            }
        }