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