DLL or LIB source code

Все, что касается электронных ключей SenseLock, но не попадает по тематике в остальные форумы раздела

DLL or LIB source code

Сообщение swd » Чт, 20 мар 2014 09:54

Ищется исходники для компиляции библиотек сенселок.
Причина банальна, все приведенное в SDK не работает :)
Получилось только прицепить саму DLL но и там не обходиться без сюрпризов, к примеру:
Код: Выделить всё
S4Control(&sl_ctx[ndev], S4_RESET_DEVICE, NULL, 0, NULL, 0, NULL );

выход с ошибкой ffffffff
Спасибо.
PS:
QT 4.7
swd
 
Сообщения: 14
Зарегистрирован: Вт, 06 авг 2013 11:57

Re: DLL or LIB source code

Сообщение Anton » Чт, 20 мар 2014 12:08

Сообщите более конкретнее, что не работает и где?
Так-же продублируйте на lock@senselock.ru
Anton
Site Admin
 
Сообщения: 195
Зарегистрирован: Пт, 06 апр 2007 15:32

Re: DLL or LIB source code

Сообщение swd » Чт, 20 мар 2014 21:10

Qt 4.7
файл проекта
Код: Выделить всё
LIBS += -L./lib -lSense4ST
INCLUDEPATH +=    ./lib

файл *.cpp
Код: Выделить всё
#include "sense4.h"

