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