Доступ к ключам через AnywhereUSB

Добрый день.

Имеется приложение, работающее с ключами Guardant Time. По ряду причин приложение необходимо запускать на виртуальной машине под HyperV. Т.к. HyperV не поддерживает проброску портов USB, то решено было использовать решение AnywhereUSB (проброска портов USB через сеть).
При подключении ключа к хабу AnywhereUSB ключ в системе обнаруживается, утилиты "Диагностика ключей" и "Программирование ключей" ключ находят без проблем и работают с ним так же, как если бы ключ был подключен к реальному порту. Однако нашей программы, нормально работающий с ключами подключенными к реальным портам, не находит ключ, подключенный через AnywhereUSB.

Пример кода

      [TestMethod]
      public void Guardant_TestNative()
      {
         uint publicCode = ###;
         uint readCode = ###;
         uint writeCode = ###;
         uint masterCode = ###;
         uint programNumber = 0;
         uint versionNumber = 1;
         var retCode = GrdApi.GrdStartup(GrdFMR.Local);
         HandleResult(retCode);
         Handle hGrd = new Handle();
         hGrd = GrdApi.GrdCreateHandle(hGrd, GrdCHM.MultiThread);
         if (hGrd.Address == 0)               // Some error found?
            HandleResult(GrdE.MemoryAllocation);

         retCode = GrdApi.GrdSetAccessCodes(hGrd, publicCode, readCode, writeCode, masterCode);
         HandleResult(retCode);

         retCode = GrdApi.GrdSetFindMode(hGrd, 
            GrdFMR.Local,// Local dongles only
            GrdFM.NProg | GrdFM.Ver | GrdFM.Type,// Check by bVer & dongle type flag
            programNumber,// check by specified program number        
            0, // Don't check by dongle id
            0, // Don't check by serial
            versionNumber, //  check by version
            0, // Don't check by bit mask
            GrdDT.GSII64, // Dongle that supports GSII64 algorithm   
            GrdFMM.ALL, // Guardant Stealth III dongle
            GrdFMI.ALL);
         HandleResult(retCode);
         
         uint id;
         FindInfo info;
         retCode = GrdApi.GrdFind(hGrd, GrdF.First, out id, out info);
         HandleResult(retCode);

         int LMS = -1; // don't use license management system
         retCode = GrdApi.GrdLogin(hGrd, LMS, GrdLM.PerStation);
         HandleResult(retCode);
         
         retCode = GrdApi.GrdCloseHandle(hGrd);
         HandleResult(retCode);
      }

      private void HandleResult(GrdE nRet)
      {
         if (nRet != GrdE.OK)
            throw new Exception(string.Format("{0}:{1}",nRet, GrdApi.PrintResult((int)nRet)));
      }

Вызов GrdApi.GrdFind возаращает AllDonglesFound.

Однако улилита диагностики говорит, что поиск проходит успешно. Результат работы утилиты "Диагностика ключей Guardant":

Диагностика установленных ключей Guardant 17.06.2011 10:26:12 
  
Модель Guardant Time USB 
Идентификационный номер ########## 
Коды доступа ENRAUPD 
Дата и время выпуска 03 Apr 2009 13:19:18 
Поддержка Windows, GSII64, PI, TRU, RTC, AES, ECC 
Время в ключе (в момент поиска) 17 Jun 2011 10:26:08 
Создание дескриптора ключа (GrdCreateHandle) Успешно 
Установка режима поиска ключа (GrdSetFindMode) Успешно 
Поиск ключа (GrdFind) Успешно 
Установка кодов доступа (GrdSetAccessCodes) Успешно 
Подключение к ключу (GrdLogin) Успешно 
Считывание таблицы LMS (GrdPI_Read/GrdRead) Для данного алгоритма/ячейки 
                                            не предусмотрен данный вид сервиса 
Проверка ключа (GrdCheck) Успешно 
Блокирование ключа (GrdLock) Успешно 
Чтение данных из ключа (GrdRead) Успешно 
Разблокирование ключа (GrdUnlock) Успешно 
Освобождение ключа (GrdLogout) Успешно 
Удаление дескриптора ключа (GrdCloseHandle) Успешно 

Подскажите пожалуйста, как необходимо изменить код, чтобы поддержить работу через AnywhereUSB?

Re: Доступ к ключам через AnywhereUSB

Информация по устройству
https://forum.guardant.ru/uploads/legacy/0/0/243/thumb/p162e6i2e4op47ium2oms37591.png

