Q 在NT/2000/XP中,我想用VC编写应用程序訪问硬件设备,如获取磁盘參数、读写绝对扇区数据、測试光驱实际速度等,该从哪里入手呢?

A 在NT/2000/XP中,应用程序能够通过API函数DeviceIoControl来实现对设备的訪问—获取信息,发送命令,交换数据等。利用该接口函数向指定的设备驱动发送正确的控制码及数据,然后分析它的响应,就能够达到我们的目的。

DeviceIoControl的函数原型为

BOOL DeviceIoControl(HANDLE hDevice,              // 设备句柄DWORD dwIoControlCode,       // 控制码LPVOID lpInBuffer,           // 输入数据缓冲区指针DWORD nInBufferSize,         // 输入数据缓冲区长度LPVOID lpOutBuffer,          // 输出数据缓冲区指针DWORD nOutBufferSize,        // 输出数据缓冲区长度LPDWORD lpBytesReturned,     // 输出数据实际长度单元长度LPOVERLAPPED lpOverlapped    // 重叠操作结构指针
);

设备句柄用来标识你所訪问的设备。

发送不同的控制码,能够调用设备驱动程序的不同类型的功能。在头文件winioctl.h中,提前定义的标准设备控制码,都以IOCTL或FSCTL开头。比如,IOCTL_DISK_GET_DRIVE_GEOMETRY是对物理驱动器取结构參数(介质类型、柱面数、每柱面磁道数、每磁道扇区数等)的控制码,FSCTL_LOCK_VOLUME是对逻辑驱动器的卷加锁的控制码。

输入输出数据缓冲区是否须要,是何种结构,以及占多少字节空间,全然由不同设备的不同操作类型决定。在头文件winioctl.h中,已经为标准设备提前定义了一些输入输出数据结构。重叠操作结构指针设置为NULL,DeviceIoControl将进行堵塞调用;否则,应在编程时按异步操作设计。

Q 设备句柄是从哪里获得的?

A 设备句柄能够用API函数CreateFile获得。它的原型为

HANDLE CreateFile(LPCTSTR lpFileName,                         // 文件名称/设备路径DWORD dwDesiredAccess,                      // 訪问方式DWORD dwShareMode,                          // 共享方式LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全描写叙述符指针DWORD dwCreationDisposition,                // 创建方式DWORD dwFlagsAndAttributes,                 // 文件属性及标志HANDLE hTemplateFile                        // 模板文件的句柄
);

CreateFile这个函数用处非常多,这里我们用它“打开”设备驱动程序,得到设备的句柄。操作完毕后用CloseHandle关闭设备句柄。

与普通文件名称有所不同,设备驱动的“文件名称”(常称为“设备路径”)形式固定为“//./DeviceName”(注意在C程序中该字符串写法为“.//DeviceName”),DeviceName必须与设备驱动程序内定义的设备名称一致。

一般地,调用CreateFile获得设备句柄时,訪问方式參数设置为0或GENERIC_READ|GENERIC_WRITE,共享方式參数设置为FILE_SHARE_READ|FILE_SHARE_WRITE,创建方式參数设置为OPEN_EXISTING,其他參数设置为0或NULL。

Q 但是,我怎么知道设备名称是什么呢?

A 一些存储设备的名称是微软定义好的,不可能有什么变化。大体列出例如以下

软盘驱动器 A:, B:
硬盘逻辑分区 C:, D:, E:, ...
物理驱动器 PHYSICALDRIVEx
CD-ROM, DVD/ROM CDROMx
磁带机 TAPEx

当中,物理驱动器不包含软驱和光驱。逻辑驱动器能够是IDE/SCSI/PCMCIA/USB接口的硬盘分区(卷)、光驱、MO、CF卡等,甚至是虚拟盘。x=0,1,2 ……

其他的设备名称需通过驱动接口的GUID调用设备管理函数族取得,这里暂不讨论。

Q 请举一个简单的样例说明怎样通过DeviceIoControl訪问设备驱动程序。

A 这里有一个从MSDN上摘抄来的demo程序,演示在NT/2000/XP中怎样通过DeviceIoControl获取硬盘的基本參数。

/* The code of interest is in the subroutine GetDriveGeometry. Thecode in main shows how to interpret the results of the IOCTL call. */#include <windows.h>
#include <winioctl.h>BOOL GetDriveGeometry(DISK_GEOMETRY *pdg)
{HANDLE hDevice;               // handle to the drive to be examinedBOOL bResult;                 // results flagDWORD junk;                   // discard resultshDevice = CreateFile(".//PhysicalDrive0",  // drive to open0,                // no access to the driveFILE_SHARE_READ | // share modeFILE_SHARE_WRITE,NULL,             // default security attributesOPEN_EXISTING,    // disposition0,                // file attributesNULL);            // do not copy file attributesif (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive{return (FALSE);}bResult = DeviceIoControl(hDevice,     // device to be queriedIOCTL_DISK_GET_DRIVE_GEOMETRY,     // operation to performNULL, 0,               // no input bufferpdg, sizeof(*pdg),     // output buffer&junk,                 // # bytes returned(LPOVERLAPPED) NULL);  // synchronous I/OCloseHandle(hDevice);return (bResult);
}int main(int argc, char *argv[])
{DISK_GEOMETRY pdg;            // disk drive geometry structureBOOL bResult;                 // generic results flagULONGLONG DiskSize;           // size of the drive, in bytesbResult = GetDriveGeometry (&pdg);if (bResult){printf("Cylinders = %I64d/n", pdg.Cylinders);printf("Tracks per cylinder = %ld/n", (ULONG) pdg.TracksPerCylinder);printf("Sectors per track = %ld/n", (ULONG) pdg.SectorsPerTrack);printf("Bytes per sector = %ld/n", (ULONG) pdg.BytesPerSector);DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *(ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;printf("Disk size = %I64d (Bytes) = %I64d (Mb)/n", DiskSize,DiskSize / (1024 * 1024));}else{printf("GetDriveGeometry failed. Error %ld./n", GetLastError());}return ((int)bResult);
}

