有两种方式可以让设备和应用程序之间联系:
1. 通过为设备创建的一个符号链;
2. 通过输出到一个接口
WDM驱动程序建议使用输出到一个接口而不推荐使用创建符号链的方法。这个接口保证PDO的安全,也保证安全地创建一个惟一的、独立于语言的访问设备的方法。
一个应用程序使用Win32APIs来调用设备。在某个Win32 APIs和设备对象的分发函数之间存在一个映射关系。
获得对设备对象访问的第一步就是打开一个设备对象的句柄。
用符号链打开一个设备的句柄
为了打开一个设备,应用程序需要使用CreateFile。如果该设备有一个符号链出口,应用程序可以用下面这个例子的形式打开句柄:
hDevice = CreateFile("\\\\.\\OMNIPORT3",
GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL ,NULL
);
文件路径名的前缀“\\.\”告诉系统本调用希望打开一个设备。这个设备必须有一个符号链,以便应用程序能够打开它。有关细节查看有关Kdevice和CreateLink的内容。在上述调用中第一个参数中前缀后的部分就是这个符号链的名字。
注意:CreatFile中的第一个参数不是Windows 98/2000中驱动程序(.sys文件)的路径。是到设备对象的符号链。
如果使用DriverWizard产生驱动程序,它通常使用类KunitizedName来构成设备的符号链。这意味着符号链名有一个附加的数字,通常是0。例如:如果链接名称的主干是L“TestDevice”那么在CreateFile中的串就该是“\\\\.\\TestDevice0”。
如果应用程序需要被覆盖的I/O,第六个参数(Flags)必须或上FILE_FLAG_OVERLAPPED。
使用一个输出接口打开句柄
用这种方式打开一个句柄会稍微麻烦一些。DriverWorks库提供两个助手类来使获得对该接口的访问容易一些,这两个类是CDeviceInterface, 和 CdeviceInterfaceClass。
CdeviceInterfaceClass类封装了一个设备信息集,该信息集包含了特殊类中的所有设备接口信息。
应用程序能有用CdeviceInterfaceClass类的一个实例来获得一个或更多的CdeviceInterface类的实例。CdeviceInterface类是一个单一设备接口的抽象。它的成员函数DevicePath()返回一个路径名的指针,该指针可以在CreateFile中使用来打开设备。
下面用一个小例子来显示这些类最基本的使用方法:
extern GUID TestGuid;
HANDLE OpenByInterface(
GUID* pClassGuid,
DWORD instance,
PDWORD pError
)
{
CDeviceInterfaceClass DevClass(pClassGuid, pError);
if (*pError != ERROR_SUCCESS)
return INVALID_HANDLE_VALUE;
CDeviceInterface DevInterface(&DevClass, instance, pError);
if (*pError != ERROR_SUCCESS)
return INVALID_HANDLE_VALUE;
cout << "The device path is "
<< DevInterface.DevicePath()
<< endl;
HANDLE hDev;
hDev = CreateFile(
DevInterface.DevicePath(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hDev == INVALID_HANDLE_VALUE)
*pError = GetLastError();
return hDev;
}
在设备中执行I/O操作
一旦应用程序获得一个有效的设备句柄,它就能使用Win32 APIs来产生到设备对象的IRPs。下面的表显示了这种对应关系。
Win32 API DRIVER_FUNCTION_xxx
IRP_MJ_xxx KDevice subclass member function
CreateFile CREATE Create
ReadFile READ Read
WriteFile WRITE Write
DeviceIoControl DEVICE_CONTROL DeviceControl
CloseHandle CLOSE
CLEANUP Close
CleanUp
需要解释一下设备类成员的Close和CleanUp:CreateFile使内核为设备创建一个新的文件对象。这使得多个句柄可以映射同一个文件对象。当这个文件对象的最后一个用户级句柄被撤销后,I/O管理器调用CleanUp。当没有任何用户级和核心级的对文件对象的访问的时候,I/O管理器调用Close。
如果被打开的设备不支持指定的功能,则调用相应的Win32将引起错误(无效功能)。
以前为Windows95编写的VxD的应用程序代码中可能会在打开设备的时候使用FILE_FLAG_DELETE_ON_CLOSE属性。在Windows NT/2000中,建议不要使用这个属性,因为它将导致没有特权的用户企图打开这个设备,这是不可能成功的。
I/O管理器将ReadFile和WriteFile的buff参数转换成IRP域的方法依赖于设备对象的属性。当设备设置DO_DIRECT_IO标志,I/O管理器将buff锁住在存储器中,并且创建了一个存储在IRP中的MDL域。一个设备可以通过调用Kirp::Mdl来存取MDL。
当设备设置DO_BUFFERED_IO标志,设备对象分别通过KIrp::BufferedReadDest或 KIrp::BufferedWriteSource为读或写操作获得buff地址。
当设备不设置DO_BUFFERED_IO标志也不设置DO_DIRECT_IO,内核设置IRP 的UserBuffer域来对应ReadFile或WriteFile中的buff参数。然而,存储区并没有被锁住而且地址只对调用进程有效。驱动程序可以使用KIrp::UserBuffer来存取IRP域。
对于DeviceIoControl调用,buffer参数的转换依赖于特殊的I/O控制代码,它不在设备对象的特性中。宏CTL_CODE(在winioctl.h中定义)用来构造控制代码。这个宏的其中一个参数指明缓冲方法是METHOD_BUFFERED, METHOD_IN_DIRECT, METHOD_OUT_DIRECT, 或METHOD_NEITHER。下面的表显示了这些方法和与之对应的能获得输入缓冲与输出缓冲的KIrp中的成员函数:
Method Input Buffer Parameter Output Buffer Parameter
METHOD_BUFFERED KIrp::IoctlBuffer
KIrp::IoctlBuffer
METHOD_IN_DIRECT KIrp::IoctlBuffer
KIrp::Mdl
METHOD_OUT_DIRECT KIrp::IoctlBuffer
KIrp::Mdl
METHOD_NEITHER KIrp::IoctlType3InputBuffer
KIrp::UserBuffer
如果控制代码指明METHOD_BUFFERED,系统分配一个单一的缓冲来作为输入与输出。驱动程序必须在向输出缓冲放数据之前拷贝输入数据。驱动程序通过调用KIrp::IoctlBuffer获得缓冲地址。在完成时,I/O管理器从系统缓冲拷贝数据到提供给Ring 3级调用者使用的缓冲中。驱动程序必须在结束前存储拷贝到IRP的Information成员中的数据个数。
如果控制代码不指明METHOD_IN_DIRECT或METHOD_OUT_DIRECT,则DeviceIoControl的参数呈现不同的含义。参数InputBuffer被拷贝到一个系统缓冲,这个缓冲驱动程序可以通过调用KIrp::IoctlBuffer。参数OutputBuffer被映射到KMemory对象,驱动程序对这个对象的访问通过调用KIrp::Mdl来实现。对于METHOD_OUT_DIRECT,调用者必须有对缓冲的写访问权限。
注意,对METHOD_NEITHER,内核只提供虚拟地址;它不会做映射来配置缓冲。虚拟地址只对调用进程有效。
这里是一个用METHOD_BUFFERED的例子:
首先,使用宏CTL_CODE来定义一个IOCTL代码:
#define IOCTL_MYDEV_GET_FIRMWARE_REV \
CTL_CODE (FILE_DEVICE_UNKNOWN,0,METHOD_BUFFERED,FILE_ANY_ACCESS)
现在使用一个DeviceIoControl调用:
BOOLEAN b;
CHAR FirmwareRev[60];
ULONG FirmwareRevSize;
b = DeviceIoControl(hDevice, IOCTL_MYDEV_GET_VERSION_STRING,
NULL, // no input 注意,这里放的是包含有执行操作命令的字符串指针
0,
FirmwareRev, //这里是output串指针,存放从驱动程序中返回的字符串。
sizeof(FirmwareRev),& FirmwareRevSize,
NULL // not overlapped I/O
);
如果输出缓冲足够大,设备拷贝串到里面并将拷贝的资结束设置到FirmwareRevSize中。
在驱动程序中,代码看起来如下所示:
const char* FIRMWARE_REV = "FW 16.33 v5";
NTSTATUS MyDevice::DeviceControl( KIrp I )
{
ULONG fwLength=0;
switch ( I.IoctlCode() )
{
case IOCTL_MYDEV_GET_FIRMWARE_REV:
fwLength = strlen(FIRMWARE_REV)+1;
if (I.IoctlOutputBufferSize() >= fwLength)
{
strcpy((PCHAR)I.IoctlBuffer(),FIRMWARE_REV);
I.Information() = fwLength;
return I.Complete(STATUS_SUCCESS);
}
else
{
}
case . . .
}
}
资源简介:这个是基于minifilter过滤驱动架构的,关于驱动层与应用程序通信的代码的应用程序部分的DEMO,是使用DOS界面,输入一个文件名,可以隐藏指定文件的文件过滤驱动的应用层实现代码,可以编译通过
上传时间: 2014-01-13
上传用户:362279997
资源简介:驱动程序与应用程序间的通信,附有几段小程序加以说明。
上传时间: 2017-02-06
上传用户:baitouyu
资源简介:有两种方式可以让设备和应用程序之间联系:1. 通过为设备创建的一个符号链;2. 通过输出到一个接口WDM驱动程序建议使用输出到一个接口而不推荐使用创建符号链的方法。这个接口保证PDO的安全,也保证安全地创建一个惟一的、独立于语言的访问设备的方法。一个...
上传时间: 2013-10-17
上传用户:gai928943
资源简介:一个简单的驱动开发示例程序!通过应用程序与驱动程来完成字符显示!是一个WDM开发的入门级程序!但很经典!可以装载里面的范例驱动并看到运行结果!
上传时间: 2014-02-08
上传用户:独孤求源
资源简介:数码管驱动芯片PT6961与51单片机的接口程序,包含C语言和汇编两个版本的代码,以及连接电路和pt6961 的datasheet
上传时间: 2016-01-24
上传用户:thuyenvinh
资源简介:驱动与应用程序通信的例子,适合入门。简单易懂。
上传时间: 2016-02-28
上传用户:qweqweqwe
资源简介:DSP系列之TMS320VC5509的USB接口PC机端的驱动和测试应用程序。可识别设备,和DSP进行双向的数据通信。
上传时间: 2016-09-30
上传用户:Amygdala
资源简介:本电路主要显示两种液晶显示模块并详细介绍JHD162AJ及FYD12864与51单片机的接口及相应的应用程序.
上传时间: 2016-10-10
上传用户:plsee
资源简介:C语言编写的温湿度传感器SHT11与51单片机的接口驱动程序,做毕业设计很辛苦弄好的,网上找不到的哦!
上传时间: 2013-12-25
上传用户:chongcongying
资源简介:Linux2.6内核驱动实例包: globalmem驱动、含并发控制的globalmem驱动、globalfifo驱动、poll应用程序范例、异步通知应用程序范例、支持异步通知的globalfifo、 S3C2410实时钟驱动、秒设备驱动与应用程序、DMA范例、静态映射范例、作为input设备触摸屏驱动、...
上传时间: 2014-01-14
上传用户:czl10052678
资源简介:一个ucos下的usb程序 包括底层驱动以及一部分应用程序 但是没有ucos的源代码 需要自己添加在souce目录中
上传时间: 2013-12-18
上传用户:gundan
资源简介:用汇编语音编写的基于320TMSC54XXDSP的异步串行口与PC机的接口程序,在ccs5000平台测试通过
上传时间: 2015-04-30
上传用户:宋桃子
资源简介:这是从别人网站上刚刚下载的PIC单片机程序,应用IIC的接口应用程序,请大家来参考使用
上传时间: 2015-05-16
上传用户:标点符号
资源简介:我写的手机版俄罗斯方块游戏! 里面就两个类! 有很详细的注释! 参考文献: 精通java手机游戏与应用程序设计 陈立伟 张克非 黎秀红/编者
上传时间: 2015-05-25
上传用户:himbly
资源简介:数字电位器X9241与PIC单片机的接口及程序设计
上传时间: 2014-11-27
上传用户:2525775
资源简介:基于VHDL语言开发的mcu与外部器件的接口程序,解决了高速mcu与低速外部器件的接口问题。
上传时间: 2015-07-22
上传用户:xlcky
资源简介:基于320×240图形点阵液晶与51单片机的接口设计程序。采用C51编程制作。
上传时间: 2015-11-30
上传用户:hasan2015
资源简介:DSP与PC通信的接口程序,用VB编写。可以在此基础上自行添加功能和显示
上传时间: 2014-01-07
上传用户:bruce
资源简介:MATLAB工具箱的神经网络理论与应用程序源代码
上传时间: 2014-08-24
上传用户:jeffery
资源简介:实用的单片机开发与应用程序,包括:中值滤波子程序,AD转换类程序,16、32位整型数开方,单片机音乐程序--祝你平安。对初学者很有帮助的。MCU development and practical applications, including: median filter subroutine, AD converter type of proceedi...
上传时间: 2016-01-27
上传用户:sunjet
资源简介:s3c2410gpio操作代码,包含wince的驱动和evc应用程序
上传时间: 2013-12-26
上传用户:TF2015
资源简介:该程序用来测试89C51与IDE硬盘的接口
上传时间: 2016-02-08
上传用户:csgcd001
资源简介:一个LED的简单驱动程序 与测试程序。
上传时间: 2016-03-10
上传用户:2404
资源简介:单片机与GSM模块的接口程序,含有对GSM信息的编码和解码等。
上传时间: 2016-05-04
上传用户:youlongjian0
资源简介:TI公司的USB键盘例子程序,包括驱动,固件,应用程序等.
上传时间: 2014-01-12
上传用户:恋天使569
资源简介:一个嵌入linux下s3c2410通过i2c读写eerom的驱动程序和应用程序。
上传时间: 2013-12-11
上传用户:海陆空653
资源简介:《LabVIEW 程序设计与应用》的随书代码光盘的内容。
上传时间: 2013-12-17
上传用户:1427796291
资源简介:msp430单片机与电子指南针的接口程序,包含了数码显示与数据存储,两者接口是rs232标准串行接口。
上传时间: 2014-01-15
上传用户:shawvi
资源简介:实时时钟芯片DS1302的设计与应用程序源代码
上传时间: 2014-01-06
上传用户:66666
资源简介:2位A/D转换器ADS7804与51单片机的接口及程序设计用的是C语言
上传时间: 2014-01-14
上传用户:13681659100