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

📄 fspylib.c

📁 过滤驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    IsAttached - This is set to TRUE if our filter is attached to this device
        stack, otherwise this is set to FALSE.

    StackDeviceObject - Set to a device object in the stack identified by the
        DeviceName.  If this is non-NULL, the caller is responsible for removing
        the reference put on this object before it was returned.

    AttachedDeviceObject - Set to the DeviceObject which FileSpy has previously
        attached to the device stack identify by DeviceName.  If this is
        non-NULL, the caller is responsible for removing the reference put on
        this object before it was returned.

Return Value:

    Returns STATUS_SUCCESS if we were able to successfully translate the
    DeviceName into a device stack and return the StackDeviceObject.  If an
    error occurs during the translation of the DeviceName into a device stack,
    the appropriate error code is returned.

--*/
{
    PNAME_CONTROL volumeName = NULL;
    NTSTATUS status;
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK openStatus;
    PFILE_OBJECT volumeFileObject;
    HANDLE fileHandle;
    PDEVICE_OBJECT baseFsDeviceObject;

    PAGED_CODE();

    //
    //  Initialize return state
    //

    ASSERT( NULL != StackDeviceObject );
    ASSERT( NULL != OurAttachedDeviceObject );
    ASSERT( NULL != IsAttached );

    *StackDeviceObject = NULL;
    *OurAttachedDeviceObject = NULL;
    *IsAttached = FALSE;

    //
    //  Setup the name to open
    //

    status = NLAllocateNameControl( &volumeName, &gFileSpyNameBufferLookasideList );

    if (!NT_SUCCESS( status )) {

        return status;
    }

    status = NLCheckAndGrowNameControl( volumeName,
                                         sizeof(L"\\DosDevices\\") +
                                         DeviceName->Name.Length );
    if (!NT_SUCCESS( status )) {

        return status;
    }

    RtlAppendUnicodeToString( &volumeName->Name, L"\\DosDevices\\" );
    RtlAppendUnicodeStringToString( &volumeName->Name, &DeviceName->Name );

    //
    //  Initialize objectAttributes.  Note that this does not *copy* the
    //  volume name, so we cannot release volumeName until we're done with
    //  objectAttributes.
    //

    InitializeObjectAttributes( &objectAttributes,
                                &volumeName->Name,
                                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                NULL,
                                NULL );

    //
    //  Open the file object for the given device.
    //

    status = ZwCreateFile( &fileHandle,
                           SYNCHRONIZE|FILE_READ_DATA,
                           &objectAttributes,
                           &openStatus,
                           NULL,
                           0,
                           FILE_SHARE_READ|FILE_SHARE_WRITE,
                           FILE_OPEN,
                           FILE_SYNCHRONOUS_IO_NONALERT,
                           NULL,
                           0 );

    NLFreeNameControl( volumeName, &gFileSpyNameBufferLookasideList );

    if (STATUS_OBJECT_PATH_NOT_FOUND == status ||
        STATUS_OBJECT_NAME_INVALID == status) {

        //
        //  Maybe this name didn't need the "\DosDevices\" prepended to the
        //  name.  Try the open again using just the DeviceName passed in.
        //

         InitializeObjectAttributes( &objectAttributes,
                                     &DeviceName->Name,
                                     OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                     NULL,
                                     NULL );

        //
        //  Open the file object for the given device.
        //

        status = ZwCreateFile( &fileHandle,
                               SYNCHRONIZE|FILE_READ_DATA,
                               &objectAttributes,
                               &openStatus,
                               NULL,
                               0,
                               FILE_SHARE_READ|FILE_SHARE_WRITE,
                               FILE_OPEN,
                               FILE_SYNCHRONOUS_IO_NONALERT,
                               NULL,
                               0 );

        if (!NT_SUCCESS( status )) {

            return status;
        }

        //
        //  We were able to open the device using the name passed in, so
        //  now we will fall through and do the rest of this work.
        //

    } else if (!NT_SUCCESS( status )) {

        return status;
    }

    //
    //  Get a pointer to the volumes file object.
    //

    status = ObReferenceObjectByHandle( fileHandle,
                                        FILE_READ_DATA,
                                        *IoFileObjectType,
                                        KernelMode,
                                        &volumeFileObject,
                                        NULL );

    if(!NT_SUCCESS( status )) {

        ZwClose( fileHandle );
        return status;
    }

    //
    //  Get the device object we want to attach to (parent device object
    //  in chain).
    //

    baseFsDeviceObject = IoGetBaseFileSystemDeviceObject( volumeFileObject );

    if (baseFsDeviceObject == NULL) {

        ObDereferenceObject( volumeFileObject );
        ZwClose( fileHandle );

        return STATUS_INVALID_DEVICE_STATE;
    }

    //
    //  Now see if we are attached to this device stack.  Note that we need to
    //  keep this file object open while we do this search to ensure that the
    //  stack won't get torn down while SpyIsAttachedToDevice does its work.
    //

    *IsAttached = SpyIsAttachedToDevice( baseFsDeviceObject,
                                         OurAttachedDeviceObject );

    //
    //  Return the base file system's device object to represent this device
    //  stack even if we didn't find our device object in the stack.
    //

    ObReferenceObject( baseFsDeviceObject );
    *StackDeviceObject = baseFsDeviceObject;

    //
    //  Close our handle
    //

    ObDereferenceObject( volumeFileObject );
    ZwClose( fileHandle );

    return STATUS_SUCCESS;
}

