我想编写一个内核驱动程序程序,其中创建文件时需要通知我

发布于 2025-01-27 04:10:50 字数 1217 浏览 3 评论 0原文

我使用这个在其创建的项目的地方IRP_MJ_CREATE的处理程序。显示所有创建或打开系统的文件。 IRP_MJ_CREATE的文档是:

i/o管理器在新文件或 正在创建目录,或者当现有文件,设备, 目录或卷正在打开。

通常,此IRP代表用户模式应用程序发送 称为Microsoft Win32功能,例如CreateFile或代表 称为函数的内核模式组件 IocreateFile,IocreateFileSpefifieDeviceObjecthint,Zwcreatefile或 zwopenfile。

如果创建请求成功完成,则应用程序或 内核模式组件接收到文件对象的句柄。

下面的该程序打印了打开,创建的所有文件或卷。

main.c


    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);
}

我只需要驱动程序才能在创建文件或目录时才打印。

I used the reference of this project where it creates a handler for IRP_MJ_CREATE. which displays all the files which are created or opened the system.
The documentation of IRP_MJ_CREATE is this:

The I/O Manager sends an IRP_MJ_CREATE request when a new file or
directory is being created, or when an existing file, device,
directory, or volume is being opened.

Normally this IRP is sent on behalf of a user-mode application that
has called a Microsoft Win32 function such as CreateFile or on behalf
of a kernel-mode component that has called a function such as
IoCreateFile, IoCreateFileSpecifyDeviceObjectHint, ZwCreateFile, or
ZwOpenFile.

If the create request is completed successfully, the application or
kernel-mode component receives a handle to the file object.

This program below prints all the files or volumes which are opened, created.

main.c


    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);
}

I just need the driver to print only when a file or directory is created.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

春夜浅 2025-02-03 04:10:50

在实际文件系统驱动程序之前正在调用您的过滤器驱动程序。但是,您想在文件系统驱动程序处理IRP后检查结果。根据 this 您的文章,您可以简单地检查irp-&gt; iostatus.Information == file_created

现在,您只需要让文件系统驱动程序知道您与IRP有更多的处理,因此它不会调用iocpleterequest 并释放IRP。 To do so we can use scenario 2 out of the

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;
}

使用 a>您基于,您可以简单地将功能更改为此。

Your filter driver is being called before the actual file system driver. However you want to check the result after the file system driver handled the irp. according to this article, you can simply check irp->IoStatus.Information == FILE_CREATED.

Now you only need to let the file system driver know that you have more processing to do with the irp, so it won't call IoCompleteRequest and free the irp. To do so we can use scenario 2 out of the Cheat Sheet. It will end up something like this:

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;
}

When using the example you based on, you can simply change the function to this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文