我想向连接到我的计算机(win7 64 位)的 PC/SC 阅读器发送 IOCTL 命令。为了发送 IOCTL 命令,我需要一个 HANDLE 到我无法创建的设备。
该设备在设备管理器中列为“OMNIKEY 1021”,物理设备对象名称为“\Device\USBPDO-15”。使用“winobj”工具,我可以检测到symlinks:usb #vid_076b&pid_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1d1-bf5d-0000f805f530} USB#Vid_076b&pid_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
我的问题:我无法使用 CreateFile 函数创建此设备的有效句柄:
我在 MSDN/Google 上发现了几种可能的格式,可用作 CreateFile 函数的 lpFileName 参数,但它们似乎都不起作用:
\\?\Device\USBPDO-15
\\.\Device\USBPDO-15
\\GLOBAL??\Device\USBPDO-15
\GLOBAL??\Device\USBPDO-15
\\.\USBPDO-15
\\?\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\.\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
\\?\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\\.\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\GLOBAL??\USB#VID_076B&PID_1021#5&291f6990&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
代码示例:
#include <iostream>
#include <Windows.h>
int main (int argc, char* argv[])
{
HANDLE handle = CreateFile (
L"\\\\.\\Device\\USBPDO-15",
0,
FILE_SHARE_READ, //FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0, //FILE_FLAG_OVERLAPPED,
NULL
);
if (handle == INVALID_HANDLE_VALUE)
std::cout << "INVALID HANDLE" << std::endl;
else
std::cout << "HANDLE: " << std::hex << handle << std::endl;
}
笔记:
- 返回的句柄总是无效的
- 始终以管理员身份运行,因此权限应该不是问题
编辑:
解决方案:
- PC/SC 服务拥有设备的独占所有权,因此任何调用“CreateFile”的尝试都会失败。
- 解决方案是内核空间驱动程序,它允许您将 IRP 传递给驱动程序。(我能够实现 KMDF 过滤器驱动程序来更改发送/接收到设备的数据)