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

📄 fspylib.c

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

    This routine will attach the FileSpyDeviceObject to the filter stack
    that DeviceObject is in.

    NOTE:  If there is an error in attaching, the caller is responsible
        for deleting the FileSpyDeviceObject.

Arguments:

    DeviceObject - The device object in the stack to which we want to attach.

    FilespyDeviceObject - The filespy device object that is to be attached to
            "DeviceObject".

Return Value:

    Returns STATUS_SUCCESS if the filespy deviceObject could be attached,
    otherwise an appropriate error code is returned.

--*/
{
    PFILESPY_DEVICE_EXTENSION devExt = FilespyDeviceObject->DeviceExtension;
    NTSTATUS status = STATUS_SUCCESS;
    ULONG i;

    PAGED_CODE();
    ASSERT( IS_FILESPY_DEVICE_OBJECT( FilespyDeviceObject ) );
#if WINVER >= 0x0501
    ASSERT( !SpyIsAttachedToDevice( DeviceObject, NULL ) );
#endif

    //
    //  Insert pointer from extension back to owning device object
    //

    devExt->NLExtHeader.ThisDeviceObject = FilespyDeviceObject;

    //
    //  Propagate flags from Device Object we are trying to attach to.
    //  Note that we do this before the actual attachment to make sure
    //  the flags are properly set once we are attached (since an IRP
    //  can come in immediately after attachment but before the flags would
    //  be set).
    //

    if (FlagOn( DeviceObject->Flags, DO_BUFFERED_IO )) {

        SetFlag( FilespyDeviceObject->Flags, DO_BUFFERED_IO );
    }

    if (FlagOn( DeviceObject->Flags, DO_DIRECT_IO )) {

        SetFlag( FilespyDeviceObject->Flags, DO_DIRECT_IO );
    }

    //
    //  It is possible for this attachment request to fail because this device
    //  object has not finished initializing.  This can occur if this filter
    //  loaded just as this volume was being mounted.
    //

    for (i=0; i < 8; i++) {

        LARGE_INTEGER interval;

        //
        //  Attach our device object to the given device object
        //  The only reason this can fail is if someone is trying to dismount
        //  this volume while we are attaching to it.
        //

        status = SpyAttachDeviceToDeviceStack( FilespyDeviceObject,
                                               DeviceObject,
                                               &devExt->NLExtHeader.AttachedToDeviceObject );

        if (NT_SUCCESS(status) ) {

            //
            //  Do all common initializing of the device extension.
            //

            SetFlag(devExt->Flags,IsVolumeDeviceObject);

            SpyInitDeviceNamingEnvironment( FilespyDeviceObject );

            SPY_LOG_PRINT( SPYDEBUG_DISPLAY_ATTACHMENT_NAMES,
                           ("FileSpy!SpyAttachToMountedDevice:            Attaching to volume        %p \"%wZ\"\n",
                            devExt->NLExtHeader.AttachedToDeviceObject,
                            &devExt->NLExtHeader.DeviceName) );

            //
            //  Add this device to our attachment list
            //

            ExAcquireFastMutex( &gSpyDeviceExtensionListLock );
            InsertTailList( &gSpyDeviceExtensionList, &devExt->NextFileSpyDeviceLink );
            ExReleaseFastMutex( &gSpyDeviceExtensionListLock );
            SetFlag(devExt->Flags,ExtensionIsLinked);

            return STATUS_SUCCESS;
        }

        //
        //  Delay, giving the device object a chance to finish its
        //  initialization so we can try again
        //

        interval.QuadPart = (500 * DELAY_ONE_MILLISECOND);   //delay 1/2 second
        KeDelayExecutionThread( KernelMode, FALSE, &interval );
    }

    return status;
}


