内存对象有METHOD_BUFFERD、METHOD_DIRECT和METHOD_NEITHER三种。
METHOD_NEITHER方式缓冲区在WDF里处理时比较复杂。
METHOD_NEITHER的IO请求不是来自用户程序,来自内存模块,获取缓冲区方式跟其它两种一样。特别的是如果IO请求来自用户程序,则缓冲区是在用户空间申请的,在内核使用用户缓冲,有许多限制,它要与指定的进程上下文相关才有效。这时获取缓冲区变复杂了,必须先把用户地址转成能在内核里自由使用的内核地址。
在WDF里,交由WDF驱动处理的IO请求,先入队列等候,在交给对象处理。入队等候过程将导致IO请求以异步方式处理。用户指针在内核中如果以异步方式使用,会出问题的,因为内核对应的用户进程环境在不停变化。解决办法是在IO请求入队列前,将用户地址代表的内存页锁定到内存,出现映射到一个内核地址。
上图中,用户进程发送一个请求给内核,框架代理内核驱动的接口,WDF得到IO请求,把它封装成IO请求对象。
这时IO请求还没有入队列,将用户指针转成内核指针。
WDF驱动通过接口WdfDeviceInitSetIoInCallerContextCallback注册一个EvtIoCallerContext回调函数,在一个WDFREQUEST对象被放入队列之前对其”前处理“。
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
FORCEINLINE
WdfDeviceInitSetIoInCallerContextCallback(
_In_
PWDFDEVICE_INIT DeviceInit,
_In_
PFN_WDF_IO_IN_CALLER_CONTEXT EvtIoInCallerContext
)
EvtIoCallerContext回调函数原型如下:
VOID EvtIoCallerContext (
<