public static NtfsFile OpenFile(NtfsDirectory dir, string file) { NtfsFile currFile = dir.ListFiles(false).SingleOrDefault(s => s.Name.Equals(file, StringComparison.InvariantCultureIgnoreCase)); Debug.Assert(currFile != null); return(currFile); }
public void EnumerateChilds() { Random rand = new Random(); using (TempDir tmpDir = new TempDir()) { // Make files byte[] data = new byte[1024 * 1024]; for (int i = 0; i < 10; i++) { rand.NextBytes(data); File.WriteAllBytes(Path.Combine(tmpDir.Directory.FullName, i + ".bin"), data); } // Make dirs for (int i = 0; i < 10; i++) { rand.NextBytes(data); tmpDir.Directory.CreateSubdirectory("dir" + i); } // Discover dir in NTFSLib char driveLetter = tmpDir.Directory.FullName[0]; RawDisk disk = new RawDisk(driveLetter); NTFSDiskProvider provider = new NTFSDiskProvider(disk); NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0); NtfsDirectory ntfsDir = NTFSHelpers.OpenDir(ntfsWrapper, tmpDir.Directory.FullName); // Enumerate files List <NtfsFile> ntfsFiles = ntfsDir.ListFiles().ToList(); Assert.AreEqual(10, ntfsFiles.Count); for (int i = 0; i < 10; i++) { Assert.AreEqual(1, ntfsFiles.Count(s => s.Name == i + ".bin")); } // Enumerate dirs List <NtfsDirectory> ntfsDirs = ntfsDir.ListDirectories().ToList(); Assert.AreEqual(10, ntfsDirs.Count); for (int i = 0; i < 10; i++) { Assert.AreEqual(1, ntfsDirs.Count(s => s.Name == "dir" + i)); } } }
public static IEnumerable <NtfsFile> EnumerateFiles(char driveLetter, string directory) { if (string.IsNullOrWhiteSpace(directory)) { throw new ArgumentException("String cannot be null, empty or whitespace.", nameof(directory)); } using (RawDisk disk = new RawDisk(driveLetter, FileAccess.Read)) { NTFSDiskProvider provider = new NTFSDiskProvider(disk); NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, rawDiskCacheRecordSize); NtfsDirectory ntfsDir = NTFSHelpers.OpenDir(ntfsWrapper, directory); return(ntfsDir.ListFiles()); } }
private static uint FindPathMftId(Options opts) { string[] pathParts = opts.Source.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); string[] pathParents = pathParts.Skip(1).Take(pathParts.Length - 2).ToArray(); if (pathParts.Length == 1) { // Chosen path is root return((uint)SpecialMFTFiles.RootDir); } using (RawDisk disk = new RawDisk(opts.Drive)) { NTFSWrapper ntfs = new NTFSWrapper(new NTFSDiskProvider(disk), 4); // Navigate to parent directory NtfsDirectory parentDir = ntfs.GetRootDirectory(); for (int i = 0; i < pathParents.Length; i++) { parentDir = parentDir.ListDirectories(false).FirstOrDefault(s => s.Name.Equals(pathParents[i], StringComparison.InvariantCultureIgnoreCase)); if (parentDir == null) { return(uint.MaxValue); } } // Select the correct child IEnumerable <NtfsFileEntry> childs = parentDir.ListFiles(false); NtfsFileEntry child = childs.FirstOrDefault(s => s.Name.Equals(pathParts.Last(), StringComparison.InvariantCultureIgnoreCase)); if (child == null) { return(uint.MaxValue); } // Return the childs id return(child.MFTRecord.MFTNumber); } }
private static void PrintPaths(RawDisk disk, Options options) { uint mftId = uint.MaxValue; if (options.PathType == PathType.MftId) { AwesomeConsole.WriteLine("Specified an Mft Id - skipping forward-only search", ConsoleColor.DarkGreen); mftId = options.MftId; } else if (options.PathType == PathType.File || options.PathType == PathType.Directory) { AwesomeConsole.WriteLine("Conducting forward-only path search", ConsoleColor.Green); string[] pathParts = options.PathArgument.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); string[] pathParents = pathParts.Skip(1).Take(pathParts.Length - 2).ToArray(); NTFSWrapper ntfs = new NTFSWrapper(new NTFSDiskProvider(disk), 4); NtfsDirectory dir = ntfs.GetRootDirectory(); PrintName(dir.Name); AwesomeConsole.Write(" "); PrintReference(dir.MFTRecord.FileReference); AwesomeConsole.WriteLine(); string pathSoFar = options.Drive + ":\\"; for (int i = 0; i < pathParents.Length; i++) { AwesomeConsole.Write(pathSoFar, ConsoleColor.DarkYellow); if (dir == null) { PrintName(pathParents[i]); AwesomeConsole.Write(" "); PrintError("(Unable to find parent)"); AwesomeConsole.WriteLine(); } else { dir = dir.ListDirectories(false).FirstOrDefault(s => s.Name.Equals(pathParents[i], StringComparison.InvariantCultureIgnoreCase)); if (dir == null) { PrintName(pathParents[i]); AwesomeConsole.Write(" "); PrintError("(Unable to find this)"); AwesomeConsole.WriteLine(); } else { PrintName(dir.Name); AwesomeConsole.Write(" "); PrintReference(dir.MFTRecord.FileReference); AwesomeConsole.WriteLine(); } } pathSoFar = Path.Combine(pathSoFar, pathParents[i] + "\\"); } AwesomeConsole.Write(pathSoFar, ConsoleColor.DarkYellow); if (dir == null) { PrintName(pathParts.Last()); AwesomeConsole.Write(" "); PrintError("(Unable to find parent)"); AwesomeConsole.WriteLine(); } else { IEnumerable <NtfsFileEntry> childs = options.PathType == PathType.File ? (IEnumerable <NtfsFileEntry>)dir.ListFiles(false) : dir.ListDirectories(false); NtfsFileEntry child = childs.FirstOrDefault(s => s.Name.Equals(pathParts.Last(), StringComparison.InvariantCultureIgnoreCase)); if (child == null) { PrintName(pathParts.Last()); AwesomeConsole.Write(" "); PrintError("(Unable to find this)"); AwesomeConsole.WriteLine(); } else { PrintName(child.Name); AwesomeConsole.Write(" "); PrintReference(child.MFTRecord.FileReference); AwesomeConsole.WriteLine(); mftId = child.MFTRecord.MFTNumber; AwesomeConsole.WriteLine("Search completed, found MftId: " + mftId); } } } AwesomeConsole.WriteLine(); { NTFSWrapper wrapper = new NTFSWrapper(new NTFSDiskProvider(disk), 4); if (wrapper.FileRecordCount < mftId) { PrintError("Unable to locate the specified file, aborting."); AwesomeConsole.WriteLine(); return; } AwesomeConsole.WriteLine("Conducting backwards-only path search", ConsoleColor.Green); Dictionary <uint, List <string> > paths = new Dictionary <uint, List <string> >(); List <string> finalPaths = new List <string>(); FileRecord baseRecord = wrapper.ReadMFTRecord(mftId); foreach (AttributeFileName fileName in baseRecord.Attributes.OfType <AttributeFileName>().Concat(baseRecord.ExternalAttributes.OfType <AttributeFileName>())) { uint parentId = fileName.ParentDirectory.FileId; if (paths.ContainsKey(parentId)) { paths[parentId].Add(fileName.FileName); } else { paths[parentId] = new List <string> { fileName.FileName } }; } do { Dictionary <uint, List <string> > newPaths = new Dictionary <uint, List <string> >(); foreach (KeyValuePair <uint, List <string> > keyValuePair in paths) { if (keyValuePair.Key == (uint)SpecialMFTFiles.RootDir) { finalPaths.AddRange(keyValuePair.Value.Select(s => Path.Combine(options.Drive + ":\\", s))); } else { FileRecord record = wrapper.ReadMFTRecord(keyValuePair.Key); foreach (AttributeFileName fileName in record.Attributes.OfType <AttributeFileName>().Concat(record.ExternalAttributes.OfType <AttributeFileName>())) { uint parentId = fileName.ParentDirectory.FileId; if (newPaths.ContainsKey(parentId)) { newPaths[parentId].AddRange(keyValuePair.Value.Select(s => Path.Combine(fileName.FileName, s))); } else { newPaths[parentId] = new List <string>(keyValuePair.Value.Select(s => Path.Combine(fileName.FileName, s))); } } } } paths = newPaths; } while (paths.Any()); AwesomeConsole.WriteLine("Got " + finalPaths.Count + " paths"); foreach (string finalPath in finalPaths) { PrintName(finalPath); AwesomeConsole.WriteLine(); } } }
private static void DisplayDetails(NTFSWrapper wrapper, Options opts, NtfsDirectory dir) { Console.WriteLine("Listing details for " + dir.Name); IEnumerable <NtfsFileEntry> subDirs = dir.ListDirectories(!opts.ShowAllNames); IEnumerable <NtfsFileEntry> subFiles = dir.ListFiles(!opts.ShowAllNames); foreach (NtfsFileEntry entry in subDirs.Concat(subFiles)) { if (opts.ShowAllStreams) { // Stream display var streams = entry.MFTRecord.Attributes.Concat(entry.MFTRecord.ExternalAttributes).GroupBy(s => new { s.AttributeName, s.Type }); foreach (var stream in streams) { AwesomeConsole.WriteLine(); } } else { // Simple file display AwesomeConsole.Write(entry.TimeModified.ToString("yyyy-MM-dd HH:mm")); AwesomeConsole.Write(" "); if (opts.ShowFileIds) { AwesomeConsole.Write(entry.MFTRecord.FileReference); AwesomeConsole.Write(" "); } if (entry is NtfsDirectory) { AwesomeConsole.Write("<DIR>"); } else { AttributeData dataAttrib = entry.MFTRecord.Attributes.OfType <AttributeData>().FirstOrDefault(s => s.NameLength == 0); long fileSize = -1; if (dataAttrib != null && dataAttrib.NonResidentFlag == ResidentFlag.Resident) { fileSize = dataAttrib.ResidentHeader.ContentLength; } else if (dataAttrib != null && dataAttrib.NonResidentFlag == ResidentFlag.NonResident) { fileSize = (long)dataAttrib.NonResidentHeader.ContentSize; } AwesomeConsole.Write(fileSize.ToString("N0")); } AwesomeConsole.Write(" "); AwesomeConsole.Write(entry.Name); AwesomeConsole.WriteLine(); } } // Volume in drive C has no label. // Volume Serial Number is 50C3-B38B // Directory of C:\ //23-08-2012 12:51 1.024 .rnd //12-05-2013 13:04 <DIR> AMD //03-03-2013 09:51 <SYMLINKD> Cygwin [C:\Program Files (x86)\Cygwin] //14-11-2012 23:24 <DIR> Intel //14-07-2009 05:20 <DIR> PerfLogs //20-05-2013 18:14 <DIR> Program Files //20-05-2013 18:20 <DIR> Program Files (x86) //12-05-2013 13:08 <DIR> ProgramData //11-05-2013 14:49 <DIR> Python27 //18-01-2013 02:13 <DIR> Temp //19-05-2013 18:21 378.273.792 test.bin //24-02-2013 02:32 <DIR> Users //21-05-2013 13:37 <DIR> Windows // 2 File(s) 378.274.816 bytes // 11 Dir(s) 21.434.728.448 bytes free }