VOID
SpyCleanupMountedDevice (
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:

    This cleans up any allocated memory in the device extension.

Arguments:

    DeviceObject - The device we are cleaning up

Return Value:

--*/
{
    PFILESPY_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;

    PAGED_CODE();

    ASSERT(IS_FILESPY_DEVICE_OBJECT( DeviceObject ));

    SpyCleanupDeviceNamingEnvironment( DeviceObject );

    //
    //  Cleanup the name lookup device extension header.
    //

    NLCleanupDeviceExtensionHeader( &devExt->NLExtHeader );

    //
    //  Cleanup the user names.
    //

    if (devExt->UserNames.Buffer != NULL) {

        ExFreePoolWithTag( devExt->UserNames.Buffer,
                           FILESPY_DEVNAME_TAG );
    }

    //
    //  Unlink from global list.
    //

    if (FlagOn(devExt->Flags,ExtensionIsLinked)) {

        ExAcquireFastMutex( &gSpyDeviceExtensionListLock );
        RemoveEntryList( &devExt->NextFileSpyDeviceLink );
        ExReleaseFastMutex( &gSpyDeviceExtensionListLock );
        ClearFlag(devExt->Flags,ExtensionIsLinked);
    }
}

////////////////////////////////////////////////////////////////////////
//                                                                    //
//                    Start/stop logging routines                     //
//                                                                    //
////////////////////////////////////////////////////////////////////////

//
//  VERSION NOTE:
//
//  On Windows 2000, we will try to attach a new FileSpy device object to the
//  device stack represented by the DeviceObject parameter.  We cannot get the
//  real storage stack device at this time, so this field will be set to NULL
//  in the device extension.  We also cannot get the device name as it is named
//  in the storage stack for this volume (e.g., \Device\HarddiskVolume1), so we
//  will just use the users name for the device for our device name.  On
//  Windows 2000, this information is only available as the device mounts.
//
//  On Windows XP and later, we will try to attach a new FileSpy device object
//  to the device stack represented by the DeviceObject parameter.  We are able
//  to get the disk device object for this stack, so that will be appropriately
//  set in the device extension.  We will also be able to get the device name
//  as it is named by the storage stack.
//
//  MULTIVERSION NOTE:
//
//  In SpyAttachToDeviceOnDemand, you see the code to determine which method of
//  determining if we are already attached based on the dynamically loaded
//  functions present.  If this driver is build for Windows 2000 specifically,
//  this logic will not be used.
//

NTSTATUS
SpyAttachToDeviceOnDemand (
    IN PDEVICE_OBJECT DeviceObject,
    IN PNAME_CONTROL UserDeviceName,
    IN OUT PDEVICE_OBJECT *FileSpyDeviceObject
    )
/*++

Routine Description:

    This routine does what is necessary to attach to a device sometime after
    the device has been mounted.

Arguments:

    DeviceObject - The device object that represents the file system stack
        for the volume named by UserDeviceName.

    UserDeviceName - Name of device for which logging should be started

    FileSpyDeviceObject - Set to the new filespy device object that was
        attached if we could successfully attach.

Return Value:

    STATUS_SUCCESS if we were able to attach, or an appropriate error code
    otherwise.

--*/
{
    PAGED_CODE();

    //
    //  If this device is a DFS device, we do not want to attach to it, so
    //  do this quick check here and return an error if this is the case.
    //
    //  DFS will just redirect the operation to the appropriate redirector.  If
    //  you are interested in monitoring these IOs, you should attach to the
    //  redirectors.  You cannot attach to these on demand by naming the DFS
    //  device, therefore we fail these requests.
    //

    if (DeviceObject->DeviceType == FILE_DEVICE_DFS) {

        return STATUS_NOT_SUPPORTED;
    }

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

        ASSERT( NULL != gSpyDynamicFunctions.GetDeviceAttachmentBaseRef &&
                NULL != gSpyDynamicFunctions.GetStorageStackDeviceObject );

        return SpyAttachToDeviceOnDemandWXPAndLater( DeviceObject,
                                                     UserDeviceName,
                                                     FileSpyDeviceObject );
    } else {
#endif

        return SpyAttachToDeviceOnDemandW2K( DeviceObject,
                                             UserDeviceName,
                                             FileSpyDeviceObject );
#if WINVER >= 0x0501
    }
#endif
}

NTSTATUS
SpyAttachToDeviceOnDemandW2K (
    IN PDEVICE_OBJECT DeviceObject,
    IN PNAME_CONTROL UserDeviceName,
    IN OUT PDEVICE_OBJECT *FileSpyDeviceObject
    )
