SCardTransmit() всегда возвращает ошибку

Я работаю над бесконтактным считывателем RFID-карт SCM, используя ссылку API Microsoft SmartCard.

Как я понял, обычный процесс взаимодействия со смарт-картой:
1. Установить контекст с помощью SCardEstablishContext()
2. Вывести список всех считывателей, подключенных к системе, с помощью SCardListReaders()
3 .Выберите считыватель и подождите, пока в него будет вставлена ​​карта.
4. После обнаружения карты возвращается функция SCardGetStatusChange().
5. Подключитесь к карте через выбранный считыватель с помощью SCardConnect()< br> 6. Говорите с картой с помощью SCardTransmit()

Все шаги до 5 работают нормально, что означает, что я получил правильный дескриптор карты. Карта может быть дополнительно проверена с помощью функции SCardStatus(), которая возвращает согласованный протокол и ATR карты, что также является правильным. Но когда я пытаюсь отправить любую команду APDU с помощью SCardTransmit(), она возвращает ошибку (код ошибки 14, который, я думаю, SCARD_E_CANT_DISPOSE).

Я понятия не имею, что идет не так или чего не хватает. Я пробовал разные APDU, например. самый простой APDU для чтения UID карты путем выдачи {0xFF, 0xCA, 0x00, 0x00, 0x00}. Я проверил этот APDU с помощью инструмента отладки SCM TestResMan, и он возвращает мне правильный UID карты. Я использую карту MiFARE 1k и бесконтактный считыватель SCM SCL011.

Пожалуйста, найдите фрагмент кода SCardTransmit() ниже (все предыдущие функции вернули успех).

SCARD_IO_REQUEST sioreq;
sioreq.dwProtocol = 2; // SCARD_PROTOCOL_T1
sioreq.cbPciLength = 8;

SCARD_IO_REQUEST rioreq;
rioreq.dwProtocol = 2; // SCARD_PROTOCOL_T1
rioreq.cbPciLength = 8;

byte sendbuffer[256], receivebuffer[256];
ULONG sendbufferLen, receivebufferLen, sizeofUID;

sendbuffer[0] = 0xFF; // CLA - Instruction Class
sendbuffer[1] = 0xCA; // Instruction code
sendbuffer[2] = 0x00; // P1 - 1st parameter
sendbuffer[3] = 0x00; // P2 - 2nd parameter
sendbuffer[4] = 0x00;
sendbufferLen = 0x05;

retval = objScWrapper->SCardTransmit(hCardHandle, &sioreq, sendbuffer,
                                     sendbufferLen, NULL, receivebuffer, 
                                     &receivebufferLen);

Пожалуйста, дайте мне знать, если у кого-нибудь есть какие-либо подсказки или указатели...
TIA !!


person S.K.    schedule 03.02.2012    source источник


Ответы (2)


Размер вашего приемного буфера составляет 256 байт, но вы запрашиваете 256 байт (Le = 00h), и приемный буфер также ожидает слов состояния (состоящих из двух байтов, SW1 и SW2).

Поэтому я думаю, что ваш код ошибки 14 - это общий OUT_OF_MEMORY для приемного буфера.

Ваш командный буфер также слишком мал, чтобы вместить 5 байтов заголовка + макс. 255 байт данных команды. Конечно, оба они слишком малы для работы с ADPU увеличенной длины.

В настоящее время Windows довольно требовательна к размерам буфера считывателя смарт-карт для считывателей, совместимых с PCSC. Используйте не менее 5 + 255 = 260 байт для буфера команд и 256 + 2 байта для буфера приема. Повторно используйте буферы или безопасно избавьтесь от них, иначе у вас будет утечка памяти.

person Maarten Bodewes    schedule 15.03.2012

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

1) Когда вы подключаетесь через SCardConnect, вы подключаетесь с эксклюзивным, общим или прямым доступом? 2) Вы уверены, что при подключении к карте протокол, по которому подключена карта, - T1? 3) Какова цель SCARD_IO_REQUEST rioreq; строки в образце этот объект, кажется, не используется? 4) Я вижу, что вы проходите через оболочку, чтобы сделать вызов API. Вы можете поделиться внутренней реализацией SCardTrasmit в обертке?

Я отредактирую этот ответ на основе обновленного вопроса.

person Chris Evans    schedule 07.03.2012