Мониторинг удалений и изменений на томе NTFS с помощью MFT_ENUM_DATA

Я использую этот код для заполнения базы данных всех файлов на диске:

TCHAR szVolumePath[_MAX_PATH] = L"\\\\.\\d:";

HANDLE hDrive = CreateFile(szVolumePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);

MFT_ENUM_DATA_V0 med = { 0 };
med.StartFileReferenceNumber = 0;
med.LowUsn = 0;
med.HighUsn = MAXLONGLONG;

DWORD cb;
PUSN_RECORD pRecord;

unsigned char pData[sizeof(DWORDLONG) + 0x10000] = { 0 };

while (DeviceIoControl(hDrive, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL) != FALSE)
{
pRecord = (PUSN_RECORD)&pData[sizeof(USN)];
while ((PBYTE)pRecord < (pData + cb))
{
wstring sz((LPCWSTR)(PBYTE)pRecord + pRecord->FileNameOffset, pRecord->FileNameLength / sizeof(WCHAR));

// file the database

pRecord = (PUSN_RECORD)((PBYTE)pRecord + pRecord->RecordLength);
}
med.StartFileReferenceNumber = *(DWORDLONG *)pData;
}

Как только цикл завершен, база данных успешно заполнена.

Но как продолжить (в качестве фоновой задачи) отслеживать в реальном времени изменения / удаления файлов? (пример: отобразить MessageBox() «Файл readme.txt был переименован.»)

Должен ли я перезапускать такой цикл каждую 1 секунду, с med.StartFileReferenceNumber = самый высокий FileReferenceNumber, который вы видели раньше?


Примечание: я немного не хочу запускать этот код каждую 1 секунду (99% времени, даром). Делая это каждые 10 секунд, вы избежите использования такого большого количества ресурсов, но перед обнаружением изменений будет задержка, в то время как я знаю некоторые программы индексирования, которые не имеют такой задержки.

Примечание 2: я читаю Как я могу обнаружить только удаленные, измененные и созданные файлы на томе? но цель основного ответа — запустить его один раз, а не постоянно в фоновом режиме.

Примечание 3: я посмотрел на этот полезный пример кода от Microsoft Следить за дисками NTFS: объяснение журнала изменений Windows 2000 .

Примечание 4: я должен держать FSCTL_ENUM_USN_DATA для начальной загрузки базы данных, а затем использовать FSCTL_READ_USN_JOURNAL вместо?

Note5: ReadDirectoryChangesW или же FindNextChangeNotification (первый дает полный путь изменений в уведомлениях, второй нет) не может быть использован, потому что он не даст FileReferenceNumber удаленного файла (нужно открыть файл и использовать NtQueryInformationFile получить это; но это невозможно для удаленных файлов); и FileReferenceNumber необходим для обновления файловая база данных (файловая база данных использует карту / словарь с FileReferenceNumbers в качестве ключей).

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]