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

📄 filespy.c

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

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

    //
    //  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 shows both methods.  Admittedly, the code
    //  would be simplified if you chose to only use one method or the other,
    //  but you should be able to easily adapt this for your needs.
    //

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

        SPY_COMPLETION_CONTEXT_WXP_OR_LATER completionContext;

        IoCopyCurrentIrpStackLocationToNext ( Irp );

        completionContext.RecordList = recordList;
        KeInitializeEvent( &completionContext.WaitEvent,
                           NotificationEvent,
                           FALSE );

        IoSetCompletionRoutine( Irp,
                                SpyFsControlCompletion,
                                &completionContext,     //context parameter
                                TRUE,
                                TRUE,
                                TRUE );

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

        //
        //  Wait for the operation to complete
        //

        if (STATUS_PENDING == status) {

            status = KeWaitForSingleObject( &completionContext.WaitEvent,
                                            Executive,
                                            KernelMode,
                                            FALSE,
                                            NULL );
            ASSERT(STATUS_SUCCESS == status);
        }

        //
        //  Verify the IoCompleteRequest was called
        //

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

        status = SpyFsControlMountVolumeComplete( DeviceObject,
                                                  Irp,
                                                  newDeviceObject );

    } else {
#endif
        completionContext = ExAllocatePoolWithTag( NonPagedPool,
                                                   sizeof( SPY_COMPLETION_CONTEXT_W2K ),
                                                   FILESPY_CONTEXT_TAG );

        if (completionContext == NULL) {

            IoSkipCurrentIrpStackLocation( Irp );

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

        } else {

            completionContext->RecordList = recordList;

            ExInitializeWorkItem( &completionContext->WorkItem,
                                  SpyFsControlMountVolumeCompleteWorker,
                                  completionContext );

            completionContext->DeviceObject = DeviceObject,
            completionContext->Irp = Irp;
            completionContext->NewDeviceObject = newDeviceObject;

            IoCopyCurrentIrpStackLocationToNext ( Irp );

            IoSetCompletionRoutine( Irp,
                                    SpyFsControlCompletion,
                                    completionContext,     //context parameter
                                    TRUE,
                                    TRUE,
                                    TRUE );

            status = IoCallDriver( devExt->NLExtHeader.AttachedToDeviceObject, Irp );
        }
#if WINVER >= 0x0501
    }
#endif
    return status;
}

VOID
SpyFsControlMountVolumeCompleteWorker (
    IN PSPY_COMPLETION_CONTEXT_W2K Context
    )
/*++

Routine Description:

    The worker thread routine that will call our common routine to do the
    post-MountVolume work.

Arguments:

    Context - The context passed to this worker thread.

Return Value:

    None.

--*/
{
    SpyFsControlMountVolumeComplete( Context->DeviceObject,
                                     Context->Irp,
                                     Context->NewDeviceObject );

    ExFreePoolWithTag( Context, FILESPY_CONTEXT_TAG );
}

NTSTATUS
SpyFsControlMountVolumeComplete (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PDEVICE_OBJECT NewDeviceObject
    )
/*++

Routine Description:

    This does the post-Mount work and must be done at PASSIVE_LEVEL.

Arguments:

    DeviceObject - The device object for this operation,

    Irp - The IRP for this operation that we will complete once we are finished
        with it.

Return Value:

    Returns the status of the mount operation.

--*/
{
    PVPB vpb;
    PFILESPY_DEVICE_EXTENSION newDevExt = NewDeviceObject->DeviceExtension;
    PDEVICE_OBJECT attachedDeviceObject;
    NTSTATUS status;
    BOOLEAN justAttached = FALSE;

    PAGED_CODE();

    //
    //  Get the correct VPB from the real device object saved in our
    //  device extension.  We do this because the VPB in the IRP stack
    //  may not be the correct VPB when we get here.  The underlying
    //  file system may change VPBs if it detects a volume it has
    //  mounted previously.
    //

    vpb = newDevExt->NLExtHeader.StorageStackDeviceObject->Vpb;

    //
    //  See if the mount was successful.
    //

    if (NT_SUCCESS( Irp->IoStatus.Status )) {

        //
        //  Acquire lock so we can atomically test if we area already attached
        //  and if not, then attach.  This prevents a double attach race
        //  condition.
        //

        ExAcquireFastMutex( &gSpyAttachLock );

        //
        //  The mount succeeded.  If we are not already attached, attach to the
        //  device object.  Note: one reason we could already be attached is
        //  if the underlying file system revived a previous mount.
        //

        if (!SpyIsAttachedToDevice( vpb->DeviceObject,
            &attachedDeviceObject )) {

            //
            //  Attach to the new mounted volume.  The correct file system
            //  device object that w

⌨️ 快捷键说明

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