Hi,
There seems to be an issue with SCardGetStatusChange on reader insertion,
this is critical with e-gate, we did a simple fix for it, where,
SCardGetStatusChange keeps a count of the number of readers attached to the
system and returns if
. The reader count changed.
The patch is for pcsclite 1.2.9-beta7.
The patch addresses 2 issues.
1. A sleep is added to avoid a starvation problem in multithreaded
environment. (This was posted on the web by Damien Sauveron.
http://lists.drizzle.com/pipermail/muscle/2004-May/002041.html)
2. Fix to make SCardGetStatusChange to return on reader
insertion/removal, this is critical for e-gates, because pcscd sees e-gate
insertion/removal as a reader insertion/removal. The function returns
SCARD_S_SUCCESS for this case so that existing application are not broken.
This was tested on Mandriva 10.1 with USB v3 reader (generic CCID reader
driver) and e-gate. The drivers for both were downloaded from linuxnet.com.
Please let me know if this is good enough to be added to the baseline, the
patch is give below, let me know if you need the patch file itself.
Regards,
Najam.
--- pcsc-lite-1.2.9-beta7/src/winscard_clnt.c 2005-03-02
11:08:03.000000000 -0600
+++ pcsc-lite-1.2.9-beta7_with_bugfix/src/winscard_clnt.c 2005-09-02
17:21:12.561210280 -0500
@@ -58,6 +58,7 @@ static struct _psContextMap
static short isExecuted = 0;
static int mapAddr = 0;
+static int g_CurrentReaderCount = 0;
static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
@@ -169,6 +170,16 @@ static LONG SCardEstablishContextTH(DWOR
SYS_CloseFile(mapAddr); /* Close the memory
map file */
return SCARD_F_INTERNAL_ERROR;
}
+ /* Get the initial reader count on the system,
+ * this is needed for a fix for SCardGetStatusChange
where
+ * it will now return on reader removal/insertions.
+ */
+ if ((readerStates[i])->readerID != 0 &&
+ (readerStates[i])->readerName != NULL &&
+ (readerStates[i])->readerName[0] != '\0' )
+ {
+ ++g_CurrentReaderCount;
+ }
}
for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
@@ -1063,7 +1074,9 @@ LONG SCardGetStatusChange(SCARDCONTEXT h
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
- if ((readerStates[i])->readerID != 0)
+ if ((readerStates[i])->readerID != 0 &&
+ (readerStates[i])->readerName != NULL &&
+ (readerStates[i])->readerName[0] != '\0'
)
{
/*
* Reader was found
@@ -1148,7 +1161,26 @@ LONG SCardGetStatusChange(SCARDCONTEXT h
SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
return SCARD_E_NO_SERVICE;
}
+
+ int newReaderCount = 0, i = 0, ReaderCountChanged = 0;
+ if(j == 0)
+ {
+ for( i=0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++ )
+ {
+ if ((readerStates[i])->readerID != 0 &&
+ (readerStates[i])->readerName != NULL &&
+ (readerStates[i])->readerName[0] != '\0' )
+ {
+ ++newReaderCount;
+ }
+ }
+ if( newReaderCount != g_CurrentReaderCount )
+ {
+ ReaderCountChanged = 1;
+ g_CurrentReaderCount = newReaderCount;
+ }
+ }
currReader = &rgReaderStates[j];
/************ Look for IGNORED readers ****************************/
@@ -1402,7 +1434,17 @@ LONG SCardGetStatusChange(SCARDCONTEXT h
currReader->dwEventState |=
SCARD_STATE_CHANGED;
dwBreakFlag = 1;
}
-
+ /*
+ * There is a starvation problem in
+ * multithreaded environment. To grab
+ * the mutex, this is required.
+ */
+
SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ SYS_USleep(PCSCLITE_STATUS_WAIT);
+
SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ /*
+ * starvation fix ends here
+ */
} /* End of SCARD_STATE_UNKNOWN */
} /* End of SCARD_STATE_IGNORE */
@@ -1412,8 +1454,20 @@ LONG SCardGetStatusChange(SCARDCONTEXT h
*/
j = j + 1;
if (j == cReaders)
- j = 0;
-
+ {
+ if( !dwBreakFlag )
+ {
+ /* break if the reader count changed,
+ * so that the calling application can update
+ * the reader list
+ */
+ if( ReaderCountChanged )
+ {
+ break;
+ }
+ }
+ j = 0;
+ }
/*
* Declare all the break conditions
*/
_______________________________________________
Muscle mailing list
[email protected]
http://lists.drizzle.com/mailman/listinfo/muscle