title: Send IOCTL to Windows device driver - CreateFile fails
body: <p>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.</p>
  
  <p>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&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
  USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}</p>
  
  <p><strong>My problem: I cannot create a valid handle to this device with the CreateFile function:</strong></p>
  
  <p>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:</p>
  
  <pre><code>\\?\Device\USBPDO-15
  \\.\Device\USBPDO-15
  \\GLOBAL??\Device\USBPDO-15
  \GLOBAL??\Device\USBPDO-15
  \\.\USBPDO-15
  \\?\USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
  \\.\USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
  \\GLOBAL??\USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
  \GLOBAL??\USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{50dd5230-ba8a-11d1-bf5d-0000f805f530}
  \\?\USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
  \\.\USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
  \\GLOBAL??\USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
  \GLOBAL??\USB#VID_076B&amp;PID_1021#5&amp;291f6990&amp;0&amp;1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
  </code></pre>
  
  <p><strong>Code sample</strong>:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;Windows.h&gt;
  
  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 &lt;&lt; "INVALID HANDLE" &lt;&lt; std::endl;
      else
          std::cout &lt;&lt; "HANDLE: " &lt;&lt; std::hex &lt;&lt; handle &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p><strong>Notes:</strong></p>
  
  <ul>
  <li>The returned handle is always invalid</li>
  <li>Always running as Administrator, so the privileges should not be a problem</li>
  </ul>
  
  <p>edit:</p>
  
  <p><strong>Solution:</strong></p>
  
  <ul>
  <li>The PC/SC service takes exclusive ownership of the devices, so any attempt to call 'CreateFile' will always fail.</li>
  <li>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)</li>
  </ul>