Контроль очередности рутокенов

Приветствую
Как драйвер контролирует порядок устройств, то есть какой рутокен под номером 0, какой 1 и так далее? И вообще контролирует ли?
Если контролирует, то есть ли возможность через ваше апи поменять порядок рутокенов, то есть который был под номером 1, сделать его нулевым, и наоборот?
В данный момент я решаю это переподключением устройств через вин апи, то есть отключаю все рутокены, и подключаю их в нужном порядке...
Хотелось бы узнать, есть ли менее извращенный способ?

Re: Контроль очередности рутокенов

regnor, добрый день. Порядковый номер устройству назначает Smart Card Resource Manager.

Скорее вам подойдут эти API:
- https://docs.microsoft.com/en-us/window … -functions
- https://docs.microsoft.com/en-us/window … -functions

(2022-04-07 20:30:17 отредактировано regnor)

Re: Контроль очередности рутокенов

да, спасибо, потратил целый день на исследования, но добился результата))
пример, переименовываем первый рутокен в нулевой

    SCARDCONTEXT hContext; // дискриптор контекста
    LONG         result; // результат
    LPTSTR       pmszReaders = NULL; // имена групп ридеров, NULL - все
    LPTSTR       pReader; // список ридеров
    DWORD        cch = SCARD_AUTOALLOCATE; // длина буффера

    // Получаем контекст
    result = SCardEstablishContext(SCARD_SCOPE_SYSTEM,
                                   NULL,
                                   NULL,
                                   &hContext);
    if (SCARD_S_SUCCESS != result)
    {
        return 1;
    }

    // Получаем список ридеров
    result = SCardListReaders(hContext,
                              pmszReaders,
                              (LPTSTR)&pmszReaders,
                              &cch);
    if (SCARD_S_SUCCESS != result)
    {
        return 2;
    }

    // Выводим в консоль
    pReader = pmszReaders;
    while ('\0' != *pReader)
    {
        printf("SCardListReaders %S\n", pReader);
        pReader = pReader + wcslen((wchar_t *)pReader) + 1;
    }

    // Освобождение памяти
    result = SCardFreeMemory(hContext, pmszReaders);
    if (SCARD_S_SUCCESS != result)
    {
        return 3;
    }


    // Переименовывание ридера

    SCARDHANDLE hCardHandle; // дискриптор ридера
    DWORD       dwAP; // флаг протокола

    // Подключаемся к ридеру
    result = SCardConnectA(hContext,
                           "Aktiv Rutoken ECP 1",
                           SCARD_SHARE_SHARED,
                           SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
                           &hCardHandle,
                           &dwAP);
    if (SCARD_S_SUCCESS != result)
    {
        return 4;
    }

    LPBYTE pbAttr = NULL; // указатель на буффер с атрибутом, в нашем случае имя
    DWORD  cByte = SCARD_AUTOALLOCATE; // длина буффера

    // Получаем атрибуты ридера
    result = SCardGetAttrib(hCardHandle,
                            SCARD_ATTR_DEVICE_SYSTEM_NAME,
                            (LPBYTE)&pbAttr,
                            &cByte);
    if (SCARD_S_SUCCESS != result)
    {
        return 5;
    }

    // Добавляем новое имя ридеру
    result = SCardIntroduceReader(hContext,
                                  TEXT("Aktiv Rutoken ECP 0"),
                                  (LPCTSTR)pbAttr);
    if (SCARD_S_SUCCESS != result)
    {
        return 6;
    }

    // Удаляем старое имя
    result = SCardForgetReaderA(hContext, "Aktiv Rutoken ECP 1");
    if (SCARD_S_SUCCESS != result)
    {
        return 7;
    }

    // Дисконект от ридера
    result = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
    if (SCARD_S_SUCCESS != result)
    {
        return 8;
    }

    // Освобождение памяти
    result = SCardFreeMemory(hContext, pbAttr);
    if (SCARD_S_SUCCESS != result)
    {
        return 9;
    }