Re: Доступ к ключам через AnywhereUSB

Вопрос снимается, обнаружил, что если вызывать SetAccessCodes после Find, то всё нормально работает.

         uint publicCode = ###;
         uint readCode = ###;
         uint writeCode = ###;
         uint masterCode = ###;
         uint programNumber = 0;
         uint versionNumber = 1;
         var retCode = GrdApi.GrdStartup(GrdFMR.Local);
         Assert.AreEqual(retCode, GrdE.OK, GrdApi.PrintResult((int)retCode));
         Handle hGrd = new Handle();
         hGrd = GrdApi.GrdCreateHandle(hGrd, GrdCHM.MultiThread);
         Assert.AreNotEqual(hGrd.Address, 0, GrdApi.PrintResult((int)GrdE.MemoryAllocation));

         retCode = GrdApi.GrdSetFindMode(hGrd, GrdFMR.Local,// Local dongles only
            GrdFM.NProg | GrdFM.Ver | GrdFM.Type,// Check by bVer & dongle type flag
               programNumber,// check by specified program number        
               0, // Don't check by dongle id
               0, // Don't check by serial
               versionNumber, //  check by version
               0, // Don't check by bit mask
               GrdDT.GSII64, // Dongle that supports GSII64 algorithm   
               GrdFMM.ALL, // Guardant Stealth III dongle
               GrdFMI.ALL);
         uint id;
         FindInfo info;
         retCode = GrdApi.GrdFind(hGrd, GrdF.First, out id, out info);
         Assert.AreEqual(retCode, GrdE.OK, GrdApi.PrintResult((int)retCode));


         retCode = GrdApi.GrdSetAccessCodes(hGrd, publicCode, readCode, writeCode, masterCode);
         Assert.AreEqual(retCode, GrdE.OK, GrdApi.PrintResult((int)retCode));

         int LMS = -1; // don't use license management system
         retCode = GrdApi.GrdLogin(hGrd, LMS, GrdLM.PerStation);
         Assert.AreEqual(retCode, GrdE.OK, GrdApi.PrintResult((int)retCode));

         retCode = GrdApi.GrdLogout(hGrd);
         Assert.AreEqual(retCode, GrdE.OK, GrdApi.PrintResult((int)retCode));
         
         retCode = GrdApi.GrdCloseHandle(hGrd);
         Assert.AreEqual(retCode, GrdE.OK, GrdApi.PrintResult((int)retCode));

         retCode = GrdApi.GrdCleanup();
         Assert.AreEqual(retCode, GrdE.OK, GrdApi.PrintResult((int)retCode));

Re: Доступ к ключам через AnywhereUSB

dsmirnov пишет:

....
Вызов GrdApi.GrdFind возаращает AllDonglesFound.
....

Если это поможет: в текущем релизе API, функция GrdFind работает не так, как описано в документации. А именно, в документации заявлено: "Если не будет найдено ни одного ключа, удовлетворяющего критериям поиска, функция вернет ошибку GrdE_DongleNotFound". На самом деле, при запуске программы без подключеных ключей, эта функция возвращает ошибку GrdE_AllDonglesFound.

Re: Доступ к ключам через AnywhereUSB

Добрый день, dsmirnov!

Порядок вызова GrdFind() и GrdSetAccessCodes() в общем случае не должен влиять на результат поиска ключей. Эти функции лишь задают в различных полях hGrd критерии поиска ключей, используемых одинаковым образом при GrdFind() и GrdLogin().

Возможно, проблема заключалась в функции обработки ошибок, либо в неверно заданных кодах доступа.

romik,
Да, в процессе поиска ключей ситуации "Все ключи найдены" и "Более ни одного ключа не найдено" было принято считать эквивалентными.

Re: Доступ к ключам через AnywhereUSB

Будьте внимательны также, при таком порядке вызова функций (GrdSetFind, GrdFind, GrdSetAccessCodes, GrdLogin (как указано во втором Вашем коде) при вызове GrdFind будут найдены все возможные ключи Guardant, удовлетворяющие критериям поиска GrdSetFindMode, с любыми кодами доступа (в т.ч. не Вашими), в то время как логин будет производиться только в ключи кодами доступа, заданными GrdSetAccessCodes.

Т.О. Может возникнуть ситуация, когда будут найдены ключи, логин в которые сделать будет нельзя.

Поэтому рекомендуется все же вызывать GrdSetAccessCodes перед GrdFind. Также отмечу, что вызов GrdFind, вообще говоря, необязателен.