Получение пути до дочернего устройства

Доброго времени суток. Есть два рутокена, которые подключены к компьютеру. Появилась необходимость периодически отключать один из них. Делаю это через утилиту devcon.exe, которая входит в состав WDK. Отключаю устройство чтения смарт карт Microsoft Usbccid (WUDF) по пути к экземпляру. Опытным путем вычислил (могу, конечно, ошибаться), что PKI-Core записывает в вектор устройства по порядковому номеру, который находиться в дочернем элементе устройства чтения смарт карт Microsoft Usbccid (WUDF), пример на скринеhttps://forum.rutoken.ru/uploads/images/2021/04/44d4624efdbba23a87e05ddffb13f89b.jpg
Соответственно, если там 0, то это первый элемент в векторе, 1 - второй и так далее.
Так же в свою очередь у устройства смарт карты есть родитель - это пусть до экземпляра устройства чтения смарт карт Microsoft Usbccid (WUDF), которое нужно отключить, скрин ниже
https://forum.rutoken.ru/uploads/images/2021/04/ffbcdb1a733bb119c16749bbcc00cebf.jpg

Отсюда вопрос, можно ли как то через ваше апи получить путь до дочернего элемента устройство чтения смарт карт Microsoft Usbccid (WUDF) или наоборот, получить путь до родителя устройства смарт карты?
Спасибо.

P.S.
В winapi пока ничего не нашел...

Re: Получение пути до дочернего устройства

Добрый день!

Можем подсказать направление: https://stackoverflow.com/questions/142 … csc-reader

С помощью SCardGetAttrib() можно сопоставить имя считывателя, например, "Aktiv Rutoken ECP 0" c VID и PID.

В целом кажется, что здесь есть все то, что вы ищите:
https://medium.com/@ermmarat/workaround … 12eaa2de67

Открытый код разработки: https://github.com/MarErm27/workaroundF … nInWindows

Re: Получение пути до дочернего устройства

Благодарю! Да, это то что нужно!

(2021-05-11 14:37:45 отредактировано regnor)

Re: Получение пути до дочернего устройства

Я поторопился, когда сказал, что это то что нужно))
Нашел решение, если кому понадобиться пример ниже

#include <iostream>
#include <windows.h>
#include <setupapi.h>
#include <cfgmgr32.h>

int main()
{
    CONFIGRET CMResult = CR_SUCCESS;
    WCHAR DeviceInstanceID[] = L"USB\\VID_0A89&PID_0030\\5&3B0D2CFF&0&7"; // путь экземпляра родителя

    DEVNODE ParentDeviceNode = 0;
    CMResult = CM_Locate_DevNodeW((PDEVINST) &ParentDeviceNode, DeviceInstanceID, CM_LOCATE_DEVNODE_NORMAL); // дескриптор родительского экземпляра

    if (CMResult != CR_SUCCESS)
    {
        return -1;
    }
    else
    {
        DEVINST FirstChildDeviceNode = 0;
        CMResult = CM_Get_Child((PDEVINST) &FirstChildDeviceNode, ParentDeviceNode, 0x0); // Получаем первый дочерний элемент

        DEVINST SecondChildDeviceNode = 0;
        CMResult = CM_Get_Sibling((PDEVINST) &SecondChildDeviceNode, FirstChildDeviceNode, 0x0); // Получаем второй дочерний элементы

        if (CMResult != CR_SUCCESS)
        {
            return -2;
        }
        else
        {
            ULONG ChildDBuffLength = 0;
            CMResult = CM_Get_Device_ID_Size(&ChildDBuffLength, SecondChildDeviceNode, 0x0); // получаем размер необходимого буффера для вывода пути дочернего элемента
            if (CMResult != CR_SUCCESS)
            {
                return -3;
            }
            else
            {
                WCHAR * ChildInstanceIDBuff = (WCHAR *) calloc(ChildDBuffLength, sizeof(WCHAR)); // выделяем память для пути до дочернего элемента
                CMResult = CM_Get_Device_IDW(SecondChildDeviceNode, ChildInstanceIDBuff, ChildDBuffLength, 0x0); // получаем путь до дочернего элемента

                if (CMResult != CR_SUCCESS)
                {
                    return -4;
                }
                else
                {
                    std::cout << "Found child device: ";
                    std::wcout << ChildInstanceIDBuff << std::endl;
                }

                free(ChildInstanceIDBuff);
            }
        }
    }

    return 0;
}