gpt4 book ai didi

c++ - 将 IOCTL 发送到 Windows 设备驱动程序 - CreateFile 失败

转载 作者:可可西里 更新时间:2023-11-01 12:43:32 27 4
gpt4 key购买 nike

我想向连接到我的计算机(win7 64 位)的 PC/SC 阅读器发送 IOCTL 命令。为了发送 IOCTL 命令,我需要一个设备句柄,但我无法创建它。

设备在设备管理器中列为“OMNIKEY 1021”,物理设备对象名称为“\Device\USBPDO-15”。使用“WinObj”工具,我可以检测到 2 个符号链接(symbolic link):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}

我的问题:我无法使用 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 过滤器驱动程序来更改发送到设备/从设备接收的数据)

最佳答案

试试我的方法。我正在使用 Setup API 枚举系统中的所有 USB 事件设备并获取路径。这样您就可以确定 CreateFile 不喜欢的是路径还是其他参数。

如果有人感兴趣,我稍后会添加一些评论。

HDEVINFO hDevInfo = SetupDiGetClassDevs( &_DEVINTERFACE_USB_DEVICE, 0, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if(hDevInfo == INVALID_HANDLE_VALUE)
{
return ERR_FAIL;
}

std::vector<SP_INTERFACE_DEVICE_DATA> interfaces;

for (DWORD i = 0; true; ++i)
{
SP_DEVINFO_DATA devInfo;
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
BOOL succ = SetupDiEnumDeviceInfo(hDevInfo, i, &devInfo);
if (GetLastError() == ERROR_NO_MORE_ITEMS)
break;
if (!succ) continue;

SP_INTERFACE_DEVICE_DATA ifInfo;
ifInfo.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
if (TRUE != SetupDiEnumDeviceInterfaces(hDevInfo, &devInfo, &(_DEVINTERFACE_USB_DEVICE), 0, &ifInfo))
{
if (GetLastError() != ERROR_NO_MORE_ITEMS)
break;
}
interfaces.push_back(ifInfo);
}

std::vector<SP_INTERFACE_DEVICE_DETAIL_DATA*> devicePaths;
for (size_t i = 0; i < interfaces.size(); ++i)
{
DWORD requiredSize = 0;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &(interfaces.at(i)), NULL, NULL, &requiredSize, NULL);
SP_INTERFACE_DEVICE_DETAIL_DATA* data = (SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc(requiredSize);
assert (data);
data->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);

if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &(interfaces.at(i)), data, requiredSize, NULL, NULL))
{
continue;
}
devicePaths.push_back(data);
}

关于c++ - 将 IOCTL 发送到 Windows 设备驱动程序 - CreateFile 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8263380/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com