-
Notifications
You must be signed in to change notification settings - Fork 2
/
Monitor.cpp
70 lines (66 loc) · 2.6 KB
/
Monitor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "Monitor.h"
#include <QDebug>
#include <string>
Monitor::Monitor(int id, HANDLE root_handle, USN_JOURNAL_DATA journal) : id(id), root_handle(root_handle), journal(journal) {
last_usn = journal.NextUsn;
}
void Monitor::run() {
while(true) {
constexpr int BUFLEN = 1 << 18;
CHAR buffer[BUFLEN];
auto query = getNext(last_usn, 1);
while (true) {
waitNext(query.get());
auto journal_query = getNext(query->StartUsn, 0);
DWORD br;
while (DeviceIoControl(root_handle, FSCTL_READ_USN_JOURNAL,
journal_query.get(), sizeof(*journal_query.get()),
buffer, BUFLEN,
&br, nullptr)) {
if (br == 8)break;
auto PUsnRecord = (PUSN_RECORD)(((PCHAR)buffer) + sizeof(USN));
DWORD dwRetBytes = br - sizeof(USN);
while (dwRetBytes>0) {
if (PUsnRecord->FileName[0] != L'$' && PUsnRecord->FileName[0] != L'~') {
qDebug() << "-----------------\n";
qDebug() << "Filename " << QString::fromWCharArray(PUsnRecord->FileName, PUsnRecord->FileNameLength / 2) << "\n";
qDebug() << "Reason " << QString("%1").arg(PUsnRecord->Reason, 0, 16) << "\n";
qDebug() << "FileRef " << PUsnRecord->FileReferenceNumber << "\n";
qDebug() << "ParentFileRef " << PUsnRecord->ParentFileReferenceNumber << "\n";
qDebug() << query->StartUsn;
qDebug() << *(USN*)buffer - query->StartUsn;
emit sendPUSN(id, PUsnRecord);
}
DWORD recordLen = PUsnRecord->RecordLength;
dwRetBytes -= recordLen;
PUsnRecord = (PUSN_RECORD)(((PCHAR)PUsnRecord) + recordLen);
}
journal_query->StartUsn = *(USN*)buffer;
}
last_usn = *(USN*)buffer;
query->StartUsn = last_usn;
}
}
qDebug() << "Monitor end\n";
}
std::unique_ptr<READ_USN_JOURNAL_DATA> Monitor::getNext(USN start_usn, int byte_wait) {
auto query = std::make_unique<READ_USN_JOURNAL_DATA>();
query->StartUsn = start_usn;
query->ReasonMask = 0xFFFFFFFF;
query->ReturnOnlyOnClose = FALSE;
query->Timeout = 0;
query->BytesToWaitFor = byte_wait;
query->UsnJournalID = journal.UsnJournalID;
query->MinMajorVersion = 2;
query->MaxMajorVersion = 2;
return query;
}
bool Monitor::waitNext(PREAD_USN_JOURNAL_DATA data) const {
DWORD br;
bool ok = true;
ok = DeviceIoControl(root_handle, FSCTL_READ_USN_JOURNAL,
data, sizeof(*data),
&data->StartUsn, sizeof(data->StartUsn),
&br, nullptr);
return ok;
}