state = DeviceIoControl(DeviceHandle, PCIe_WRITE_SIZE,
&inData, 4, NULL, NULL, NULL, NULL);
NTSTATUS WdfRequestRetrieveOutputBuffer(
WDFREQUEST Request,
size_t MinimumRequiredSize,
PVOID *Buffer,
size_t *Length
NTSTATUS WdfRequestRetrieveInputBuffer(
WDFREQUEST Request,
size_t MinimumRequiredLength,
PVOID *Buffer,
size_t *Length
将write请求的数据写入设备对象上下文,然后当read请求过来的时候,将设备上下文里面的数据读出来并且返回给用户模式程序,wdf提供两个函数,这两个函数可以获取请求的输入输出缓冲,read请求只有outptbuffer,write请求只有inputbuffer;IOcontrol请求同事拥有输入输出缓冲;
status = WdfRequestRetrieveOutputBuffer(
Request,
sizeof(ULONG64),
&outBuffer,
这段代码获取request的输出请求,outbuffer是一个指针,如果函数调用成功,那么outbuffer将指向一个输出缓冲,指向一个内核模式下的地址,可直接读取或写入数据,read请求函数成功,write请求则失败。
上篇中,我们设备打开函数已经得到了我们PCIe设备的句柄了。接下来我们来看看,设备打开之后,上层软件是怎样利用该句柄实现对设备上具体寄存器的访问的。
1:寄存器写操作
上层应用程序写操作函数代码:
/********************************************************************/
/* Write register 3
本文为看雪论精华文章看雪论坛作者ID:低调putchar 一、概述Windows操作系统中,文件系统过滤驱动的过滤设备绑定在文件系统(FSD)设备之上,监视和过滤我们的文件访问。当应用层发起文件操作调用时内核层都会转换为IRP发送到设备栈中位于栈顶的设备,然后通过IO栈单元(IO_STACK_LOCATION)保存一些参数把IRP请求继续向下层设备发送,最后至FSD,由FSD完成实际的文...
驱动程序和客户应用程序经常需要进行数据交换,但我们知道驱动程序和客户应用程序可能不在同一个地址空间,因此操作系统必须解决两者之间的数据交换。
驱动层和应用层通信,主要是靠DeviceIoControl函数,下面是该函数的原型:
BOOL DeviceIoControl (
HANDLE hDevice, // 设备句柄
DWORD dwIoControlCode, // IOCTL请求
不应该以ret来判断DeviceIoControl的结果,而应该以lpBytesReturned。
READ操作,lpBytesReturned返回实际读的字节数;WRITE操作,lpBytesReturned返回实际写的字节数。
句柄, Handle, 表达处理、控制之意。内核不会直接暴露指针给用户空间,这样会增大内核风险。相反,内核抽象出Handle给用户态,不管是文件、进程、线程等对象,通过Handle可以隐藏内核细节,统一控制对象。不可避免,内核态对于Handle必须转换成指针才能处理。
windows驱动编程-应用与内核通信: 在编写windows驱动的时候,用户层和内核层的通信必不可少(胡扯-…-)。本文实现,用户层发送数据给内核驱动->内核驱动保存数据->用户层再原样从内核驱动中将数据读取出来。
本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:
在上面的两篇博文中,介绍了IRP与派遣函数,以及我们通过了一个例子“磁盘设备的绝对读写”来演示了在应用程序中是如何向一个设备发出I/O请求的。这篇博文将演示在驱动程序中处理一个非常简单的I/O请求——由DeviceIoControl这个Win32API经过一系列的调用,在内核中
前言: 最近需要对Windows中的设备进行编程操作,其中涉及到非常重要的函数DeviceIoControl,在使用的时候也比较的复杂,国内这一块中文资料比较少,在学习之余顺便将其翻译出来,以供参考,如有错误,欢迎指正。lcb0281@163点comMSDN原文地址:DeviceIoControl function DeviceIoControl 将控制代码直接发送到指定的设备驱动...
IOCP 是一种基于操作系统内核的异步 I/O 实现方式,它利用操作系统内核提供的异步 I/O 接口来实现异步 I/O 操作。等待异步 I/O 操作完成。当I/O操作完成时,操作系统将完成的I/O请求从内核的I/O请求队列中取出,并将其结果信息(如读取的数据、错误码等)放入到一个称为完成包(Completion Packet)的数据结构中。通过使用GetQueuedCompletionStatus函数,应用程序可以实现高效的异步I/O操作,避免了阻塞等待I/O操作完成的情况,提高了系统的吞吐量和响应速度。