继续我之前的问题,我可以使用这个delphi 单元来使用这个EnumMFTEntries() 函数实现疯狂的 FAST 驱动器扫描,但是我在执行以下任务时遇到了麻烦:
任务#1:查询change journal
以获取新修改的文件(更改、重命名、删除等...)
在阅读了该函数以及 StCroixSkipper 的 USN Journal Explorer(在 C# 中)之后,我调整了这个损坏的例程。EnumMFTEntries()
由于某种原因,报告的文件名总是#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;
任务 #2:限制扫描到某个文件夹?
如果我没记错的话,似乎可以通过在EnumMFTEntries()函数中定义来部分地做到这一点,但目前尚不清楚如何做到这一点。StartUsn
任务#3:获取文件名的完整路径?
例如,EnumMFTEntries()
总是只返回名称及其父文件夹参考号,不清楚获取完整路径的最快方法是什么。
我希望我没有问太多,这些任务真的是息息相关的,我真的希望社区在这里帮助Delphi开发人员轻松实现疯狂的快速文件夹扫描。尽管它很有用,但变更日志/MFT 是最有趣但被遗忘的技术之一。这必须改变!