DeviceIOControl读写硬盘设备

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

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

BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);
哈哈,参数很多,并且还都很抽象,不要紧,咱们一个一个击破它markdown

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

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

搞定hDevice!code

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

lpInBuffer: 设备操控请求数据的缓冲区基址,若是dwIoControlCode 指定了一个操做,该操做不须要输入数据,那么这个参数设为NULL接口

nInBufferSize:lplnBuffer的size原型

lpOutBuffer:存放输出数据的buffer,一样,若是dwIoControlCode 指定了一个操做,该操做不须要处理输出数据,那么这个参数设为NULLit

nOutBufferSize:haha,别说你不知道什么什么意思,pass

lpBytesReturned:实际输出数据的bytes

lpOverlapped:Ignored; set to NULL.(Are you understand?)

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

CTL_CODE原型:

define CTL_CODE(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!

相关文章
相关标签/搜索