Send IOCTL to Windows device driver - CreateFile fails

15,912

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

Solution 2

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

Share:
15,912

Related videos on Youtube

bmotmans
Author by

bmotmans

Updated on June 04, 2022

Comments

  • bmotmans
    bmotmans almost 2 years

    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)
    • Alexey Frunze
      Alexey Frunze over 12 years
      Some device drivers accept only names that have extra known-only-to-them stuff in the names after "device name\". There may be other special ways for opening as well. I wonder if you can find out more using the kernel debugger (WinDbg), setting breakpoints here and there and looking at what's being passed to/from the driver.
  • bmotmans
    bmotmans over 12 years
    This pointed me to the correct string to use for my device, namely: L"\\\\?\\usb#vid_076b&pid_1021#6&3225591f&0&1#{50dd5230-ba8a‌​-11d1-bf5d-0000f805f‌​530}\\slot0" , I will accept this comment as the solution when I can find the cause of the "Access is denied" error that I now receive.
  • Violet Giraffe
    Violet Giraffe over 12 years
    @bmotmans: try GENERIC_READ or GENERIC_READ | GENERIC_WRITE as the second parameter to CreateFile, leave all other flags '0'.
  • bmotmans
    bmotmans over 12 years
    This causes the error "The parameter is incorrect". Apparently the 'dwCreationDisposition' parameter must always be set (OPEN_EXISTING)
  • Violet Giraffe
    Violet Giraffe over 12 years
    @bmotmans: Of course, sorry, forgot that one. And what happens when you set it to OPEN_EXISTING?
  • bmotmans
    bmotmans over 12 years
    same thing when only using the OPEN_EXISTING parameter. (all other parameters with value 0)
  • Violet Giraffe
    Violet Giraffe over 12 years
    @bmotmans: I meant GENERIC_READ or GENERIC_READ | GENERIC_WRITE and OPEN_EXISTING, with all other flags being 0. That's the combination I am only able to open USB device with.
  • bmotmans
    bmotmans over 12 years
    Same thing, "Access is denied". I'm starting to believe that another process has exclusive ownership over the driver/device, blocking my CreateFile attempts.
  • Violet Giraffe
    Violet Giraffe over 12 years
    @bmotmans: I'm afraid I've shared all the experience I have. I have no idea how to fix ACCESS_DENIED.
  • serup
    serup almost 6 years
    how is this different from what he is already doing - you need to provide a more clear answer