예제 #1
0
        public override void ExtendFast(long additionalNumberOfBytes)
        {
            if (additionalNumberOfBytes % this.BytesPerSector > 0)
            {
                throw new ArgumentException("additionalNumberOfBytes must be a multiple of BytesPerSector");
            }

            long       length = this.Size;
            bool       hasManageVolumePrivilege = SecurityUtils.ObtainManageVolumePrivilege();
            FileStream stream = new FileStream(this.Path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read, 0x1000, FILE_FLAG_NO_BUFFERING | FileOptions.WriteThrough);

            try
            {
                stream.SetLength(length + additionalNumberOfBytes);
            }
            catch
            {
                stream.Close();
                throw;
            }
            if (hasManageVolumePrivilege)
            {
                FileStreamUtils.SetValidLength(stream, length + additionalNumberOfBytes);
            }
            stream.Close();
        }
예제 #2
0
        /// <param name="size">In bytes</param>
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="System.UnauthorizedAccessException"></exception>
        internal static RawDiskImage Create(string path, long size, int bytesPerSector)
        {
            if (size % bytesPerSector > 0)
            {
                throw new ArgumentException("size must be a multiple of bytesPerSector");
            }

            bool hasManageVolumePrivilege = false;

            if (IsWin32())
            {
                // calling AdjustTokenPrivileges and then immediately calling SetFileValidData will sometimes result in ERROR_PRIVILEGE_NOT_HELD.
                // We can work around the issue by obtaining the privilege before obtaining the handle.
                hasManageVolumePrivilege = SecurityUtils.ObtainManageVolumePrivilege();
            }

            FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);

            try
            {
                stream.SetLength(size);
            }
            catch (IOException)
            {
                stream.Close();
                try
                {
                    // Delete the incomplete file
                    File.Delete(path);
                }
                catch (IOException)
                {
                }
                throw;
            }

            if (hasManageVolumePrivilege)
            {
                try
                {
                    FileStreamUtils.SetValidLength(stream, size);
                }
                catch (IOException)
                {
                }
            }

            stream.Close();
            return(new RawDiskImage(path, bytesPerSector));
        }
예제 #3
0
        /// <exception cref="System.IO.IOException"></exception>
        public override void Extend(long numberOfAdditionalBytes)
        {
            if (numberOfAdditionalBytes % this.BytesPerSector > 0)
            {
                throw new ArgumentException("numberOfAdditionalBytes must be a multiple of BytesPerSector");
            }
#if Win32
            // calling AdjustTokenPrivileges and then immediately calling SetFileValidData will sometimes result in ERROR_PRIVILEGE_NOT_HELD.
            // We can work around the issue by obtaining the privilege before obtaining the handle.
            bool hasManageVolumePrivilege = SecurityUtils.ObtainManageVolumePrivilege();
#endif
            if (!m_isExclusiveLock)
            {
                m_stream = OpenFileStream();
            }
            else
            {
                // Workaround for AdjustTokenPrivileges issue
                ReleaseLock();
                ExclusiveLock();
            }

            m_stream.SetLength(m_size + numberOfAdditionalBytes);
            m_size += numberOfAdditionalBytes;
#if Win32
            if (hasManageVolumePrivilege)
            {
                try
                {
                    FileStreamUtils.SetValidLength(m_stream, m_size);
                }
                catch (IOException)
                {
                }
            }
#endif
            if (!m_isExclusiveLock)
            {
                m_stream.Close();
            }
        }
예제 #4
0
        /// <param name="length">In bytes</param>
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="System.UnauthorizedAccessException"></exception>
        public static VirtualHardDisk Create(string path, long length)
        {
            bool       hasManageVolumePrivilege = SecurityUtils.ObtainManageVolumePrivilege();
            FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);

            try
            {
                stream.SetLength(length + 512); // VHD footer is 512 bytes
                if (hasManageVolumePrivilege)
                {
                    FileStreamUtils.SetValidLength(stream, length + 512);
                }
            }
            catch (IOException)
            {
                stream.Close();
                try
                {
                    // Delete the incomplete file
                    File.Delete(path);
                }
                catch (IOException)
                {
                }
                throw;
            }

            VHDFooter footer = new VHDFooter();

            footer.OriginalSize = (ulong)length;
            footer.CurrentSize  = (ulong)length;
            footer.SetCurrentTimeStamp();
            footer.SetDiskGeometry((ulong)length / DiskImage.DEFAULT_BYTES_PER_SECTOR);
            stream.Seek(length, SeekOrigin.Begin);
            stream.Write(footer.GetBytes(), 0, VHDFooter.Length);
            stream.Close();
            return(new VirtualHardDisk(path));
        }