I am implementing a PKCS#11 library which will communicate with card readers using winscard in windows and PCSC in MAC.
I am using the following sample code to get the card change status from readers. It works fine in MAC and returns 0x0122 for dwEventState. But in windows SCardGetStatusChange always returns 6 and dwEventState not changed.
Though SCardConnect successfully connect with the reader in windows and returns card handle.
#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;
}
Output of the code is as follows
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
Please help.
I have a mistake in my source
rv = SCardGetStatusChange(hCard, 0, &rgReaderStates, 2);
hCard should be replaced with hContext
rv = SCardGetStatusChange(hContext, 0, &rgReaderStates, 2);
Don't know why it provide accurate output on MAC