예제 #1
0
        private static NtfsDirectory FindDir(NTFSWrapper wrapper, Options opts)
        {
            string[] pathParts = opts.PathArgument.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();

            if (pathParts.Length == 0)
            {
                // Chosen path is root
                return(wrapper.GetRootDirectory());
            }

            // Navigate to directory
            NtfsDirectory dir = wrapper.GetRootDirectory();

            for (int i = 0; i < pathParts.Length; i++)
            {
                dir = dir.ListDirectories(false).FirstOrDefault(s => s.Name.Equals(pathParts[i], StringComparison.InvariantCultureIgnoreCase));

                if (dir == null)
                {
                    return(null);
                }
            }

            // Return the last directory
            return(dir);
        }
        public void SimpleFile()
        {
            byte[] randomData = new byte[65 * 4096];
            _random.NextBytes(randomData);

            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                File.WriteAllBytes(tmpFile.File.FullName, randomData);

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
예제 #3
0
        public IActionResult Get([FromQuery] string id)
        {
            var req = id;

            if (Regex.IsMatch(id, @"^([a-zA-Z]\:)\/") || Regex.IsMatch(id, @"^([a-zA-Z]\:)\\") || Regex.IsMatch(id, @"^\\\\"))
            {
                id = id;
            }
            else
            {
                //id = @"\\" + (id.Replace("/", "\\"));
                id = @"\\" + (id.Replace(@"/", @"\"));
            }


            var    folder = new NtfsDirectory(id);
            var    result = new vmNtfsDirectory(folder, appConfiguration.ApiRootUrl, req);
            string json   = JsonConvert.SerializeObject(result, Formatting.Indented);

            json = json.Replace(@"\\", @"\");

            //return Ok(result);
            //return Ok(json);

            return(new ContentResult
            {
                Content = json,
                ContentType = "application/json",
                StatusCode = 200
            });
        }
예제 #4
0
        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);
        }
예제 #5
0
        /* TODO:
         * List streams ($DATA, $BITMAP ..)
         * List alternate namings (Win32, DOS, POSIX)
         * Toggle FileID's
         * List matching attributes
         * Recursive
         * Deleted records
         */

        static void Main(string[] args)
        {
            Options opts = new Options();

            bool success = opts.Parse(args);

            if (!success)
            {
                AwesomeConsole.WriteLine("Unable to parse the commandline:");
                PrintError(opts.ErrorDetails);
                AwesomeConsole.WriteLine();
                AwesomeConsole.WriteLine("Try --help for more informations");
                return;
            }

            if (opts.ActionType == ActionType.ShowHelp)
            {
                opts.DisplayHelp();
                return;
            }

            using (RawDisk disk = new RawDisk(opts.Drive))
            {
                NTFSWrapper wrapper = new NTFSWrapper(new NTFSDiskProvider(disk), 1);

                NtfsDirectory dir = null;

                if (opts.PathType == PathType.Directory)
                {
                    dir = FindDir(wrapper, opts);
                }

                if (dir == null)
                {
                    PrintError("The given path didn't exist");
                    AwesomeConsole.WriteLine();

                    switch (opts.PathType)
                    {
                    case PathType.Directory:
                        PrintError("Specified " + opts.PathType + ": " + opts.PathArgument);
                        break;
                    }

                    AwesomeConsole.WriteLine();
                    return;
                }

                // Display
                DisplayDetails(wrapper, opts, dir);
            }

            if (Debugger.IsAttached)
            {
                Console.ReadLine();
            }
        }
예제 #6
0
        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));
                }
            }
        }
