我使用了這個專案的參考,它為 IRP_MJ_CREATE 創建了一個處理程式。它顯示了系統創建或打開的所有檔案。IRP_MJ_CREATE 的檔案是這樣的:
I/O 管理器在創建新檔案或目錄時,或在打開現有檔案、設備、目錄或卷時發送 IRP_MJ_CREATE 請求。
通常,此 IRP 代表已呼叫 Microsoft Win32 函式(如 CreateFile)的用戶模式應用程式或代表已呼叫函式(如 IoCreateFile、IoCreateFileSpecifyDeviceObjectHint、ZwCreateFile 或 ZwOpenFile)的內核模式組件發送。
如果創建請求成功完成,應用程式或內核模式組件將接收到檔案物件的句柄。
下面的這個程式列印所有打開、創建的檔案或卷。
主程式
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i)
{
DriverObject->MajorFunction[i] = FsFilterDispatchPassThrough;
}
//creating handle for IRP_MJ_CREATE.
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsFilterDispatchCreate;
// IRP_MJ_CREATE IRP Handler
NTSTATUS FsFilterDispatchCreate(
__in PDEVICE_OBJECT DeviceObject,
__in PIRP Irp
)
{
PFILE_OBJECT pFileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
DbgPrint("%wZ\n", &pFileObject->FileName);
return FsFilterDispatchPassThrough(DeviceObject, Irp);
}
我只需要在創建檔案或目錄時列印驅動程式。
uj5u.com熱心網友回復:
將我的評論總結為一個有組織的解決方案。
您的過濾器驅動程式在實際檔案系統驅動程式之前被呼叫。但是,您想在檔案系統驅動程式處理 irp 后檢查結果。根據這篇文章,您可以簡單地檢查irp->IoStatus.Information == FILE_CREATED.
現在您只需要讓檔案系統驅動程式知道您對 irp 有更多的處理,因此它不會呼叫IoCompleteRequest和釋放 irp。為此,我們可以使用Cheat Sheet中的場景 2 。它最終會是這樣的:
NTSTATUS
CompletionRoutine_2(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
UNREFERENCED_PARAMETER(DeviceObject);
if (Irp->PendingReturned == TRUE) {
//
// You will set the event only if the lower driver has returned
// STATUS_PENDING earlier. This optimization removes the need to
// call KeSetEvent unnecessarily and improves performance because the
// system does not have to acquire an internal lock.
//
KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
}
// This is the only status you can return.
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
FsFilterDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
KEVENT event;
NTSTATUS status;
KeInitializeEvent(&event, NotificationEvent, FALSE);
//
// You are setting completion routine, so you must copy
// current stack location to the next. You cannot skip a location
// here.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
CompletionRoutine_2,
&event,
TRUE,
TRUE,
TRUE
);
PFSFILTER_DEVICE_EXTENSION pDevExt = (PFSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
status = IoCallDriver(pDevExt->AttachedToDeviceObject, Irp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Executive, // WaitReason
KernelMode, // must be Kernelmode to prevent the stack getting paged out
FALSE,
NULL // indefinite wait
);
status = Irp->IoStatus.Status;
}
// Your logic
if (Irp->IoStatus.Information == FILE_CREATED) {
PFILE_OBJECT pFileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
DbgPrint("%wZ\n", &pFileObject->FileName);
}
//
// Because you stopped the completion of the IRP in the CompletionRoutine
// by returning STATUS_MORE_PROCESSING_REQUIRED, you must call
// IoCompleteRequest here.
//
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
使用您基于的示例時,您可以簡單地將功能更改為此。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/474447.html
上一篇:如何獲得焦點視窗處理程式
