USN Journal i ExportFromUSN
Wyszukiwanie plików w Eksploratorze Windows jest zepsute. Wchodzę na "Ten komputer", wpisuję nazwę pliku i czekam. I czekam. Irytujące.
Chciałem zrobić coś na wzór uproszczonego Everything z ładniejszym UI. Żeby to osiągnąć, musiałem zrozumieć jak Everything działa tak szybko.
Co to USN Journal?
USN Journal (Update Sequence Number Journal) to wbudowany mechanizm NTFS, który rejestruje każdą zmianę w systemie plików. Każdy plik i folder na dysku NTFS ma swój unikalny numer referencyjny (File Reference Number, FRN). Journal zapisuje co się zmieniło i kiedy.
Zamiast skanować cały dysk plik po pliku, można poprosić system o listę wszystkich rekordów z
Master File Table (MFT). To właśnie robi plik ExportFromUSN.cpp w moim projekcie
FileFinder.
winioctl.h i kody FSCTL
Aby komunikować się z USN Journal, trzeba użyć funkcji DeviceIoControl z Windows API.
Nagłówek winioctl.h definiuje kody sterujące (FSCTL), które mówią systemowi co chcemy
zrobić:
FSCTL_ENUM_USN_DATA– enumeruje rekordy MFT, zwraca listę wszystkich plików i folderów na dysku.FSCTL_READ_USN_JOURNAL– czyta zmiany z journala w czasie rzeczywistym.FSCTL_QUERY_USN_JOURNAL– sprawdza status journala (czy istnieje, jaki ma zakres USN).
Struktury danych
Windows API oferuje kilka wersji struktur do pracy z USN Journal:
MFT_ENUM_DATA
Struktura wejściowa dla FSCTL_ENUM_USN_DATA. Określa zakres USN i od którego numeru
FRN zacząć enumerację. Przy pierwszym wywołaniu StartFileReferenceNumber ustawiam na
0, a przy kolejnych używam wartości zwróconej z poprzedniego wywołania.
USN_RECORD
Rekord zwracany przez system. Istnieje kilka wersji:
USN_RECORD_V2– najczęściej używana, zawiera FRN, ParentFRN, nazwę pliku, atrybuty.USN_RECORD_V3– używa 128-bitowych FRN (dla ReFS i nowszych wersji Windows).USN_RECORD_V4– dodatkowe informacje o zakresach zmian.
W moim projekcie używam V2, bo wystarcza do NTFS i jest prostsza w obsłudze. Pole
MajorVersion w rekordzie mówi którą wersję dostaliśmy.
Jak działa ExportFromUSN
Plik wykonuje następujące kroki:
- Otwiera uchwyt do dysku (
CreateFilena\\.\C:). - Sprawdza czy USN Journal istnieje (
FSCTL_QUERY_USN_JOURNAL). - W pętli wywołuje
FSCTL_ENUM_USN_DATA, za każdym razem przesuwającStartFileReferenceNumber. - Dla każdego rekordu wyciąga FRN, ParentFRN i nazwę pliku.
- Zapisuje dane do pliku CSV (później konwertowanego na SQLite).
Cały skan dysku z milionami plików trwa kilka sekund. Dla porównania, rekurencyjne przechodzenie
przez FindFirstFile/FindNextFile trwałoby minuty.
Wersje struktur
Microsoft dodaje nowe wersje struktur w kolejnych wersjach Windows. Przy wyborze wersji trzeba pamiętać o kompatybilności:
USN_JOURNAL_DATA_V0,V1,V2– różne wersje metadanych journala.USN_RECORD_V2,V3,V4– różne formaty rekordów.
Używam V2 bo działa na Windows 7+ i nie potrzebuję 128-bitowych FRN.
Więcej o projekcie: FileFinder