DeviceIoControl解读

设备驱动程序可以被当作内核模式函数包来看待,I/O控制代码就是用来指定访问其中的哪个函数的。DeviceIoControl函数的dwIoControlCode参数就是这个代码,它指出了我们需要进行的操作,以及如何进行操作。 
控制代码是32位数字型常量,可以CTL_CODE宏来定义,它们定义在winioctl.inc和ntddk.inc文件中。 

控制代码中各数据位字段的含义如下: 
◎ DeviceType--设备类型(16bit)指出了设备的类型,微软保留了0-7FFFh的取值,剩下的8000h-0FFFFh供开发商定义新的内 核模式驱动程序。我们可以在\include\w2k\ntddk.inc文件中找到一组FILE_DEVICE_XXX符号常量,这些值都是微软保留的 值,我们可以使用其中的FILE_DEVICE_UNKNOWN。当然你也可以定义另外一个FILE_DEVICE_XXX值 
◎ Access--存取代码(2bit)指明应用程序存取设备的方式,由于这个字段只有2位,所以只有4种可能性: 
· FILE_ANY_ACCESS (0)--最大的存取权限,就是什么操作都可以 
· FILE_READ_ACCESS (1)--读权限,设备将数据传递到指定的缓冲区 
· FILE_WRITE_ACCESS (2)--写权限,可以从内存中向设备传递数据 
· FILE_READ_ACCESS or FILE_WRITE_ACCESS (3)--读写权限,设备和内存缓冲区之间可以互相传递数据 
◎ Function--功能代码(12bit)用来描述要进行的操作,我们可以用800h-0FFFh来定义自己的I/O控制代码,0-7FFh之间的值是被微软保留的,用来定义公用的I/O控制代码 
◎ Method--缓冲模式(2bit)表示I/O管理器如何对输入和输出的数据进行缓冲,这个字段的长度是2位,所以有4种可能性: 
· METHOD_BUFFERED (0)--对I/O进行缓冲 
· METHOD_IN_DIRECT (1)--对输入不进行缓冲 
· METHOD_OUT_DIRECT (2)--对输出不进行缓冲 
· METHOD_NEITHER (3)--都不缓冲 

缓冲模式的管理我们会在后面进行更详细的讨论,当前最重要的是,虽然进行缓冲会带来一些额外的内存开销,但却是最安全的,因为系统已经做好了相关的全部工 作。在传输的数据小于一页(4Kb)的时候,驱动程序通常使用缓冲方式的I/O,因为对大量小块内存进行内存锁定带来的开销也是很大的。在 VirtToPhys驱动程序中,我们使用带缓冲的方式。 
读者可以手工去定义I/O控制代码,但是使用CTL_CODE宏会方便得多,它提供了创建IOCTL值的算法,具体如下: 

CTL_CODE MACRO DeviceType:= <0> , Function:= <0> , Method:= <0> , Access:= <0> 
EXITM %(((DeviceType) SHL 16) OR ((Access) SHL 14) OR ((Function) SHL 2) OR (Method)) 
ENDM 

CTL_CODE宏在winioctl.inc文件和ntddk.inc文件中都有定义。

在应用程序里定义的CTL_CODE和驱动中IRP_MJ_DEVICE_CONTROL的函数里控制码对应即可。在驱动程序里取出码值进行对比操作,如:
   dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
    switch (dwIoControlCode)
    {
     // 我们约定,缓冲区共两个DWORD,第一个DWORD为端口,第二个DWORD为数据
     // 一般做法是专门定义一个结构,此处简单化处理了
     case IOCTL_MYPORT_READ_BYTE:   // 从端口读字节
      pvIOBuffer[1] = _inp(pvIOBuffer[0]);
      Irp->IoStatus.Information = 8;   // 输出长度为8
      break;
     case IOCTL_MYPORT_WRITE_BYTE:   // 写字节到端口
      _outp(pvIOBuffer[0], pvIOBuffer[1]);
      break;
     default:   // 不支持的IOCTL
      Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值