chapter 9.2: I/O Target创建及管理

driver可以直接调用framework方法访问默认I/O target:WdfDeviceGetIoTarget 


KMDF:Remote I/O target 创建
驱动需要创建并打开I/O target。
WdfIoTargetCreate:创建,并不关联特定I/O target(WDF_OBJECT_ATTRIBUTES)
WdfIoTargetOpen:关联目标设备/设备栈/文件(WDF_IO_TARGET_OPEN_PARAMS)
WdfIoTargetOpen:关闭target后,驱动还可以调用它关联一个不同的目标。(WDF_IO_TARGET_OPEN_PARAMS)
------/I/O Target Parameters Structure的初始化方法\--------
I/O target parameters structure:target device名称、callbacks
WDF_IO_TARGET_OPEN_PARAMS_INIT_XXX:一些结构初始化方法
下表,如何选择这些方法:
   

If your driver

Use

Identifies the target by the name of the device, device interface, or file, and you want the framework to create a new file

The CREATE_BY_NAME version of the initialization function, and supply an access mask in the Desired-Access parameter that specifies the access rights that your driver requires.

Identifies the target by name, and you want the framework to fail the open request if the specified target does not exist

The OPEN_BY_NAME version of the initialization function, and supply an access mask in the Desired-Access parameter that specifies the access rights that your driver requires.

Supplies a pointer to a WDM DEVICE_OBJECT

The EXISTING_DEVICE version of the initialization function. By using this initialization function, a driver that has a pointer to a WDM device object for another device stack can use that stack as a remote I/O target.


    CREATE_BY_NAME方法最常用
访问权限:
    STANDARD_RIGHTS_READ
    STANDARD_RIGHTS_WRITE 
    STANDARD_RIGHTS_ALL:read write delete
WDF_IO_TARGET_OPEN_PARAMS Structure的内容如下:
   

Field name

Description

Type

One of the following values of the WDF_IO_TARGET_OPEN_TYPE enumeration:

WdfIoTargetOpenUseExistingDevice

WdfIoTargetOpenByName

WdfIoTargetOpenReopen

Filled in for the driver by the initialization functions.

EvtIoTargetQueryRemove

Pointer to the EvtIoTargetQueryRemove callback.

EvtIoTargetRemoveCanceled

Pointer to the EvtIoTargetRemoveCanceled callback.

EvtIoTargetRemoveComplete

Pointer to the EvtIoTargetRemoveComplete callback.

TargetDeviceObject

Pointer to a WDM DEVICE_OBJECT; filled in as required by the initialization function;

required for EXISTING_DEVICE version.

TargetFileObject

Pointer to a FILE_OBJECT;

used only for WdfIoTargetOpenUseExistingDevice.

TargetDeviceName

Unicode string that identifies the I/O target by name;

filled in as required by the initialization function;

required for OPEN_BY_NAME version.

DesiredAccess

Value of type ACCESS_MASK;

filled in as required by the initialization function.

ShareAccess

A bit mask that contains zero or more of the following flags:

FILE_SHARE_READ,

FILE_SHARE_WRITE, or

FILE_SHARE_DELETE.

FileAttributes

A bit mask of FILE_ATTRIBUTE_Xxxx flags, typically FILE_ATTRIBUTE_NORMAL;

filled in as required by the initialization functions.

CreateDisposition

Constant that defines system actions for file creation.

CreateOptions

A bit mask of file option flags;

filled in as required by the initialization functions.

EaBuffer

An extended attributes buffer for file creation.

EaBufferLength

Length of the extended attributes buffer.

AllocationSize

Initial size to allocate if the target is a file.

FileInformation

Status information returned if WdfIoTargetOpen creates a file.


若目标是一个file,通过name打开,那么可以使用FileAttributes和CreateOptions
见ZwCreateFile


KMDF例子:
Toastmon,创建及打开一个remote I/O target,Toastmon.c
NTSTATUS Toastmon_OpenDevice(
    WDFDEVICE Device,
    PUNICODE_STRING SymbolicLink,
    WDFIOTARGET *Target
    )
{
    NTSTATUS                    status = STATUS_SUCCESS;
    WDF_IO_TARGET_OPEN_PARAMS   openParams;
    WDFIOTARGET                 ioTarget;
    WDF_OBJECT_ATTRIBUTES       attributes;

    // [1]
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, TARGET_DEVICE_INFO);
    // [2]
    status = WdfIoTargetCreate(deviceExtension->WdfDevice, &attributes, &ioTarget);
    if (!NT_SUCCESS(status)) {
        return status;
    }
    . . .  //Code to set up timers omitted
    // [3]
    WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(&openParams,
                                                SymbolicLink,
                                                STANDARD_RIGHTS_ALL);
    // [4]
    openParams.ShareAccess = FILE_SHARE_WRITE | FILE_SHARE_READ;
    // [5]
    openParams.EvtIoTargetQueryRemove = ToastMon_EvtIoTargetQueryRemove;
    openParams.EvtIoTargetRemoveCanceled = ToastMon_EvtIoTargetRemoveCanceled;
    openParams.EvtIoTargetRemoveComplete = ToastMon_EvtIoTargetRemoveComplete;
    // [6]
    status = WdfIoTargetOpen(ioTarget, &openParams);
    if (!NT_SUCCESS(status)) {
        WdfObjectDelete(ioTarget);
        return status;
    }
    . . .  //More code omitted
    return status;
}
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE:初始化I/O target object的context area。
WdfIoTargetCreate:创建target obj
WDF_IO_TARGET_OPEN_PARAMS structure:描述了打开target的参数
WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME:填充上个内容,访问权限为:STANDARD_RIGHTS_ALL
ShareAccess:表示是否驱动需要独占的对目标的访问。
EvtIoTargetQueryRemove, EvtIoTargetRemoveCanceled, 和EvtIoTargetRemoveComplete:注册回调函数
WdfIoTargetOpen:打开object


