(2017-06-29 01:46:12 отредактировано vlad-mal)

Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Здравствуйте.
Пытаюсь в цикле обеспечить эксклюзивный доступ к ключу Guardant Sign Net, размещенном на другой машине в локальной сети (использую сервер GLDS.EXE)

Начало_Цикла
  fStatus := GrdLock(fGrdHandle, 1000, 30000, GrdLM_All);
  Проверка_Значения (fStatus);
  ...
  ... // Что-то делаю
  ...
Конц_Цикла

Одна итерация цикла у меня выполняется чуть больше 1 сек, и я задал значение параметра dwTimeoutAutoUnlock равным 30 сек, чтобы гарантированно перекрыть 2 сек и в случае "зависания" приложения разблокировать ключ не позднее, чем через полминуты.
Предполагаю, что повторный вызов GrdLock() в той же сессии всего лишь сдвинет время автоматического разблокирования ключа но очередные 30 сек.

Однако выяснилось, что после 10 итераций GrdLock() возвращает код

  GrdE_DongleLocked = 23; { Guardant dongle is busy (locked by another copy of protected application)}

- хотя никакое другое приложение данный ключ не использовало.

-----------

Расскажите, пожалуйста, об особенностях работы метода GrdLock() в случае его повторного вызова до достижения момента времени, заданном в dwTimeoutAutoUnlock.

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Экспериментирую...

Задал время выполнения итерации цикл равным ровно 1 секунда

Начало_Цикла
  fStatus := GrdLock(fGrdHandle, 1000, aValue, GrdLM_All);
  Проверка_Значения (fStatus);
  ...
  ... // Что-то делаю
  ...
Конц_Цикла

Выяснил:

Если значение времени авторазблокировки aValue меньше времени итерации цикла (например, aValue = 900, а dwTimeoutAutoUnlock = 1000), то GrdLock() всегда отрабатывает успешно.

Если значение времени авторазблокировки aValue больше времени итерации цикла (например, aValue = 1100, а dwTimeoutAutoUnlock = 1000), то GrdLock() отрабатывает успешно лишь 10 раз.

Непонятно, как блокировать ключ с учетом появившихся в результате экспериментов новых сведений.
Можно, конечно, после первого успешного захвата ключа просто периодически вызывать GrdLock(), не заботясь о коде завершения ("это же я первым ключ захватил!"), но в случае с перезапуском удаленного сервера, такая тактика, имхо, не будет правильной...

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Подключил к экспериментам метод   GrdGetInfo() с параметром GrdGIL_LockCounter.
Метод возвращает счетчик блокировок ключа.

Итак:

Счетчик увеличивается на 1 при вызове GrdLock().
Счетчик уменьшается на 1 при вызове GrdUnlock() либо автоматически, по достижении момента времени, равного моменту последнего вызова GrdLock() плюс время, заданное в параметре dwTimeoutAutoUnlock.
Если счетчик равен 10, то вызов GrdLock() завершится с кодом GrdE_DongleLocked.

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Повторил эксперименты с ключами Guardant Sign - выяснил, что поведение у их точно такое же, как и Guardnt Sign Net.

Можно было бы такое поведение и в документации отразить, тем более, что вопрос уже возникал: https://forum.guardant.ru/post/1092

~~~~~~~~~~~~~~~~~

Остался вопрос: как обеспечить эксклюзивный доступ к ключу в цикле, и при этом не заблокировать ключ надолго в случае "зависания" приложения?

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

vlad-mal пишет:

...

Остался вопрос: как обеспечить эксклюзивный доступ к ключу в цикле, и при этом не заблокировать ключ надолго в случае "зависания" приложения?

Придумал костыль:

- в начало цикла, перед вызовом GrdLock()

var
  fLockCounter: DWORD;
begin
...
  Начало_Цикла

    while True do begin
      GrdGetInfo(fGrdHandle, GrdGIL_LockCounter, @fLockCounter, SizeOf(DWORD));
      if fLockCounter <= 1 then Break; // fLockCounter и так маленький (< 10)
      FStatus := GrdUnlock(fGrdHandle);
      if FStatus <> GrdE_OK then 
        //  действия в случае, когда ключ захвачен в другой сессии
    end;

    FStatus := GrdLock(...);
    if FStatus <> GrdE_OK then 
      //  действия в случае, когда ключ захвачен в другой сессии
