/// <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 = VolumeHandlePool.ObtainHandle(m_volumeGuid, 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)
                    {
                        VolumeHandlePool.ReleaseHandle(m_volumeGuid);
                    }
                }
                return(buffer);
            }
            else
            {
                // we always release invalid handle
                VolumeHandlePool.ReleaseHandle(m_volumeGuid);
                // get error code and throw
                int    errorCode = Marshal.GetLastWin32Error();
                string message   = String.Format("Can't read sector {0} from volume {1}, Win32 Error: {2}", sectorIndex, m_volumeGuid, errorCode);
                throw new IOException(message);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Windows will flush all cached data to the volume before locking it.
        /// Note: we can only lock a dynamic volume if the disk is online.
        /// </summary>
        /// <returns>True if a new lock has been obtained</returns>
        public static bool ExclusiveLock(Guid windowsVolumeGuid, FileAccess fileAccess)
        {
            bool newAllocation;
            // Windows Vista / 7: Valid handle cannot be obtained for a dynamic volume using ShareMode.ReadWrite.
            // The FSCTL_LOCK_VOLUME documentation demands ShareMode.ReadWrite, but ShareMode.None or ShareMode.Write will work too.
            SafeFileHandle handle = VolumeHandlePool.ObtainHandle(windowsVolumeGuid, fileAccess, ShareMode.None, out newAllocation);

            if (newAllocation)
            {
                if (!handle.IsInvalid)
                {
                    bool success = VolumeUtils.LockVolume(handle);
                    if (!success)
                    {
                        VolumeHandlePool.ReleaseHandle(windowsVolumeGuid);
                    }
                    return(success);
                }
                else
                {
                    VolumeHandlePool.ReleaseHandle(windowsVolumeGuid);
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Note that the volume will be remounted again on first access.
        /// </summary>
        public static bool DismountVolume(Guid windowsVolumeGuid)
        {
            bool           releaseHandle;
            SafeFileHandle handle  = VolumeHandlePool.ObtainHandle(windowsVolumeGuid, FileAccess.ReadWrite, ShareMode.ReadWrite, out releaseHandle);
            bool           success = false;

            if (!handle.IsInvalid)
            {
                success = VolumeUtils.DismountVolume(handle);
            }

            if (releaseHandle) // new allocation
            {
                VolumeHandlePool.ReleaseHandle(windowsVolumeGuid);
            }
            return(success);
        }
        /// <summary>
        /// Volume should be locked at this point for this call to have any effect
        /// </summary>
        /// <returns></returns>
        public bool AllowExtendedIO()
        {
            bool           releaseHandle;
            SafeFileHandle handle = VolumeHandlePool.ObtainHandle(m_volumeGuid, FileAccess.ReadWrite, ShareMode.None, out releaseHandle);

            if (!handle.IsInvalid)
            {
                bool result = VolumeControl.AllowExtendedIO(handle);
                if (releaseHandle)
                {
                    VolumeHandlePool.ReleaseHandle(m_volumeGuid);
                }
                return(result);
            }
            else
            {
                // we always release invalid handle
                VolumeHandlePool.ReleaseHandle(m_volumeGuid);
                return(false);
            }
        }
        public void WriteSectorsUnbuffered(long sectorIndex, byte[] data)
        {
            if (data.Length % m_bytesPerSector > 0)
            {
                throw new IOException("Cannot write partial sectors");
            }

            if (!m_isReadOnly)
            {
                bool           releaseHandle;
                SafeFileHandle handle = VolumeHandlePool.ObtainHandle(m_volumeGuid, FileAccess.ReadWrite, ShareMode.None, 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)
                        {
                            VolumeHandlePool.ReleaseHandle(m_volumeGuid);
                        }
                    }
                }
                else
                {
                    // we always release invalid handle
                    VolumeHandlePool.ReleaseHandle(m_volumeGuid);
                    // get error code and throw
                    int    errorCode = Marshal.GetLastWin32Error();
                    string message   = String.Format("Can't write to sector {0} of volume {1}, Win32 errorCode: {2}", sectorIndex, m_volumeGuid, errorCode);
                    throw new IOException(message);
                }
            }
        }
Esempio n. 6
0
 public static bool ReleaseLock(Guid windowsVolumeGuid)
 {
     return(VolumeHandlePool.ReleaseHandle(windowsVolumeGuid));
 }