IoCreateStreamFileObjectLite和IoCreateStreamFileObject

上 WRK 代码

PFILE_OBJECT
IoCreateStreamFileObjectLite(
    IN PFILE_OBJECT FileObject OPTIONAL,
    IN PDEVICE_OBJECT DeviceObject OPTIONAL
    )

/*++

Routine Description:

    This routine is invoked to create a new file object that represents an
    alternate data stream for an existing file object.  The input file object
    represents the file object that already exists for a file, and the newly
    created stream file object is used to access other parts of the file
    other than the data.  Some uses of stream file objects are the EAs or
    the SECURITY_DESCRIPTORs on the file.  The stream file object allows
    the file system to cache these parts of the file just as if they were
    an entire to themselves.

    It is also possible to use stream file objects to represent virtual
    volume files.  This allows various parts of the on-disk structure to
    be viewed as a virtual file and therefore be cached using the same logic
    in the file system.  For this case, the device object pointer is used
    to create the file object.

    <strong>This call differs from IoCreateStreamFileObject in that it performs no
    handle management and does not result in a call to the file system
    cleanup entry.</strong>

Arguments:

    FileObject - Pointer to the file object to which the new stream file
        is related.  This pointer is optional.

    DeviceObject - Pointer to the device object on which the stream file
        is to be opened.  This pointer is not optional if the FileObject
        pointer is not specified.

Return Value:

    The function value is a pointer to the newly created stream file object.

--*/

{
    PFILE_OBJECT newFileObject;
    OBJECT_ATTRIBUTES objectAttributes;
    NTSTATUS status;

    PAGED_CODE();

    //
    // Begin by getting the device object from either the file object or
    // the device object parameter.
    //

    if (ARGUMENT_PRESENT( FileObject )) {
        DeviceObject = FileObject->DeviceObject;
    }

    //
    // if the driver has been marked for an unload or deleted operation, and
    // the reference count goes to zero, then the driver may need to be
    // unloaded or deleted at this point.
    // file that is being made, not a real file open request.  In essence,
    // no new file is really being opened.
    //

    IopInterlockedIncrementUlong( LockQueueIoDatabaseLock,
                                  &DeviceObject->ReferenceCount );

    //
    // Initialize the object attributes that will be used to create the file
    // object.
    //

    InitializeObjectAttributes( &objectAttributes,
                                (PUNICODE_STRING) NULL,
                                0,
                                (HANDLE) NULL,
                                (PSECURITY_DESCRIPTOR) NULL );

    //
    // Create the new file object.
    //

    <strong>status = ObCreateObject( KernelMode,
                             IoFileObjectType,
                             &objectAttributes,
                             KernelMode,
                             (PVOID) NULL,
                             (ULONG) sizeof( FILE_OBJECT ),
                             (ULONG) sizeof( FILE_OBJECT ),
                             0,
                             (PVOID *) &newFileObject );</strong>

    if (!NT_SUCCESS( status )) {
        IopDecrementDeviceObjectRef( DeviceObject, FALSE, FALSE );
        ExRaiseStatus( status );
    }

    //
    // Initialize the common fields of the file object.
    //

    RtlZeroMemory( newFileObject, sizeof( FILE_OBJECT ) );
    newFileObject->Type = IO_TYPE_FILE;
    newFileObject->Size = sizeof( FILE_OBJECT );
    <strong>newFileObject->DeviceObject = DeviceObject;</strong>
    newFileObject->Flags = FO_STREAM_FILE;
    KeInitializeEvent( &newFileObject->Event, SynchronizationEvent, FALSE );

    //
    //  Clean up from the creation.
    //

    ObFreeObjectCreateInfoBuffer(OBJECT_TO_OBJECT_HEADER(newFileObject)->ObjectCreateInfo);
    OBJECT_TO_OBJECT_HEADER(newFileObject)->ObjectCreateInfo = NULL;

    newFileObject->Flags |= FO_HANDLE_CREATED;
    ASSERT( newFileObject->Type == IO_TYPE_FILE );

    //
    // Synchronize here with the file system to make sure that
    // volumes don't go away while en route to the FS.
    //

    if (DeviceObject->Vpb) {
        IopInterlockedIncrementUlong( LockQueueIoVpbLock,
                                      (PLONG) &DeviceObject->Vpb->ReferenceCount );
    }

    return newFileObject;
}

