前の質問の続きで、この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 は、最も興味深いが忘れられているテクノロジの 1 つです。これは変わらなければなりません!