/*++

Routine Description:

    VERSION: Windows 2000

    This routine does what is necessary to attach to a device sometime after
    the device has been mounted.

    Note that on Windows 2000, we cannot get the disk device object, therefore
    we will just use the Users device name as our name here.

Arguments:

    DeviceObject - The device object that represents the file system stack
        for the volume named by UserDeviceName.

    UserDeviceName - Name of device for which logging should be started

    FileSpyDeviceObject - Set to the new filespy device object that was
        attached if we could successfully attach.

Return Value:

    STATUS_SUCCESS if we were able to attach, or an appropriate error code
    otherwise.

--*/
{
    NTSTATUS status;
    PFILESPY_DEVICE_EXTENSION devExt;

    PAGED_CODE();

    ASSERT( FileSpyDeviceObject != NULL );

    //
    //  Create a new device object so we can attach it in the filter stack
    //

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

    if (!NT_SUCCESS( status )) {

        return status;
    }

    //
    //  Initialize device extension (don't know the storage stack device)
    //

    devExt = (*FileSpyDeviceObject)->DeviceExtension;

    NLInitDeviceExtensionHeader( &devExt->NLExtHeader,
                                 *FileSpyDeviceObject,
                                 NULL );

    devExt->Flags = 0;

    //
    //  Set Device Name - we will just use the user-entered device
    //  name on W2K.  No DOS name since we don't have the storage stack
    //  device object.
    //

    status = NLAllocateAndCopyUnicodeString( &devExt->NLExtHeader.DeviceName,
                                             &UserDeviceName->Name,
                                             FILESPY_DEVNAME_TAG );

    if (!NT_SUCCESS(status)) {

        goto ErrorAndCleanup;
    }

    //
    //  Call the routine to attach to a mounted device.
    //

    status = SpyAttachToMountedDevice( DeviceObject,
                                       *FileSpyDeviceObject );

    if (!NT_SUCCESS( status )) {

        goto ErrorAndCleanup;
    }

    return status;


ErrorAndCleanup:

    SPY_LOG_PRINT( SPYDEBUG_ERROR,
                   ("FileSpy!SpyStartLoggingDevice: Could not attach to \"%wZ\"; logging not started; status=%08x\n",
                    &UserDeviceName->Name,
                    status) );

    SpyCleanupMountedDevice( *FileSpyDeviceObject );

    IoDeleteDevice( *FileSpyDeviceObject );
    *FileSpyDeviceObject = NULL;

    return status;
}

#if WINVER >= 0x0501

NTSTATUS
SpyAttachToDeviceOnDemandWXPAndLater (
    IN PDEVICE_OBJECT DeviceObject,
    IN PNAME_CONTROL UserDeviceName,
    IN OUT PDEVICE_OBJECT *FileSpyDeviceObject
    )
/*++

Routine Description:

    This routine does what is necessary to attach to a device sometime after
    the device has been mounted.

Arguments:

    DeviceObject - The device object that represents the file system stack
        for the volume named by UserDeviceName.

    UserDeviceName - Name of device for which logging should be started

    FileSpyDeviceObject - Set to the new filespy device object that was
        attached if we could successfully attach.

Return Value:

    STATUS_SUCCESS if we were able to attach, or an appropriate error code
    otherwise.

--*/
{

    NTSTATUS status;
    PFILESPY_DEVICE_EXTENSION devExt;
    PDEVICE_OBJECT baseFileSystemDeviceObject = NULL;
    PDEVICE_OBJECT storageStackDeviceObject = NULL;
    PNAME_CONTROL devName = NULL;
    PDEVICE_OBJECT getNameDeviceObject;

    PAGED_CODE();

    ASSERT( FileSpyDeviceObject != NULL );

    //
    //  If this is a network file system, there will not be a disk device
    //  associated with this device, so there is no need to make this request
    //  of the IO Manager.  We will get the name of the network file system
    //  later from the baseFileSystemDeviceObject vs. the
    //  storageStackDeviceObject which is used to retrieve the device name for
    //  local volumes.
    //

    baseFileSystemDeviceObject = (gSpyDynamicFunctions.GetDeviceAttachmentBaseRef)( DeviceObject );

    if (FILE_DEVICE_NETWORK_FILE_SYSTEM != baseFileSystemDeviceObject->DeviceType) {

        //
        //  If this is not a network file system, query the IO M

⌨️ 快捷键说明

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