IO目标对象的细节

转载自:http://blog.163.com/prince_william@126/blog/static/16976816120122711272459/


IO目标对象的细节  

2012-03-07 15:03:57|  分类:WDF |字号 订阅

IO目标是对IO请求将发送到的目标驱动的描述。比如,向另一个内核驱动中的设备发送一个IOCTL命令,这个远程设备对象就是IOCTL命令的IO目标。
新定义这么一个对象并不是为了形象上的好看,而是赋予了它很多实用的妙处。
(1)请求以同步方式发送到IO目标对象。
(2)请求以异步方式发送到IO目标对象。
(3)为发送到IO目标的请求设置超时,如果预期时间内仍未完成,就取消请求。
(4)IO目标对象可以被启动、停止、关闭,只有启动后的IO目标对象才能接受请求,否则将关闭外接请求通道。
(5)跟踪并维护发送到IO目标的IO请求。比如删除目标对象后,所有排队于其中的IO请求对象都将被删除。


调用WdfIoTargetGetDevice函数可以获取被封装的设备对象句柄
WDFDEVICEWdfIoTargetGetDevice(IN WDFIOTARGET IoTarget);
IO目标对象分为 普通对象特殊对象两种, 普通目标对象就是WDFIOTARGET,特殊目标对象目前只有一种,即USB IO目标对象。USB IO目标对象并没有一个对应的类型被暴露出来,而是隐藏在诸如WDFUSBDEVICE、WDFUSBPIPE这些对象内部,然后通过这些对象句柄来使用特殊IO目标对象。
普通IO目标对象,即WDFIOTARGET对象分为本地和远程两种,在有些资料中,本地IO目标对象还被称为默认对象,如果某个请求继续在当前设备栈中传递,则对应的WDFIOTARGET对象为本地的;若被传递到其它的设备栈中,不管此设备栈是否也通过本驱动,则对应的WDFIOTARGET对象统称为远程的。
可以直接从设备对象中获取WDFIOTARGET对象,所获取的对象对应着当前设备栈中的下一层设备。

WDFIOTARGET WdfDeviceGetIoTarget(IN WDFDEVICE Device);

通过此方式获取的WDFIOTARGET对象,称为此设备对象的本地(或默认)WDFIOTARGET对象,凡是发送到此设备对象的WDFREQUEST对象若要在设备栈中继续传递,则应当将请求发送到此本地目标对象。一个默认事件回调函数可实现如下:

void SomeEvtCallback(WDFDEVICE Device,WDFREQUEST Request)

{

//让IO请求在当前设备栈中继续传递

WdfRequestSend(Request,WdfDeviceGetIoTarget(Device),NULL);

}


使用一个远程IO目标对象需要经过两个步骤:第一步,创建远程IO目标对象;第二步,打开此对象。调用WdfIoTargetCreate接口新建一个IO目标对象:

NTSTATUS WdfIoTargetCreate(

IN WDFDEVICE Device, //

IN OPTIONAL PWDF_OBJECT_ATTRIBUTES IoTargetAttributes,

OUT WDFIOTARGET* IoTarget);

Device就是 被创建的IO目标对象的拥有者,在默认情况下,就是被创建的IO目标对象的父对象(可通过在IoTargetAttributes中设置ParentObject改变此默认情况)。参数IoTargetAttributes用来设置新建WDFIOTARGET对象的属性,可直接传入WDF_NO_OBJECT_ATTRIBUTES。参数IoTarget返回新建的目标对象,一个新建的目标对象是“空的”,并没有和任何“目标”相关联。所以在正式被使用前,还需要通过调用WdfIoTargetOpen接口函数将它打开,并和一个“目标”挂钩。

WDF_OBJECT_ATTRIBUTES ioTargetAttribute;

WDFIOTARGET ioTarget;

WDF_IO_TARGET_OPEN_PARAMS openParams;

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&ioTargetAttribute,

TARGET_DEVICE_INFO);

status=WdfIoTargetCreate(device,

&ioTargetAttribute,

&ioTarget);

if(!NT_SUCCESS(status)) return status;

//刚刚创建的IO目标对象是空的

//需要通过打开操作,与一个实际的目标对象挂钩

WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME(&openParams,

SymbolicLink,

STANDARD_RIGHTS_ALL);

status = WdfIoTargetOpen(ioTarget,&openParams);

if(!NT_SUCCESS(status)){

WdfObjectDelete(ioTarget);

return status;

}

WDFIOTARGET对象有一个状态标志,它可以处于启动、停止和终止等状态;只有当一个WDFIOTARGET对象处于启动状态时,发送到它的IO请求才会被处理;

NTSTATUS WdfIoTargetStart(IN WDFIOTARGET IoTarget);

此接口函数用来启动一个WDFIOTARGET对象;相应的,还存在停止与终止接口;

NTSTATUS WdfIoTargetStop(IN WDFIOTARGET IoTarget);

NTSTATUS WdfIoTargetClose(IN WDFIOTARGET IoTarget);

由于只有WDFIOTARGET对象启动后,IO请求才能被正确处理,所以在传递请求前先查看WDFIOTARGET对象的状态。

WDF_IO_TARGET_STATE WdfIoTargetGetState(WDFIOTARGET Tar);

枚举类型WDF_IO_TARGET_STATE定义了所有的WDFIOTARGET对象状态:

typedef enum _WDF_IO_TARGET_STATE{

WdfIoTargetStateUndefine = 0, //无效状态,不可以使用

WdfIoTargetStarted, //已经启动

WdfIoTargetStopped, //被停止

WdfIoTargetClosedForQueryRemove, //请求被移除,故而不久设备将被移除

WdfIoTargetClosed, //已经被移除

WdfIoTargetDeleted, //被删除

}WDF_IO_TARGET_STATE,*PWDF_IO_TARGET_STATE;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值