实战DeviceIoControl,以及与KernelIoControl的区别

      在NT/2000/XP中,从安全性、可靠性、稳定性上考虑,应用程序和操作系统是分开的,操作系统代码运行在核心态,有权访问系统数据和硬件,能执行特权指令;应用程序运行在用户态,能够使用的接口和访问系统数据的权限都受到严格限制。当用户程序调用系统服务时,处理器捕获该调用,然后把调用的线程切换到核心态。当系统服务完成后,操作系统将线程描述表切换回用户态,调用者继续运行(基本上是个切入系统再从系统返回的概念)。应用程序可以通过API函数DeviceIoControl来实现对设备的访问—获取信息,发送命令,交换数据等。利用该接口函数向指定的设备驱动发送正确的控制码及数据,然后分析它的响应,就可以达到我们的目的。所以编写驱动程序分成两部分,上层访问部分,和设备驱动部分,两者就通过约定的CTL_CODE来联系。这就是WDM驱动模型。

      实际上,我们平常做的基于一定硬件的二次开发,一般会先安装驱动程序(DRV)和用户接口的运行库(DLL),然后在此基础上开发出我们的应用程序(APP)。DRV、DLL、APP三者分别运行在核心态、核心态/用户态联络带、用户态。

(1)

      实战DeviceIoControl,以及与KernelIoControl的区别_第1张图片

设备句柄用来标识你所访问的设备。发送不同的控制码,可以调用设备驱动程序的不同类型的功能。在头文件winioctl.h中,预定义的标准设备控制码,都以IOCTL或FSCTL开头。例如,IOCTL_DISK_GET_DRIVE_GEOMETRY是对物理驱动器取结构参数(介质类型、柱面数、每柱面磁道数、每磁道扇区数等)的控制码,FSCTL_LOCK_VOLUME是对逻辑驱动器的卷加锁的控制码。输入输出数据缓冲区是否需要,是何种结构,以及占多少字节空间,完全由不同设备的不同操作类型决定。在头文件winioctl.h中,已经为标准设备预定义了一些输入输出数据结构。重叠操作结构指针设置为NULL,DeviceIoControl将进行阻塞调用;否则,应在编程时按异步操作设计。

(2)

      实战DeviceIoControl,以及与KernelIoControl的区别_第2张图片

      CreateFile这个函数用处很多,这里我们用它“打开”设备驱动程序,得到设备的句柄。操作完成后用CloseHandle关闭设备句柄。与普通文件名有所不同,设备驱动的“文件名”(常称为“设备路径”)形式固定为“//./DeviceName”(注意在C程序中该字符串写法为“////.//DeviceName”),DeviceName必须与设备驱动程序内定义的设备名称一致。一般地,调用CreateFile获得设备句柄时,访问方式参数设置为0或GENERIC_READ|GENERIC_WRITE,共享方式参数设置为FILE_SHARE_READ|FILE_SHARE_WRITE,创建方式参数设置为OPEN_EXISTING,其它参数设置为0或NULL。

(3)总结一下通过DeviceIoControl访问设备驱动程序的“三步曲”:首先用CreateFile取得设备句柄,然后用DeviceIoControl与设备进行I/O,最后别忘记用CloseHandle关闭设备句柄。举例如下:

   实战DeviceIoControl,以及与KernelIoControl的区别_第3张图片

   实战DeviceIoControl,以及与KernelIoControl的区别_第4张图片

(4)DeviceIoControl与KernelIoControl的区别

      DeviceIoControl 是发送特定设备的IoCtrl;而KernelIoControl是发送OemIoCtrl。详述一下:应用程序或者驱动程序调用DeviceIoControl,从而可以调用到对应的驱动的xxx_IOControl;而调用KernelIoControl,内核便转而调用PLATFORM/COMMON/SRC/COMMON/IOCTL/IoCtl.c下面的OEMIoControl函数。

 

参考原文:http://blog.csdn.net/bhw98/archive/2003/05/27/19660.aspx

你可能感兴趣的:(数据结构,编程,File,null,dll,disk)