private void GetRootFrnEntry() { string driveRoot = string.Concat("\\\\.\\", _drive); driveRoot = string.Concat(driveRoot, Path.DirectorySeparatorChar); IntPtr hRoot = PInvokeWin32.CreateFile(driveRoot, 0, PInvokeWin32.FILE_SHARE_READ | PInvokeWin32.FILE_SHARE_WRITE, IntPtr.Zero, PInvokeWin32.OPEN_EXISTING, PInvokeWin32.FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero); if (hRoot.ToInt32() != PInvokeWin32.INVALID_HANDLE_VALUE) { PInvokeWin32.BY_HANDLE_FILE_INFORMATION fi = new PInvokeWin32.BY_HANDLE_FILE_INFORMATION(); bool bRtn = PInvokeWin32.GetFileInformationByHandle(hRoot, out fi); if (bRtn) { UInt64 fileIndexHigh = (UInt64)fi.FileIndexHigh; UInt64 indexRoot = (fileIndexHigh << 32) | fi.FileIndexLow; FileNameAndFrn f = new FileNameAndFrn(driveRoot, 0); _directories.Add(indexRoot, f); } else { throw new IOException("GetFileInformationbyHandle() returned invalid handle", new Win32Exception(Marshal.GetLastWin32Error())); } PInvokeWin32.CloseHandle(hRoot); } else { throw new IOException("Unable to get root frn entry", new Win32Exception(Marshal.GetLastWin32Error())); } }
public void DoEnumerate(Object _params) { Params myparams = (_params as Params); string[] ntfs_disks = myparams.localDrives.Split(','); string[] extensions = myparams.extensions.Split(','); JobStatus status = myparams.jobStatus; if (status == null) { status = new JobStatus("NtfsEnum"); } Stopwatch watch = myparams.jobWatch; if (watch == null) { watch = new Stopwatch(); watch.Start(); } foreach (string disk_letter in ntfs_disks) { if (disk_letter.Trim().Length == 0) { continue; } if (status.Cancelled) { break; } Dictionary <UInt64, FileNameAndFrn> result = null; NTFS ntfs = new NTFS(); status.Description = string.Format("listing ntfs journal on {0}...", disk_letter); ntfs.Drive = disk_letter;// "D:"; try { ntfs.EnumerateVolume(out result, extensions); /*new string[] {".bab" }); * { ".h", "*.hpp", "*.inl", "*.c", "*.cpp", ".txt", ".cs", "*.htm*", "*.ini", * "*.xml", "*.rtf", "*.doc" * });*/ } catch (Win32Exception win32_e) { win32_e = win32_e; } catch (Exception e) { e = e; } //status.Description = string.Format("listed {0} files for processing in {1} on {2}", result.Count, watch.ElapsedMilliseconds / 1000.0, disk_letter); int num_file = 0; bool should_close; myparams.fileProcessor.Start(out should_close); if (result != null) { foreach (KeyValuePair <UInt64, FileNameAndFrn> entry in result) { if (status.Cancelled) { break; } FileNameAndFrn file = (FileNameAndFrn)entry.Value; string full_path = ntfs.DirectoryFromFrn(file.ParentFrn) + @"\" + file.Name; full_path = full_path.Substring(4); myparams.fileProcessor.ProcessFile(full_path); num_file++; if ((num_file % 101) == 1) { status.Progress = (num_file * 100) / result.Count; status.Description = string.Format("ntfs on {3} processing file {0}/{1} - {2}", num_file, result.Count, StringFu.TimeSpanToString(new TimeSpan((long)(watch.ElapsedMilliseconds) * 10000)), disk_letter); } } } myparams.fileProcessor.End(should_close); string info = string.Format("ntfs file enum: {0} files - {1}", result.Count, watch.ElapsedMilliseconds / 1000.0); Console.WriteLine(info); //status.Description = info; } if (myparams.jobStatus == null) { status.RemoveFromQueue(); status = null; } if (myparams.jobWatch == null) { watch = null; } }
unsafe public void EnumerateFiles(IntPtr medBuffer, ref Dictionary <ulong, FileNameAndFrn> files, string[] fileExtensions) { IntPtr pData = Marshal.AllocHGlobal(sizeof(UInt64) + 0x10000); PInvokeWin32.ZeroMemory(pData, sizeof(UInt64) + 0x10000); uint outBytesReturned = 0; while (false != PInvokeWin32.DeviceIoControl(_changeJournalRootHandle, PInvokeWin32.FSCTL_ENUM_USN_DATA, medBuffer, sizeof(PInvokeWin32.MFT_ENUM_DATA), pData, sizeof(UInt64) + 0x10000, out outBytesReturned, IntPtr.Zero)) { IntPtr pUsnRecord = new IntPtr(pData.ToInt32() + sizeof(Int64)); while (outBytesReturned > 60) { PInvokeWin32.USN_RECORD usn = new PInvokeWin32.USN_RECORD(pUsnRecord); if (0 != (usn.FileAttributes & PInvokeWin32.FILE_ATTRIBUTE_DIRECTORY)) { // // handle directories // if (!_directories.ContainsKey(usn.FileReferenceNumber)) { _directories.Add(usn.FileReferenceNumber, new FileNameAndFrn(usn.FileName, usn.ParentFileReferenceNumber)); } else { // this is debug code and should be removed when we are certain that // duplicate frn's don't exist on a given drive. To date, this exception has // never been thrown. Removing this code improves performance.... throw new Exception(string.Format("Duplicate FRN: {0} for {1}", usn.FileReferenceNumber, usn.FileName)); } } else { // // handle files // bool add = true; if (fileExtensions != null && fileExtensions.Length != 0) { add = false; string s = Path.GetExtension(usn.FileName); foreach (string extension in fileExtensions) { if (0 == string.Compare(s, extension, true)) { add = true; break; } } } if (add) { if (!files.ContainsKey(usn.FileReferenceNumber)) { files.Add(usn.FileReferenceNumber, new FileNameAndFrn(usn.FileName, usn.ParentFileReferenceNumber)); } else { FileNameAndFrn frn = files[usn.FileReferenceNumber]; if (0 != string.Compare(usn.FileName, frn.Name, true)) { // Log.InfoFormat( // "Attempt to add duplicate file reference number: {0} for file {1}, file from index {2}", // usn.FileReferenceNumber, usn.FileName, frn.Name); throw new Exception(string.Format("Duplicate FRN: {0} for {1}", usn.FileReferenceNumber, usn.FileName)); } } } } pUsnRecord = new IntPtr(pUsnRecord.ToInt32() + usn.RecordLength); outBytesReturned -= usn.RecordLength; } Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0)); } Marshal.FreeHGlobal(pData); }