应用程序与驱动程序的通信

Windows应用程序与WDM通信的一般过程是:

①应用程序先用CreateFile函数打开设备,

②然后用ReadFile从WDM中读取数据,用WriteFile函数向WDM写数据,用DeviceIoControl函数向WDM发送自定义的控制信息,

③最后用CloseHandle函数关闭设备。对于异步IO请求还可以用CancelIo函数取消。

IRP的详细图示如下:应用程序与驱动程序的通信_第1张图片应用程序与驱动程序的通信_第2张图片

 

这些函数调用使得IO管理器产生相应的IRP发送给驱动程序

用户空间函数 主功能号 参数结构

CreateFile

IRP_MJ_CREATE

Create

ReadFile IRP_MJ_READ Read
WriteFile IRP_MJ_WRITE WRITE
DeviceIoControl IRP_MJ_DEVICE_CONTROL DeviceIoControl
CloseHandle IRP_MJ_CLOSE/CLEANUP Close
     对于第一个主功能号IRP_MJ_CREATE,不能与DRIVE_ENTRY函数中的CreateDevice函数相混淆,不能把自定义的CreateDevice函数注册到MajorFunction[IRP_MJ_CREATE]中。
    在CreateDevice函数中我们要使用IoCreateDevice函数来创建设备,主功能号为IRP_MJ_CREATE的Create函数直接完成该Irp就可以了,这里涉及到一个主次的问题,首先由IoCreateDevice创建设备之后,才有主功能号函数之说。
    对于IRP_MJ_READ,如果是Buffered方式,驱动程序应该将从硬件设备中读到数据存放在IRP头部的AssociatedIrp.SystemBuffer所指定的内存中;如果是Direct方式,则应将数据放入IRP头部的MdlAddress所描述的内存中
    对于IRP_MJ_WRITE,如果是Buffered方式,驱动程序应该将从IRP头部的AssociatedIrp.SystemBuffer所指定的内存中读取用户数据;如果是Direct方式,则应从IRP头部的MdlAddress所描述的内存中读取用户数据。最后将数据写入到硬件设备中。
    对于IRP_MJ_DEVICE_CONTROL,Win32程序使用DeviceIoControl函数来传递参数到驱动:

DeviceIoControl( Handle, // 设备句柄

                                              Code, // 32bit的自定义的控制码

                                                                                InputData, InputLength, // 输入数据缓冲区地址、长度

                                                                                      OutputData, OutputLength, // 输出数据缓冲区地址、长度

                                    &Feedback, // 反馈数据

                           &Overlapped);

对于code参数,它的定义是这样的:(M为传输方式)

注:                    ①如果使用METHOD_BUFFERED方式, 输入、输出缓冲区都用AssociatedIrp. SystemBuffer指定;

                          ②如果用METHOD_IN_DIRECT方式,则输入用MdlAddress指定,输出用AssociatedIrp. SystemBuffer指定;

                          ③如果用METHOD_OUT_DIRECT方式,则输入用AssociatedIrp. SystemBuffer指定,输出用MdlAddress指定。

                          ④如果用METHOD_NEITHER方式,则输入用Type3InputBuffer指定,输出用UserBuffer指定。

你可能感兴趣的:(windows,IO)