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

📄 filespy.c

📁 一个文件过滤驱动程序的例子
💻 C
📖 第 1 页 / 共 5 页
字号:
			FileCtxPtr2->DeleteOnClose = DeleteOnClose;

			ExReleaseFastMutex(&DevExt->FsCtxTableMutex);

		    IsNeedEncrypt = FALSE;
			
		   // we need handle file synchronously

		   KeWaitForSingleObject(&FileCtxPtr2->Event, Executive, KernelMode, FALSE, NULL);
			
		   KeSetEvent(&FileCtxPtr2->Event, IO_NO_INCREMENT, FALSE);
		}

		*/
     if (newName != NULL) {

            NLFreeNameControl( newName, &gFileSpyNameBufferLookasideList );
        }

     
   // Irp->IoStatus.Status = status;
	//IoCompleteRequest(Irp, IO_NO_INCREMENT);

//	return status;
	 //
    //  This is NOT our gControlDeviceObject, so let SpyPassThrough handle
    //  it appropriately
    //

	 IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
   // return SpyPassThrough( DeviceObject, Irp );
}

NTSTATUS
SpyFsControl (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine is invoked whenever an I/O Request Packet (IRP) w/a major
    function code of IRP_MJ_FILE_SYSTEM_CONTROL is encountered.  For most
    IRPs of this type, the packet is simply passed through.  However, for
    some requests, special processing is required.

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.

--*/

{
    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp );

    PAGED_CODE();

    //
    //  If this is for our control device object, fail the operation
    //

    if (gControlDeviceObject == DeviceObject) {

        //
        //  If the specified debug level is set, output what operation
        //  we are seeing to the debugger.
        //

        if (FlagOn( gFileSpyDebugLevel, SPYDEBUG_TRACE_IRP_OPS )) {

            SpyDumpIrpOperation( TRUE, Irp );
        }

        //
        //  If this device object is our control device object rather than
        //  a mounted volume device object, then this is an invalid request.
        //

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

        IoCompleteRequest( Irp, IO_NO_INCREMENT );

        return STATUS_INVALID_DEVICE_REQUEST;
    }

    ASSERT(IS_FILESPY_DEVICE_OBJECT( DeviceObject ));

    //
    //  Process the minor function code.
    //

    switch (pIrpSp->MinorFunction) {

        case IRP_MN_MOUNT_VOLUME:

            return SpyFsControlMountVolume ( DeviceObject, Irp );

        case IRP_MN_LOAD_FILE_SYSTEM:

            return SpyFsControlLoadFileSystem ( DeviceObject, Irp );

        case IRP_MN_USER_FS_REQUEST:
        {
            switch (pIrpSp->Parameters.FileSystemControl.FsControlCode) {

                case FSCTL_DISMOUNT_VOLUME:
                {
                    PFILESPY_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;

                    SPY_LOG_PRINT( SPYDEBUG_DISPLAY_ATTACHMENT_NAMES,
                                   ("FILESPY!SpyFsControl:                        Dismounting volume         %p \"%wZ\"\n",
                                    devExt->NLExtHeader.AttachedToDeviceObject,
                                    &devExt->NLExtHeader.DeviceName) );
                    break;
                }
            }
            break;
        }
    }

    //
    // This is a regular FSCTL that we need to let the filters see
    // Just do the callbacks for all the filters & passthrough
    //

    return SpyPassThrough( DeviceObject, Irp );
}


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

/*++

Routine Description:

    This routine is invoked for the completion of a mount/LoadFS request.  This
    will load the IRP and then signal the waiting dispatch routine.

Arguments:

    DeviceObject - Pointer to this driver's device object that was attached to
            the file system device object

    Irp - Pointer to the IRP that was just completed.

    Context - Pointer to the device object allocated during the down path so
            we wouldn't have to deal with errors here.

Return Value:

    The return value is always STATUS_SUCCESS.

--*/

