(2023-12-28 16:01:20 отредактировано ajuvolkov)

GrdRead возвращает ошибку GrdE_DongleLocked

Добрый день. Есть старый рабочий код, который ранее использовался с USB ключами Guardant Code и проблем с ним не возникало.

В декабре заказали ключ, прошили его так же как прошивали год назад аналогичные ключи. Код перестал работать с данным ключом. При попытке вызвать GrdRead  из другого потока (не из того где происходила инициализация ключа), данная функция возвращает ошибку GrdE_DongleLocked, при этом если вызвать данную функцию из потока, где ключ был проинициализирован, все ок.

Работаем c Guardant SDK 7 под Windows 10

Ключ инициализируется для многопоточной работы:
GrdCreateHandle(0, GrdCHM_MultiThread, NULL);

Подскажите в чем может быть проблема?

Код инициализации и проверки ключа (отдельный поток в приложении):

    void working_thread_body()
    {
        try {

            int rc;
            rc = GrdStartup(GrdFMR_Local);
            if (rc != GrdE_OK) {
                throw st::joint::exception("Guardiant license key: Failed to initialize. RC=[%d]", rc);
            }

            m_grd = GrdCreateHandle(0, GrdCHM_MultiThread, NULL);
            if (!m_grd) {
                throw st::joint::exception("Failed to create handle. RC=[%d]", rc);
            }

            auto grd_handle_guard = st::sfl::finally([&]() {close_handle();});

            rc = GrdSetAccessCodes(m_grd, m_public_key, m_private_key, NULL, NULL);
            if (rc != GrdE_OK) {
                throw st::joint::exception("Guardiant license key: Failed to set access code. RC=[%d]", rc);
            }

            rc = GrdSetFindMode(m_grd, GrdFMR_Local, GrdFM_ID, 0, m_key_id, 0, 0, 0, 0, GrdFMM_ALL, GrdFMI_USB);
            if (rc != GrdE_OK) {
                throw st::joint::exception("Guardiant license key: Failed to set find mode. RC=[%d]", rc);
            }

            DWORD id;
            TGrdFindInfo grd_fi;
            rc = GrdFind(m_grd, GrdF_First, &id, &grd_fi);
            if (GrdE_OK != rc) {
                throw st::joint::exception("Guardiant license key: Failed to find the key [%x]. RC=[%d]", m_key_id, rc);
            }
       
            rc = GrdLogin(m_grd, 0xFFFFFFFF, 0);
            if (GrdE_OK != rc) {
                throw st::joint::exception("Guardiant license key: Failed to login to the key. RC=[%d]", rc);
            }

            rc = GrdLock(m_grd, 0, 0xFFFFFFFF, GrdLM_All);
            if (GrdE_OK != rc) {
                if (GrdE_DongleLocked == rc) {
                    throw st::joint::exception("Guardiant license key: Failed to lock the key. RC=[%d]. The dongle is busy or already locked by another application", rc);
                }
                throw st::joint::exception("Guardiant license key: Failed to lock the key. RC=[%d]", rc);
            }
            auto grd_lock_guard = st::sfl::finally([&]() {unlock();});
           
            m_key_initialization_proc_done = true;
            m_key_initialization_proc_cv.notify_one();

            m_run = true;

#ifdef ST_SFL_PLATFORM_WINDOWS
            // window is needed for WM_ENDSESSION message handling to gracefully unlock the key on Windows logout/shutdown
            auto wnd = st::geobase::glwnd::create_window(
                "",
                "geobase_wnd_msg_handling_window",
                true,
                0,
                0,
                800,
                600,
                false,
                false,
                false,
                4,5,
                false,
                -1
            );
            st::geobase::glwnd::set_wnd_end_session_callback(wnd, [&](){
                std::lock_guard<std::mutex> lock(m_sync);
                unlock();
                close_handle();
                m_run = false;
            });
#endif

            auto last_check_time = std::chrono::steady_clock::now();

            while (m_run)
            {
                std::this_thread::sleep_for(std::chrono::milliseconds(30));

#ifdef ST_SFL_PLATFORM_WINDOWS
                if (wnd) {
                    glwnd::handle_window_system_msg(wnd);
                }
#endif
                if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - last_check_time).count() > 10)
                {
                    if (m_grd) {
                        const auto rc = GrdCheck(m_grd);
                        if (GrdE_OK != rc)
                        {
                            if (GrdE_DongleNotFound == rc) {
                                throw st::joint::exception("Guardiant license key: The dongle wasn't found");
                            }
                            throw st::joint::exception("Guardiant license key: Failed to check dongle [%d]", rc);
                        }
                    }
                    last_check_time = std::chrono::steady_clock::now();
                }
            }
        }
        catch (st::joint::exception &exc)
        {
            st::logger::error(exc.what());
            m_run = false;

            if (!m_key_initialization_proc_done)
            {
                m_key_initialization_proc_done = true;
                m_key_initialization_proc_cv.notify_one();
            }

            m_license_violation_callback();
        }
    }

Код, который читает данные из ключа (вызывается из другого потока):

   unsigned int get_max_value()
    {
        std::lock_guard<std::mutex> lock(m_sync);
        if (m_grd) {
            unsigned int maxcon = 1;
            int rc = GrdRead(m_grd, 0x0028, sizeof(unsigned int), &maxcon, NULL);
            if (GrdE_OK != rc) {
                if (GrdE_DongleNotFound == rc) {
                    st::joint::exception("Guardiant license key: Failed to read value from the key. The dongle wasn't found");
                }
                throw st::joint::exception("Guardiant license key: Failed to read value from the key: [%d]", rc);
            }
            return maxcon;
        }
        return 0;
    }

Вот здесь GrdRead возвращает код ошибки GrdE_DongleLocked

Re: GrdRead возвращает ошибку GrdE_DongleLocked

Добрый день.
Просьба прислать полный отчет диагностики для проблемного ключа на почту hotline@guardant.ru.

(2024-01-09 12:27:01 отредактировано ajuvolkov)

Re: GrdRead возвращает ошибку GrdE_DongleLocked

Добрый день! Выслал.

Re: GrdRead возвращает ошибку GrdE_DongleLocked

Добрый день. Спасибо. Ответили в почте.

Re: GrdRead возвращает ошибку GrdE_DongleLocked

Здравствуйте. Вчера ответил вам на почту, но пока что не получил ответа ваших специалистов

Re: GrdRead возвращает ошибку GrdE_DongleLocked

Добрый день. Ответили вам на почту.