vpcd win32: fixed race condition

This commit is contained in:
Frank Morgner
2014-03-26 17:47:50 +01:00
parent a1131dd83a
commit 8f77abdc00
3 changed files with 48 additions and 93 deletions

View File

@@ -1,84 +1,9 @@
[Driver] [Driver]
NumReaders=12 NumReaders=1
[Reader0] [Reader0]
RPC_TYPE=0 RPC_TYPE=2
VENDOR_NAME=VirtualCard VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=BixReader VENDOR_IFD_TYPE=Virtual PCD
DECIVE_UNIT=0 TCP_PORT=35963
DECIVE_UNIT=0
[Reader1]
RPC_TYPE=1
VENDOR_NAME=VirtualCard
VENDOR_IFD_TYPE=BixReader
DECIVE_UNIT=1
[Reader2]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35963
DECIVE_UNIT=2
[Reader3]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35964
DECIVE_UNIT=3
[Reader4]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35965
DECIVE_UNIT=4
[Reader5]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35966
DECIVE_UNIT=5
[Reader6]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35967
DECIVE_UNIT=6
[Reader7]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35968
DECIVE_UNIT=7
[Reader8]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35969
DECIVE_UNIT=8
[Reader9]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35970
DECIVE_UNIT=9
[Reader10]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35971
DECIVE_UNIT=10
[Reader11]
RPC_TYPE=2
VENDOR_NAME=Virtual Smart Card Architecture
VENDOR_IFD_TYPE=Virtual PCD
TCP_PORT=35972
DECIVE_UNIT=11

View File

@@ -93,6 +93,7 @@ public:
bool cardPresent; bool cardPresent;
VpcdReader(); VpcdReader();
~VpcdReader();
bool QueryTransmit(BYTE *APDU,int APDUlen,BYTE *Resp,int *Resplen); bool QueryTransmit(BYTE *APDU,int APDUlen,BYTE *Resp,int *Resplen);
bool QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset=false); bool QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset=false);
bool CheckATR(); bool CheckATR();
@@ -101,4 +102,6 @@ public:
void init(wchar_t *section); void init(wchar_t *section);
void signalRemoval(void); void signalRemoval(void);
void signalInsertion(void); void signalInsertion(void);
CRITICAL_SECTION ioSection;
}; };

View File

@@ -13,8 +13,13 @@ int VpcdReader::portBase;
VpcdReader::VpcdReader() { VpcdReader::VpcdReader() {
rpcType=2; rpcType=2;
state=SCARD_ABSENT; state = SCARD_ABSENT;
cardPresent = false; cardPresent = false;
InitializeCriticalSection(&ioSection);
}
VpcdReader::~VpcdReader() {
DeleteCriticalSection(&ioSection);
} }
void VpcdReader::init(wchar_t *section) { void VpcdReader::init(wchar_t *section) {
portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",VPCDPORT,L"BixVReader.ini"); portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",VPCDPORT,L"BixVReader.ini");
@@ -24,12 +29,19 @@ void VpcdReader::init(wchar_t *section) {
bool VpcdReader::CheckATR() { bool VpcdReader::CheckATR() {
bool r = false; bool r = false;
struct vicc_ctx *vicc_ctx = (struct vicc_ctx *) ctx;
{
SectionLocker lock(ioSection);
if (vicc_present((struct vicc_ctx *) ctx) == 1) { if (vicc_present((struct vicc_ctx *) ctx) == 1) {
signalInsertion();
r = true; r = true;
} else { }
}
if (r) {
signalInsertion();
}
else {
signalRemoval(); signalRemoval();
} }
@@ -41,7 +53,10 @@ bool VpcdReader::QueryTransmit(BYTE *APDU,int APDUlen,BYTE *Resp,int *Resplen) {
bool r = false; bool r = false;
if (APDU && APDUlen && Resp && Resplen) { if (APDU && APDUlen && Resp && Resplen) {
rapdu_len = vicc_transmit((struct vicc_ctx *) ctx, APDUlen, APDU, &rapdu); {
SectionLocker lock(ioSection);
rapdu_len = vicc_transmit((struct vicc_ctx *) ctx, APDUlen, APDU, &rapdu);
}
if (rapdu_len > 0) { if (rapdu_len > 0) {
memcpy(Resp, rapdu, rapdu_len); memcpy(Resp, rapdu, rapdu_len);
*Resplen = rapdu_len; *Resplen = rapdu_len;
@@ -61,7 +76,10 @@ bool VpcdReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
bool r = false; bool r = false;
if (ATR && ATRsize) { if (ATR && ATRsize) {
atr_len = vicc_getatr((struct vicc_ctx *) ctx, &atr); {
SectionLocker lock(ioSection);
atr_len = vicc_getatr((struct vicc_ctx *) ctx, &atr);
}
if (atr_len > 0) { if (atr_len > 0) {
/* TODO do length checking on length of ATR when ATRsize is /* TODO do length checking on length of ATR when ATRsize is
* correctly initialized by Reader.cpp */ * correctly initialized by Reader.cpp */
@@ -70,7 +88,10 @@ bool VpcdReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
free(atr); free(atr);
r = true; r = true;
if (reset) if (reset)
{
SectionLocker lock(ioSection);
vicc_reset((struct vicc_ctx *) ctx); vicc_reset((struct vicc_ctx *) ctx);
}
} else { } else {
signalRemoval(); signalRemoval();
} }
@@ -81,7 +102,10 @@ bool VpcdReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
DWORD VpcdReader::startServer() { DWORD VpcdReader::startServer() {
breakSocket = false; breakSocket = false;
ctx = vicc_init(NULL, port); {
SectionLocker lock(ioSection);
ctx = vicc_init(NULL, port);
}
while (!breakSocket) { while (!breakSocket) {
CheckATR(); CheckATR();
Sleep(1000); Sleep(1000);
@@ -92,8 +116,11 @@ DWORD VpcdReader::startServer() {
void VpcdReader::shutdown() { void VpcdReader::shutdown() {
breakSocket=true; breakSocket=true;
WaitForSingleObject(serverThread,10000); WaitForSingleObject(serverThread,10000);
serverThread=NULL; serverThread = NULL;
vicc_exit((struct vicc_ctx *) ctx); {
SectionLocker lock(ioSection);
vicc_exit((struct vicc_ctx *) ctx);
}
state=SCARD_ABSENT; state=SCARD_ABSENT;
ctx = NULL; ctx = NULL;
if (waitRemoveIpr!=NULL) { if (waitRemoveIpr!=NULL) {