Я реализую библиотеку PKCS # 11, которая будет общаться с кард-ридерами, используя winscard в окнах и PCSC в MAC.
Я использую следующий пример кода, чтобы получить статус изменения карты от читателей.
Он отлично работает в MAC и возвращает 0x0122 для dwEventState.
Но в окнах SCardGetStatusChange всегда возвращает 6 и dwEventState не изменилось.
Хотя SCardConnect успешно соединяется с ридером в windows и возвращает дескриптор карты.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#else
#include <winscard.h>
#endif
int printResult (char *s, int rv){
printf("%s %x \n", s, rv);
return 0;
}
int main(void)
{
LONG rv;
SCARDCONTEXT hContext;
LPTSTR mszReaders , pReader;
SCARDHANDLE hCard;
DWORD dwReaders, dwActiveProtocol;
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
printResult("SCardEstablishContext", rv);
#ifdef SCARD_AUTOALLOCATE
dwReaders = SCARD_AUTOALLOCATE;
rv = SCardListReaders(hContext, NULL, (LPTSTR)&mszReaders, &dwReaders);
printResult("SCardListReaders", rv);
#else
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
printResult("SCardListReaders", rv)
mszReaders = calloc(dwReaders, sizeof(char));
rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
printResult("SCardListReaders", rv)
#endif
int count = 0;
switch( rv )
{
case SCARD_E_NO_READERS_AVAILABLE:
printf("Reader is not in groups.\n");
// Take appropriate action.
// ...
break;
case SCARD_S_SUCCESS:
{
pReader = mszReaders;
while ( 0 != *pReader )
{
++count;
printf("Reader: %s\n", pReader );
rv = SCardConnect(hContext, pReader, SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
printResult("SCardConnect", rv);
if (rv == SCARD_S_SUCCESS){
SCARD_READERSTATE rgReaderStates;
rgReaderStates.dwEventState = 0;
rgReaderStates.dwCurrentState = SCARD_STATE_UNAWARE;
rgReaderStates.szReader = pReader;
// rgReaderStates.szReader = "OMNIKEY CardMan 3x21 0";
rv = SCardGetStatusChange(hCard, 0, &rgReaderStates, 2);
printf("CurrentState : 0x%08lX Event State : 0x%08lX RV=%ld\n", rgReaderStates.dwCurrentState, rgReaderStates.dwEventState, rv);
}
// Advance to the next value.
pReader = pReader + strlen(pReader) + 1;
}
printf("Number of readers %d\n",count);
// printf("reader name: %s\n", mszReaders[1]);
// Free the memory.
break;
}
default:
printf("Failed SCardListReaders\n");
// Take appropriate action.
// ...
break;
}
rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);
printResult("SCardDisconnect", rv);
#ifdef SCARD_AUTOALLOCATE
rv = SCardFreeMemory(hContext, mszReaders);
printResult("SCardFreeMemory", rv);
#else
free(mszReaders);
#endif
rv = SCardReleaseContext(hContext);
printResult("SCardReleaseContext", rv);
return 0;
}
Вывод кода выглядит следующим образом
SCardEstablishContext 0
SCardListReaders 0
Reader: OMNIKEY CardMan 3x21 0
SCardConnect 0
CurrentState : 0x00000000 Event State : 0x00000000 RV=6
Reader: OMNIKEY CardMan 3x21 1
SCardConnect 0
CurrentState : 0x00000000 Event State : 0x00000000 RV=6
Number of readers 2
SCardDisconnect 0
SCardFreeMemory 0
SCardReleaseContext 0
Пожалуйста помоги.
У меня ошибка в моем источнике
rv = SCardGetStatusChange(hCard, 0, &rgReaderStates, 2);
hCard следует заменить на hContext
rv = SCardGetStatusChange(hContext, 0, &rgReaderStates, 2);
Не знаю, почему это обеспечивает точный вывод на MAC
Других решений пока нет …