private void ScanMtf(ScanningState state, CancellationToken token)
        {
            FileNodeIndexes[]      fileItemsLookup;
            List <FileNodeIndexes> fileItems = new List <FileNodeIndexes>();

            DriveInfo driveInfo = new DriveInfo(Path.GetPathRoot(state.RootPath));

            using (NtfsReader ntfs = new NtfsReader(driveInfo, RetrieveMode.StandardInformations)) {
                fileItemsLookup = new FileNodeIndexes[ntfs.NodeCount];
                ReadMft(state, ntfs, fileItemsLookup, fileItems, token);
            }

            foreach (FileNodeIndexes indexes in fileItems)
            {
                FileItemBase    item          = indexes.FileItem;
                FileNodeIndexes parentIndexes = fileItemsLookup[indexes.ParentNodeIndex];
                if (indexes.NodeIndex == indexes.ParentNodeIndex)
                {
                    // This must be the drive root
                }
                else if (parentIndexes != null)
                {
                    ((FolderItem)parentIndexes.FileItem).AddItem(item,
                                                                 ref parentIndexes.FileCollection, ref parentIndexes.FirstFile);
                }
                else
                {
                    // This must be the root
                }
                if (AsyncChecks(token))
                {
                    return;
                }
            }
        }
        private void ReadMft(ScanningState state, NtfsReader ntfs, FileNodeIndexes[] fileItemsLookup,
                             List <FileNodeIndexes> fileItems, CancellationToken token)
        {
            foreach (INtfsNode node in ntfs.EnumerateNodes(state.RootPath))
            {
                string fullPath = PathUtils.TrimSeparatorDotEnd(node.FullName);
                bool   isRoot   = (node.NodeIndex == node.ParentNodeIndex);
                if (!isRoot && SkipFile(state, Path.GetFileName(fullPath), fullPath))
                {
                    continue;
                }
                FileItemBase child;
                bool         reparsePoint = node.Attributes.HasFlag(FileAttributes.ReparsePoint);
                if (isRoot)
                {
                    child = state.Root;
                }
                else if (node.Attributes.HasFlag(FileAttributes.Directory))
                {
                    if (!state.IsDrive && state.RootPath == node.FullName.ToUpperInvariant())
                    {
                        child = state.Root;
                    }
                    else
                    {
                        child = new FolderItem(new ScanFileInfo(node));
                    }
                }
                else
                {
                    ExtensionItem extension = Extensions.GetOrAddFromPath(node.Name);
                    FileItem      file      = new FileItem(new ScanFileInfo(node), extension);
                    child = file;
                    if (!reparsePoint)
                    {
                        TotalScannedSize += child.Size;
                    }
                }
                FileNodeIndexes indexes = new FileNodeIndexes(child, node);
                fileItemsLookup[node.NodeIndex] = indexes;

                if (!reparsePoint)
                {
                    fileItems.Add(indexes);
                }

                if (AsyncChecks(token))
                {
                    return;
                }
            }
        }