Send IOCTL to Windows device driver - CreateFile fails

时光怂恿深爱的人放手 提交于 2019-11-30 03:17:47

问题


I want to send an IOCTL command to a PC/SC reader connected to my computer (win7 64 bit). In order to send an IOCTL command I need a HANDLE to the device, which I'm unable to create.

The device is listed as "OMNIKEY 1021" in the device manager, the physical device object name is "\Device\USBPDO-15". Using the "WinObj" tool, I can detect 2 symlinks: 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}

My problem: I cannot create a valid handle to this device with the CreateFile function:

I found several possible formats on MSDN/Google to use as the lpFileName param of the CreateFile function, but none of them seem to work:

\\?\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}

Code sample:

#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;
}

Notes:

  • The returned handle is always invalid
  • Always running as Administrator, so the privileges should not be a problem

edit:

Solution:

  • The PC/SC service takes exclusive ownership of the devices, so any attempt to call 'CreateFile' will always fail.
  • The solution is a kernel space driver, this allows you to pass IRP's to the driver. (I was able to implement a KMDF filter driver to alter data sent/received to/from the device)

回答1:


Try it my way. I'm using Setup API to enumerate all USB active devices in the system and get paths. That way you can find out whether it's the path or other arguments that CreateFile doesn't like.

I'll add some comments a bit later, if anyone's interested.

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);
    }



回答2:


Just try with CreateFile(L"\\\\.\\{GUID}",etc...



来源:https://stackoverflow.com/questions/8263380/send-ioctl-to-windows-device-driver-createfile-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!