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的问题。首先,我得确认用户的问题是什么。他说“DeviceIoControl 返回1”,可能需要解释这个返回值的含义。 首先,我应该回忆一下DeviceIoControl的基本信息。DeviceIoControl是Windows API中的一个函数,用于直接与设备驱动程序通信。通常,它的返回值类型是BOOL,也就是成功返回非零值(TRUE),失败返回0(FALSE)。但用户提到返回1,这应该是指返回值为TRUE的情况,也就是1,表示成功。 接下来,我需要详细解释这个返回值的意义。当DeviceIoControl返回1时,说明IOCTL请求已经成功发送到设备驱动程序,并且驱动程序处理了这个请求。但是,这并不一定意味着操作本身完全成功,只是说明请求被正确传递和处理了。用户需要检查GetLastError的结果,因为有时候即使DeviceIoControl返回成功,具体的错误可能通过GetLastError返回,或者需要检查输出缓冲区的数据。 然后,我需要考虑用户可能的后续问题,比如为什么有时候返回成功但操作没效果。这时候应该提到,驱动程序可能内部处理时遇到了问题,但依然返回了成功状态,或者可能输出缓冲区中的数据包含了更多的状态信息。因此,建议用户检查输出参数和缓冲区内容,以及调用GetLastError来获取扩展错误信息。 另外,用户可能需要知道如何正确使用DeviceIoControl,比如参数的正确设置,特别是输入输出缓冲区的指针和大小,以及控制代码是否正确。这时候需要提醒用户确保这些参数正确,否则即使函数返回成功,实际结果可能不如预期。 还要注意不同Windows版本或驱动程序可能的行为差异,但一般来说,返回TRUE表示函数调用本身成功,而具体操作结果需要进一步确认。 总结一下,回答的结构应该是先说明返回1的含义,然后解释其背后的情况,接着给出后续步骤的建议,比如检查GetLastError和输出缓冲区,最后可能提醒参数正确性的重要性。这样用户能够逐步排查问题,确保正确使用DeviceIoControl函数。</think>当`DeviceIoControl`函数返回**1**(即`TRUE`)时,表示该函数已成功将I/O控制码(IOCTL)请求发送到目标设备驱动程序,并且驱动程序已正确处理该请求。以下是对此问题的详细分步解释: --- ### 1. **`DeviceIoControl`的基本作用** - **功能**:`DeviceIoControl`是Windows API中用于与设备驱动程序通信的核心函数。它允许用户态程序通过**控制码(IOCTL)**向驱动程序发送自定义命令,实现设备控制、配置或数据传输。 - **返回值类型**:`BOOL`(非零值`TRUE`表示成功,`0`表示失败)。 --- ### 2. **返回1(TRUE)的含义** - **成功发送请求**:返回值1仅表示IOCTL请求已成功传递到驱动程序,且驱动程序已确认接收。 - **不保证操作完全成功**:即使返回1,**实际请求的操作是否成功**需进一步验证。例如: - 驱动程序可能接收请求但内部处理失败。 - 输出缓冲区可能未按预期填充数据。 --- ### 3. **后续验证步骤** - **(1) 检查扩展错误信息**: ```c if (DeviceIoControl(...) == TRUE) { // 成功,但需进一步验证 } else { DWORD error = GetLastError(); // 失败时获取错误码 } ``` - 即使返回1,仍建议调用`GetLastError()`,某些驱动程序可能在成功返回的同时设置错误码。 - **(2) 验证输出缓冲区**: - 若IOCTL需要返回数据(如读取设备状态),需检查输出缓冲区是否被正确填充。 - 示例代码片段: ```c DWORD bytesReturned = 0; if (DeviceIoControl(hDevice, IOCTL_EXAMPLE, inputBuffer, inputSize, outputBuffer, outputSize, &bytesReturned, NULL)) { if (bytesReturned == 0) { // 可能未获取到有效数据 } } ``` - **(3) 驱动程序日志**: - 若具备调试条件,检查驱动程序的调试输出(如WinDbg的`DbgPrint`日志),确认其内部是否真正完成操作。 --- ### 4. **常见问题场景** - **场景1**:返回1但未生效 - **原因**:驱动程序接收请求但未执行操作(如参数无效但未返回错误)。 - **解决**:检查输入参数和缓冲区是否符合驱动程序要求。 - **场景2**:返回1但`GetLastError()`非零 - **原因**:驱动程序可能调用`SetLastError()`后仍返回`TRUE`(非标准做法,但可能存在)。 - **解决**:以`GetLastError()`结果为准。 --- ### 5. **关键参数验证** - **控制码(IOCTL)**:确保使用的IOCTL值与驱动程序支持的匹配。 - **输入/输出缓冲区**: - 缓冲区指针不可为`NULL`(除非允许)。 - 缓冲区大小需符合驱动程序预期。 - **设备句柄**:确认句柄已通过`CreateFile`正确打开且具有所需权限。 --- ### 总结 当`DeviceIoControl`返回1时,首先确认请求已成功传递,但需进一步检查输出缓冲区、`bytesReturned`及`GetLastError()`,以全面验证操作的实际结果。若问题持续,建议结合驱动程序日志或内核调试工具(如WinDbg)深入分析。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值