...
... Тело цикла
...
Конец_Цикла

Описание: приведенный код не позволяет счетчику блокировок увеличиться до недопустимого значения.
Если счетчик не боле, чем 1, то предполагается, что ключ был захвачен в этом сеансе. Иначе (счетчик больше 1), выполняется попытка уменьшить значение счетчика блокировок. Если не получилось - следовательно, ключ заблокирован в другой сессии.

~~~~~~~~

Ну, хоть так.

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Бред...

При параллельном запуске приложений, первое приложение блокирует ключ по GrdLock().  При этом значение параметра dwTimeoutAutoUnlock в GrdLogout() равно 0xFFFFFFFF, т.е. время блокирования не ограничено и блокировка может быть снята только функцией GrdUnlock.

Запускается второе приложение, которое вполне логично получает отказ по GrdLock() (т.к. первое уже заблокировало ключ), затем это второе приложение просто выполняем GrdLogout(), GrdCloseHandle(), потом затем снова инициализирует дескриптор ключа, выполняем поиск ключа, и - вуа-ля! - вызов GrdLock() выполняется успешно, первое приложение "отваливается" от ключа с кодом GrdE_DongleLocked - ну, красота, в общем.

Еще раз напомню, что значение параметра dwTimeoutAutoUnlock в GrdLogout() равно 0xFFFFFFFF, т.е. время блокирования не ограничено и блокировка может быть снята только функцией GrdUnlock (согласно документации).


Уважаемые разработчики, кто-нибудь вообще тестировал метод GrdLock()?

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Добрый день. У нас подобное поведение не воспроизводится. Просьба прислать на почту hotline@guardant.ru следующие данные

Пример с исходным кодом
Версия SDK с которой проводите защиту
Версия ОС
Среда разработки
Отчет утилиты диагностики ключа, с которым защищаетесь

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Отправил письмо.

1. К письму приложен 7z - архив, в нем - исходник тестового приложения, само приложение и инструкция по сборке и запуску в MS Word файле Readme.doc. Тест касается https://forum.guardant.ru/post/3662/#p3662

2. По поводу ограничения количества вызовов GrdLock() - https://forum.guardant.ru/post/3659/#p3659 - тест не создавал, для повторения достаточно в цикле вызывать

  fStatus := GrdLock(fGrdHandle, 1000, Cardinal(-1), GrdLM_All);

- анализируя возвращаемый код fStatus и подсчитывая количество итераций цикла.

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Добрый день. В SDK 6.31 была ошибка с GrdLock. В SDK 7.3 данная ошибка исправлена. Необходимо обновить SDK.

Обратите внимание! При установке\обновлении Guardant SDK, на компьютере с уже установленным ранее SDK, строго необходимо делать резервную копию базы данных утилиты программирования GrdUtil.exe.

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

1. К сожалению, в SDK 7.3 вы почему-то отказались от поддержки Windows XP. Отказаться от обслуживания старых клиентов мы не готовы.

2. Уточните, пожалуйста, о какой "исправленной ошибке" идет речь? О той, где одно приложение может разблокировать другое, или о той, где одно приложение может "безнаказанно" вызвать GrdLock() лишь 10 раз?

(2017-07-05 16:42:18 отредактировано Тимофей Ершов)

Re: Поясните, пожалуйста, работу GRDLock для ключей Sign/SignNet

Добрый день.

1. Приложения, защищенные с SDK 7.3 должны работать работать и на Windows XP в том числе. Совместимость есть. Однако сам комплект разработчика все же рекомендуем устанавливать на современных операционных системах.

2. Сегодня такую информацию мы уточнить не можем, так как SDK 6.3 обновлялся более 3 лет назад. Вероятно обе ваши ошибки имеют одну природу происхождения, и связаны с некорректной работой инструментов, входящих в SDK 6.3. Уточните, воспроизводятся ли такие ошибки на SDK 7.3?