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