Exemplo n.º 1
0
        /// <summary>
        /// This method is used to read the record segment of the MFT itself.
        /// Only after strapping the MFT we can use GetFileRecordSegment which relies on the MFT file record.
        /// </summary>
        private FileRecordSegment ReadFileRecordSegment(long mftStartLCN, long segmentNumber)
        {
            long sectorIndex = mftStartLCN * m_volume.SectorsPerCluster + segmentNumber * m_volume.SectorsPerFileRecordSegment;

            byte[]            bytes  = m_volume.ReadSectors(sectorIndex, m_volume.SectorsPerFileRecordSegment);
            FileRecordSegment result = new FileRecordSegment(bytes, 0, segmentNumber);

            return(result);
        }
        public byte[] ReadSectors(long firstSectorIndex, int count)
        {
            int  sectorsPerCluster     = m_volume.SectorsPerCluster;
            int  bytesPerSector        = m_volume.BytesPerSector;
            long firstClusterVCN       = firstSectorIndex / sectorsPerCluster;
            long lastSectorIndexToRead = firstSectorIndex + count - 1;
            long lastClusterVCNToRead  = lastSectorIndexToRead / sectorsPerCluster;

            if (firstClusterVCN < LowestVCN || firstClusterVCN > HighestVCN)
            {
                string message = String.Format("Cluster VCN {0}-{1} is not within the valid range ({2}-{3})", firstClusterVCN, lastClusterVCNToRead, LowestVCN, HighestVCN);
                throw new ArgumentOutOfRangeException(message);
            }

            long highestSectorIndex = (HighestVCN + 1) * sectorsPerCluster - 1;

            if (lastSectorIndexToRead > highestSectorIndex)
            {
                lastSectorIndexToRead = highestSectorIndex;
            }

            byte[] result            = new byte[count * bytesPerSector];
            ulong  firstBytePosition = (ulong)firstSectorIndex * (uint)bytesPerSector;

            if (firstBytePosition < ValidDataLength)
            {
                KeyValuePairList <long, int> sequence = m_attributeRecord.DataRunSequence.TranslateToLBN(firstSectorIndex, count, sectorsPerCluster);
                long bytesRead = 0;
                foreach (KeyValuePair <long, int> run in sequence)
                {
                    byte[] data = m_volume.ReadSectors(run.Key, run.Value, m_contentType);
                    Array.Copy(data, 0, result, bytesRead, data.Length);
                    bytesRead += data.Length;
                }
            }

            int numberOfBytesToReturn = count * bytesPerSector;

            if (firstBytePosition + (uint)numberOfBytesToReturn > FileSize)
            {
                // If the last sector is only partially used or we have been asked to read beyond FileSize, trim result.
                numberOfBytesToReturn = (int)(FileSize - (ulong)firstSectorIndex * (uint)bytesPerSector);
                byte[] resultTrimmed = new byte[numberOfBytesToReturn];
                Array.Copy(result, resultTrimmed, numberOfBytesToReturn);
                result = resultTrimmed;
            }

            if (firstBytePosition < ValidDataLength && ValidDataLength < firstBytePosition + (uint)numberOfBytesToReturn)
            {
                // Zero-out bytes outside ValidDataLength
                int numberOfValidBytesInResult = (int)(ValidDataLength - firstBytePosition);
                ByteWriter.WriteBytes(result, numberOfValidBytesInResult, new byte[result.Length - numberOfValidBytesInResult]);
            }

            return(result);
        }
        /// <summary>
        /// This method is used to read the record segment(s) of the MFT itself.
        /// Only after strapping the MFT we can use GetFileRecordSegment which relies on the MFT file record.
        /// </summary>
        private FileRecordSegment ReadMftRecordSegment(long mftStartLCN, long segmentNumber)
        {
            long sectorIndex = mftStartLCN * m_volume.SectorsPerCluster + segmentNumber * m_volume.SectorsPerFileRecordSegment;

            byte[] segmentBytes = m_volume.ReadSectors(sectorIndex, m_volume.SectorsPerFileRecordSegment, ContentType.MftData);
            MultiSectorHelper.RevertUsaProtection(segmentBytes, 0);
            FileRecordSegment result = new FileRecordSegment(segmentBytes, 0, segmentNumber);

            return(result);
        }