{
    PRECORD_LIST recordList = ((PSPY_COMPLETION_CONTEXT)Context)->RecordList;

    ASSERT(IS_FILESPY_DEVICE_OBJECT( DeviceObject ));
    UNREFERENCED_PARAMETER( DeviceObject );

    //
    //  Log the completion (if we need to)
    //

    if (NULL != recordList) {

        SpyLogIrpCompletion( Irp, recordList );
    }

#if WINVER >= 0x0501
    if (IS_WINDOWSXP_OR_LATER()) {

        PKEVENT event = &((PSPY_COMPLETION_CONTEXT_WXP_OR_LATER)Context)->WaitEvent;

        //
        //  Wake up the dispatch routine
        //

        KeSetEvent(event, IO_NO_INCREMENT, FALSE);

    } else {
#endif

        //
        //  For Windows 2000, if we are not at passive level, we should
        //  queue this work to a worker thread using the workitem that is in
        //  Context.
        //

        if (KeGetCurrentIrql() > PASSIVE_LEVEL) {

            //
            //  We are not at passive level, but we need to be to do our work,
            //  so queue off to the worker thread.

            ExQueueWorkItem( &(((PSPY_COMPLETION_CONTEXT_W2K)Context)->WorkItem),
                             DelayedWorkQueue );

        } else {

            PSPY_COMPLETION_CONTEXT_W2K completionContext = Context;

            //
            //  We are already at passive level, so we will just call our
            //  worker routine directly.
            //

            (completionContext->WorkItem.WorkerRoutine)(completionContext->WorkItem.Parameter);
        }

#if WINVER >= 0x0501
    }
#endif

    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS
SpyFsControlMountVolume (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This processes a MOUNT VOLUME request

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.

--*/

{
    PFILESPY_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp );
    PDEVICE_OBJECT newDeviceObject;
    PFILESPY_DEVICE_EXTENSION newDevExt;
    NTSTATUS status;
    PRECORD_LIST recordList = NULL;
    PSPY_COMPLETION_CONTEXT_W2K completionContext;
    PNAME_CONTROL newDeviceName;

    PAGED_CODE();
    ASSERT(IS_FILESPY_DEVICE_OBJECT( DeviceObject ));

    //
    //  We should only see these FS_CTLs to control device objects.
    //

    ASSERT(!FlagOn(devExt->Flags,IsVolumeDeviceObject));

    //
    //  This is a mount request.  Create a device object that can be
    //  attached to the file system's volume device object if this request
    //  is successful.  We allocate this memory now since we can not return
    //  an error after the completion routine.
    //
    //  Since the device object we are going to attach to has not yet been
    //  created (it is created by the base file system) we are going to use
    //  the type of the file system control device object.  We are assuming
    //  that the file system control device object will have the same type
    //  as the volume device objects associated with it.
    //

    status = IoCreateDevice( gFileSpyDriverObject,
                             sizeof( FILESPY_DEVICE_EXTENSION ),
                             NULL,
                             DeviceObject->DeviceType,
                             0,
                             FALSE,
                             &newDeviceObject );

    if (!NT_SUCCESS( status )) {

        //
        //  If we can not attach to the volume, then simply skip it.
        //

        SPY_LOG_PRINT( SPYDEBUG_ERROR,
                       ("FileSpy!SpyFsControlMountVolume: Error creating volume device object, status=%08x\n",
                        status) );

        return SpyPassThrough( DeviceObject, Irp );
    }

    newDevExt = newDeviceObject->DeviceExtension;

    //
    //  Initialize the name lookup device extension header
    //
    //  We need to save the RealDevice object pointed to by the VPB
    //  parameter because this VPB may be changed by the underlying
    //  file system.  Both FAT and CDFS may change the VPB address if
    //  the volume being mounted is one they recognize from a previous
    //  mount.
    //
    //

    NLInitDeviceExtensionHeader( &newDevExt->NLExtHeader,
                                 newDeviceObject,
                                 pIrpSp->Parameters.MountVolume.Vpb->RealDevice );

    newDevExt->Flags = 0;

    RtlInitEmptyUnicodeString( &newDevExt->UserNames, NULL, 0 );

    //
    //  Get the name of this device
    //

#   define MVInsufResMsg "FileSpy!SpyFsControlMountVolume: Error getting device name, insufficient resources, status=%08x\n"


    newDeviceName = NLGetAndAllocateObjectName( newDevExt->NLExtHeader.StorageStackDeviceObject,
                                                &gFileSpyNameBufferLookasideList );

    if (newDeviceName == NULL) {

        //
        //  Can't allocate space for retrieving the device name. Skip device.
        //

        SPY_LOG_PRINT( SPYDEBUG_ERROR,
                       (MVInsufResMsg,
                        status) );

        IoDeleteDevice( newDeviceObject );
        return SpyPassThrough( DeviceObject, Irp );
    }

    //
    //  Save the name in our device object extension
    //

    status = NLAllocateAndCopyUnicodeString( &newDevExt->NLExtHeader.DeviceName,
                                             &newDeviceName->Name,
                                             FILESPY_DEVNAME_TAG );

    //
    //  Release name control
    //

    NLFreeNameControl( newDeviceName, &gFileSpyNameBufferLookasideList );

    //
    //  If we couldn't copy the name we are low on resources, quit now
    //

    if (!NT_SUCCESS(status)) {

        SPY_LOG_PRINT( SPYDEBUG_ERROR,
           (MVInsufResMsg,
            status) );

        IoDeleteDevice( newDeviceObject);
        return SpyPassThrough( DeviceObject, Irp );
    }

    //
    //  Since we have our own private completion routine we need to
    //  do our own logging of this operation, do it now.
    //

    if (SHOULD_LOG( DeviceObject )) {

        //
        // Lock the IRP if we can
        //

        recordList = SpyNewRecord(0);

        if (recordList) {

            SpyLogIrp( Irp, recordList );
        }
    }


		//
	// Initialize some useful variables
	//
	ExInitializeFastMutex(&newDevExt->FsCtxTableMutex);
	RtlInitializeGenericTable(&newDevExt->FsCtxTable,
		SfGenericCompareRoutine,
		SfGenericAllocateRoutine,
		SfGenericFreeRoutine,
		NULL
		);
    //
    //  Send the IRP to the legacy filters.  Note that the IRP we are sending
    //  down is for our CDO, not the new VDO that we have been passing to
    //  the mini-filters.
    //

    //
    //  VERSION NOTE:
    //
    //  On Windows 2000, we cannot simply synchronize back to the dispatch
    //  routine to do our post-mount processing.  We need to do this work at
    //  passive level, so we will queue that work to a worker thread from
    //  the completion routine.
    //
    //  For Windows XP and later, we can safely synchronize back to the dispatch
    //  routine.  The code below s

⌨️ 快捷键说明

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