DeviceIoControl这个api我们用的不多,但是很重要,有时会帮助我们实现一些特别的需求, 如获取硬件设备信息、与硬件设备通信(读写数据)等,对照msdn,下面我们详细解释一下这个api的用法(有什么错误再所难免,各位不吝指教啊)。
DeviceIoControl是用来控制我们指定设备的输入输出操作,使设备按照我们发的指令去工作。

DeviceIoControl是kernel32中的函数,需要包含的头文件是winbase.h,先看函数原型

BOOL DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped
); hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped
);

哈哈,参数不少,而且还都很抽象,没关系,我们一个一个击破它

来到第一个参数,hDevice,当然是要操作的设备的句柄了,这个句柄需要通过CreateFile的返回值中获取,对于createfile这里只做一个粗略的解释:

  • HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile
    );  lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile
    ); 

参数:要打开的文件名,访问权限,共享模式,安全属性,文件存在与不存在时的文件创建模式,文件属性设定(隐藏、只读、压缩、指定为系统文件等),文件副本句柄。要说明的是第一个参数lpFileName,是设备的名称或者是和设备关连的驱动的名称,一般用\\.\DeviceName的形式,比如要打开逻辑驱动盘A就用\\.\a,也可以用\\.\PhysicalDevice0,\\.\PhsycalDebive1来指定物理驱动器,\\.\PhysicalDevice0表示本机的物理驱动器0(一般是主硬盘),从而来获取硬盘的序列号、模块名、扇区数、磁头数等相关信息

搞定hDevice!

dwIoControlCode: 当然就是控制设备的指令了,指令怎么来是个问题,微软已经定义好了很多种操作,在winioctl.h文件中,但最终都是通过CTL_CODE宏来实现的,其实这就是一种通信协议。CTL_CODE的具体用法在最后来介绍。

lpInBuffer: 设备操控请求数据的缓冲区基址,如果dwIoControlCode 指定了一个操作,该操作不需要输入数据,那么这个参数设为NULL

nInBufferSizelplnBuffer的size

lpOutBuffer:存放输出数据的buffer,同样,如果dwIoControlCode 指定了一个操作,该操作不需要处理输出数据,那么这个参数设为NULL

nOutBufferSizehaha,别说你不知道什么什么意思,pass

lpBytesReturned实际输出数据的bytes

lpOverlappedIgnored; set to NULL.(Do you understand?)

下面来到第二个参数的详解,CTL_CODE的定义与应用:

CTL_CODE原型:

#define CTL_CODE(DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
)DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)
)

可以看到,这个宏四个参数,自然是一个32位分成了4部分,高16位存储设备类型( 这里不列举了,看msdn哦),14~15位访问权限,2~13位操作功能,最后一个就是确定缓冲区(别忘记上面DeviceIOControl中缓冲区的定义哦)是如何与I/O和文件系统数据缓冲区进行数据传递的方式(具体取值查看msdn)我们最常用的就是METHOD_BUFFERED

Function codes 0-2047 are reserved for Microsoft; codes 2048-4095 are reserved for OEMs and IHVs. (我们能用的是2048~4095)

看以下一段:

这个宏经常用来定义IOCTL(I/O控制)和FSCTL(文件系统控制)功能控制代码,所有的IOCTLs必须通过这种方式定义,以确保这些指令能被Microsoft,以及其他的硬件厂商通信接口所识别

The following illustration shows the format of the resulting IOCTL.

援引微软定义的一个指令:锁卷

#define FSCTL_LOCK_VOLUME               CTL_CODE(FILE_DEVICE_FILE_SYSTEM,  6, METHOD_BUFFERED, FILE_ANY_ACCESS)

Game over!

