Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah saya boleh mengesan perubahan fail dengan cekap pada volum NTFS menggunakan fungsi FSCTL_ENUM_USN_DATA?
Mengesan Perubahan pada Kelantangan: Penyelesaian Terperinci
Untuk mengesan pemadaman, pengubahsuaian dan penciptaan fail secara berkesan pada volum NTFS, anda boleh gunakan fungsi FSCTL_ENUM_USN_DATA. Pendekatan ini menawarkan beberapa kelebihan:
Langkah Pelaksanaan:
Contoh program C yang menunjukkan pendekatan ini disediakan di bawah, mencari fail bernama "test .txt" dan memaparkan maklumat tentang perubahan dan direktori induk mereka:
<code class="c++">#include <Windows.h> #include <stdio.h> #define BUFFER_SIZE (1024 * 1024) int main() { HANDLE drive = CreateFileW(L"\\?\c:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_FLAG_NO_BUFFERING, NULL); MFT_ENUM_DATA mft_enum_data; USN maxusn; USN_RECORD *record; // Query USN journal for information if (DeviceIoControl(drive, FSCTL_QUERY_USN_JOURNAL, NULL, 0, &maxusn, sizeof(USN), NULL, NULL)) { mft_enum_data.StartFileReferenceNumber = 0; mft_enum_data.LowUsn = 0; mft_enum_data.HighUsn = maxusn; DWORDLONG nextid, filecount = 0; for (;;) { void *buffer = VirtualAlloc(NULL, BUFFER_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (DeviceIoControl(drive, FSCTL_ENUM_USN_DATA, &mft_enum_data, sizeof(mft_enum_data), buffer, BUFFER_SIZE, NULL, NULL)) { nextid = *((DWORDLONG *)buffer); record = (USN_RECORD *)((USN *)buffer + 1); while (record < (USN_RECORD *)(((BYTE *)buffer) + BUFFER_SIZE)) { filecount++; WCHAR *filename = (WCHAR *)(((BYTE *)record) + record->FileNameOffset); if (wcsncmp(filename, L"test.txt", 8) == 0) { printf("=================================================================\n"); printf("RecordLength: %u\n", record->RecordLength); printf("MajorVersion: %u\n", (DWORD)record->MajorVersion); printf("MinorVersion: %u\n", (DWORD)record->MinorVersion); printf("FileReferenceNumber: %lu\n", record->FileReferenceNumber); printf("ParentFRN: %lu\n", record->ParentFileReferenceNumber); printf("USN: %lu\n", record->Usn); printf("Timestamp: %lu\n", record->TimeStamp); printf("Reason: %u\n", record->Reason); printf("SourceInfo: %u\n", record->SourceInfo); printf("SecurityId: %u\n", record->SecurityId); printf("FileAttributes: %x\n", record->FileAttributes); printf("FileNameLength: %u\n", (DWORD)record->FileNameLength); printf("FileName: %.*ls\n", record->FileNameLength, filename); // Reconstruct file path by matching parent file reference numbers DWORD bytecount; if (DeviceIoControl(drive, FSCTL_ENUM_USN_DATA, &mft_enum_data, sizeof(mft_enum_data), buffer, BUFFER_SIZE, &bytecount, NULL)) { USN_RECORD *parent_record = (USN_RECORD *)((USN *)buffer + 1); if (parent_record->FileReferenceNumber == record->ParentFileReferenceNumber) { printf("Parent File:\n"); printf("=================================================================\n"); printf("FileName: %.*ls\n", parent_record->FileNameLength, (WCHAR *)(((BYTE *)parent_record) + parent_record->FileNameOffset)); } } } record = (USN_RECORD *)(((BYTE *)record) + record->RecordLength); } mft_enum_data.StartFileReferenceNumber = nextid; } else { printf("FSCTL_ENUM_USN_DATA failed\n"); break; } if (nextid == 0) break; } printf("Total Files: %lu\n", filecount); } else { printf("FSCTL_QUERY_USN_JOURNAL failed\n"); } if (drive != INVALID_HANDLE_VALUE) CloseHandle(drive); return 0; }</code>
Atas ialah kandungan terperinci Bagaimanakah saya boleh mengesan perubahan fail dengan cekap pada volum NTFS menggunakan fungsi FSCTL_ENUM_USN_DATA?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!