public static byte[] GetRecordBytes(string volume, int index) { // Get handle for volume IntPtr hVolume = NativeMethods.getHandle(volume); // Get filestream based on hVolume using (FileStream streamToRead = NativeMethods.getFileStream(hVolume)) { // Get Volume Boot Record Ntfs.VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Determine start of MFT ulong mftStartOffset = VBR.MFTStartIndex * VBR.BytesPerCluster; // Get FileRecord for $MFT FileRecord mftRecord = MasterFileTable.GetRecord(streamToRead, volume); // Get $MFT Data Attribute NonResident data = null; foreach (Attr attr in mftRecord.Attribute) { if (attr.Name == Attr.ATTR_TYPE.DATA) { data = attr as NonResident; } } // Iterate through fragments of the MFT foreach (DataRun dr in data.DataRun) { ulong DataRunRecords = ((ulong)dr.ClusterLength * (ulong)VBR.BytesPerCluster) / (ulong)VBR.BytesPerFileRecord; // Check if index can be found in current DataRun if (index < (int)DataRunRecords) { ulong recordOffset = ((ulong)dr.StartCluster * (ulong)VBR.BytesPerCluster) + ((ulong)index * (ulong)VBR.BytesPerFileRecord); byte[] recordBytesRaw = NativeMethods.readDrive(streamToRead, recordOffset, (ulong)VBR.BytesPerFileRecord); ApplyFixup(ref recordBytesRaw); return(recordBytesRaw); } // Decrement index for the number of FileRecords in the current DataRun else { index -= ((int)dr.ClusterLength * (int)VBR.BytesPerCluster) / (int)VBR.BytesPerFileRecord; } } throw new Exception("Could not find the FileRecord requested..."); } }
public static FileRecord[] GetInstances(string volume) { IntPtr hVolume = NativeMethods.getHandle(volume); using (FileStream streamToRead = NativeMethods.getFileStream(hVolume)) { // Get the FileRecord for the $MFT file //FileRecord mftRecord = new FileRecord(FileRecord.GetRecordBytes(volume, 0), volume); byte[] mftBytes = MasterFileTable.GetBytes(streamToRead, volume); // Determine the size of an MFT File Record int bytesPerFileRecord = (int)(VolumeBootRecord.Get(streamToRead)).BytesPerFileRecord; // Calulate the number of entries in the MFT int fileCount = mftBytes.Length / bytesPerFileRecord; // Instantiate an array of FileRecord objects FileRecord[] recordArray = new FileRecord[fileCount]; // Instantiate a byte array large enough to store the bytes belonging to a file record byte[] recordBytes = new byte[bytesPerFileRecord]; // Now we need to iterate through all possible index values for (int index = 0; index < fileCount; index++) { // Check if current record has been instantiated if (recordArray[index] == null) { // Copy filerecord bytes into the recordBytes byte[] Array.Copy(mftBytes, index * bytesPerFileRecord, recordBytes, 0, recordBytes.Length); // Take UpdateSequence into account ApplyFixup(ref recordBytes); // Instantiate FileRecord object recordArray[index] = new FileRecord(ref recordArray, recordBytes, volume); } } return(recordArray); } }