资源描述:
《实战DevceIoControl之一通过API访问设备驱动程序.doc》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、实战DeviceIoControl之一:通过API访问设备驱动程序原作:bhw98Q 在NT/2000/XP中,我想用VC编写应用程序访问硬件设备,如获取磁盘参数、读写绝对扇区数据、测试光驱实际速度等,该从哪里入手呢?A 在NT/2000/XP中,应用程序可以通过API函数DeviceIoControl来实现对设备的访问获取信息,发送命令,交换数据等。利用该接口函数向指定的设备驱动发送正确的控制码及数据,然后分析它的响应,就可以达到我们的目的。DeviceIoControl的函数原型为BOOLDeviceIoControl(HANDLEhDevice,//设备句柄DWORDdwIoCont
2、rolCode,//控制码LPVOIDlpInBuffer,//输入数据缓冲区指针DWORDnInBufferSize,//输入数据缓冲区长度LPVOIDlpOutBuffer,//输出数据缓冲区指针DWORDnOutBufferSize,//输出数据缓冲区长度LPDWORDlpBytesReturned,//输出数据实际长度单元长度LPOVERLAPPEDlpOverlapped//重叠操作结构指针);设备句柄用来标识你所访问的设备。发送不同的控制码,可以调用设备驱动程序的不同类型的功能。在头文件winioctl.h中,预定义的标准设备控制码,都以IOCTL或FSCTL开头。例如,IOC
3、TL_DISK_GET_DRIVE_GEOMETRY是对物理驱动器取结构参数(介质类型、柱面数、每柱面磁道数、每磁道扇区数等)的控制码,FSCTL_LOCK_VOLUME是对逻辑驱动器的卷加锁的控制码。输入输出数据缓冲区是否需要,是何种结构,以及占多少字节空间,完全由不同设备的不同操作类型决定。在头文件winioctl.h中,已经为标准设备预定义了一些输入输出数据结构。重叠操作结构指针设置为NULL,DeviceIoControl将进行阻塞调用;否则,应在编程时按异步操作设计。Q 设备句柄是从哪里获得的?A 设备句柄可以用API函数CreateFile获得。它的原型为HANDLECreat
4、eFile(LPCTSTRlpFileName,//文件名/设备路径DWORDdwDesiredAccess,//访问方式DWORDdwShareMode,//共享方式LPSECURITY_ATTRIBUTESlpSecurityAttributes,//安全描述符指针DWORDdwCreationDisposition,//创建方式DWORDdwFlagsAndAttributes,//文件属性及标志HANDLEhTemplateFile//模板文件的句柄);CreateFile这个函数用处很多,这里我们用它“打开”设备驱动程序,得到设备的句柄。操作完成后用CloseHandle关闭设备
5、句柄。与普通文件名有所不同,设备驱动的“文件名”(常称为“设备路径”)形式固定为“\.DeviceName”(注意在C程序中该字符串写法为“\\.\DeviceName”),DeviceName必须与设备驱动程序内定义的设备名称一致。一般地,调用CreateFile获得设备句柄时,访问方式参数设置为0或GENERIC_READ
6、GENERIC_WRITE,共享方式参数设置为FILE_SHARE_READ
7、FILE_SHARE_WRITE,创建方式参数设置为OPEN_EXISTING,其它参数设置为0或NULL。Q 可是,我怎么知道设备名称是什么呢?A 一些存储设备的名称是微软定义
8、好的,不可能有什么变化。大体列出如下软盘驱动器A:,B:硬盘逻辑分区C:,D:,E:,...物理驱动器PHYSICALDRIVExCD-ROM,DVD/ROMCDROMx磁带机TAPEx其中,物理驱动器不包括软驱和光驱。逻辑驱动器可以是IDE/SCSI/PCMCIA/USB接口的硬盘分区(卷)、光驱、MO、CF卡等,甚至是虚拟盘。x=0,1,2...其它的设备名称需通过驱动接口的GUID调用设备管理函数族取得,这里暂不讨论。Q 请举一个简单的例子说明如何通过DeviceIoControl访问设备驱动程序。A 这里有一个从MSDN上摘抄来的demo程序,演示在NT/2000/XP中如何通过D
9、eviceIoControl获取硬盘的基本参数。/*ThecodeofinterestisinthesubroutineGetDriveGeometry.ThecodeinmainshowshowtointerprettheresultsoftheIOCTLcall.*/#include#includeBOOLGetDriveGeometry(DISK_GEOMETRY*pd