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

时间:2011-11-24 23:19:13

标签: c++ windows driver device ioctl

我想将IOCTL命令发送到连接到我的电脑的PC / SC阅读器(win7 64位)。 为了发送IOCTL命令,我需要一个HANDLE到设备,我无法创建。

设备在设备管理器中列为“OMNIKEY 1021”,物理设备对象名称为“\ Device \ USBPDO-15”。使用“WinObj”工具,我可以检测到2个符号链接: 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过滤器驱动程序来改变发送到设备/从设备接收的数据)

2 个答案:

答案 0 :(得分:7)

以我的方式尝试。我正在使用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);
    }

答案 1 :(得分:1)

试试CreateFile(L"\\\\.\\{GUID}",etc..