继续my previous question,我可以使用此delphi unit来使用此EnumMFTEntries() function实施疯狂的快速驱动器扫描,但我无法执行以下任务:
change journal
以获取新修改的文件(更改,重命名,删除等等)在阅读EnumMFTEntries()
函数以及StCroixSkipper's USN Journal Explorer(在C#中)之后,我调整了此已损坏的例程。
由于某些原因,文件名始终为#0
function EnumUsnEntries(ARootHandle : Cardinal; AMFTEnumBuff : Pointer; EnumCallBack : TMFTEnumCallback) : Boolean;
var
P : Pointer;
UsnEnum : Pointer;
BytesRet : Cardinal;
PUSN : PUSNRecord;
ReadUSN : TReadUSNJournalData;
PReadUSN : PReadUSNJournalData;
UsnJournalData : TUSNJournalData;
BUF_SIZE : Integer;
begin
Result := False;
if (ARootHandle = INVALID_HANDLE_VALUE) OR (AMFTEnumBuff = nil) then
Exit;
QueryUSNJournal(ARootHandle, UsnJournalData);
with ReadUSN do
begin
StartUsn := UsnJournalData.NextUsn;
ReasonMask := USN_REASON_DATA_OVERWRITE OR USN_REASON_DATA_EXTEND OR USN_REASON_NAMED_DATA_OVERWRITE OR USN_REASON_NAMED_DATA_TRUNCATION OR
USN_REASON_FILE_CREATE OR USN_REASON_FILE_DELETE OR USN_REASON_EA_CHANGE OR USN_REASON_SECURITY_CHANGE OR
USN_REASON_RENAME_OLD_NAME OR USN_REASON_RENAME_NEW_NAME OR USN_REASON_INDEXABLE_CHANGE OR USN_REASON_BASIC_INFO_CHANGE OR
USN_REASON_HARD_LINK_CHANGE OR USN_REASON_COMPRESSION_CHANGE OR USN_REASON_ENCRYPTION_CHANGE OR
USN_REASON_OBJECT_ID_CHANGE OR USN_REASON_REPARSE_POINT_CHANGE OR USN_REASON_STREAM_CHANGE OR USN_REASON_CLOSE;
ReturnOnlyOnClose := 0;
Timeout := 0;
BytesToWaitFor := 0;
UsnJournalID := UsnJournalData.UsnJournalID;
end; // with
BUF_SIZE := SizeOf(ReadUSN);
GetMem(P, BUF_SIZE);
try
ZeroMemory(P, BUF_SIZE);
while DeviceIoControl(ARootHandle, FSCTL_READ_USN_JOURNAL, Addr(ReadUSN){UsnEnum}, SizeOf(ReadUSN{TReadUSNJournalData}), P, BUF_SIZE, BytesRet, nil) do
begin
PUSN := PUSNRecord{PReadUSNJournalData}(Integer(P) + SizeOf(Int64));
while (BytesRet > 0{60}) do
begin
if Not EnumCallBack(PUSN, nil{Extra}) then
Exit;
if PUSN.RecordLength > 0 then
Dec(BytesRet, PUSN.RecordLength)
else
Break;
PUSN := PUSNRecord(Cardinal(PUSN) + PUSN.RecordLength);
end; // while
CopyMemory(UsnEnum{MFTEnum}, P, SizeOf(Int64));
end; // while
Result := True;
finally
FreeMem(P);
end; // try/finally
end;
如果我没有弄错的话,似乎可以通过在EnumMFTEntries()函数中定义StartUsn
来部分这样做,但目前还不清楚该如何做这一点。
例如,EnumMFTEntries()
始终只返回名称及其父文件夹引用号,但不清楚获取完整路径的最快方法是什么。
我希望我不要求太多,这些任务真的密切相关,我真的希望社区能帮助这里让Delphi开发人员轻松实现疯狂的快速文件夹扫描。尽管它有用,但改变期刊/ MFT是最有趣但尚未被遗忘的技术之一。这必须改变!
答案 0 :(得分:2)
在任务#2上:您可以通过首先发出FSCTL_READ_FILE_USN_DATA来获取最后一次更改的usn数,然后将FSTCL_READ_USN_JOURNAL与分配给该usn编号的StartUsn成员一起发送到该特定文件/目录,以获取有关变更的有效信息( timrstamp,理由)。但是,只能通过这种方式获得最后的更改。为了获得所有更改,我认为只能通过特定文件引用号过滤读取usn日志数据。有关MSDN Library的更多信息。