title: Figuring which printer name corresponds to which device ID
body: <p>My goal is to open a printer connected via USB using the <code>CreateFile</code> (and then issue some <code>WriteFile</code>s and <code>ReadFile</code>s).</p>
  
  <p>If the printer was an LPT one, I would simply do <code>CreateFile("LPT1:", ...)</code>. But for USB printers, there is a special device path that must be passed to <code>CreateFile</code> in order to open that printer.</p>
  
  <p>This device path, <a href="http://www.dreamincode.net/forums/topic/52713-communicating-with-usb-printer/" rel="nofollow noreferrer">as I was able to find</a>, is retrieved via <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff551069.aspx" rel="nofollow noreferrer"><code>SetupDiGetClassDevs</code></a> -> <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff551015.aspx" rel="nofollow noreferrer"><code>SetupDiEnumDeviceInterfaces</code></a> -> <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff551120.aspx" rel="nofollow noreferrer"><code>SetupDiGetDeviceInterfaceDetail</code></a> -> <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff552343.aspx" rel="nofollow noreferrer"><code>DevicePath</code> member</a> and looks like this:</p>
  
  <blockquote>
    <p><code>\\?\usb#vid_0a5f&amp;pid_0027#46a072900549#{28d78fad-5a12-11d1-ae5b-0000f803a8c2}</code></p>
  </blockquote>
  
  <p>All that is fine, but what I have as the input is the human-readable printer name, as seen in <code>Devices and Printers</code>. The <code>SetupDi*</code> functions don't seem to use that, they only operate on <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff541327.aspx" rel="nofollow noreferrer">device instance IDs</a>. So the question is now <strong>how to get device instance ID from the printer name one would pass to <code>OpenPrinter</code></strong>.</p>
  
  <p>It's not difficult to observe that the GUID part of the above is the <code>GUID_DEVINTERFACE_USBPRINT</code>, and <code>\\?\usb</code> is fixed, so the only bit I'm really interested in is <code>vid_0a5f&amp;pid_0027#46a072900549#</code>. This path I can easily look up manually in the printer properties dialog:</p>
  
  <blockquote>
    <p>Go to Devices and Printers<br>
    Right-click the printer<br>
    Properties<br>
    Switch to Hardware tab<br>
    Select the printing device, such as ZDesigner LP2844-Z<br>
    Properties<br>
    Switch to Details tab<br>
    Select 'Parent' from the dropdown.</p>
  </blockquote>
  
  <p>But I have no idea how to do that programmatically provided the only thing given is the printer name as seen in the Device and Printers panel.</p>
  
  <hr>
  
  <p>P.S. 1: I'm not interested in opening the printer with <code>OpenPrinter</code> and then using <code>WritePrinter</code> / <code>ReadPrinter</code>. That has been done, works fine, but now the goal is different.</p>
  
  <p>P.S. 2: <strong>I'll be OK with a simpler way to convert the readable printer name to something that can be passed to <code>CreateFile</code></strong>.</p>
  
  <p>P.S. 3: <a href="https://stackoverflow.com/questions/1846340/reading-status-from-zebra-printer">This question</a>, to which I have posted an <a href="https://stackoverflow.com/a/10659778/11683">answer</a>, is very related to what I ultimately want to do.</p>
  
  <p>P.S. 4: The other way round is also fine: <strong>If it is possible to obtain the readable name from the <a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff552344.aspx" rel="nofollow noreferrer"><code>SP_DEVINFO_DATA</code></a> structure, that will also be the answer</strong>, although a less convenient one.</p>