DeviceIOControl详解-各个击破相关推荐

  1. DeviceIoControl详解

    DeviceIoControl的使用说明 应用程序和驱动程序的通信过程是:应用程序使用CreateFile函数打开设备,然后用DeviceIoControl与驱动程序进行通信,包括读和写两种操作.还可 ...

  2. 应用程序与驱动程序交互函数DeviceIoControl详解

    这种通信方式,就是驱动程序和应用程序自定义一种IO控制码,然后调用DeviceIoControl函数,IO管理器会产生一个MajorFunction 为IRP_MJ_DEVICE_CONTROL(De ...

  3. js 正则中冒号代表什么_javascript中正则表达式语法详解

    好久都没有写博客了,主要是太懒了,尤其是在阳春三月,风和日丽的日子,太阳暖暖的照在身上,真想美美的睡上一觉.就导致了这篇博客拖到现在才开始动笔,javascript的正则这一块也不是什么新的东西,主要 ...

  4. vue-cli脚手架中webpack配置基础文件详解

    一.前言 vue-cli是构建vue单页应用的脚手架,输入一串指定的命令行从而自动生成vue.js+wepack的项目模板.这其中webpack发挥了很大的作用,它使得我们的代码模块化,引入一些插件帮 ...

  5. 抓到Netty一个隐藏很深的内存泄露Bug | 详解Recycler对象池的精妙设计与实现

    本系列Netty源码解析文章基于 4.1.56.Final版本 最近在 Review Netty 代码的时候,不小心用我的肉眼抓到了一个隐藏很深很深的内存泄露 Bug. 于是笔者将这个故事-哦不 -事 ...

  6. 孙子兵法之36计详解

    孙子兵法之36计详解 第一套 胜战计 第一计 瞒天过海 备周而意怠,常见则不疑,阴在阳之内,不在阳之对.太阳,太阴. 译:认为准备万分周到,就容易松劲:平时看惯了的,就往往不在怀疑了,秘计隐藏在暴露的 ...

  7. 《Windows驱动开发技术详解》学习笔记

    Abstract   如果推荐 Windows 驱动开发的入门书,我强烈推荐<Windows驱动开发技术详解>.但是由于成书的时间较早,该书中提到的很多工具和环境都已不可用或找不到,而本文 ...

  8. Windows API函数大全---附:windows运行命令详解

    1. API之网络函数             WNetAddConnection 创建同一个网络资源的永久性连接             WNetAddConnection2 创建同一个网络资源的连 ...

  9. 详解Oracle架构、原理、进程,学会世间再无复杂架构

    详解Oracle架构.原理.进程,学会世间再无复杂架构 学习是一个循序渐进的过程,从面到点.从宏观到微观,逐步渗透,各个击破,对于Oracle, 怎么样从宏观上来理解呢?先来看一个图,这个图取自于教材 ...

最新文章

  1. SpringBoot | 第三十六章:集成多CacheManager
  2. matlab获取标量
  3. “欢迎光临”用其他各国语言怎么写、怎么说?
  4. Java 8 stream forEach filter anyMatch
  5. SpringCloud Eureka自我保护机制
  6. javascript运算符_JavaScript中的按位运算符
  7. SVN仓库迁移到Git遇到的两个问题和解决办法
  8. 前端地图之色斑图渲染(数据格式为.tif的栅格数据)(一)——以leaflet为例
  9. 关闭Windows10 易升
  10. android qq输入法表情,QQ输入法(Android)4.8 表情进行时
  11. 【Magick++】创建图像
  12. 五、完成Teigha.net对CAD文件中的Entity实体进行编辑修改功能,包括字体,样式,颜色,备注XData等属性
  13. Lae程序员小漫画(三),仅供一乐
  14. 微信小程序口袋奇兵选服务器,口袋奇兵小程序
  15. Vant组件NavBar导航栏使用时去除下方白线问题
  16. [软考]协议VS合同
  17. C++实现大整数乘法
  18. 【MySQL】InnoDB存储引擎
  19. 分区表与普通表之间切换的报错
  20. python 顶层模块理解 ValueError: attempted relative import beyond top-level package

热门文章

  1. python七段数码管显示字母代码_python实现七段数码管显示
  2. 东方财富:资金流向表爬虫
  3. 利用Chrome Headless模式网页转PDF
  4. Android 修改系统默认输入法
  5. 微信开发者工具预览二维码无法显示
  6. Google Play App Store 年度最佳应用及游戏盘点
  7. ArcGISPro制作辐射4风格地图
  8. 写给小白:AWS,开启新世界大门的钥匙
  9. 计算机网络三元组,计算机网络chap07 传输层(1) - 三元组 五元组.pdf
  10. HR问“什么时间可以入职”,这样回答最保险!