很简单 1 创建一个FILE_OBJECT 对象newFileObject

             2 将newFileObject和DeviceObject相关联 newFileObject->DeviceObject = DeviceObject; 

我们继续看 IoCreateStreamFileObject

PFILE_OBJECT
IoCreateStreamFileObject(
    IN PFILE_OBJECT FileObject OPTIONAL,
    IN PDEVICE_OBJECT DeviceObject OPTIONAL
    )
{
    return (IoCreateStreamFileObjectEx(FileObject, DeviceObject, NULL));
}


PFILE_OBJECT
IoCreateStreamFileObjectEx(
    IN PFILE_OBJECT FileObject OPTIONAL,
    IN PDEVICE_OBJECT DeviceObject OPTIONAL,
    OUT PHANDLE FileHandle OPTIONAL
    )

/*++

Routine Description:

    This routine is invoked to create a new file object that represents an
    alternate data stream for an existing file object.  The input file object
    represents the file object that already exists for a file, and the newly
    created stream file object is used to access other parts of the file
    other than the data.  Some uses of stream file objects are the EAs or
    the SECURITY_DESCRIPTORs on the file.  The stream file object allows
    the file system to cache these parts of the file just as if they were
    an entire to themselves.

    It is also possible to use stream file objects to represent virtual
    volume files.  This allows various parts of the on-disk structure to
    be viewed as a virtual file and therefore be cached using the same logic
    in the file system.  For this case, the device object pointer is used
    to create the file object.

Arguments:

    FileObject - Pointer to the file object to which the new stream file
        is related.  This pointer is optional.

    DeviceObject - Pointer to the device object on which the stream file
        is to be opened.  This pointer is not optional if the FileObject
        pointer is not specified.

    FileHandle - Out parameter for handle if necessary.

Return Value:

    The function value is a pointer to the newly created stream file object.

--*/

{
    PFILE_OBJECT newFileObject;
    OBJECT_ATTRIBUTES objectAttributes;
    <strong>HANDLE handle;</strong>
    NTSTATUS status;

    PAGED_CODE();

    //
    // Begin by getting the device object from either the file object or
    // the device object parameter.
    //

    if (ARGUMENT_PRESENT( FileObject )) {
        DeviceObject = FileObject->DeviceObject;
    }

    //
    // Increment the reference count for the target device object.  Note
    // that no check is made to determine whether or not the device driver
    // is attempting to unload since this is an implicit open of a pseudo-
    // file that is being made, not a real file open request.  In essence,
    // no new file is really being opened.
    //

    IopInterlockedIncrementUlong( LockQueueIoDatabaseLock,
                                  &DeviceObject->ReferenceCount );

    //
    // Initialize the object attributes that will be used to create the file
    // object.
    //

    InitializeObjectAttributes( &objectAttributes,
                                (PUNICODE_STRING) NULL,
                                OBJ_KERNEL_HANDLE,
                                (HANDLE) NULL,
                                (PSECURITY_DESCRIPTOR) NULL );

    //
    // Create the new file object.
    //

    status = ObCreateObject( KernelMode,
                             IoFileObjectType,
                             &objectAttributes,
                             KernelMode,
                             (PVOID) NULL,
                             (ULONG) sizeof( FILE_OBJECT ),
                             (ULONG) sizeof( FILE_OBJECT ),
                             0,
                             (PVOID *) &newFileObject );

    if (!NT_SUCCESS( status )) {
        IopDecrementDeviceObjectRef( DeviceObject, FALSE, FALSE );
        ExRaiseStatus( status );
    }

    //
    // Initialize the common fields of the file object.
    //

    RtlZeroMemory( newFileObject, sizeof( FILE_OBJECT ) );
    newFileObject->Type = IO_TYPE_FILE;
    newFileObject->Size = sizeof( FILE_OBJECT );
    newFileObject->DeviceObject = DeviceObject;
    newFileObject->Flags = FO_STREAM_FILE;
    KeInitializeEvent( &newFileObject->Event, SynchronizationEvent, FALSE );

    //
    // Insert the device object into the table.  Note that this is done w/a
    // pointer bias so that the object cannot go away if some random user
    // application closes the handle before this code is finished w/it.
    //

    <strong>status = ObInsertObject( newFileObject,
                             NULL,
                             FILE_READ_DATA,
                             1,
                             (PVOID *) &newFileObject,
                             &handle );</strong>

    if (!NT_SUCCESS( status )) {
        ExRaiseStatus( status );
    }

    //
    // The insert completed successfully.  Update the bookkeeping so that the
    // fact that there is a handle is reflected.
    //

    newFileObject->Flags |= FO_HANDLE_CREATED;
    ASSERT( newFileObject->Type == IO_TYPE_FILE );

    //
    // Synchronize here with the file system to make sure that
    // volumes don't go away while en route to the FS.
    //

    if (DeviceObject->Vpb) {
        IopInterlockedIncrementUlong( LockQueueIoVpbLock,
                                      (PLONG) &DeviceObject->Vpb->ReferenceCount );
    }

    //
    // Finally, close the handle to the file. and clear the forward cluster
    //

    <strong>if (FileHandle == NULL) {
        ObCloseHandle( handle , KernelMode);
    } else {
        *FileHandle = handle;

        //
        // Get rid of the reference in ObInsertObject.
        //

        ObDereferenceObject(newFileObject);
    }
</strong>
    ASSERT( NT_SUCCESS( status ) );

    return newFileObject;
}