соотв в проекте создана папка lib в которую помещен файлы Sense4ST.lib sense4.h
в процессе компиляции имеем
Код: Выделить всё
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib /defaultlib:setupapi.lib ' unrecognized
Warning: .drectve `-defaultlib:LIBC ' unrecognized
Warning: .drectve `-defaultlib:OLDNAMES ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:LIBC ' unrecognized
Warning: .drectve `-defaultlib:OLDNAMES ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib /defaultlib:setupapi.lib ' unrecognized
Warning: .drectve `-defaultlib:LIBC ' unrecognized
Warning: .drectve `-defaultlib:OLDNAMES ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:LIBC ' unrecognized
Warning: .drectve `-defaultlib:OLDNAMES ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:LIBC ' unrecognized
Warning: .drectve `-defaultlib:OLDNAMES ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib ' unrecognized
Warning: .drectve `-defaultlib:uuid.lib /defaultlib:setupapi.lib ' unrecognized
Warning: .drectve `-defaultlib:LIBC ' unrecognized
Warning: .drectve `-defaultlib:OLDNAMES ' unrecognized
./lib/Sense4ST.lib(./Release/sense4.obj):D:\work\sourcesafe:(.text[_S4Enum@8]+0x11): undefined reference to `_except_list'
./lib/Sense4ST.lib(./Release/sense4.obj):D:\work\sourcesafe:(.text[_S4Enum@8]+0x19): undefined reference to `_except_list'
./lib/Sense4ST.lib(./Release/sense4.obj):D:\work\sourcesafe:(.text[_S4Enum@8]+0x44): undefined reference to `_except_list'
./lib/Sense4ST.lib(./Release/sense4.obj):D:\work\sourcesafe:(.text[_S4Enum@8]+0xe7): undefined reference to `_except_list'
./lib/Sense4ST.lib(./Release/sense4.obj):D:\work\sourcesafe:(.text[_S4Open@4]+0x11): undefined reference to `_except_list'
./lib/Sense4ST.lib(./Release/sense4.obj):D:\work\sourcesafe:(.text[_S4Open@4]+0x19): more undefined references to `_except_list' follow
./lib/Sense4ST.lib(./Release/usbcomm.obj):E:\itoken\itoken3\:(.text[__SU_GetDeviceList]+0x8a): undefined reference to `_imp__SetupDiGetClassDevsA@16'
./lib/Sense4ST.lib(./Release/usbcomm.obj):E:\itoken\itoken3\:(.text[__SU_GetDeviceList]+0xf3): undefined reference to `_imp__SetupDiEnumDeviceInfo@12'
./lib/Sense4ST.lib(./Release/usbcomm.obj):E:\itoken\itoken3\:(.text[__SU_GetDeviceList]+0x106): undefined reference to `_imp__SetupDiGetDeviceRegistryPropertyA@28'
./lib/Sense4ST.lib(./Release/usbcomm.obj):E:\itoken\itoken3\:(.text[__SU_GetDeviceList]+0x236): undefined reference to `_imp__SetupDiDestroyDeviceInfoList@4'
./lib/Sense4ST.lib(./Release/usbcomm.obj):E:\itoken\itoken3\:(.text[__SU_GetDeviceList]+0x271): undefined reference to `_imp__SetupDiDestroyDeviceInfoList@4'
collect2: ld returned 1 exit status
mingw32-make[1]: *** [debug\tiris_rw.exe] Error 1
mingw32-make: *** [debug] Error 2
Процесс «C:\QtSDK\mingw\bin\mingw32-make.exe» завершился с кодом 2.

откладываем статические библиотеки, и пробуем подключить sense4.dll
Код: Выделить всё
//подключаем заголовки
#include "sense4.h"
#include <QLibrary>
// опеределение переменных
typedef DWORD (__cdecl *pS4Enum) (SENSE4_CONTEXT *pS4CtxList, DWORD *pdwCtxListSize);
QLibrary* slockLib;
pS4Enum         S4Enum         = NULL;
//в конструкторе
slockLib = new QLibrary("sense4", parent);
slockLib->load();
if (slockLib->isLoaded())
{
    S4Enum = (pS4Enum)slockLib->resolve("S4Enum");
}
// тестовая функция
PSENSE4_CONTEXT Enum(void)
{
   unsigned long err = S4_SUCCESS, ndev, Len;
   BYTE SN[250] = {0,0,0,0,0,0,0,0};
   S4OPENINFO oi;
   //if (!LoadLib) return NULL;
   ctx_size = 0;
   if (err = S4Enum(NULL, &ctx_size), err != S4_INSUFFICIENT_BUFFER) return NULL; // определение размера контекста
   sl_ctx = (PSENSE4_CONTEXT)new char[ctx_size];
   if (err = S4Enum(sl_ctx, &ctx_size), err != S4_SUCCESS) return NULL;
   // пробежка по всем подключенным устройствам
   for(ndev = 0 ; ndev < ctx_size/sizeof(SENSE4_CONTEXT); ndev ++ )
   {
      oi.dwS4OpenInfoSize = sizeof(S4OPENINFO);
      oi.dwShareMode = S4_SHARE_MODE;
      //open the specified device
      err = S4OpenEx(&sl_ctx[ndev], &oi);
      if(err != S4_SUCCESS) return NULL;
      err = S4ChangeDir((PSENSE4_CONTEXT)&sl_ctx[ndev], "\\" );
      if(err != S4_SUCCESS) return NULL;
      err = S4VerifyPin(&sl_ctx[ndev], (BYTE*)"12345678", 8, S4_USER_PIN);
      if(err != S4_SUCCESS) return NULL;
      err = S4Control(&sl_ctx[ndev], S4_GET_SERIAL_NUMBER, SN, 0, SN, 8, &Len );
      if(err != S4_SUCCESS) return NULL;
      Len = 0;
      err = S4Control(&sl_ctx[ndev], S4_LED_DOWN, SN, 0, SN, 0, &Len);
      Len = 0;
      err = S4Control(&sl_ctx[ndev], S4_LED_UP, SN, 0, SN, 0, &Len);
      Len = 0;
      err = S4Control(&sl_ctx[ndev], S4_RESET_DEVICE, SN, 0, SN, 0, &Len );
      if(err != S4_SUCCESS) return NULL;
      return &sl_ctx[ndev];
   }
   return NULL;
}

в итоге серийник читается, но это единственное что работает.
Код: Выделить всё
err = S4Control(&sl_ctx[ndev], S4_LED_DOWN, SN, 0, SN, 0, &Len)

по непонятным причинам SN заполняется данными, хотя не должен.
то же касается и
Код: Выделить всё
err = S4Control(&sl_ctx[ndev], S4_RESET_DEVICE, SN, 0, SN, 0, &Len );

после выполнения функции
Len = 0x17;
SN - содержит ATR и нули
err = 0xffffffff;
если делать по форме
Код: Выделить всё
err = S4Control(&sl_ctx[ndev], S4_RESET_DEVICE, NULL, 0, NULL, 0, NULL );

то, как вы понимаете, Access violation потому что нельзя писать в ячейку памяти 0 данные.

Интересует конечно работа со статической библиотекой, DLL взял как выход из ситуации ...
на почту так же продублировал.
Спасибо.
swd
 
Сообщения: 14
Зарегистрирован: Вт, 06 авг 2013 11:57

Re: DLL or LIB source code

Сообщение swd » Пт, 21 мар 2014 10:17

ответ саппорта.
Статическая библиотеку требует дополнительной линковки с libcmt.lib, oldnames.lib и setupapi.lib
S4_LED_DOWN и S4_RESET_DEVICE не используют параметры, поэтому вместо указателя на память необходимо передавать NULL в обоих параметрах. Правильно вызывать вот так:err = S4Control(&sl_ctx[ndev], S4_RESET_DEVICE, NULL, 0, NULL, 0, &Len);

И мой соответственно.
setupapi.lib я в студии 2008 не нашел. Остальные есть, но это ее личные библиотеки, и использование их как то некорректно ...
Поставим вопрос иначе, как использовать статическую линковку в компиляторе minGW GCC в среде QT4.7 так как примеры по этому поводу отсутствуют.
Что касается DLL то ваш ответ меня не устраивает, уж извините но:
в документации четко указанно что параметров на вход и на выход нет.
Но данные возвращаются после функций
Код: Выделить всё
      err = S4Control(&sl_ctx[ndev], S4_GET_SERIAL_NUMBER, SN, 0, SN, 8, &Len ); // вычитать серийник
      err = S4Control(&sl_ctx[ndev], S4_LED_DOWN, NULL, 0, NULL, 0, &Len); // вычитать серийник
      err = S4Control(&sl_ctx[ndev], S4_LED_UP, NULL, 0, NULL, 0, &Len); // вычитать серийник
      err = S4Control(&sl_ctx[ndev], S4_RESET_DEVICE, NULL, 0, NULL, 0, &Len ); // вычитать серийник

и если в случае с серийником все правильно, то в остальных случаях их там (буфер SN) быть не должно.
но они есть, и в случае с S4_RESET_DEVICE их 23 байта. И попадая в буфер SN они его явно переполняют, что приводит к нелигитимной :) записи в другие адреса. Даже притом что параметр S4_RESET_DEVICE стоит NULL возврат данных все равно идет в этот SN, так как ранее указатель на нее был передан. считаю что проблема именно в DLL так как в VS2008 со статической библиотекой все в норме.
Спасибо.
PS:
Может проблем было бы меньше если ваша фирма предоставила бы разработчикам возможность работы с ключем на аппаратном уровне, к примеру с использованием libusb доступной как в unix так и в window системах. Ну или привела бы исходники для компиляции библиотек для тех случаев когда примеры отсутствуют.
swd
 
Сообщения: 14
Зарегистрирован: Вт, 06 авг 2013 11:57

Re: DLL or LIB source code

Сообщение hijaq » Сб, 22 мар 2014 04:20

Скопирую ответ сюда тоже, но в дальнейшем предлагаю выбрать всё же какое-то одно (на ваш выбор) место для обсуждения этого вопроса.

По большому счёту Sense4ST.lib использовать с mingw тоже не корректно, так как она создана для cl, а не gcc и, что логично, использует библиотеки от MS. Статическая линковка с mingw gcc официально не поддерживается.

По поводу параметров - я согласен, это не корректное поведение и спасибо что указали на это. Со своей стороны могу сказать, что с 2007 года вы первый, кто с этим столкнулся и о таком поведении просто не было известно, т.к. видимо никто до этого не запускал S4Control() с передачей указателей на память там, где они передаваться не должны. Мы обязательно передадим разработчику о таком поведении функции чтобы они это исправили, но вы со своей стороны тоже постарайтесь не заниматься настойчиво стрельбой в ногу там, где это делать не обязательно =)

Вопрос передачи низкоуровневых протоколов - это разговор отдельный и только для исключительных случаев. И, к сожалению, я не думаю что библиотека для Windows будет переписываться на использование libusb в какое-то обозримое будущее.
hijaq
Site Admin
 
Сообщения: 213
Зарегистрирован: Пт, 06 апр 2007 14:50

Re: DLL or LIB source code

Сообщение swd » Сб, 22 мар 2014 12:10

Хорошо, будем обсуждать тут. все таки больше людей его смотрят, и вероятно кто то уже с подобным имел дело.
Да и оформить ответ можно более информативно, равно как и понять суть проблемы.
Статическая линковка с mingw gcc официально не поддерживается.

1. Если официально она не поддерживается, то это как то должно быть указано, уж точно я не первый кто с 2007 года использует minGW.
постарайтесь не заниматься настойчиво стрельбой в ногу там, где это делать не обязательно =)

2. Никакой беспорядочной стрельбы, все в пределах документации.
Все функции вызываются из dll, надеюсь в правильности их подключения (приведенное в предыдущем посте) сомнений не возникает.
Код: Выделить всё
unsigned long err = S4_SUCCESS, ndev, Len, i;
BYTE SN[250];
S4OPENINFO oi;
if (!LoadLib) return NULL;
ctx_size = 0;
if (err = S4Enum(NULL, &ctx_size), err != S4_INSUFFICIENT_BUFFER) return NULL; // определение размера контекста
sl_ctx = (PSENSE4_CONTEXT)new char[ctx_size];
if (err = S4Enum(sl_ctx, &ctx_size), err != S4_SUCCESS) return NULL;
ndev = 0; // пока он у нас единственный
oi.dwS4OpenInfoSize = sizeof(S4OPENINFO);
oi.dwShareMode = S4_SHARE_MODE;
//open the specified device
err = S4OpenEx(&sl_ctx[ndev], &oi);
if(err != S4_SUCCESS) return NULL;
err = S4ChangeDir((PSENSE4_CONTEXT)&sl_ctx[ndev], "\\" );
if(err != S4_SUCCESS) return NULL;
err = S4VerifyPin(&sl_ctx[ndev], (BYTE*)"12345678", 8, S4_USER_PIN);
if(err != S4_SUCCESS) return NULL;

тут пока подготовка, проблем в работе не выявлено.
BYTE SN[250]; выделено исключительно в демонстрационных целях из расчета размера коммуникационного буфера, нормальный размер буфера 8.
Код: Выделить всё
for (i = 0; i < 250; i++) SN[i] = 0xff;
err = S4Control(&sl_ctx[ndev], S4_GET_SERIAL_NUMBER, SN, 0, SN, 8, &Len ); // вычитать серийник

а вот что после выполнения функции на самом деле
Изображение
Как видите, серийник был передан, это полезная часть функции, но реально возвращено 22 байта
а это значит, что если буфер SN будет 8 байт, то еще 14 байт перезапишут какие нибудь переменные, или стек ... как повезет.
едем дальше
Код: Выделить всё
Len = 0;
for (i = 0; i < 250; i++) SN[i] = 0xff;
err = S4Control(&sl_ctx[ndev], S4_LED_DOWN, NULL, 0, NULL, 0, &Len); // погасить светодиод

казалось бы ну что может быть проще, ан нет, вот ответ
Изображение
имеем 50 байт в буфере SN.
кстати обратите внимание на параметры, по всем указателям стоит NULL а буфер SN меняется.
давайте так же предположим, что компилятор minGW работает правильно, и как такое возможно ?
предполагаю что все таки возможно .... выглядит это в dll примерно так:
Код: Выделить всё
// глобальные переменные
char *inBuff = NULL;
char *outBuff = NULL;
int nIN = 0;
int nOUT = 0;
// и в функции Control
S4Control(&sl_ctx[ndev], S4_GET_SERIAL_NUMBER, ptrIN, bIN, ptrOUT, bOUT, &Len )
{
    if (ptrIN != NULL) inBuff = ptrIN;
    if (ptrOUT != NULL) outBuff = ptrOUT;
    nIN = bIn;
    nOUT = bOUT;
   .......
   .......
   .......
}

таким образом вызвав однажды функцию с параметрами значение входного и выходного указателя на буфера уже установлены, и во всех остальных вызовах без параметров они не равны NULL.
ну а мы тем временем продолжаем и вновь зажигаем светодиод
Код: Выделить всё
Len = 0;
for (i = 0; i < 250; i++) SN[i] = 0xff;
err = S4Control(&sl_ctx[ndev], S4_LED_UP, NULL, 0, NULL, 0, &Len); // зажигаем светодиод

а вот что после вызова.
Изображение
уже 78 байт.
ну и наконец сбросим ключ
Код: Выделить всё
Len = 0;
for (i = 0; i < 250; i++) SN[i] = 0xff;
err = S4Control(&sl_ctx[ndev], S4_RESET_DEVICE, NULL, 0, NULL, 0, &Len ); // ресет

и вот результат
Изображение
к сожалению скромный размер монитора не позволяет мне показать весь буфер, но в начале передается ATR и что то там еще.
Мы обязательно передадим разработчику о таком поведении функции чтобы они это исправили

Спасибо, надеюсь описанное выше его убедит в этом.
к выше приведенному добавлю, что если многократно повторять включение светодиода, (биться головой о стенку) то буфера 250 байт не хватит, ибо оно в него со смещением постоянно пишет, и никаких проверок выхода за граничные параметры так же не предусмотрены (стена все таки ломается).
но вы со своей стороны тоже постарайтесь не заниматься настойчиво стрельбой в ногу там, где это делать не обязательно =)

и пожалуйста, не отстреливайте ему конечности, они еще приходятся :)
не думаю что библиотека для Windows будет переписываться на использование libusb в какое-то обозримое будущее.

это был просто как вариант, по сути при большом желании все это можно сделать и самому, другой вопрос зачем если все уже сделано, нужно только доработать напильником.
В приложении добавил переработанный sense4.h и пару файлов для удобного использования DLL в minGW, надеюсь кому то они будут полезными, потому как
Статическая линковка с mingw gcc официально не поддерживается.

и так же надеюсь, что это временно :)
Спасибо.
Вложения
minGW_dll.rar
(6.89 Кб) Скачиваний: 512
swd
 
Сообщения: 14
Зарегистрирован: Вт, 06 авг 2013 11:57

Re: DLL or LIB source code

Сообщение hijaq » Вс, 23 мар 2014 04:44

Я с mingw ещё не смотрел, но подозреваю, что эти игры со стеком - какие-то особенности непосредственно mingw или связки mingw+Qt. При использовании dll из msvc никаких записей в неположенное место в стеке не происходит (было выделено 250 байт и заполнено 0xFF, вызов функции - S4Control(&ctx, S4_GET_SERIAL_NUMBER, &sn, 8, &sn, 8, &ret)):
Изображение

Тоже самое происходит и если вызывать S4Control(&ctx, S4_GET_SERIAL_NUMBER, NULL, 0, &sn, 8, &ret) и при вызове других контрольных кодов.

Если вы пришлёте мне на почту какой-то минимальный запускаемый проект (включая sense4.dll), который воспроизводит эту ошибку - это немного ускорит процесс. На сколько я понимаю, версия Qt - 4.8, mingw - который идёт в стандартной к нему комплектации?
hijaq
Site Admin
 
Сообщения: 213
Зарегистрирован: Пт, 06 апр 2007 14:50

Re: DLL or LIB source code

Сообщение swd » Вс, 23 мар 2014 11:41

Я с mingw ещё не смотрел, но подозреваю, что эти игры со стеком - какие-то особенности непосредственно mingw или связки mingw+Qt. При использовании dll из msvc никаких записей в неположенное место в стеке не происходит (было выделено 250 байт и заполнено 0xFF, вызов функции - S4Control(&ctx, S4_GET_SERIAL_NUMBER, &sn, 8, &sn, 8, &ret)):

может проблема связана с соглашениями о вызовах ... ?
письмо постоянно возвращается, даже с паролем в архиве, на всякий случай вот ссылка на QT 4.7.4. 1,5 гб
https://www.dropbox.com/s/0u3mqek3rphf3 ... 1_3_en.exe
будет доступна пару дней..
Спасибо.
Вложения
libtest.rar
(340.97 Кб) Скачиваний: 522
swd
 
Сообщения: 14
Зарегистрирован: Вт, 06 авг 2013 11:57

Re: DLL or LIB source code

Сообщение hijaq » Вс, 23 мар 2014 20:04

Поменяйте __cdecl на __stdcall
hijaq
Site Admin
 
Сообщения: 213
Зарегистрирован: Пт, 06 апр 2007 14:50

Re: DLL or LIB source code

Сообщение swd » Вс, 23 мар 2014 20:36

Огромное Спасибо.
Все заработало.
swd
 
Сообщения: 14
Зарегистрирован: Вт, 06 авг 2013 11:57


Вернуться в Разное

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

cron