没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
实战
DeviceIoControl
通过 API 访问设备驱动程序
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, DVDROM CDROMx
磁带机 TAPEx
其中,物理驱动器不包括软驱和光驱。逻辑驱动器可以是 IDE/SCSI/PCMCIA/USB 接口
的硬盘分区 ( 卷 ) 、 光驱 、 MO 、 CF 卡等 , 甚至是虚拟盘 。 x=0 , 1 , 2 …… 其它的设备名称需
通过驱动接口的 GUID 调用设备管理函数族取得,这里暂不讨论。
Q: 请举一个简单的例子说明如何通过 DeviceIoControl 访问设备驱动程序。
A: 这里有一个从 MSDN 上摘抄来的 demo 程序,演示在 NT/2000/XP 中如何通 过
DeviceIoControl 获取硬盘的基本参数。
#include <windows.h>
#include <winioctl.h>
BOOL GetDriveGeometry(DISK_GEOMETRY *pdg)
{
HANDLE hDevice;
BOOL bResult;
DWORD junk;
hDevice = CreateFile("\\\\.\\PhysicalDrive0",
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
return false;
}
bResult = DeviceIoControl(hDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL, 0,
pdg, sizeof(*pdg),
&junk,
(LPOVERLAPPED) NULL);
CloseHandle(hDevice);
return (bResult);
}
int main(int argc, char *argv[])
{
DISK_GEOMETRY pdg;
BOOL bResult;
ULONGLONG DiskSize;
bResult = 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);
}
剩余62页未读,继续阅读
资源评论
wangzaixieshi
- 粉丝: 0
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功