//
//  VERSION NOTE:
//
//  In Windows 2000, the APIs to safely walk an arbitrary file system device
//  stack were not supported.  If we can guarantee that a device stack won't
//  be torn down during the walking of the device stack, we can walk from
//  the base file system's device object up to the top of the device stack
//  to see if we are attached.  We know the device stack will not go away if
//  we are in the process of processing a mount request OR we have a file object
//  open on this device.
//
//  In Windows XP and later, the IO Manager provides APIs that will allow us to
//  walk through the chain safely using reference counts to protect the device
//  object from going away while we are inspecting it.  This can be done at any
//  time.
//
//  MULTIVERSION NOTE:
//
//  If built for Windows XP or later, this driver is built to run on
//  multiple versions.  When this is the case, we will test for the presence of
//  the new IO Manager routines that allow for a filter to safely walk the file
//  system device stack and use those APIs if they are present to determine if
//  we have already attached to this volume.  If these new IO Manager routines
//  are not present, we will assume that we are at the bottom of the file
//  system stack and walk up the stack looking for our device object.
//

BOOLEAN
SpyIsAttachedToDevice (
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PDEVICE_OBJECT *AttachedDeviceObject OPTIONAL
    )
{
    PAGED_CODE();

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

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

        return SpyIsAttachedToDeviceWXPAndLater( DeviceObject,
                                                 AttachedDeviceObject );
    } else {
#endif

        return SpyIsAttachedToDeviceW2K( DeviceObject, AttachedDeviceObject );

#if WINVER >= 0x0501
    }
#endif
}

BOOLEAN
SpyIsAttachedToDeviceW2K (
    PDEVICE_OBJECT DeviceObject,
    PDEVICE_OBJECT *AttachedDeviceObject OPTIONAL
    )
/*++

Routine Description:

    VERSION: Windows 2000

    This routine walks up the device stack from the DeviceObject passed in
    looking for a device object that belongs to our filter.

    Note:  For this routine to operate safely, the caller must ensure two
        things:
        * the DeviceObject is the base file system's device object and therefore
        is at the bottom of the file system stack
        * this device stack won't be going away while we walk up this stack.  If
        we currently have a file object open for this device stack or we are
        in the process of mounting this device, this guarantee is satisfied.

Arguments:

    DeviceObject - The device chain we want to look through

    AttachedDeviceObject - Set to the DeviceObject which FileSpy
            has previously attached to DeviceObject.  If this is non-NULL,
            the caller must clear the reference put on this device object.

Return Value:

    TRUE if we are attached, FALSE if not

--*/
{
    PDEVICE_OBJECT currentDeviceObject;

    PAGED_CODE();

    for (currentDeviceObject = DeviceObject;
         currentDeviceObject != NULL;
         currentDeviceObject = currentDeviceObject->AttachedDevice) {

        if (IS_FILESPY_DEVICE_OBJECT( currentDeviceObject )) {

            //
            //  We are attached.  If requested, return the found device object.
            //

            if (ARGUMENT_PRESENT( AttachedDeviceObject )) {

                ObReferenceObject( currentDeviceObject );
                *AttachedDeviceObject = currentDeviceObject;
            }

            return TRUE;
        }
    }

    //
    //  We did not find ourselves on the attachment chain.  Return a NULL
    //  device object pointer (if requested) and return we did not find
    //  ourselves.
    //

    if (ARGUMENT_PRESENT( AttachedDeviceObject )) {

        *AttachedDeviceObject = NULL;
    }

    return FALSE;
}

#if WINVER >= 0x0501

BOOLEAN
SpyIsAttachedToDeviceWXPAndLater (
    PDEVICE_OBJECT DeviceObject,
    PDEVICE_OBJECT *AttachedDeviceObject OPTIONAL
    )
/*++

Routine Description:

    VERSION: Windows XP and later

    This walks down the attachment chain looking for a device object that
    belongs to this driver.  If one is found, the attached device object
    is returned in AttachedDeviceObject.

Arguments:

    DeviceObject - The device chain we want to look through

    AttachedDeviceObject - Set to the DeviceObject which FileSpy
            has previously attached to DeviceObject.

Return Value:

    TRUE if we are attached, FALSE if not

--*/
{
    PDEVICE_OBJECT currentDevObj;
    PDEVICE_OBJECT nextDevObj;

    PAGED_CODE();

    //
    //  Get the device object at the TOP of the attachment chain
    //

    ASSERT( NULL != gSpyDynamicFunctions.GetAttachedDeviceReference );
    currentDevObj = (gSpyDynamicFunctions.GetAttachedDeviceReference)( DeviceObject );

    //
    //  Scan down the list to find our device object.
    //

    do {

        if (IS_FILESPY_DEVICE_OBJECT( currentDevObj )) {

            //
            //  We have found that we are already attached.  If we are
            //  returning the device object, leave it referenced else remove
            //  the reference.
            //

            if (NULL != AttachedDeviceObject) {

                *AttachedDeviceObject = currentDevObj;

            } else {

                ObDereferenceObject( currentDevObj );
            }

            return TRUE;
        }

        //
        //  Get the next attached object.  This puts a reference on
        //  the device object.
        //

        ASSERT( NULL != gSpyDynamicFunctions.GetLowerDeviceObject );
        nextDevObj = (gSpyDynamicFunctions.GetLowerDeviceObject)( currentDevObj );

        //
        //  Dereference our current device object, before
        //  moving to the next one.
        //

        ObDereferenceObject( currentDevObj );

        currentDevObj = nextDevObj;

    } while (NULL != currentDevObj);

    //
    //  Mark no device returned.
    //

    if (ARGUMENT_PRESENT(AttachedDeviceObject)) {

        *AttachedDeviceObject = NULL;
    }

    return FALSE;
}

#endif //WINVER >= 0x0501

NTSTATUS
SpyAttachToMountedDevice (
    IN PDEVICE_OBJECT DeviceObject,
    IN PDEVICE_OBJECT FilespyDeviceObject
    )
/*++

Routine Description:

    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

⌨️ 快捷键说明

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