예제 #1
0
        /// <summary>
        /// Available on Windows Vista and newer
        /// </summary>
        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 = PhysicalDiskUtils.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("Can't take disk {0} offline, Win32 Error: {1}", m_physicalDiskIndex, errorCode);
                    throw new IOException(message);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Sector refers to physical disk blocks, we can only read complete blocks
        /// </summary>
        public byte[] ReadSectorsUnbuffered(long sectorIndex, int sectorCount)
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.Read, ShareMode.ReadWrite, out releaseHandle);

            if (!handle.IsInvalid)
            {
                FileStreamEx stream = new FileStreamEx(handle, FileAccess.Read);
                byte[]       buffer = new byte[m_bytesPerSector * sectorCount];
                try
                {
                    stream.Seek(sectorIndex * m_bytesPerSector, SeekOrigin.Begin);
                    stream.Read(buffer, 0, m_bytesPerSector * sectorCount);
                }
                finally
                {
                    stream.Close(releaseHandle);
                    if (releaseHandle)
                    {
                        PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
                    }
                }
                return(buffer);
            }
            else
            {
                // we always release invalid handle
                PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
                // get error code and throw
                int    errorCode = Marshal.GetLastWin32Error();
                string message   = String.Format("Can't read sector {0} from disk {1}, Win32 Error: {2}", sectorIndex, m_physicalDiskIndex, errorCode);
                throw new IOException(message, errorCode);
            }
        }
예제 #3
0
        private void PopulateDescription()
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.Read, ShareMode.ReadWrite, out releaseHandle);

            if (!handle.IsInvalid)
            {
                m_description  = PhysicalDiskUtils.GetDeviceDescription(handle);
                m_serialNumber = PhysicalDiskUtils.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("Can't read from disk {0}", m_physicalDiskIndex);
                if (errorCode == (int)Win32Error.ERROR_FILE_NOT_FOUND)
                {
                    throw new DriveNotFoundException(message);
                }
                else
                {
                    FileStreamEx.ThrowIOError(errorCode, message);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Available on Windows Vista and newer
        /// </summary>
        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 = PhysicalDiskUtils.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("Can't get disk {0} online status, Win32 Error: {1}", m_physicalDiskIndex, errorCode);
                throw new IOException(message);
            }
        }
예제 #5
0
        public void WriteSectorsUnbuffered(long sectorIndex, byte[] data)
        {
            if (data.Length % m_bytesPerSector > 0)
            {
                throw new IOException("Cannot write partial sectors");
            }

            if (IsReadOnly)
            {
                throw new UnauthorizedAccessException("Attempted to perform write on a readonly disk");
            }

            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.ReadWrite, ShareMode.Read, out releaseHandle);

            if (!handle.IsInvalid)
            {
                FileStreamEx stream = new FileStreamEx(handle, FileAccess.Write);
                try
                {
                    stream.Seek(sectorIndex * m_bytesPerSector, SeekOrigin.Begin);
                    stream.Write(data, 0, data.Length);
                    stream.Flush();
                }
                finally
                {
                    stream.Close(releaseHandle);
                    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("Can't write to sector {0} of disk {1}", sectorIndex, m_physicalDiskIndex);
                FileStreamEx.ThrowIOError(errorCode, message);
            }
        }
예제 #6
0
        private void PopulateDiskInfo()
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.Read, ShareMode.ReadWrite, out releaseHandle);

            if (!handle.IsInvalid)
            {
                if (!PhysicalDiskUtils.IsMediaAccesible(handle))
                {
                    throw new DeviceNotReadyException();
                }
                DISK_GEOMETRY diskGeometry = PhysicalDiskUtils.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("Can't read from disk {0}", m_physicalDiskIndex);
                if (errorCode == (int)Win32Error.ERROR_FILE_NOT_FOUND)
                {
                    throw new DriveNotFoundException(message);
                }
                else
                {
                    FileStreamEx.ThrowIOError(errorCode, message);
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Invalidates the cached partition table and re-enumerates the device
        /// </summary>
        public void UpdateProperties()
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.ReadWrite, ShareMode.Read, out releaseHandle);

            if (!handle.IsInvalid)
            {
                bool success = PhysicalDiskUtils.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);
            }
        }
예제 #8
0
        public bool ExclusiveLock()
        {
            bool           releaseHandle;
            SafeFileHandle handle = PhysicalDiskHandlePool.ObtainHandle(m_physicalDiskIndex, FileAccess.ReadWrite, ShareMode.Read, out releaseHandle);

            if (releaseHandle) // new allocation
            {
                if (!handle.IsInvalid)
                {
                    return(true);
                }
                else
                {
                    // we always release invalid handle
                    PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex);
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
예제 #9
0
 public bool ReleaseLock()
 {
     return(PhysicalDiskHandlePool.ReleaseHandle(m_physicalDiskIndex));
 }