Berjalan Buffer Perubahan Catatan Jurnal
Kode kontrol yang mengembalikan nomor urutan pembaruan (USN) mengubah rekaman jurnal, FSCTL_READ_USN_JOURNAL dan FSCTL_ENUM_USN_DATA, mengembalikan data serupa dalam buffer output. Keduanya mengembalikan USN diikuti dengan nol atau lebih rekaman jurnal perubahan, masing-masing dalam struktur USN_RECORD_V2 atau USN_RECORD_V3.
Volume target untuk operasi USN harus ReFS atau NTFS 3.0 atau yang lebih baru. Untuk mendapatkan versi volume NTFS, buka prompt perintah dengan hak akses Administrator dan jalankan perintah berikut:
FSUtil.exe FSInfo NTFSInfo X**:**
di mana X adalah huruf kandar volume.
Daftar berikut mengidentifikasi cara untuk mendapatkan catatan jurnal perubahan:
- Gunakan FSCTL_ENUM_USN_DATA untuk mendapatkan daftar (enumerasi) dari semua catatan jurnal perubahan antara dua ASN.
- Gunakan FSCTL_READ_USN_JOURNAL agar lebih selektif, seperti memilih alasan tertentu untuk perubahan atau mengembalikan saat file ditutup.
Catatan
Kedua operasi ini hanya mengembalikan subset rekaman jurnal perubahan yang memenuhi kriteria yang ditentukan.
USN yang dikembalikan sebagai item pertama dalam buffer output adalah USN dari nomor rekaman berikutnya yang akan diambil. Gunakan nilai ini untuk melanjutkan membaca rekaman dari batas akhir ke depan.
Anggota FileName dari USN_RECORD_V2 atau USN_RECORD_V3 berisi nama file tempat rekaman yang dimaksud berlaku. Panjang nama file bervariasi, jadi USN_RECORD_V2 dan USN_RECORD_V3 adalah struktur panjang variabel. Anggota pertama mereka, RecordLength, adalah panjang struktur (termasuk nama file), dalam byte.
Saat Anda bekerja dengan anggota FileName dari struktur USN_RECORD_V2 dan USN_RECORD_V3 , jangan asumsikan bahwa nama file berisi pemisah '\0' berikutnya. Untuk menentukan panjang nama file, gunakan anggota FileNameLength .
Contoh berikut memanggil FSCTL_READ_USN_JOURNAL dan berjalan buffer catatan jurnal perubahan yang dikembalikan operasi.
#include <Windows.h>
#include <WinIoCtl.h>
#include <stdio.h>
#define BUF_LEN 4096
void main()
{
HANDLE hVol;
CHAR Buffer[BUF_LEN];
USN_JOURNAL_DATA JournalData;
READ_USN_JOURNAL_DATA ReadData = {0, 0xFFFFFFFF, FALSE, 0, 0};
PUSN_RECORD UsnRecord;
DWORD dwBytes;
DWORD dwRetBytes;
int I;
hVol = CreateFile( TEXT("\\\\.\\c:"),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if( hVol == INVALID_HANDLE_VALUE )
{
printf("CreateFile failed (%d)\n", GetLastError());
return;
}
if( !DeviceIoControl( hVol,
FSCTL_QUERY_USN_JOURNAL,
NULL,
0,
&JournalData,
sizeof(JournalData),
&dwBytes,
NULL) )
{
printf( "Query journal failed (%d)\n", GetLastError());
return;
}
ReadData.UsnJournalID = JournalData.UsnJournalID;
printf( "Journal ID: %I64x\n", JournalData.UsnJournalID );
printf( "FirstUsn: %I64x\n\n", JournalData.FirstUsn );
for(I=0; I<=10; I++)
{
memset( Buffer, 0, BUF_LEN );
if( !DeviceIoControl( hVol,
FSCTL_READ_USN_JOURNAL,
&ReadData,
sizeof(ReadData),
&Buffer,
BUF_LEN,
&dwBytes,
NULL) )
{
printf( "Read journal failed (%d)\n", GetLastError());
return;
}
dwRetBytes = dwBytes - sizeof(USN);
// Find the first record
UsnRecord = (PUSN_RECORD)(((PUCHAR)Buffer) + sizeof(USN));
printf( "****************************************\n");
// This loop could go on for a long time, given the current buffer size.
while( dwRetBytes > 0 )
{
printf( "USN: %I64x\n", UsnRecord->Usn );
printf("File name: %.*S\n",
UsnRecord->FileNameLength/2,
UsnRecord->FileName );
printf( "Reason: %x\n", UsnRecord->Reason );
printf( "\n" );
dwRetBytes -= UsnRecord->RecordLength;
// Find the next record
UsnRecord = (PUSN_RECORD)(((PCHAR)UsnRecord) +
UsnRecord->RecordLength);
}
// Update starting USN for next call
ReadData.StartUsn = *(USN *)&Buffer;
}
CloseHandle(hVol);
}
Ukuran dalam byte dari rekaman apa pun yang ditentukan oleh struktur USN_RECORD_V2 atau USN_RECORD_V3 paling banyak ((MaxComponentLength - 1) * Width) + Size
di mana MaxComponentLength adalah panjang maksimum dalam karakter nama file rekaman. Lebar adalah ukuran karakter lebar, dan Ukurannya adalah ukuran struktur.
Untuk mendapatkan panjang maksimum, panggil fungsi GetVolumeInformation dan periksa nilai yang diarahkan oleh parameter lpMaximumComponentLength. Kurangi satu dari MaxComponentLength untuk memperhitungkan fakta bahwa definisi USN_RECORD dan USN_RECORD_V3 menyertakan satu karakter nama file.
Dalam bahasa pemrograman C, ukuran rekaman terbesar yang mungkin adalah sebagai berikut:
(MaxComponentLength - 1) * sizeof(WCHAR) + sizeof(USN_RECORD)