5

I get an device instance path like

L"\\\\?\\USB#VID_0403&PID_6001#6&2cc2d230&0&2#{219d0508-57a8-4ff5-97a1-bd86587c6c7e}"

from IWDFRemoteInterfaceInitialize::RetrieveSymbolicLink.
But for CM_Get_Parent I need the DEVINST/DWORD of the device which drives me crazy.
I've tried for example

instancePath = L"\\\\?\\USB#VID_0403&PID_6001#6&2cc2d230&0&2#{219d0508-57a8-4ff5-97a1-bd86587c6c7e}";
HDEVINFO hinfo = SetupDiGetClassDevs(NULL, instancePath, NULL, DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES);

and some other SetupDi... voodoo with no success. Any help is highly appreciated because -as mentioned- I haven't been able to get around this madness for hours now and though there are dozens of examples for the other way round (devid->instance path) I haven't found any for instance path->DEVINST.

1
  • 1
    I'm having the exact same problem. Answers would sitll be appreciated. Commented Oct 20, 2013 at 16:41

2 Answers 2

2

While modifying the path will probably work, the Windows docs explicitly say that you should not parse device paths.

You can do it with the CfgMgr32 API, though, using CM_Get_Device_Interface_PropertyW () and DEVPKEY_Device_InstanceId:

#include <cfgmgr32.h>
#include <initguid.h> // needed for devpkey.h to parse properly
#include <devpkey.h>

#include <cassert>
#include <string>
#include <vector>

/*
 *   @brief The following retrieves the Device Instance ID from the main device path.
 *   @param device_path A device path that has the form of the following:
 *                      \\?\usb#vid_[VENDOR_ID]&pid_[PRODUCT_ID]#INSTANCE_ID#{[DEVICE_INTERFACE_GUID]}
 *
 *                      Where the following components are described as:
 *                          1. VENDOR_ID             - The vendor ID of the device.
 *                          2. PRODUCT_ID            - The product ID of the device.
 *                          3. INSTANCE_ID           - The unique ID generated when the device connects to the host.
 *                          4. DEVICE_INTERFACE_GUID - The GUID that describes the interface of the device.
 *                                                     This is NOT the same as the "Device Class GUID."
 *   @return The Device Instance ID (linked below). A Device Instance ID has the form of:
 *           <device-id>\<instance-id>
 *
 *           Example: USB\VID_2109&PID_0813\7&3981c8d6&0&2
 *   @see https://learn.microsoft.com/en-us/windows-hardware/drivers/install/device-instance-ids
 *   @see https://learn.microsoft.com/en-us/windows/win32/api/cfgmgr32/nf-cfgmgr32-cm_get_device_interface_propertyw
 */
std::wstring map_path (LPCWSTR device_path) {
    ULONG buf_size = 0;
    DEVPROPTYPE type;
    CM_Get_Device_Interface_PropertyW(
        device_path, &DEVPKEY_Device_InstanceId, &type,
        nullptr, &buf_size, 0);

    std::vector<BYTE> buffer(buf_size);
    auto result = CM_Get_Device_Interface_PropertyW(
        device_path, &DEVPKEY_Device_InstanceId, &type,
        buffer.data(), &buf_size, 0);

    assert(result == CR_SUCCESS);
    assert(type == DEVPROP_TYPE_STRING);

    // buffer will be null-terminated
    return reinterpret_cast<wchar_t*>(buffer.data());
}
Sign up to request clarification or add additional context in comments.

Comments

1

As you said, there's not a direct way.

However, you should be able to get a Device Instance ID from your Device Path / Device Interface ID by means of some string editing, following the below steps:

  1. Remove entirely the starting \\\\?\\ part, until the USB.
  2. Remove entirely the last {...} part
  3. Replace # with \

Starting from

"\\\\?\\USB#VID_0403&PID_6001#6&2cc2d230&0&2#{219d0508-57a8-4ff5-97a1-bd86587c6c7e}"

you should now have

"USB\VID_0403&PID_6001\6&2cc2d230&0&2\"

which should be a valid Device Instance ID. If it's not, try removing the last "\" too.

Then, you can feed this to CM_Locate_DevNode() and get the wanted DEVINST.

1 Comment

Although you can parse the device path string, the Windows documentation denotes one should not do this. I believe this is because the format of device path strings is allowed to change in the future. Take a look at alexmerry's answer below. They provide a function for retrieving this string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.