⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfilter.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:

Arguments:

    DeviceObject - Pointer to the device object for this driver.

    IRP - Pointer to the request packet representing the I/O request.

Return Value:

    The function value is the status of the operation.

Note:

    A note to file system filter implementers:
        This routine actually "passes" through the request by taking this
        driver out of the IRP stack.  If the driver would like to pass the
        I/O request through, but then also see the result, then rather than
        taking itself out of the loop it could keep itself in by copying the
        caller's parameters to the next stack location and then set its own
        completion routine.

        Hence, instead of calling:

            IoSkipCurrentIrpStackLocation( Irp );

        You could instead call:

            IoCopyCurrentIrpStackLocationToNext( Irp );
            IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE );


        This example actually NULLs out the caller's I/O completion routine, but
        this driver could set its own completion routine so that it would be
        notified when the request was completed (see SfCreate for an example of
        this).

--*/

{
    PIO_STACK_LOCATION pIrp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  Sfilter doesn't allow handles to its control device object to be
    //  created, therefore, no other operation should be able to come through.
    //

    ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

    //
    //  File systems should NEVER receive a power IRP
    //

    ASSERT(pIrp->MajorFunction != IRP_MJ_POWER);

    //
    //  Get this driver out of the driver stack and get to the next driver as
    //  quickly as possible.
    //

    IoSkipCurrentIrpStackLocation( Irp );

    //
    //  Call the appropriate file system driver with the request.
    //

    return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
                          Irp );
}



NTSTATUS
SfCreate (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This function filters create/open operations.  It simply establishes an
    I/O completion routine to be invoked if the operation was successful.

Arguments:

    DeviceObject - Pointer to the target device object of the create/open.

    Irp - Pointer to the I/O Request Packet that represents the operation.

Return Value:

    The function value is the status of the call to the file system's entry
    point.

--*/

{
    NTSTATUS status;
    PNAME_CONTROL fileName = NULL;
    PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
    BOOLEAN cacheName;

    PAGED_CODE();

    //
    //  If this is for our control device object, don't allow it to be opened.
    //

    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {

        //
        //  Sfilter doesn't allow for any communication through its control
        //  device object, therefore it fails all requests to open a handle
        //  to its control device object.
        //
        //  See the FileSpy sample for an example of how to allow creates to
        //  the filter's control device object and manage communication via
        //  that handle.
        //

        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest( Irp, IO_NO_INCREMENT );

        return STATUS_INVALID_DEVICE_REQUEST;
    }

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));


    //
    //  If debugging is enabled, do the processing required to see the packet
    //  upon its completion.  Otherwise, let the request go with no further
    //  processing.
    //

    if (!FlagOn( SfDebug, SFDEBUG_DO_CREATE_COMPLETION |
                          SFDEBUG_GET_CREATE_NAMES|
                          SFDEBUG_DISPLAY_CREATE_NAMES )) {

        //
        //  We don't want to get filenames, display filenames, or
        //  call our completion routine.  Don't put us on the stack
        //  and call the next driver.
        //

        IoSkipCurrentIrpStackLocation( Irp );

        return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
                              Irp );

    }

    if (FlagOn( SfDebug, SFDEBUG_GET_CREATE_NAMES |
                         SFDEBUG_DISPLAY_CREATE_NAMES ) &&
        !FlagOn(devExt->Flags,SFDEVFL_DISABLE_VOLUME)) {

        //
        //  Debugging specifies that we need to get the filename
        //

        NAME_LOOKUP_FLAGS LookupFlags = 0x00000000;

        //
        //  If DosName has been set, indicate via flags that we
        //  want to use it when getting the full file name.
        //

        if (devExt->NLExtHeader.DosName.Length != 0) {

            SetFlag( LookupFlags, NLFL_USE_DOS_DEVICE_NAME );
        }

        //
        //  Indicate we are in pre-create
        //

        SetFlag( LookupFlags, NLFL_IN_CREATE );

        if (FlagOn( irpSp->Parameters.Create.Options, FILE_OPEN_BY_FILE_ID )) {

            //
            //  The file is being opened by ID, not file name.
            //

            SetFlag( LookupFlags, NLFL_OPEN_BY_ID );
        }

        if (FlagOn( irpSp->Flags, SL_OPEN_TARGET_DIRECTORY )) {

            //
            //  The file's parent directory should be opened
            //

            SetFlag( LookupFlags, NLFL_OPEN_TARGET_DIR );
        }


        //
        //  Retrieve the file name.  Note that in SFilter we don't do any name
        //  caching.
        //

        status = NLAllocateNameControl( &fileName, &gSfNameBufferLookasideList );

        if (NT_SUCCESS( status )) {

            //
            //  We are okay not checking the return value here because
            //  the GetFullPathName function will set the Unicode String
            //  length to 0. So either way, in an error it will print an empty string
            //

            status = NLGetFullPathName( irpSp->FileObject,
                                        fileName,
                                        &devExt->NLExtHeader,
                                        LookupFlags,
                                        &gSfNameBufferLookasideList,
                                        &cacheName );
        }

    }

    if (FlagOn( SfDebug, SFDEBUG_DISPLAY_CREATE_NAMES |
                         SFDEBUG_DO_CREATE_COMPLETION ) &&
        !FlagOn(devExt->Flags,SFDEVFL_DISABLE_VOLUME)) {

        //
        //  Debugging flags indicate we must do completion.
        //  Note that to display file names we must do completion
        //  because we don't know IoStatus.Status and IoStatus.Information
        //  until post-create.
        //

        KEVENT waitEvent;

        //
        //  Initialize an event to wait for the completion routine to occur
        //

        KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );

        //
        //  Copy the stack and set our Completion routine
        //

        IoCopyCurrentIrpStackLocationToNext( Irp );

        IoSetCompletionRoutine(
            Irp,
            SfCreateCompletion,
            &waitEvent,
            TRUE,
            TRUE,
            TRUE );

        //
        //  Call the next driver in the stack.
        //

        status = IoCallDriver( devExt->NLExtHeader.AttachedToDeviceObject, Irp );

        //
        //  Wait for the completion routine to be called
        //

        if (STATUS_PENDING == status) {

            NTSTATUS localStatus = KeWaitForSingleObject( &waitEvent,
                                                          Executive,
                                                          KernelMode,
                                                          FALSE,
                                                          NULL );
            ASSERT(STATUS_SUCCESS == localStatus);
        }

        //
        //  Verify the IoCompleteRequest was called
        //

        ASSERT(KeReadStateEvent(&waitEvent) ||
               !NT_SUCCESS(Irp->IoStatus.Status));

        //
        //  If debugging indicates we should display file names, do it.
        //

        if (irpSp->Parameters.Create.Options & FILE_OPEN_BY_FILE_ID) {

            SF_LOG_PRINT( SFDEBUG_DISPLAY_CREATE_NAMES,
                          ("SFilter!SfCreate: OPENED        fo=%p %08x:%08x   %wZ (FID)\n",
                           irpSp->FileObject,
                           Irp->IoStatus.Status,
                           Irp->IoStatus.Information,
                           &fileName->Name) );

        } else {

            SF_LOG_PRINT( SFDEBUG_DISPLAY_CREATE_NAMES,
                          ("SFilter!SfCreate: OPENED        fo=%p st=%08x:%08x   %wZ\n",
                           irpSp->FileObject,
                           Irp->IoStatus.Status,
                           Irp->IoStatus.Information,
                           &fileName->Name) );
        }

        //
        //  Release the name control structure if we have
        //

        if (fileName != NULL) {

            NLFreeNameControl( fileName, &gSfNameBufferLookasideList );
        }

        //
        //  Save the status and continue processing the IRP
        //

        status = Irp->IoStatus.Status;

        IoCompleteRequest( Irp, IO_NO_INCREMENT );

        return status;

    } else {

        //
        //  Free the name control if we have one
        //

        if (fileName != NULL) {

            NLFreeNameControl( fileName, &gSfNameBufferLookasideList );
        }

        //
        //  Debugging flags indicate we did not want to display the file name
        //  or call completion routine.
        //  (ie SFDEBUG_GET_CREATE_NAMES && !SFDEBUG_DO_CREATE_COMPLETION)
        //

        IoSkipCurrentIrpStackLocation( Irp );

        return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
                              Irp );
    }
}


