From ed8ea297e790fd0e26e1a04148a3e6de2ea46dca Mon Sep 17 00:00:00 2001 From: Mike McDonald Date: Mon, 2 Jun 2014 11:08:32 -0400 Subject: [PATCH] Modified SCardConnect/SCardDisconnect logic to prevent more than one card from being connected to a context. Trying to connect more than once to a context without doing a disconnect can cause a deadlock in the pcsclite daemon (pcscd). --- winpr/libwinpr/smartcard/smartcard_pcsc.c | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 5ba47a958..3553db8e8 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -386,9 +386,22 @@ SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard) return pCard->hContext; } +BOOL PCSC_IsCardHandleConnected(SCARDCONTEXT hContext) +{ + PCSC_SCARDCONTEXT* pContext; + + pContext = PCSC_GetCardContextData(hContext); + + if (!pContext) + return FALSE; + + return pContext->hCard ? TRUE : FALSE; +} + PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; + PCSC_SCARDCONTEXT* pContext; pCard = (PCSC_SCARDHANDLE*) calloc(1, sizeof(PCSC_SCARDHANDLE)); @@ -399,6 +412,10 @@ PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hContext, SCARDHANDLE hCar InitializeCriticalSectionAndSpinCount(&(pCard->lock), 4000); + pContext = PCSC_GetCardContextData(hContext); + + pContext->hCard = hCard; + if (!g_CardHandles) g_CardHandles = ListDictionary_New(TRUE); @@ -410,6 +427,7 @@ PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hContext, SCARDHANDLE hCar void PCSC_DisconnectCardHandle(SCARDHANDLE hCard) { PCSC_SCARDHANDLE* pCard; + PCSC_SCARDCONTEXT* pContext; pCard = PCSC_GetCardHandleData(hCard); @@ -418,6 +436,10 @@ void PCSC_DisconnectCardHandle(SCARDHANDLE hCard) DeleteCriticalSection(&(pCard->lock)); + pContext = PCSC_GetCardContextData(pCard->hContext); + + pContext->hCard = 0; + free(pCard); if (!g_CardHandles) @@ -1597,6 +1619,9 @@ WINSCARDAPI LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, if (!g_PCSC.pfnSCardConnect) return SCARD_E_NO_SERVICE; + if (PCSC_IsCardHandleConnected(hContext)) + return SCARD_E_SHARING_VIOLATION; + szReaderPCSC = PCSC_GetReaderNameFromAlias((char*) szReader); if (!szReaderPCSC)