#include "internal.h" #include "VirtualSCReader.h" #include "reader.h" #include "device.h" #include #include "memory.h" #include #include "sectionLocker.h" #include "../../src/vpcd/vpcd.h" int VpcdReader::portBase; VpcdReader::VpcdReader() { rpcType=2; state = SCARD_ABSENT; cardPresent = false; InitializeCriticalSection(&ioSection); } VpcdReader::~VpcdReader() { DeleteCriticalSection(&ioSection); } void VpcdReader::init(wchar_t *section) { portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",VPCDPORT,L"BixVReader.ini"); port=(short) GetPrivateProfileInt(section,L"TCP_PORT",portBase+instance,L"BixVReader.ini"); } bool VpcdReader::CheckATR() { bool r = false; { SectionLocker lock(ioSection); if (vicc_present((struct vicc_ctx *) ctx) == 1) { r = true; } } if (r) { signalInsertion(); } else { signalRemoval(); } return r; } bool VpcdReader::QueryTransmit(BYTE *APDU,int APDUlen,BYTE *Resp,int *Resplen) { unsigned char *rapdu = NULL; ssize_t rapdu_len; bool r = false; if (APDU && APDUlen && Resp && Resplen) { { SectionLocker lock(ioSection); rapdu_len = vicc_transmit((struct vicc_ctx *) ctx, APDUlen, APDU, &rapdu); } if (rapdu_len > 0) { memcpy(Resp, rapdu, rapdu_len); *Resplen = rapdu_len; free(rapdu); r = true; } else { signalRemoval(); } } return r; } bool VpcdReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) { unsigned char *atr = NULL; int atr_len; bool r = false; if (ATR && ATRsize) { { SectionLocker lock(ioSection); atr_len = vicc_getatr((struct vicc_ctx *) ctx, &atr); } if (atr_len > 0) { /* TODO do length checking on length of ATR when ATRsize is * correctly initialized by Reader.cpp */ memcpy(ATR, atr, atr_len); *ATRsize = atr_len; free(atr); r = true; if (reset) { SectionLocker lock(ioSection); vicc_reset((struct vicc_ctx *) ctx); } } else { signalRemoval(); } } return r; } DWORD VpcdReader::startServer() { breakSocket = false; { SectionLocker lock(ioSection); ctx = vicc_init(NULL, port); } while (!breakSocket) { CheckATR(); Sleep(1000); } return 0; } void VpcdReader::shutdown() { breakSocket=true; WaitForSingleObject(serverThread,10000); serverThread = NULL; { SectionLocker lock(ioSection); vicc_exit((struct vicc_ctx *) ctx); } state=SCARD_ABSENT; ctx = NULL; if (waitRemoveIpr!=NULL) { SectionLocker lock(device->m_RequestLock); if (waitRemoveIpr->UnmarkCancelable()==S_OK) waitRemoveIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED)); waitRemoveIpr=NULL; } if (waitInsertIpr!=NULL) { SectionLocker lock(device->m_RequestLock); if (waitInsertIpr->UnmarkCancelable()==S_OK) waitInsertIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED)); waitInsertIpr=NULL; } } void VpcdReader::signalRemoval(void) { if (cardPresent) { cardPresent = false; state=SCARD_ABSENT; if (waitRemoveIpr!=NULL) { SectionLocker lock(device->m_RequestLock); if (waitRemoveIpr->UnmarkCancelable()==S_OK) { waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0); } waitRemoveIpr=NULL; } if (waitInsertIpr!=NULL) { SectionLocker lock(device->m_RequestLock); if (waitInsertIpr->UnmarkCancelable()==S_OK) { waitInsertIpr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0); } waitInsertIpr=NULL; } } } void VpcdReader::signalInsertion(void) { if (!cardPresent) { cardPresent = true; if (waitInsertIpr!=NULL) { if (initProtocols()) { SectionLocker lock(device->m_RequestLock); if (waitInsertIpr->UnmarkCancelable()==S_OK) waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0); waitInsertIpr=NULL; state=SCARD_SWALLOWED; } } } }