Пример #1
0
        public void Extend()
        {
            ulong additionalDataLength   = (ulong)(m_volume.BytesPerFileRecordSegment * ExtendGranularity);
            ulong additionalBitmapLength = ExtendGranularity / 8;
            // We calculate the maximum possible number of free cluster required
            long numberOfClustersRequiredForData   = (long)Math.Ceiling((double)additionalDataLength / m_volume.BytesPerCluster);
            long numberOfClustersRequiredForBitmap = (long)Math.Ceiling((double)additionalBitmapLength / m_volume.BytesPerCluster);

            if (numberOfClustersRequiredForData + numberOfClustersRequiredForBitmap > m_volume.NumberOfFreeClusters)
            {
                throw new DiskFullException();
            }

            // We have to extend the bitmap first because one of the constructor parameters is the size of the data.
            // MFT Bitmap: ValidDataLength could be smaller than FileSize, however, we will later copy the value of ValidDataLength.
            // to the MFT mirror, we have to make sure that the copy will not become stale after writing beyond the current ValidDataLength.
            m_mftFile.Bitmap.ExtendBitmap(ExtendGranularity, true);

            // MFT Data: ValidDataLength must be equal to FileSize.
            // This will take care of the FileNameRecord and RootDirectory index as well.
            // Note: The NTFS v5.1 driver does not bother updating the FileNameRecord.
            m_mftFile.WriteData(m_mftFile.Data.Length, new byte[additionalDataLength]);

            // Update the MFT mirror
            MasterFileTable mftMirror = new MasterFileTable(m_volume, false, true);
            // When the MFT has an attribute list, CHKDSK expects the mirror to contain the segment references from the MFT as-is.
            FileRecordSegment mftRecordSegmentFromMirror = mftMirror.GetFileRecordSegment(MasterFileTableSegmentNumber);

            mftRecordSegmentFromMirror.ImmediateAttributes.Clear();
            mftRecordSegmentFromMirror.ImmediateAttributes.AddRange(m_mftFile.FileRecord.BaseSegment.ImmediateAttributes);
            // CHKDSK seems to expect the mirror's NextAttributeInstance to be the same as the MFT.
            mftRecordSegmentFromMirror.NextAttributeInstance = m_mftFile.FileRecord.BaseSegment.NextAttributeInstance;
            mftMirror.UpdateFileRecordSegment(mftRecordSegmentFromMirror);
        }
Пример #2
0
 public override void Write(byte[] buffer, int offset, int count)
 {
     byte[] data = new byte[count];
     Array.Copy(buffer, offset, data, 0, count);
     m_file.WriteData((ulong)m_position, data);
     m_position += count;
 }
Пример #3
0
 public override void Write(byte[] buffer, int offset, int count)
 {
     if (!CanWrite)
     {
         throw new AccessViolationException("Stream was not opened for write access");
     }
     byte[] data = new byte[count];
     Array.Copy(buffer, offset, data, 0, count);
     m_file.WriteData((ulong)m_position, data);
     m_position += count;
 }