我们首先看见的差别在于 Routine Description, IoCreateStreamFileObjectLite比IoCreateStreamFileObjectEx多了一段描述

<strong>This call(IoCreateStreamFileObjectLite) differs from IoCreateStreamFileObject in that it performs no
handle management and does not result in a call to the file system cleanup entry.</strong>

正因为 Lite轻量级的意思, 所以IoCreateStreamFileObjectLite相对而言,缺少了 句柄管理以及不会导 文件系统的 Cluanup 这个 入口的调用。

那么, 代码里究竟区别在哪里呢?

在 IoCreateStreamFileObjectEx 多声明了一个变量

<pre name="code" class="cpp">HANDLE handle;

 而两个函数之间的差别也就是关于这个变量的 

<pre name="code" class="cpp">status = ObInsertObject( newFileObject,
                             NULL,
                             FILE_READ_DATA,
                             1,
                             (PVOID *) &newFileObject,
                             &handle );

 
if (FileHandle == NULL) {
        ObCloseHandle( handle , KernelMode);
    } else {
        *FileHandle = handle;

        //
        // Get rid of the reference in ObInsertObject.
        //

        ObDereferenceObject(newFileObject);
    }
我们看这个函数  ObInsertObject

NTSTATUS
ObInsertObject (
    __in PVOID Object,
    __in_opt PACCESS_STATE AccessState,
    __in_opt ACCESS_MASK DesiredAccess,
    __in ULONG ObjectPointerBias,
    __out_opt PVOID *NewObject,
    __out_opt PHANDLE Handle
    )

/*++

Routine Description:

    This routine inserts an object into the current processes handle table.

    The Object header includes a pointer to a SecurityDescriptor passed in
    an object creation call.  This SecurityDescriptor is not assumed to have
    been captured.  This routine is responsible for making an appropriate
    SecurityDescriptor and removing the reference in the object header.

Arguments:

    Object - Supplies a pointer to the new object body

    AccessState - Optionally supplies the access state for the new
        handle

    DesiredAccess - Optionally supplies the desired access we want for the
        new handle

    ObjectPointerBias - Supplies a bias to apply for the pointer count for the
        object

    <strong>NewObject - Optionally receives the pointer to the new object that we've
        created a handle for

    Handle - Receives the new handle, If NULL then no handle is created.
             Objects that don't have handles created must be unnamed and
             have an object bias of zero.</strong>

Return Value:

    An appropriate NTSTATUS value.

--*/

{......}
这个函数比较复杂 = =  以后专题分析。




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值