DeviceIOcontrol(1)

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是对逻辑驱动器的卷加锁的控制码。

 

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。

 

转载地址:http://hi.baidu.com/zhanghuikl/blog/item/37d573813b7bf9d0bc3e1e81.html

 

<think>嗯,用户问的是DeviceIoControl错误码1的问题。首先,我要确认错误码1对应的具体信息。在Windows系统中,错误码通常是通过GetLastError函数返回的,而错误码1对应的应该是ERROR_INVALID_FUNCTION。 接下来,我需要解释这个错误码的含义。ERROR_INVALID_FUNCTION意味着系统无法识别设备驱动程序请求的控制代码,或者设备驱动程序不接受该控制代码。这可能是因为调用了错误的IOCTL(设备I/O控制)代码,或者驱动程序没有正确处理这个控制代码。 然后,我需要考虑用户可能遇到这个错误的原因。可能的情况包括:使用了不正确的IOCTL代码、驱动程序不支持该操作、参数传递错误,或者设备对象无效。此外,32位和64位系统之间的不兼容也可能导致这个问题,比如传递的结构体对齐方式不正确。 接下来,我应该提供一些解决步骤。用户需要检查传入DeviceIoControl的参数是否正确,特别是dwIoControlCode。需要确认这个控制代码是否适用于目标设备和驱动程序。查阅设备的文档或头文件来确认正确的IOCTL代码是必要的。同时,检查输入和输出缓冲区的大小和格式是否正确,以及设备句柄是否有效且具有足够的权限。 另外,建议用户使用FormatMessage函数将错误码转换为可读的信息,帮助调试。检查驱动程序日志也可能提供更多线索,尤其是在驱动程序开发的情况下。如果涉及跨平台问题,需要确保结构体对齐和大小正确。 最后,需要提醒用户,这类错误通常需要结合代码和具体使用场景来分析。如果用户能提供更多上下文或代码片段,可以进一步帮助诊断问题。</think>关于DeviceIoControl错误码1的问题,以下是分步解释: 1. **错误码解析**: - 错误码1对应的系统定义是`ERROR_INVALID_FUNCTION`(可通过`FormatMessage`函数验证) - 中文解释:系统无法识别的控制操作或设备不支持此功能 2. **常见触发场景**: ```c BOOL result = DeviceIoControl( hDevice, // 设备句柄 IOCTL_INVALID_CODE, // 错误的控制代码 lpInBuffer, // 输入缓冲区 nInBufferSize, // 输入大小 lpOutBuffer, // 输出缓冲区 nOutBufferSize, // 输出大小 lpBytesReturned, // 实际返回字节数 NULL // OVERLAPPED结构 ); ``` 当`dwIoControlCode`参数包含以下问题时: - 使用了未在驱动头文件中定义的CTL_CODE - 设备对象不支持该IOCTL操作 - 控制代码生成方式错误(如错误的功能码/访问权限) 3. **诊断步骤**: - 验证控制代码: $$ CTL_CODE(DeviceType, Function, Method, Access) $$ 检查四元组参数是否与驱动定义一致 - 检查设备能力: 使用`IRP_MJ_DEVICE_CONTROL`处理例程的调试输出 - 参数验证: - 输入/输出缓冲区是否满足`METHOD_BUFFERED`要求 - 对齐问题(特别是64位系统) 4. **解决方案**: - 正确生成控制代码示例: ```c #define IOCTL_EXAMPLE CTL_CODE( FILE_DEVICE_UNKNOWN, // 设备类型 0x800, // 功能码(0-2047保留) METHOD_BUFFERED, // 数据传输方式 FILE_ANY_ACCESS) // 访问权限 ``` - 使用WinObjEx工具验证设备接口支持的操作 - 检查驱动程序INF文件中定义的兼容接口 5. **扩展知识**: - IOCTL代码结构: $$ (DeviceType << 16) | (Access << 14) | (Function << 2) | Method $$ - 常见数据传输方式: - METHOD_BUFFERED(双缓冲) - METHOD_IN_DIRECT(直接读取) - METHOD_OUT_DIRECT(直接写入) - METHOD_NEITHER(零拷贝) 建议使用调试器捕获IRP包,通过`!irp`命令查看驱动程序的处理状态。如果问题持续,需要结合驱动源码和WPP日志进行追踪分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值