public static byte[] getBytes(string volume) { // Get handle for volume IntPtr hVolume = NativeMethods.getHandle(volume); // Get filestream based on hVolume using (FileStream streamToRead = NativeMethods.getFileStream(hVolume)) { VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); FileRecord logFileRecord = GetFileRecord(volume); NonResident data = GetDataAttr(logFileRecord); return(data.GetBytes(volume)); } }
public byte[] GetBytes(string volume) { byte[] fileBytes = new byte[this.RealSize]; int offset = 0; NativeMethods.getVolumeName(ref volume); IntPtr hVolume = NativeMethods.getHandle(volume); using (FileStream streamToRead = NativeMethods.getFileStream(hVolume)) { VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); foreach (DataRun dr in this.DataRun) { if (dr.Sparse) { // Figure out how to add Sparse Bytes } else { ulong startOffset = (ulong)VBR.BytesPerCluster * (ulong)dr.StartCluster; ulong count = (ulong)VBR.BytesPerCluster * (ulong)dr.ClusterLength; byte[] dataRunBytes = NativeMethods.readDrive(streamToRead, startOffset, count); if (((ulong)offset + count) <= (ulong)fileBytes.Length) { // Save dataRunBytes to fileBytes Array.Copy(dataRunBytes, 0, fileBytes, offset, dataRunBytes.Length); // Increment Offset Value offset += dataRunBytes.Length; } else { Array.Copy(dataRunBytes, 0, fileBytes, offset, (fileBytes.Length - offset)); break; } } } return(fileBytes); } }
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); } }
public static UsnJrnl Get(string volume, ulong usn) { // Check for valid Volume name NativeMethods.getVolumeName(ref volume); // Set up FileStream to read volume IntPtr hVolume = NativeMethods.getHandle(volume); FileStream streamToRead = NativeMethods.getFileStream(hVolume); // Get VolumeBootRecord object for logical addressing VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Get the $J Data attribute (contains UsnJrnl details NonResident J = UsnJrnl.GetJStream(UsnJrnl.GetFileRecord(volume)); // Determine the length of the initial sparse pages ulong SparseLength = (ulong)J.DataRun[0].ClusterLength * VBR.BytesPerCluster; // Subtract length of sparse data from desired usn offset ulong usnOffset = usn - SparseLength; // Iterate through each data run for (int i = 1; i < J.DataRun.Length; i++) { // Determine length of current DataRun ulong dataRunLength = (ulong)J.DataRun[i].ClusterLength * VBR.BytesPerCluster; // Check if usnOffset resides in current DataRun if (dataRunLength <= usnOffset) { // If not, subtract length of DataRun from usnOffset usnOffset -= dataRunLength; } // If usnOffset resides within DataRun, parse associated UsnJrnl Entry else { // Read DataRun from disk byte[] fragmentBytes = NativeMethods.readDrive(streamToRead, ((ulong)J.DataRun[i].StartCluster * VBR.BytesPerCluster), ((ulong)J.DataRun[i].ClusterLength * VBR.BytesPerCluster)); // Instatiate a byte array that is the size of a single cluster byte[] clusterBytes = new byte[VBR.BytesPerCluster]; // Iterate through the clusters in the DataRun for (long j = 0; j < J.DataRun[i].ClusterLength; j++) { // If usnOffset is not in current cluster, then subtract cluster size from offset and iterate if (VBR.BytesPerCluster <= usnOffset) { usnOffset -= VBR.BytesPerCluster; } // Else if usnOffset is in current cluster else { // Copy current cluster bytes to clusterBytes variable Array.Copy(fragmentBytes, ((long)j * VBR.BytesPerCluster), clusterBytes, 0, clusterBytes.Length); // Parse desired UsnJrnl entry from cluster int offset = (int)usnOffset; return(new UsnJrnl(clusterBytes, volume, ref offset)); } } } } return(null); }
internal static Bitmap Get(string volume, ulong cluster) { ulong sectorOffset = cluster / 4096; ulong byteOffset = (cluster % 4096) / 8; // Check for valid Volume name NativeMethods.getVolumeName(ref volume); IntPtr hVolume = NativeMethods.getHandle(volume); // Set up FileStream to read volume FileStream streamToRead = NativeMethods.getFileStream(hVolume); // Get VolumeBootRecord object for logical addressing VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Get the Data attribute NonResident dataStream = Bitmap.GetDataStream(Bitmap.GetFileRecord(volume)); // Calulate the offset of the Bitmap file's data ulong dataRunOffset = (ulong)dataStream.DataRun[0].StartCluster * VBR.BytesPerCluster; // Calculate the offset of the sector that contains the entry for the specific cluster ulong offset = dataRunOffset + (VBR.BytesPerSector * sectorOffset); // Read appropriate sector byte[] bytes = NativeMethods.readDrive(streamToRead, offset, VBR.BytesPerSector); byte b = bytes[byteOffset]; bool inUse = false; switch (cluster % 8) { case 0: if ((b & 0x01) > 0) { inUse = true; } break; case 1: if ((b & 0x02) > 0) { inUse = true; } break; case 2: if ((b & 0x04) > 0) { inUse = true; } break; case 3: if ((b & 0x08) > 0) { inUse = true; } break; case 4: if ((b & 0x10) > 0) { inUse = true; } break; case 5: if ((b & 0x20) > 0) { inUse = true; } break; case 6: if ((b & 0x40) > 0) { inUse = true; } break; case 7: if ((b & 0x80) > 0) { inUse = true; } break; } return(new Bitmap(cluster, inUse)); }
internal static Bitmap[] GetInstances(string volume) { // Check for valid Volume name NativeMethods.getVolumeName(ref volume); // Set up FileStream to read volume IntPtr hVolume = NativeMethods.getHandle(volume); FileStream streamToRead = NativeMethods.getFileStream(hVolume); // Get VolumeBootRecord object for logical addressing VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead); // Get the Data attribute NonResident dataStream = Bitmap.GetDataStream(Bitmap.GetFileRecord(volume)); byte[] bytes = NativeMethods.readDrive(streamToRead, ((ulong)dataStream.DataRun[0].StartCluster * VBR.BytesPerCluster), ((ulong)dataStream.DataRun[0].ClusterLength * VBR.BytesPerCluster)); Bitmap[] bitmapArray = new Bitmap[bytes.Length * 8]; for (int j = 0; j < bytes.Length; j++) { for (int k = 0; k < 8; k++) { bool inUse = false; int index = ((j * 8) + k); switch (k) { case 0: if ((bytes[j] & 0x01) > 0) { inUse = true; } break; case 1: if ((bytes[j] & 0x02) > 0) { inUse = true; } break; case 2: if ((bytes[j] & 0x04) > 0) { inUse = true; } break; case 3: if ((bytes[j] & 0x08) > 0) { inUse = true; } break; case 4: if ((bytes[j] & 0x10) > 0) { inUse = true; } break; case 5: if ((bytes[j] & 0x20) > 0) { inUse = true; } break; case 6: if ((bytes[j] & 0x40) > 0) { inUse = true; } break; case 7: if ((bytes[j] & 0x80) > 0) { inUse = true; } break; } bitmapArray[index] = new Bitmap((ulong)index, inUse); } } return(bitmapArray); }
internal static VolumeBootRecord Get(FileStream streamToRead) { return(new VolumeBootRecord(VolumeBootRecord.GetBytes(streamToRead))); }
public static VolumeBootRecord Get(string path) { return(new VolumeBootRecord(VolumeBootRecord.GetBytes(path))); }