I/O target 状态管理
I/O target的优势就是可以请求和管理target的state。
I/O target跟踪queued和sent的请求,若状态改变可以直接取消它们。
I/O target 若处于stop状态,framework可以queue所有请求,直到target返回working状态,此时,I/O target就是一个cancel-safe queue。
states如下
   

State

Description

Started

The I/O target is operating and can process I/O requests.

Stopped

The I/O target has been stopped.

Stopped for query-remove

The I/O target has been stopped temporarily because removal of its device is pending. If the device is eventually removed, the target enters the Deleted state. If the device is not removed, the target typically returns to the Started state.

Closed

A remote I/O target has been closed because the driver called a close method.

Deleted

The I/O target's device has been removed. The framework cancels all I/O requests that have been queued for the I/O target.

    framework默认只有在处于Started状态才传递请求,但是可以配置成无论什么状态都传递请求。
--------------/管理I/O target状态的方法\-----------
用于启动和停止I/O target, 在目标设备移除后移除或关闭object, 同步移除,询问当前状态。
下表是所有的方法

Task

UMDF IWDFIoTargetState-Management method

KMDF method

Return the current state of the I/O target.

GetState

WdfIoTargetGetState

Open a remote I/O target.

None

WdfIoTargetOpen

Close a remote target.

None

WdfIoTargetClose

Remove an I/O target object.

Remove

None

Start sending requests to an I/O target object.

Start

WdfIoTargetStart

Stop sending I/O requests to an I/O target.

Stop

WdfIoTargetStop

Close an I/O target temporarily during a query-remove operation.

None

WdfIoTargetCloseForQuery-Remove

--------------/KMDF I/O target callbacks\----------
framework默认在蛇移除后close I/O target,而不通知driver。
驱动可以注册回调来获取通知,KMDF先调用回调,再更改状态。
EvtIoTargetXxx:发送请求时需要任何处理时使用回调函数。

Callback

Description

EvtIoTargetQueryRemove

Called when removal of the I/O target device is queried. To allow the removal, the function must call WdfIoTargetCloseForQueryRemove and return STATUS_SUCCESS. To veto the removal, the function must return a failure status such as STATUS_UNSUCCESSFUL or STATUS_INVALID_DEVICE_REQUEST.

EvtIoTargetRemoveCanceled

Called after a query-remove operation for the target device has been canceled. This function should reopen the I/O target that EvtIoTargetQueryRemove temporarily stopped by calling WdfIoTargetOpen with the WDF_IO_TARGET_OPEN_TYPE WdfIoTargetOpenReopen. This function should always return STATUS_SUCCESS.

EvtIoTargetRemoveComplete

Called when I/O target device removal is complete. This function should always return STATUS_SUCCESS.

默认I/O target没有回调函数
当I/O target删除时,KMDF默认取消所有发送到target的请求,在删除target前等待所有请求完成。驱动可以注册EvtObjectCleanup来代替默认行为。(比如驱动想阻塞型请求,并等待pending的I/O完成,而不是让framework cancel它们:WdfIoTargetStop,WdfIoTargetWaitForSentIoToComplete)
--------------/KMDF 例子,回调\--------------------
framework调用EvtIoTargetQueryRemove作为query-removal sequence的一部分。
sample中,callback停止timer,关闭I/O target object的handle
NTSTATUS ToastMon_EvtIoTargetQueryRemove(
    WDFIOTARGET IoTarget
)
{
    PAGED_CODE();
    . . .  //Timer code omitted
    WdfIoTargetCloseForQueryRemove(IoTarget);
    return STATUS_SUCCESS;
}
EvtIoTargetQueryRemove 返回错误码来防止target被移除
若返回STATUS_SUCCESS,则允许移除,callback必须调用WdfIoTargetCloseForQueryRemove来关闭handle,而不是删除对象。
若device真的被移除了,framework调用EvtIoTargetRemoveComplete回调,清空请求,删除I/O target.
若移除被取消,则调用EvtIoTargetRemoveCanceled回调:再次打开target object,然后初始化参数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值