Learning about Everything Search Method

Written in front

After using Everything, I have been interested in his search speed. I also read a lot of secrets about its principle on the Internet. Finally, I found a source code to study. The principle is to use the USN characteristics of NTFS.

principle

Explain in detail what I refer to Other people's blogs One paragraph:

When the file in the sector changes, the operating system adds a record to the USN Journal file, which contains the file name, the time of the change, the cause of the change and other information, but does not contain the content of the change. Each record is identified with a 64-digit number, called USN (Update Sequence Number). Microsoft uses each offset recorded in the log file as the USN of the record, so that the corresponding record can be obtained quickly through the USN. Obviously, USN is incremental, but not continuous.

So if you want to get the file on disk, you just need to read the log.

There are many source codes on the Internet. It is not difficult to understand how to read the log and convert it into a complete path. If you want to write one by yourself, it is also possible.

problem

I think the main issues to be considered are:
1. Continue reading from the last reading position;
2. Added or deleted file processing.

Everything Source Super Brief

It's not hard to understand the source code carefully.
In the UsnOperator class, I think the more important thing is how to continue reading.

public List<UsnEntry> GetEntries()
{
    var result = new List<UsnEntry>();
    UsnErrorCode usnErrorCode = this.QueryUSNJournal();
    if (usnErrorCode == UsnErrorCode.SUCCESS)
    {
        MFT_ENUM_DATA mftEnumData = new MFT_ENUM_DATA();
        mftEnumData.StartFileReferenceNumber = 0;

        // If you want to continue reading the log from the previous location
        // Modify lowUsn to the last UsnEntry.Usn
        mftEnumData.LowUsn = 0;
        mftEnumData.HighUsn = this.ntfsUsnJournalData.NextUsn;

        int sizeMftEnumData = Marshal.SizeOf(mftEnumData);
        IntPtr ptrMftEnumData = GetHeapGlobalPtr(sizeMftEnumData);
        Marshal.StructureToPtr(mftEnumData, ptrMftEnumData, true);

        int ptrDataSize = sizeof(UInt64) + 10000;
        IntPtr ptrData = GetHeapGlobalPtr(ptrDataSize);

        uint outBytesCount;

        while (false != Win32Api.DeviceIoControl(
            this.DriveRootHandle,
            UsnControlCode.FSCTL_ENUM_USN_DATA,
            ptrMftEnumData,
            sizeMftEnumData,
            ptrData,
            ptrDataSize,
            out outBytesCount,
            IntPtr.Zero))
        {

            IntPtr ptrUsnRecord = new IntPtr(ptrData.ToInt32() + sizeof(Int64));
            while (outBytesCount > 60)
            {
                var usnRecord = new USN_RECORD_V2(ptrUsnRecord);
                result.Add(new UsnEntry(usnRecord));
                ptrUsnRecord = new IntPtr(ptrUsnRecord.ToInt32() + usnRecord.RecordLength);
                outBytesCount -= usnRecord.RecordLength;
            }

            Marshal.WriteInt64(ptrMftEnumData, Marshal.ReadInt64(ptrData, 0));
        }

        Marshal.FreeHGlobal(ptrData);
        Marshal.FreeHGlobal(ptrMftEnumData);
    }
    return result;
}

Use FileSystem Watcher to monitor file changes

With regard to the modification and monitoring of computer files, C# has corresponding classes to deal with. It is very convenient and interesting to dig deeply:

FileSystemWatcher _watcher = new FileSystemWatcher(@"J:\", "*.*");
_watcher.Created += new FileSystemEventHandler(OnProcess);
_watcher.Changed += new FileSystemEventHandler(OnProcess);
_watcher.Deleted += new FileSystemEventHandler(OnProcess);
_watcher.Renamed += new RenamedEventHandler(OnFileRenamed);
_watcher.IncludeSubdirectories = true;
_watcher.EnableRaisingEvents = true;

download

Everything Download

Reference material

DeviceIOControl Details - Each Break

Posted by webref.eu on Tue, 26 Mar 2019 08:45:28 -0700