예제 #7
0
        public void AlternateDatastreamDirectory()
        {
            Random rand = new Random();

            byte[][] data = new byte[10][];
            for (int i = 0; i < 10; i++)
            {
                data[i] = new byte[1024 * 1024];
                rand.NextBytes(data[i]);
            }

            using (TempDir tmpDir = new TempDir())
            {
                // Make file
                for (int i = 0; i < 10; i++)
                {
                    using (SafeFileHandle fileHandle = Win32.CreateFile(tmpDir.Directory.FullName + ":alternate" + i + ":$DATA"))
                        using (FileStream fs = new FileStream(fileHandle, FileAccess.ReadWrite))
                        {
                            fs.Write(data[i], 0, data[i].Length);
                        }
                }

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

                // Check streams
                string[] streams = ntfsWrapper.ListDatastreams(ntfsDir.MFTRecord);

                Assert.AreEqual(10, streams.Length);

                for (int i = 0; i < 10; i++)
                {
                    Assert.AreEqual(1, streams.Count(s => s == "alternate" + i));
                }

                // Check data
                for (int i = 0; i < 10; i++)
                {
                    using (Stream memStream = new MemoryStream(data[i]))
                        using (Stream fileStream = ntfsWrapper.OpenFileRecord(ntfsDir.MFTRecord, "alternate" + i))
                        {
                            StreamUtils.CompareStreams(memStream, fileStream);
                        }
                }
            }
        }
        public void SparseFile()
        {
            byte[] randomData = new byte[35 * 4096];
            _random.NextBytes(randomData);

            // Clear the 16 * 4096 -> 32 * 4096 range
            Array.Clear(randomData, 16 * 4096, 16 * 4096);

            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                File.WriteAllBytes(tmpFile.File.FullName, randomData);

                using (FilesystemDeviceWrapper wrapper = Win32.GetFileWrapper(tmpFile.File.FullName))
                {
                    wrapper.FileSystemSetSparseFile(true);
                    wrapper.FileSystemSetZeroData(16 * 4096, 16 * 4096);

                    FILE_ALLOCATED_RANGE_BUFFER[] rangesData = wrapper.FileSystemQueryAllocatedRanges(0, randomData.Length);

                    // We should have 2 ranges on non-zero data
                    Assert.AreEqual(2, rangesData.Length);
                }

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);
                Assert.IsTrue(tmpFile.File.Attributes.HasFlag(FileAttributes.SparseFile));
                AttributeData attributeData = ntfsFile.MFTRecord.Attributes.OfType <AttributeData>().Single();
                Assert.IsTrue(attributeData.DataFragments.Length > 1);
                Assert.IsTrue(attributeData.DataFragments.Any(s => s.IsSparseFragment));

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
예제 #9
0
        public static IEnumerable <NtfsDirectory> GetDirectories(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.ListDirectories());
            }
        }
        public void CompressedFile()
        {
            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                // Write file data
                using (FileStream fs = File.OpenWrite(tmpFile.File.FullName))
                {
                    byte[] data = Encoding.ASCII.GetBytes("The white bunny jumps over the brown dog in a carparking lot");

                    for (int i = 0; i < 20000; i++)
                    {
                        fs.Write(data, 0, data.Length);
                    }
                }

                using (FilesystemDeviceWrapper wrapper = Win32.GetFileWrapper(tmpFile.File.FullName))
                {
                    wrapper.FileSystemSetCompression(COMPRESSION_FORMAT.LZNT1);
                }

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);
                Assert.IsTrue(tmpFile.File.Attributes.HasFlag(FileAttributes.Compressed));
                AttributeData attributeData = ntfsFile.MFTRecord.Attributes.OfType <AttributeData>().Single();
                Assert.IsTrue(attributeData.DataFragments.Any(s => s.IsCompressed));

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
예제 #11
0
        private static string GetDirectory(NtfsFile file)
        {
            StringBuilder result = new StringBuilder();

            result.Insert(0, "\\");

            NtfsDirectory dir = file.Parent;

            while (dir.Name != ".")
            {
                result.Insert(0, $"{Path.DirectorySeparatorChar}{dir.Name}");
                dir = dir.Parent;
            }

            result.Insert(0, ":");

            return(result.ToString());
        }
        public static NtfsDirectory OpenDir(NTFSWrapper ntfsWrapper, string path)
        {
            Assert.IsTrue(Path.IsPathRooted(path));

            string[] dirs = path.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);

            NtfsDirectory currDir = ntfsWrapper.GetRootDirectory();

            foreach (string dir in dirs.Skip(1))        // Skip root (C:\)
            {
                IEnumerable<NtfsDirectory> subDirs = currDir.ListDirectories(false);
                NtfsDirectory subDir = subDirs.FirstOrDefault(s => s.Name.Equals(dir, StringComparison.InvariantCultureIgnoreCase));

                Assert.IsNotNull(subDir);

                currDir = subDir;
            }

            return currDir;
        }
예제 #13
0
        //CONSTRUCTOR
        public vmNtfsDirectory(NtfsDirectory dir, string apiRoot, string reqPath)
        {
            Name         = dir.Name;
            FullPath     = dir.FullPath;
            Exists       = dir.Exists;
            Created      = dir.Created;
            LastWrite    = dir.LastWrite;
            TerminalLeaf = dir.TerminalLeaf;
            DirLink      = new Uri(apiRoot + "Dir?id=" + reqPath.Replace(@"/", @"\"));
            ScanTime     = DateTime.Now;
            //ScanUser = user;
            InheritanceEnabled = dir.InheritanceEnabled;
            Owner            = dir.Owner;
            ChildFiles       = new Dictionary <string, Uri>();
            ChildDirectories = new Dictionary <string, Uri>();
            AccessControl    = new List <vmNtfsAccessRule>();
            //foreach (var f in dir.ChildFiles)
            if (dir.ChildFiles.Any())
            {
                for (int i = 0; i < dir.ChildFiles.Count; i++)
                {
                    var uri = new Uri(apiRoot + "File?id=" + reqPath.Replace(@"/", @"\") + "\\" + dir.ChildFiles[i]);
                    ChildFiles.Add(dir.ChildFiles[i], uri);
                }
            }


            if (dir.ChildDirectories.Any())
            {
                for (int i = 0; i < dir.ChildDirectories.Count; i++)
                {
                    var uri = new Uri(apiRoot + "Dir?id=" + reqPath.Replace(@"/", @"\") + "\\" + dir.ChildDirectories[i]);
                    ChildDirectories.Add(dir.ChildDirectories[i], uri);
                }
            }

            foreach (var ar in dir.AccessControlList)
            {
                AccessControl.Add(new vmNtfsAccessRule(ar));
            }
        }
예제 #14
0
        private static uint FindPathMftId(Options opts)
        {
            string[] pathParts   = opts.PathArgument.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 = opts.PathType == PathType.File ? (IEnumerable <NtfsFileEntry>)parentDir.ListFiles(false) : parentDir.ListDirectories(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);
            }
        }
예제 #15
0
        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();
                }
            }
        }
예제 #16
0
        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
        }