NTSTATUS
SfCreateCompletion (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    )

/*++

Routine Description:

    This function is the create/open completion routine for this filter
    file system driver.  If debugging is enabled, then this function prints
    the name of the file that was successfully opened/created by the file
    system as a result of the specified I/O request.

Arguments:

    DeviceObject - Pointer to the device on which the file was created.

    Irp - Pointer to the I/O Request Packet the represents the operation.

    Context - This driver's context parameter - unused;

Return Value:

    The function value is STATUS_SUCCESS.

--*/

{
    PKEVENT event = Context;

    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( Irp );

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

    KeSetEvent(event, IO_NO_INCREMENT, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}



NTSTATUS
SfCleanupClose (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is invoked whenever a cleanup or a close request is to be
    processed. NOTE: This routine doesn't actually do anything, it is the same
    as SfPassThrough. It is only registered as the cleanup handler to ease in
    debugging (You can set a Breakpoint here instead of in the generic PassThrough.

Arguments:

    DeviceObject - Pointer to the device object for this driver.

    Irp - Pointer to the request packet representing the I/O request.

Return Value:

    The function value is the status of the operation.

Note:

    See notes for SfPassThrough for this routine.


--*/

{
    PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension);
    PIO_STACK_LOCATION irpSp;

    PAGED_CODE();

    irpSp = IoGetCurrentIrpStackLocation( Irp );

    //
    //  Sfilter doesn't allow handles to its control device object to be
    //  created, therefore, no other operation should be able to come through.
    //

    ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

    //
    //  File systems should NEVER receive a power IRP
    //

    ASSERT(irpSp->MajorFunction != IRP_MJ_POWER);

    //
    //  Display cleanup/close info if requested.  Note that we don't have a
    //  make to display so only display the file object address.
    //

    if (!FlagOn(devExt->Flags,SFDEVFL_DISABLE_VOLUME)) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -