Я пытаюсь просто проверить наличие смарт-карты в Windows. Цель состоит в том, чтобы запустить «демон», который будет выполнять действие всякий раз (и на время), когда карта вставлена.
У меня нет опыта работы с вещами такого рода. Я прочитал документацию по SCardStatus и тому подобное, но я не понимаю, как работает весь API, поэтому я немного растерялся.
Для меня было бы очень полезно, если бы у кого-то был очень простой пример полной программы, которая просто проверяет наличие карты (желательно на C ++, но я возьму то, что смогу получить!). Я был бы очень признателен. Мне не нужен какой-либо статус карты, кроме того, который существует. Спасибо!
Решение
Если вы работаете в Windows, вам нужно использовать WinSCard API, если вы используете Unix, то используйте PCSC. Эти два API очень похожи из-за стандартов, но WinSCard API намного больше и дает гораздо больше функций для использования. Эти два API реализованы на языке C, но вы можете легко обернуть их в C ++. Я просто хочу указать, что если вы собираетесь обернуть эти два API в C ++, чтобы использовать их когда-либо в Windows И в Unix, взгляните на числовые значения протоколов смарт-карт, они отличаются на этих платформах.
Комплексное решение по управлению доступом: smart-карты, биометрия, СКУД, Identity Management
Вам необходимо установить контекст (это все равно, что создать менеджер смарт-карт)
SCardEstablishContext
Он принимает 4 параметра, но для базового использования вам нужны только 2, область действия и указатель на контекстный дескриптор.
LPSCARDCONTEXT hSCardContext = NULL; int ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, if (ret != ERROR_SUCCES) . // handle error
Смарт-карты сгруппированы в разные группы. Так что есть функции для работы с группами, для ее создания и так далее.
Чтобы получить список читателей (для базовых приложений вам действительно не нужны группы)
SCardListReaders
Требуется 4 параметра, контекст, указатель на группу, указатель на читателей и указатель на количество читателей
Вы можете использовать это Lise это
char *szGroups = NULL; long readers = 0; int res = SCardListReaders(hSCardContext, szGroups, NULL, // handle errors
вы читаете счет в первую очередь. Теперь вы можете выделить память для реальных читателей.
szReaders = (char *) malloc(sizeof(char) * readers); int res = SCardListReaders(hSCardContext, szGroups, szReaders ,
Теперь у вас есть список подключенных читателей.
Вы можете подключиться к читателю так
LPSCARDHANDLE hSCard = NULL; long activeProtocols = 0; int ret = SCardConnect(hSCardContext, myReader, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_TX, activeProtocols); // .. handle errors
укажите протоколы, режим совместного использования, используйте SCARD_SHARE_EXCLUSIVE для режима совместного использования, если вы работаете с конфиденциальными данными, которые нуждаются в защите, чтобы ОС не взаимодействовала с транзакциями.
Еще раз, если вы переносите для окон и Unix (Unix не имеет протокола SCARD_PROTOCOL_TX), но это представление этих двух SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1.
Токены или смарт-карты не доступны. Как восстановить работу?
myReader — это имя подключенного читателя. подобно (LPCTSTR)»Dermalog LF10″
эти имена читателей вы получаете из функции SCardListReaders.
Теперь вы связаны с картой. при совместном использовании SCARD_SHARE_EXCLUSIVE не забудьте освободить контекст смарт-карты, потому что он заблокируется.
использование SCardDisconnect для отключения требуется 2 параметра, дескриптор SmartCard и расположение, для базового приложения расположение SCARD_LEAVE_CARD должно быть в порядке. Он указывает, что вы не хотите делать что-то особенное с картой, не хотите извлекать или что-то еще.
Транзакции являются более сложными, потому что вам нужно знать стандарты SCard, а что нет. Но я охватил основы.
Имейте в виду, что этот код может не компилироваться, вам нужно улучшать типы, для окон вам нужно преобразовывать эти типы в типы WinAPI, такие как LPCTSTR, чтобы он не жаловался, а в Unix таких типов нет, поэтому вам нужно также обойти эти проблемы ,
Другие решения
В этом примере кода предполагается, что устройства для чтения карт памяти подключены с самого начала, он не поддерживает изменение количества устройств для чтения карт.
Помимо этого, он просто спамит консоль со вставленным / не вставленным статусом карточек.
Пожалуйста, не используйте это как есть в производственном коде, большая часть проверки ошибок опущена, и некоторые сокращения используются для того, чтобы код был коротким (ish).
#pragma comment(lib, «winscard.lib») #include bool test() < DWORD dwReaders; LPSTR szReaders = NULL; SCARDCONTEXT hContext; bool bRunning = true; std::vectorcards; LONG status = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, if( status != SCARD_S_SUCCESS ) < return false; >dwReaders = SCARD_AUTOALLOCATE; if( SCardListReadersA(hContext, NULL, (LPSTR)dwReaders) == SCARD_S_SUCCESS ) < LPSTR reader = szReaders; while (reader != NULL *reader != ‘