Q 假设将设备名换成“A:”就能够取A盘參数,换成“CDROM0”就能够取CDROM參数,是这样吗?

A 这个问题暂不做回答。请动手试一下。

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

[相关资源]

bhw98的专栏:http://www.csdn.net/develop/author/netauthor/bhw98/


首次公布:2003-02-16
最后修订:2003-05-20

实战DeviceIoControl 之中的一个:通过API訪问设备驱动程序相关推荐

  1. 实验六 实现一个基于内存映射的设备驱动程序

    实验六 实现一个基于内存映射的设备驱动程序 目录 实验六 实现一个基于内存映射的设备驱动程序 实验环境 一.实验目的 二.实验内容 三.实验步骤 四.实验总结 实验环境 操作系统版本:ubuntu-1 ...

  2. HDFS简单介绍及用C语言訪问HDFS接口操作实践

    一.概述 近年来,大数据技术如火如荼,怎样存储海量数据也成了当今的热点和难点问题,而HDFS分布式文件系统作为Hadoop项目的分布式存储基础,也为HBASE提供数据持久化功能,它在大数据项目中有很广 ...

  3. Nginx 訪问日志增长暴增出现尖刀的具体分析

    前言:          Nginx日志里面Mobileweb_access.log增长特别大.一天上百兆.将近100W的訪问记录.依照我们眼下的规模,热点用户才500个左右.就算人人用手机app訪问 ...

  4. 写一个块设备驱动程序

    ----------------------- Page 1----------------------- 第 1章 +---------------------------------------- ...

  5. SoC嵌入式软件架构设计之中的一个:系统内存需求评估

    内存是SoC(System on Chip,片上系统)集成设计的重要模块.是SoC中成本比重较大的部分.内存管理的软硬件设计是SoC软件架构设计的重要一环,架构设计师必需要在成本和效率中取得平衡,做到 ...

  6. 【浅墨Unity3D Shader编程】之中的一个 夏威夷篇:游戏场景的创建 amp; 第一个Shader的书写...

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...

  7. 【微信测试号实战——01】注册一个属于你自己的微信测试号

    系列文章目录 微信测试号系列文章,快速进入 [微信测试号实战--01]注册一个属于你自己的微信测试号 文章目录 系列文章目录 前言 一.打开微信测试号官网 二.使用步骤 1.打开手机端微信 2.扫码登 ...

  8. MFC: DeviceIoControl 通过API访问设备驱动程序

    转载:http://m.blog.csdn.net/article/details?id=21602051 DeviceIoControl的其实和ReadFile和WriteFile是一样的, 不过这 ...

  9. 【Android开发VR实战】三.开发一个寻宝类VR游戏TreasureHunt

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53939303 本文出自[DylanAndroid的博客] [Android开发 ...

最新文章

  1. ARM 环境下使用azure powershell 从远程blob中拉去vhd 并创建虚拟机
  2. oracle11g快速入门习题集答案——oracle11g快速入门
  3. 播放失败246106异常代码_web前端面试题:您能读懂的Promise源码实现(手写代码)...
  4. 前端传值后端接收不到_web前端和后端哪个好
  5. mysql 的 VARCHAR VARCHAR2
  6. 学妹靠这个学会硬件开发入职华为,今天搞到100个免费名额!
  7. 公司项目拓扑的演变过程
  8. AOP的实现方式比较,cglib vs jdk
  9. 签约沈腾,易车开启三年品牌计划,穿越车市寒冬
  10. Android 开发之ViewPage官方文档学习笔记
  11. [Java] 蓝桥杯ADV-203 算法提高 8皇后·改
  12. [导入]js 关联数组 详解
  13. linux不同主机通信,Linux实现多台主机之间相互通信
  14. 【JAVA程序设计】(C00075)基于SSM的网上汽车租赁管理系统
  15. ps4插html屏幕不亮光,ps4连接显示器怎么老是黑屏
  16. Layabox 实现 PageView 翻页
  17. Java串口编程控制硬件
  18. 如何用 React 完成图片上传功能
  19. 分析mrp主要应用范围_MRP适用于相关需求的计划与控制
  20. 学习-Python列表之列表应用之降序排列

热门文章

  1. Linux下使用终端调试Python程序:pudb
  2. 户外lisp导向牌如何安装_有了激光切割导向牌,妈妈再也不用担心我迷路啦
  3. java实现随机字母数字验证码
  4. SpringBoot集成websocket(Spring方式)
  5. Nginx的location、root、alias指令用法和区别
  6. c 读取mysql中表中数据_c#读取MySQL数据表中的内容
  7. php连接不到mysql怎么解决,怎么解决php无法连接mysql的问题
  8. python中dom是什么意思_python--BOM和DOM
  9. shell脚本教学进阶——Linux三大文本处理工具之grep
  10. c语言逆序输出字符串指针,菜鸟求助-如何用指针法将一串字符按单词的倒序输出?如:i love yo...