/// <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); }