[Pcsclite-cvs-commit] r4553 - in /trunk/PCSC/src: Makefile.am pcscd.h.in pcscdaemon.c readerfactory.c readerfactory.h winscard_clnt.c winscard_svc.c winscard_svc.h
rousseau at users.alioth.debian.org
rousseau at users.alioth.debian.org
Tue Nov 17 14:48:46 UTC 2009
Author: rousseau
Date: Tue Nov 17 14:48:46 2009
New Revision: 4553
URL: http://svn.debian.org/wsvn/pcsclite/?sc=1&rev=4553
Log:
Use lists instead of fixed size arrays to store handles.
It is now possible to have:
- 200 simultaneous PC/SC clients instead of 16
- 200 SCardConnect per client instead of 16
- 200 clients per reader instead of 16
The default value of 200 can be changed by giving an argument to pcscd
--max-thread
--max-card-handle-per-thread
--max-card-handle-per-reader
Thanks to Jean-Luc Giraud for the big patch
Modified:
trunk/PCSC/src/Makefile.am
trunk/PCSC/src/pcscd.h.in
trunk/PCSC/src/pcscdaemon.c
trunk/PCSC/src/readerfactory.c
trunk/PCSC/src/readerfactory.h
trunk/PCSC/src/winscard_clnt.c
trunk/PCSC/src/winscard_svc.c
trunk/PCSC/src/winscard_svc.h
Modified: trunk/PCSC/src/Makefile.am
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/Makefile.am?rev=4553&op=diff
==============================================================================
--- trunk/PCSC/src/Makefile.am (original)
+++ trunk/PCSC/src/Makefile.am Tue Nov 17 14:48:46 2009
@@ -13,6 +13,7 @@
debug.h \
error.c \
winscard_clnt.c \
+ simclist.c \
strlcat.c \
strlcpy.c \
sys_unix.c \
@@ -20,7 +21,7 @@
utils.c \
winscard_msg.c
libpcsclite_la_LDFLAGS = -version-info 1:0:0
-libpcsclite_la_CFLAGS = $(CFLAGS) $(PTHREAD_CFLAGS) -DLIBPCSCLITE
+libpcsclite_la_CFLAGS = $(CFLAGS) $(PTHREAD_CFLAGS) -DLIBPCSCLITE -DSIMCLIST_NO_DUMPRESTORE
libpcsclite_la_LIBADD = $(COREFOUNDATION) $(LIBSMARTCARD) $(LIBDL) \
$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
Modified: trunk/PCSC/src/pcscd.h.in
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/pcscd.h.in?rev=4553&op=diff
==============================================================================
--- trunk/PCSC/src/pcscd.h.in (original)
+++ trunk/PCSC/src/pcscd.h.in Tue Nov 17 14:48:46 2009
@@ -37,17 +37,9 @@
#define PCSCLITE_STATUS_POLL_RATE 400000 /**< Status polling rate */
#define PCSCLITE_LOCK_POLL_RATE 100000 /**< Lock polling rate */
-/** Maximum applications */
-#define PCSCLITE_MAX_APPLICATIONS 16
-/** Maximum contexts by application */
-#define PCSCLITE_MAX_APPLICATION_CONTEXTS 16
-/** Maximum of applications contexts that pcscd can accept */
-#define PCSCLITE_MAX_APPLICATIONS_CONTEXTS \
- PCSCLITE_MAX_APPLICATIONS * PCSCLITE_MAX_APPLICATION_CONTEXTS
-/** Maximum channels on a reader context */
-#define PCSCLITE_MAX_READER_CONTEXT_CHANNELS 16
-/** Maximum channels on an application context */
-#define PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS 16
+#define PCSC_MAX_CONTEXT_THREADS 200
+#define PCSC_MAX_CONTEXT_CARD_HANDLES 200
+#define PCSC_MAX_READER_HANDLES 200
#define PCSCLITE_STATUS_WAIT 200000 /**< Status Change Sleep */
#define MAX_LIBNAME 100
Modified: trunk/PCSC/src/pcscdaemon.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/pcscdaemon.c?rev=4553&op=diff
==============================================================================
--- trunk/PCSC/src/pcscdaemon.c (original)
+++ trunk/PCSC/src/pcscdaemon.c Tue Nov 17 14:48:46 2009
@@ -75,7 +75,8 @@
* If the message is valid, \c CreateContextThread() is called to serve this
* request.
*/
-static void SVCServiceRunLoop(void)
+static void SVCServiceRunLoop(int customMaxThreadCounter,
+ int customMaxThreadCardHandles)
{
int rsp;
LONG rv;
@@ -98,7 +99,7 @@
/*
* Initialize the contexts structure
*/
- rv = ContextsInitialize();
+ rv = ContextsInitialize(customMaxThreadCounter, customMaxThreadCardHandles);
if (rv == -1)
{
@@ -176,6 +177,7 @@
/* now stop all the drivers */
RFCleanupReaders();
+ ContextsDeinitialize();
exit(0);
}
}
@@ -188,6 +190,9 @@
char HotPlug;
char *newReaderConfig;
struct stat fStatBuf;
+ unsigned int customMaxThreadCounter = 0;
+ unsigned int customMaxReaderHandles = 0;
+ unsigned int customMaxThreadCardHandles = 0;
int opt;
#ifdef HAVE_GETOPT_LONG
int option_index = 0;
@@ -203,10 +208,13 @@
{"critical", 0, NULL, 'C'},
{"hotplug", 0, NULL, 'H'},
{"force-reader-polling", optional_argument, NULL, 0},
+ {"max-thread", 1, NULL, 't'},
+ {"max-card-handle-per-thread", 1, NULL, 's'},
+ {"max-card-handle-per-reader", 1, NULL, 'r'},
{NULL, 0, NULL, 0}
};
#endif
-#define OPT_STRING "c:fdhvaeCH"
+#define OPT_STRING "c:fdhvaeCHt:r:s:"
rv = 0;
newReaderConfig = NULL;
@@ -291,6 +299,24 @@
HotPlug = TRUE;
break;
+ case 't':
+ customMaxThreadCounter = optarg ? atoi(optarg) : 0;
+ Log2(PCSC_LOG_INFO, "setting customMaxThreadCounter to: %d",
+ customMaxThreadCounter);
+ break;
+
+ case 'r':
+ customMaxReaderHandles = optarg ? atoi(optarg) : 0;
+ Log2(PCSC_LOG_INFO, "setting customMaxReaderHandles to: %d",
+ customMaxReaderHandles);
+ break;
+
+ case 's':
+ customMaxThreadCardHandles = optarg ? atoi(optarg) : 0;
+ Log2(PCSC_LOG_INFO, "setting customMaxThreadCardHandles to: %d",
+ customMaxThreadCardHandles);
+ break;
+
default:
print_usage (argv[0]);
return EXIT_FAILURE;
@@ -438,7 +464,7 @@
/*
* Allocate memory for reader structures
*/
- rv = RFAllocateReaderSpace();
+ rv = RFAllocateReaderSpace(customMaxReaderHandles);
if (SCARD_S_SUCCESS != rv)
at_exit();
@@ -502,7 +528,7 @@
(void)signal(SIGUSR1, signal_reload);
- SVCServiceRunLoop();
+ SVCServiceRunLoop(customMaxThreadCounter, customMaxThreadCardHandles);
Log1(PCSC_LOG_ERROR, "SVCServiceRunLoop returned");
return EXIT_FAILURE;
@@ -593,6 +619,9 @@
printf(" -e --error display error level debug messages\n");
printf(" -C --critical display critical only level debug messages\n");
printf(" --force-reader-polling ignore the IFD_GENERATE_HOTPLUG reader capability\n");
+ printf(" -t, --max-thread maximum number of threads (default %d)\n", PCSC_MAX_CONTEXT_THREADS);
+ printf(" -s, --max-card-handle-per-thread maximum number of card handle per thread (default: %d)\n", PCSC_MAX_CONTEXT_CARD_HANDLES);
+ printf(" -r, --max-card-handle-per-reader maximum number of card handle per reader (default: %d)\n", PCSC_MAX_READER_HANDLES);
#else
printf(" -a log APDU commands and results\n");
printf(" -c path to reader.conf\n");
@@ -601,6 +630,9 @@
printf(" -h display usage information\n");
printf(" -H ask the daemon to rescan the available readers\n");
printf(" -v display the program version number\n");
+ printf(" -t maximum number of threads\n");
+ printf(" -s maximum number of card handle per thread\n");
+ printf(" -r maximum number of card handle per reader\n");
#endif
}
Modified: trunk/PCSC/src/readerfactory.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/readerfactory.c?rev=4553&op=diff
==============================================================================
--- trunk/PCSC/src/readerfactory.c (original)
+++ trunk/PCSC/src/readerfactory.c Tue Nov 17 14:48:46 2009
@@ -47,6 +47,7 @@
#endif
static PREADER_CONTEXT sReadersContexts[PCSCLITE_MAX_READERS_CONTEXTS];
+static unsigned int maxReaderHandles = PCSC_MAX_READER_HANDLES;
static DWORD dwNumReadersContexts = 0;
static char *ConfigFile = NULL;
static int ConfigFileCRC = 0;
@@ -54,9 +55,28 @@
#define IDENTITY_SHIFT 16
-LONG RFAllocateReaderSpace(void)
+static int RDR_CLIHANDLES_seeker(const void *el, const void *key)
+{
+ const RDR_CLIHANDLES *rdrCliHandles = el;
+
+ if ((el == NULL) || (key == NULL))
+ Log3(PCSC_LOG_CRITICAL,
+ "RDR_CLIHANDLES_seeker called with NULL pointer: el=%X, key=%X",
+ el, key);
+
+ if (rdrCliHandles->hCard == *(SCARDHANDLE *)key)
+ return 1;
+
+ return 0;
+}
+
+
+LONG RFAllocateReaderSpace(unsigned int customMaxReaderHandles)
{
int i; /* Counter */
+
+ if (customMaxReaderHandles != 0)
+ maxReaderHandles = customMaxReaderHandles;
/* Allocate each reader structure */
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
@@ -76,6 +96,7 @@
UCHAR ucGetData[1], ucThread[1];
LONG rv, parentNode;
int i, j;
+ int lrv = 0;
if ((lpcReader == NULL) || (lpcLibrary == NULL) || (lpcDevice == NULL))
return SCARD_E_INVALID_VALUE;
@@ -171,8 +192,21 @@
(dwContext + 1) << IDENTITY_SHIFT;
(sReadersContexts[dwContext])->readerState = NULL;
- for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
- (sReadersContexts[dwContext])->psHandles[i].hCard = 0;
+ lrv = list_init(&((sReadersContexts[dwContext])->handlesList));
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %X", lrv);
+ return SCARD_E_NO_MEMORY;
+ }
+
+ lrv = list_attributes_seeker(&((sReadersContexts[dwContext])->handlesList),
+ RDR_CLIHANDLES_seeker);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_attributes_seeker failed with return value: %X", lrv);
+ return SCARD_E_NO_MEMORY;
+ }
/* If a clone to this reader exists take some values from that clone */
if (parentNode >= 0 && parentNode < PCSCLITE_MAX_READERS_CONTEXTS)
@@ -346,8 +380,21 @@
(sReadersContexts[dwContextB])->dwIdentity =
(dwContextB + 1) << IDENTITY_SHIFT;
- for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
- (sReadersContexts[dwContextB])->psHandles[i].hCard = 0;
+ lrv = list_init(&((sReadersContexts[dwContextB])->handlesList));
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %X", lrv);
+ return SCARD_E_NO_MEMORY;
+ }
+
+ lrv = list_attributes_seeker(&((sReadersContexts[dwContextB])->handlesList),
+ RDR_CLIHANDLES_seeker);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_attributes_seeker failed with return value: %X", lrv);
+ return SCARD_E_NO_MEMORY;
+ }
/* Call on the parent driver to see if the slots are thread safe */
dwGetSize = sizeof(ucThread);
@@ -412,7 +459,6 @@
while (SCARD_S_SUCCESS ==
RFReaderInfoNamePort(dwPort, lpcReader, &sContext))
{
- int i;
/* Try to destroy the thread */
rv = EHDestroyEventHandler(sContext);
@@ -466,9 +512,20 @@
sContext->dwIdentity = 0;
sContext->readerState = NULL;
- for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
- sContext->psHandles[i].hCard = 0;
-
+ while (list_size(&(sContext->handlesList)) != 0)
+ {
+ int lrv;
+ RDR_CLIHANDLES *currentHandle;
+
+ currentHandle = list_get_at(&(sContext->handlesList), 0);
+ lrv = list_delete_at(&(sContext->handlesList), 0);
+ if (lrv < 0)
+ Log2(PCSC_LOG_CRITICAL,
+ "list_delete_at failed with return value: %X", lrv);
+
+ free(currentHandle);
+ }
+ list_destroy(&(sContext->handlesList));
dwNumReadersContexts -= 1;
/* signal an event to clients */
@@ -1001,35 +1058,34 @@
* for authentication. */
randHandle = SYS_RandomInt(10, 65000);
- while (1)
- {
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
- {
- if ((sReadersContexts[i])->vHandle != 0)
+ int i;
+again:
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if ((sReadersContexts[i])->vHandle != 0)
+ {
+ RDR_CLIHANDLES *currentHandle;
+ list_t * l = &((sReadersContexts[i])->handlesList);
+
+ list_iterator_start(l);
+ while (list_iterator_hasnext(l))
{
- int j;
-
- for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
+ currentHandle = list_iterator_next(l);
+ if ((rContext->dwIdentity + randHandle) ==
+ (currentHandle->hCard))
{
- if ((rContext->dwIdentity + randHandle) ==
- (sReadersContexts[i])->psHandles[j].hCard)
- {
- /* Get a new handle and loop again */
- randHandle = SYS_RandomInt(10, 65000);
- continue;
- }
+ /* Get a new handle and loop again */
+ randHandle = SYS_RandomInt(10, 65000);
+ list_iterator_stop(l);
+ goto again;
}
}
- }
-
- /* Once the for loop is completed w/o restart a good handle was
- * found and the loop can be exited. */
- if (i == PCSCLITE_MAX_READERS_CONTEXTS)
- break;
- }
-
+ list_iterator_stop(l);
+ }
+ }
+
+ /* Once the for loop is completed w/o restart a good handle was
+ * found and the loop can be exited. */
return rContext->dwIdentity + randHandle;
}
@@ -1041,13 +1097,11 @@
{
if ((sReadersContexts[i])->vHandle != 0)
{
- int j;
-
- for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
- {
- if (hCard == (sReadersContexts[i])->psHandles[j].hCard)
- return SCARD_S_SUCCESS;
- }
+ RDR_CLIHANDLES * currentHandle;
+ currentHandle = list_seek(&((sReadersContexts[i])->handlesList),
+ &hCard);
+ if (currentHandle != NULL)
+ return SCARD_S_SUCCESS;
}
}
@@ -1062,55 +1116,89 @@
LONG RFAddReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
- {
- if (rContext->psHandles[i].hCard == 0)
- {
- rContext->psHandles[i].hCard = hCard;
- rContext->psHandles[i].dwEventStatus = 0;
- break;
- }
- }
-
- if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
- /* List is full */
- return SCARD_E_INSUFFICIENT_BUFFER;
-
+ int listLength, lrv;
+ RDR_CLIHANDLES *newHandle;
+
+ listLength = list_size(&(rContext->handlesList));
+
+ /* Throttle the number of possible handles */
+ if (listLength >= maxReaderHandles)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "Too many handles opened, exceeding configured max (%d)",
+ maxReaderHandles);
+ return SCARD_E_NO_MEMORY;
+ }
+
+ newHandle = malloc(sizeof(RDR_CLIHANDLES));
+ if (NULL == newHandle)
+ {
+ Log1(PCSC_LOG_CRITICAL, "malloc failed");
+ return SCARD_E_NO_MEMORY;
+ }
+
+ newHandle->hCard = hCard;
+ newHandle->dwEventStatus = 0;
+
+ lrv = list_append(&(rContext->handlesList), newHandle);
+ if (lrv < 0)
+ {
+ free(newHandle);
+ Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %X",
+ lrv);
+ return SCARD_E_NO_MEMORY;
+ }
return SCARD_S_SUCCESS;
}
LONG RFRemoveReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
- {
- if (rContext->psHandles[i].hCard == hCard)
- {
- rContext->psHandles[i].hCard = 0;
- rContext->psHandles[i].dwEventStatus = 0;
- break;
- }
- }
-
- if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
- /* Not Found */
+ RDR_CLIHANDLES *currentHandle;
+ int list_index, lrv;
+
+ currentHandle = list_seek(&(rContext->handlesList), &hCard);
+ if (NULL == currentHandle)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_seek failed to locate hCard=%X", hCard);
return SCARD_E_INVALID_HANDLE;
-
+ }
+
+ list_index = list_locate(&(rContext->handlesList), currentHandle);
+ if (list_index < 0)
+ Log2(PCSC_LOG_CRITICAL,
+ "list_locate failed with return value: %X", list_index);
+ else
+ {
+ lrv = list_delete_at(&(rContext->handlesList), list_index);
+ if (lrv < 0)
+ Log2(PCSC_LOG_CRITICAL,
+ "list_delete_at failed with return value: %X", lrv);
+ }
+ free(currentHandle);
+
+ /* Not Found */
return SCARD_S_SUCCESS;
}
LONG RFSetReaderEventState(PREADER_CONTEXT rContext, DWORD dwEvent)
{
- int i;
-
/* Set all the handles for that reader to the event */
- for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
- {
- if (rContext->psHandles[i].hCard != 0)
- rContext->psHandles[i].dwEventStatus = dwEvent;
+ int list_index, listSize;
+ RDR_CLIHANDLES *currentHandle;
+
+ listSize = list_size(&(rContext->handlesList));
+
+ for (list_index = 0; list_index < listSize; list_index++)
+ {
+ currentHandle = list_get_at(&(rContext->handlesList), list_index);
+ if (NULL == currentHandle)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_get_at failed at index %s",
+ list_index);
+ continue;
+ }
+
+ currentHandle->dwEventStatus = dwEvent;
}
if (SCARD_REMOVED == dwEvent)
@@ -1125,46 +1213,52 @@
LONG RFCheckReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
- {
- if (rContext->psHandles[i].hCard == hCard)
- {
- if (rContext->psHandles[i].dwEventStatus == SCARD_REMOVED)
- return SCARD_W_REMOVED_CARD;
- else
- {
- if (rContext->psHandles[i].dwEventStatus == SCARD_RESET)
- return SCARD_W_RESET_CARD;
- else
- {
- if (rContext->psHandles[i].dwEventStatus == 0)
- return SCARD_S_SUCCESS;
- else
- return SCARD_E_INVALID_VALUE;
- }
- }
- }
- }
-
- return SCARD_E_INVALID_HANDLE;
+ LONG rv;
+ RDR_CLIHANDLES *currentHandle;
+
+ currentHandle = list_seek(&(rContext->handlesList), &hCard);
+ if (NULL == currentHandle)
+ {
+ /* Not Found */
+ Log2(PCSC_LOG_CRITICAL, "list_seek failed for hCard %X", hCard);
+ return SCARD_E_INVALID_HANDLE;
+ }
+
+ switch(currentHandle->dwEventStatus)
+ {
+ case 0:
+ rv = SCARD_S_SUCCESS;
+ break;
+
+ case SCARD_REMOVED:
+ rv = SCARD_W_REMOVED_CARD;
+ break;
+
+ case SCARD_RESET:
+ rv = SCARD_W_RESET_CARD;
+ break;
+
+ default:
+ rv = SCARD_E_INVALID_VALUE;
+ }
+
+ return rv;
}
LONG RFClearReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
- {
- if (rContext->psHandles[i].hCard == hCard)
- rContext->psHandles[i].dwEventStatus = 0;
- }
-
- if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
+ RDR_CLIHANDLES *currentHandle;
+
+ currentHandle = list_seek(&(rContext->handlesList), &hCard);
+ if (NULL == currentHandle)
/* Not Found */
return SCARD_E_INVALID_HANDLE;
+ currentHandle->dwEventStatus = 0;
+
+ /* hCards should be unique so we
+ * should be able to return
+ * as soon as we have a hit */
return SCARD_S_SUCCESS;
}
Modified: trunk/PCSC/src/readerfactory.h
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/readerfactory.h?rev=4553&op=diff
==============================================================================
--- trunk/PCSC/src/readerfactory.h (original)
+++ trunk/PCSC/src/readerfactory.h Tue Nov 17 14:48:46 2009
@@ -22,6 +22,7 @@
#include "thread_generic.h"
#include "ifdhandler.h"
#include "pcscd.h"
+#include "simclist.h"
#ifdef __cplusplus
extern "C"
@@ -110,7 +111,7 @@
PCSCLITE_THREAD_T pthThread; /**< Event polling thread */
RESPONSECODE (*pthCardEvent)(DWORD); /**< Card Event sync */
PCSCLITE_MUTEX *mMutex; /**< Mutex for this connection */
- RDR_CLIHANDLES psHandles[PCSCLITE_MAX_READER_CONTEXT_CHANNELS];
+ list_t handlesList;
/**< Structure of connected handles */
union
{
@@ -138,7 +139,7 @@
typedef struct ReaderContext READER_CONTEXT, *PREADER_CONTEXT;
- LONG RFAllocateReaderSpace(void);
+ LONG RFAllocateReaderSpace(unsigned int);
LONG RFAddReader(LPSTR, DWORD, LPSTR, LPSTR);
LONG RFRemoveReader(LPSTR, DWORD);
LONG RFSetReaderName(PREADER_CONTEXT, LPSTR, LPSTR, DWORD, DWORD);
Modified: trunk/PCSC/src/winscard_clnt.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_clnt.c?rev=4553&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_clnt.c (original)
+++ trunk/PCSC/src/winscard_clnt.c Tue Nov 17 14:48:46 2009
@@ -186,18 +186,55 @@
typedef struct _psChannelMap CHANNEL_MAP;
+static int CHANNEL_MAP_seeker(const void *el, const void *key)
+{
+ const CHANNEL_MAP * channelMap = el;
+
+ if ((el == NULL) || (key == NULL))
+ {
+ Log3(PCSC_LOG_CRITICAL,
+ "CHANNEL_MAP_seeker called with NULL pointer: el=%X, key=%X",
+ el, key);
+ }
+
+ if (channelMap->hCard == *(SCARDHANDLE *)key)
+ return 1;
+
+ return 0;
+}
+
/**
* @brief Represents the an Application Context on the Client side.
*
* An Application Context contains Channels (\c _psChannelMap).
*/
-static struct _psContextMap
+struct _psContextMap
{
DWORD dwClientID; /**< Client Connection ID */
SCARDCONTEXT hContext; /**< Application Context ID */
PCSCLITE_MUTEX * mMutex; /**< Mutex for this context */
- CHANNEL_MAP psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
-} psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
+ list_t channelMapList;
+};
+typedef struct _psContextMap SCONTEXTMAP;
+
+static list_t contextMapList;
+
+static int SCONTEXTMAP_seeker(const void *el, const void *key)
+{
+ const SCONTEXTMAP * contextMap = el;
+
+ if ((el == NULL) || (key == NULL))
+ {
+ Log3(PCSC_LOG_CRITICAL,
+ "SCONTEXTMAP_seeker called with NULL pointer: el=%X, key=%X",
+ el, key);
+ }
+
+ if (contextMap->hContext == *(SCARDCONTEXT *) key)
+ return 1;
+
+ return 0;
+}
/**
* Make sure the initialization code is executed only once.
@@ -233,23 +270,21 @@
static LONG SCardAddContext(SCARDCONTEXT, DWORD);
-static LONG SCardGetContextIndice(SCARDCONTEXT);
-static LONG SCardGetContextIndiceTH(SCARDCONTEXT);
+static SCONTEXTMAP * SCardGetContext(SCARDCONTEXT);
+static SCONTEXTMAP * SCardGetContextTH(SCARDCONTEXT);
static LONG SCardRemoveContext(SCARDCONTEXT);
-static LONG SCardCleanContext(LONG indice);
-
-static LONG SCardAddHandle(SCARDHANDLE, DWORD, LPCSTR);
-static LONG SCardGetIndicesFromHandle(SCARDHANDLE, /*@out@*/ PDWORD,
- /*@out@*/ PDWORD);
-static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE, /*@out@*/ PDWORD,
- /*@out@*/ PDWORD);
+static LONG SCardCleanContext(SCONTEXTMAP *);
+
+static LONG SCardAddHandle(SCARDHANDLE, SCONTEXTMAP *, LPCSTR);
+static LONG SCardGetContextAndChannelFromHandle(SCARDHANDLE, /*@out@*/ SCONTEXTMAP * *, /*@out@*/ CHANNEL_MAP * *);
+static LONG SCardGetContextAndChannelFromHandleTH(SCARDHANDLE, /*@out@*/ SCONTEXTMAP * *, /*@out@*/ CHANNEL_MAP * *);
static LONG SCardRemoveHandle(SCARDHANDLE);
static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
LPBYTE pbAttr, LPDWORD pcbAttrLen);
void DESTRUCTOR SCardUnload(void);
-static LONG getReaderStates(LONG dwContextIndex);
+static LONG getReaderStates(SCONTEXTMAP * currentContextMap);
/*
* Thread safety functions
@@ -368,7 +403,6 @@
/*@unused@*/ LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
{
LONG rv;
- int i;
struct establish_struct scEstablishStruct;
uint32_t dwClientID = 0;
@@ -381,53 +415,36 @@
/*
* Do this only once:
- * - Initialize debug of need.
- * - Set up the memory mapped structures for reader states.
- * - Allocate each reader structure.
- * - Initialize context struct.
+ * - Initialize context list.
*/
if (isExecuted == 0)
{
- /*
- * Initializes the application contexts and all channels for each one
- */
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
+ int lrv;
+
+ /* NOTE: The list will never be freed (No API call exists to
+ * "close all contexts".
+ * Applications which load and unload the library will leak
+ * the list's internal structures. */
+ lrv = list_init(&contextMapList);
+ if (lrv < 0)
{
- int j;
-
- /*
- * Initially set the context struct to zero
- */
- psContextMap[i].dwClientID = 0;
- psContextMap[i].hContext = 0;
- psContextMap[i].mMutex = NULL;
-
- for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
- {
- /*
- * Initially set the hcard structs to zero
- */
- psContextMap[i].psChannelMap[j].hCard = 0;
- psContextMap[i].psChannelMap[j].readerName = NULL;
- }
+ Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %X", lrv);
+ return SCARD_E_NO_MEMORY;
}
- }
-
- /*
- * Is there a free slot for this connection ?
- */
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
- {
- if (psContextMap[i].dwClientID == 0)
- break;
- }
-
- if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
- {
- return SCARD_E_NO_MEMORY;
- }
+ lrv = list_attributes_seeker(&contextMapList,
+ SCONTEXTMAP_seeker);
+ if (lrv <0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_attributes_seeker failed with return value: %X", lrv);
+ list_destroy(&contextMapList);
+ return SCARD_E_NO_MEMORY;
+ }
+
+ isExecuted = 1;
+ }
+
/* Establishes a connection to the server */
if (SHMClientSetupSession(&dwClientID) != 0)
@@ -458,8 +475,6 @@
if (veStr.rv != SCARD_S_SUCCESS)
return veStr.rv;
-
- isExecuted = 1;
}
again:
@@ -488,8 +503,8 @@
if (scEstablishStruct.rv != SCARD_S_SUCCESS)
return scEstablishStruct.rv;
- /* check we do not reuse an existing phContext */
- if (-1 != SCardGetContextIndiceTH(scEstablishStruct.hContext))
+ /* check we do not reuse an existing hContext */
+ if (NULL != SCardGetContextTH(scEstablishStruct.hContext))
/* we do not need to release the allocated context since
* SCardReleaseContext() does nothing on the server side */
goto again;
@@ -529,16 +544,16 @@
{
LONG rv;
struct release_struct scReleaseStruct;
- LONG dwContextIndex;
+ SCONTEXTMAP * currentContextMap;
PROFILE_START
/*
* Make sure this context has been opened
- * and get dwContextIndex
- */
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ * and get currentContextMap
+ */
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
{
PROFILE_END(SCARD_E_INVALID_HANDLE)
return SCARD_E_INVALID_HANDLE;
@@ -557,11 +572,11 @@
return rv;
}
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the context is still opened */
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
/* the context is now invalid
* -> another thread may have called SCardReleaseContext
* -> so the mMutex has been unlocked */
@@ -571,7 +586,7 @@
scReleaseStruct.rv = SCARD_S_SUCCESS;
rv = SHMMessageSendWithHeader(SCARD_RELEASE_CONTEXT,
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
sizeof(scReleaseStruct),
PCSCLITE_WRITE_TIMEOUT, (void *) &scReleaseStruct);
@@ -585,7 +600,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scReleaseStruct, sizeof(scReleaseStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -596,7 +611,7 @@
rv = scReleaseStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
/*
* Remove the local context from the stack
@@ -693,7 +708,7 @@
{
LONG rv;
struct connect_struct scConnectStruct;
- LONG dwContextIndex;
+ SCONTEXTMAP * currentContextMap;
PROFILE_START
@@ -721,15 +736,15 @@
/*
* Make sure this context has been opened
*/
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the context is still opened */
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
/* the context is now invalid
* -> another thread may have called SCardReleaseContext
* -> so the mMutex has been unlocked */
@@ -744,7 +759,7 @@
scConnectStruct.dwActiveProtocol = 0;
scConnectStruct.rv = SCARD_S_SUCCESS;
- rv = SHMMessageSendWithHeader(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_CONNECT, currentContextMap->dwClientID,
sizeof(scConnectStruct),
PCSCLITE_READ_TIMEOUT, (void *) &scConnectStruct);
@@ -758,7 +773,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scConnectStruct, sizeof(scConnectStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -775,13 +790,13 @@
/*
* Keep track of the handle locally
*/
- rv = SCardAddHandle(*phCard, dwContextIndex, szReader);
+ rv = SCardAddHandle(*phCard, currentContextMap, szReader);
}
else
rv = scConnectStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -861,7 +876,8 @@
{
LONG rv;
struct reconnect_struct scReconnectStruct;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
PROFILE_START
@@ -875,14 +891,16 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -896,9 +914,10 @@
scReconnectStruct.dwActiveProtocol = *pdwActiveProtocol;
scReconnectStruct.rv = SCARD_S_SUCCESS;
- rv = SHMMessageSendWithHeader(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
- sizeof(scReconnectStruct),
- PCSCLITE_READ_TIMEOUT, (void *) &scReconnectStruct);
+ rv = SHMMessageSendWithHeader(SCARD_RECONNECT,
+ currentContextMap->dwClientID,
+ sizeof(scReconnectStruct),
+ PCSCLITE_READ_TIMEOUT, (void *) &scReconnectStruct);
if (rv == -1)
{
@@ -910,9 +929,9 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scReconnectStruct,
- sizeof(scReconnectStruct),
- psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_READ_TIMEOUT);
+ sizeof(scReconnectStruct),
+ currentContextMap->dwClientID,
+ PCSCLITE_READ_TIMEOUT);
if (rv < 0)
{
@@ -924,7 +943,7 @@
rv = scReconnectStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -965,7 +984,8 @@
{
LONG rv;
struct disconnect_struct scDisconnectStruct;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
PROFILE_START
@@ -976,14 +996,16 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -994,7 +1016,8 @@
scDisconnectStruct.dwDisposition = dwDisposition;
scDisconnectStruct.rv = SCARD_S_SUCCESS;
- rv = SHMMessageSendWithHeader(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_DISCONNECT,
+ currentContextMap->dwClientID,
sizeof(scDisconnectStruct),
PCSCLITE_READ_TIMEOUT, (void *) &scDisconnectStruct);
@@ -1009,7 +1032,7 @@
*/
rv = SHMMessageReceive(&scDisconnectStruct,
sizeof(scDisconnectStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -1022,7 +1045,7 @@
rv = scDisconnectStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -1069,7 +1092,8 @@
LONG rv;
struct begin_struct scBeginStruct;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
PROFILE_START
@@ -1080,14 +1104,16 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -1104,7 +1130,8 @@
do
{
- rv = SHMMessageSendWithHeader(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_BEGIN_TRANSACTION,
+ currentContextMap->dwClientID,
sizeof(scBeginStruct),
PCSCLITE_READ_TIMEOUT, (void *) &scBeginStruct);
@@ -1118,7 +1145,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scBeginStruct, sizeof(scBeginStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -1132,7 +1159,7 @@
rv = scBeginStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv);
@@ -1184,7 +1211,8 @@
LONG rv;
struct end_struct scEndStruct;
int randnum;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
PROFILE_START
@@ -1200,14 +1228,16 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -1219,7 +1249,7 @@
scEndStruct.rv = SCARD_S_SUCCESS;
rv = SHMMessageSendWithHeader(SCARD_END_TRANSACTION,
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
sizeof(scEndStruct),
PCSCLITE_READ_TIMEOUT, (void *) &scEndStruct);
@@ -1233,7 +1263,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scEndStruct, sizeof(scEndStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -1250,7 +1280,7 @@
rv = scEndStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -1267,7 +1297,8 @@
{
LONG rv;
struct cancel_transaction_struct scCancelStruct;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
PROFILE_START
@@ -1278,14 +1309,16 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -1295,7 +1328,7 @@
scCancelStruct.hCard = hCard;
rv = SHMMessageSendWithHeader(SCARD_CANCEL_TRANSACTION,
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
sizeof(scCancelStruct),
PCSCLITE_READ_TIMEOUT, (void *) &scCancelStruct);
@@ -1309,7 +1342,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scCancelStruct, sizeof(scCancelStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -1320,7 +1353,7 @@
rv = scCancelStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -1422,7 +1455,8 @@
LONG rv;
int i;
struct status_struct scStatusStruct;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
char *r;
char *bufReader = NULL;
LPBYTE bufAtr = NULL;
@@ -1458,14 +1492,16 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -1473,11 +1509,11 @@
return SCARD_E_INVALID_HANDLE;
/* synchronize reader states with daemon */
- rv = getReaderStates(dwContextIndex);
+ rv = getReaderStates(currentContextMap);
if (rv != SCARD_S_SUCCESS)
goto end;
- r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+ r = pChannelMap->readerName;
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
/* by default r == NULL */
@@ -1499,7 +1535,7 @@
scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
- rv = SHMMessageSendWithHeader(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_STATUS, currentContextMap->dwClientID,
sizeof(scStatusStruct),
PCSCLITE_READ_TIMEOUT, (void *) &scStatusStruct);
@@ -1513,7 +1549,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scStatusStruct, sizeof(scStatusStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -1535,7 +1571,7 @@
* Now continue with the client side SCardStatus
*/
- *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
+ *pcchReaderLen = strlen(pChannelMap->readerName) + 1;
*pcbAtrLen = readerStates[i].cardAtrLength;
if (pdwState)
@@ -1570,7 +1606,7 @@
rv = SCARD_E_INSUFFICIENT_BUFFER;
strncpy(bufReader,
- psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
+ pChannelMap->readerName,
dwReaderLen);
}
@@ -1602,7 +1638,7 @@
}
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -1709,7 +1745,7 @@
DWORD dwState;
DWORD dwBreakFlag = 0;
int j;
- LONG dwContextIndex;
+ SCONTEXTMAP * currentContextMap;
int currentReaderCount = 0;
LONG rv = SCARD_S_SUCCESS;
@@ -1749,22 +1785,22 @@
/*
* Make sure this context has been opened
*/
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the context is still opened */
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
/* the context is now invalid
* -> another thread may have called SCardReleaseContext
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
/* synchronize reader states with daemon */
- rv = getReaderStates(dwContextIndex);
+ rv = getReaderStates(currentContextMap);
if (rv != SCARD_S_SUCCESS)
goto end;
@@ -1791,8 +1827,8 @@
rv = SCardCheckDaemonAvailability();
if (rv != SCARD_S_SUCCESS)
{
- if (psContextMap[dwContextIndex].mMutex)
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ if (currentContextMap->mMutex)
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -2079,7 +2115,7 @@
waitStatusStruct.timeOut = dwTime;
rv = SHMMessageSendWithHeader(CMD_WAIT_READER_STATE_CHANGE,
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
sizeof(waitStatusStruct), PCSCLITE_WRITE_TIMEOUT,
&waitStatusStruct);
@@ -2093,7 +2129,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&waitStatusStruct, sizeof(waitStatusStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
dwTime);
/* timeout */
@@ -2101,7 +2137,7 @@
{
/* ask server to remove us from the event list */
rv = SHMMessageSendWithHeader(CMD_STOP_WAITING_READER_STATE_CHANGE,
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
sizeof(waitStatusStruct), PCSCLITE_WRITE_TIMEOUT,
&waitStatusStruct);
@@ -2113,7 +2149,7 @@
/* Read a message from the server */
rv = SHMMessageReceive(&waitStatusStruct, sizeof(waitStatusStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv == -1)
@@ -2137,7 +2173,7 @@
}
/* synchronize reader states with daemon */
- rv = getReaderStates(dwContextIndex);
+ rv = getReaderStates(currentContextMap);
if (rv != SCARD_S_SUCCESS)
goto end;
@@ -2169,7 +2205,7 @@
end:
Log1(PCSC_LOG_DEBUG, "Event Loop End");
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -2233,7 +2269,8 @@
{
LONG rv;
struct control_struct scControlStruct;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
PROFILE_START
@@ -2248,17 +2285,19 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
{
PROFILE_END(SCARD_E_INVALID_HANDLE)
return SCARD_E_INVALID_HANDLE;
}
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -2278,7 +2317,7 @@
scControlStruct.cbRecvLength = cbRecvLength;
rv = SHMMessageSendWithHeader(SCARD_CONTROL,
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
sizeof(scControlStruct), PCSCLITE_READ_TIMEOUT, &scControlStruct);
if (rv == -1)
@@ -2289,7 +2328,7 @@
/* write the sent buffer */
rv = SHMMessageSend((char *)pbSendBuffer, cbSendLength,
- psContextMap[dwContextIndex].dwClientID, PCSCLITE_WRITE_TIMEOUT);
+ currentContextMap->dwClientID, PCSCLITE_WRITE_TIMEOUT);
if (rv == -1)
{
@@ -2301,7 +2340,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scControlStruct, sizeof(scControlStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -2314,7 +2353,7 @@
{
/* read the received buffer */
rv = SHMMessageReceive(pbRecvBuffer, scControlStruct.dwBytesReturned,
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -2331,7 +2370,7 @@
rv = scControlStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -2533,7 +2572,8 @@
{
LONG rv;
struct getset_struct scGetSetStruct;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
rv = SCardCheckDaemonAvailability();
if (rv != SCARD_S_SUCCESS)
@@ -2542,14 +2582,16 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -2571,7 +2613,7 @@
memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
rv = SHMMessageSendWithHeader(command,
- psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
+ currentContextMap->dwClientID, sizeof(scGetSetStruct),
PCSCLITE_READ_TIMEOUT, &scGetSetStruct);
if (rv == -1)
@@ -2584,7 +2626,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scGetSetStruct, sizeof(scGetSetStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -2614,7 +2656,7 @@
rv = scGetSetStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
return rv;
}
@@ -2683,7 +2725,8 @@
LPDWORD pcbRecvLength)
{
LONG rv;
- DWORD dwContextIndex, dwChannelIndex;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * pChannelMap;
struct transmit_struct scTransmitStruct;
PROFILE_START
@@ -2699,7 +2742,8 @@
/*
* Make sure this handle has been opened
*/
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
{
*pcbRecvLength = 0;
@@ -2707,10 +2751,11 @@
return SCARD_E_INVALID_HANDLE;
}
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the handle is still valid */
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ &pChannelMap);
if (rv == -1)
/* the handle is now invalid
* -> another thread may have called SCardReleaseContext
@@ -2743,7 +2788,7 @@
}
rv = SHMMessageSendWithHeader(SCARD_TRANSMIT,
- psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
+ currentContextMap->dwClientID, sizeof(scTransmitStruct),
PCSCLITE_WRITE_TIMEOUT, (void *) &scTransmitStruct);
if (rv == -1)
@@ -2754,7 +2799,7 @@
/* write the sent buffer */
rv = SHMMessageSend((void *)pbSendBuffer, cbSendLength,
- psContextMap[dwContextIndex].dwClientID, PCSCLITE_WRITE_TIMEOUT);
+ currentContextMap->dwClientID, PCSCLITE_WRITE_TIMEOUT);
if (rv == -1)
{
@@ -2766,7 +2811,7 @@
* Read a message from the server
*/
rv = SHMMessageReceive(&scTransmitStruct, sizeof(scTransmitStruct),
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -2779,7 +2824,7 @@
{
/* read the received buffer */
rv = SHMMessageReceive(pbRecvBuffer, scTransmitStruct.pcbRecvLength,
- psContextMap[dwContextIndex].dwClientID,
+ currentContextMap->dwClientID,
PCSCLITE_READ_TIMEOUT);
if (rv < 0)
@@ -2799,7 +2844,7 @@
rv = scTransmitStruct.rv;
end:
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -2859,7 +2904,7 @@
{
DWORD dwReadersLen = 0;
int i;
- LONG dwContextIndex;
+ SCONTEXTMAP * currentContextMap;
LONG rv = SCARD_S_SUCCESS;
char *buf = NULL;
@@ -2879,25 +2924,25 @@
/*
* Make sure this context has been opened
*/
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
{
PROFILE_END(SCARD_E_INVALID_HANDLE)
return SCARD_E_INVALID_HANDLE;
}
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the context is still opened */
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
/* the context is now invalid
* -> another thread may have called SCardReleaseContext
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
/* synchronize reader states with daemon */
- rv = getReaderStates(dwContextIndex);
+ rv = getReaderStates(currentContextMap);
if (rv != SCARD_S_SUCCESS)
goto end;
@@ -2962,7 +3007,7 @@
/* set the reader names length */
*pcchReaders = dwReadersLen;
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -2984,7 +3029,7 @@
LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
{
LONG rv = SCARD_S_SUCCESS;
- LONG dwContextIndex;
+ SCONTEXTMAP * currentContextMap;
PROFILE_START
@@ -2995,8 +3040,8 @@
/*
* Make sure this context has been opened
*/
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
return SCARD_E_INVALID_HANDLE;
free((void *)pvMem);
@@ -3059,7 +3104,7 @@
LPDWORD pcchGroups)
{
LONG rv = SCARD_S_SUCCESS;
- LONG dwContextIndex;
+ SCONTEXTMAP * currentContextMap;
char *buf = NULL;
PROFILE_START
@@ -3075,15 +3120,15 @@
/*
* Make sure this context has been opened
*/
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
return SCARD_E_INVALID_HANDLE;
- (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexLock(currentContextMap->mMutex);
/* check the context is still opened */
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
/* the context is now invalid
* -> another thread may have called SCardReleaseContext
* -> so the mMutex has been unlocked */
@@ -3121,7 +3166,7 @@
end:
*pcchGroups = dwGroups;
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ (void)SYS_MutexUnLock(currentContextMap->mMutex);
PROFILE_END(rv)
@@ -3157,7 +3202,7 @@
*/
LONG SCardCancel(SCARDCONTEXT hContext)
{
- LONG dwContextIndex;
+ SCONTEXTMAP * currentContextMap;
LONG rv = SCARD_S_SUCCESS;
uint32_t dwClientID = 0;
struct cancel_struct scCancelStruct;
@@ -3167,8 +3212,8 @@
/*
* Make sure this context has been opened
*/
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (NULL == currentContextMap)
return SCARD_E_INVALID_HANDLE;
/* create a new connection to the server */
@@ -3240,7 +3285,7 @@
LONG SCardIsValidContext(SCARDCONTEXT hContext)
{
LONG rv;
- LONG dwContextIndex;
+ SCONTEXTMAP * currentContextMap;
PROFILE_START
@@ -3254,8 +3299,8 @@
/*
* Make sure this context has been opened
*/
- dwContextIndex = SCardGetContextIndice(hContext);
- if (dwContextIndex == -1)
+ currentContextMap = SCardGetContext(hContext);
+ if (currentContextMap == NULL)
rv = SCARD_E_INVALID_HANDLE;
PROFILE_END(rv)
@@ -3281,19 +3326,59 @@
*/
static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
- {
- if (psContextMap[i].hContext == 0)
- {
- psContextMap[i].hContext = hContext;
- psContextMap[i].dwClientID = dwClientID;
- psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
- (void)SYS_MutexInit(psContextMap[i].mMutex);
- return SCARD_S_SUCCESS;
- }
- }
+ int lrv;
+ SCONTEXTMAP * newContextMap;
+
+ newContextMap = malloc(sizeof(SCONTEXTMAP));
+ if (NULL == newContextMap)
+ return SCARD_E_NO_MEMORY;
+
+ Log2(PCSC_LOG_DEBUG, "Allocating new SCONTEXTMAP @%X", newContextMap);
+ newContextMap->hContext = hContext;
+ newContextMap->dwClientID = dwClientID;
+
+ newContextMap->mMutex = malloc(sizeof(PCSCLITE_MUTEX));
+ if (NULL == newContextMap->mMutex)
+ {
+ Log2(PCSC_LOG_DEBUG, "Freeing SCONTEXTMAP @%X", newContextMap);
+ free(newContextMap);
+ return SCARD_E_NO_MEMORY;
+ }
+ (void)SYS_MutexInit(newContextMap->mMutex);
+
+ lrv = list_init(&(newContextMap->channelMapList));
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %X", lrv);
+ goto error;
+ }
+
+ lrv = list_attributes_seeker(&(newContextMap->channelMapList),
+ CHANNEL_MAP_seeker);
+ if (lrv <0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_attributes_seeker failed with return value: %X", lrv);
+ list_destroy(&(newContextMap->channelMapList));
+ goto error;
+ }
+
+ lrv = list_append(&contextMapList, newContextMap);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %X",
+ lrv);
+ list_destroy(&(newContextMap->channelMapList));
+ goto error;
+ }
+
+ return SCARD_S_SUCCESS;
+
+error:
+
+ (void)SYS_MutexDestroy(newContextMap->mMutex);
+ free(newContextMap->mMutex);
+ free(newContextMap);
return SCARD_E_NO_MEMORY;
}
@@ -3303,50 +3388,39 @@
* for the passed context.
*
* This function is a thread-safe wrapper to the function
- * SCardGetContextIndiceTH().
+ * SCardGetContextTH().
*
* @param[in] hContext Application Context whose index will be find.
*
* @return Index corresponding to the Application Context or -1 if it is
* not found.
*/
-static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
-{
- LONG rv;
+static SCONTEXTMAP * SCardGetContext(SCARDCONTEXT hContext)
+{
+ SCONTEXTMAP * currentContextMap;
(void)SCardLockThread();
- rv = SCardGetContextIndiceTH(hContext);
+ currentContextMap = SCardGetContextTH(hContext);
(void)SCardUnlockThread();
- return rv;
+ return currentContextMap;
}
/**
- * @brief Get the index from the Application Context vector \c _psContextMap
+ * @brief Get the address from the Application Context list \c _psContextMap
* for the passed context.
*
* This functions is not thread-safe and should not be called. Instead, call
- * the function SCardGetContextIndice().
+ * the function SCardGetContext().
*
* @param[in] hContext Application Context whose index will be find.
*
- * @return Index corresponding to the Application Context or -1 if it is
+ * @return Address corresponding to the Application Context or NULL if it is
* not found.
*/
-static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
-{
- int i;
-
- /*
- * Find this context and return its spot in the array
- */
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
- {
- if ((hContext == psContextMap[i].hContext) && (hContext != 0))
- return i;
- }
-
- return -1;
+static SCONTEXTMAP * SCardGetContextTH(SCARDCONTEXT hContext)
+{
+ return list_seek(&contextMapList, &hContext);
}
/**
@@ -3360,34 +3434,63 @@
*/
static LONG SCardRemoveContext(SCARDCONTEXT hContext)
{
- LONG retIndice;
-
- retIndice = SCardGetContextIndiceTH(hContext);
-
- if (retIndice == -1)
+ SCONTEXTMAP * currentContextMap;
+ currentContextMap = SCardGetContextTH(hContext);
+
+ if (NULL == currentContextMap)
return SCARD_E_INVALID_HANDLE;
else
- return SCardCleanContext(retIndice);
+ return SCardCleanContext(currentContextMap);
}
-static LONG SCardCleanContext(LONG indice)
-{
- int i;
-
- psContextMap[indice].hContext = 0;
- (void)SHMClientCloseSession(psContextMap[indice].dwClientID);
- psContextMap[indice].dwClientID = 0;
- free(psContextMap[indice].mMutex);
- psContextMap[indice].mMutex = NULL;
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
- {
- /*
- * Reset the \c hCard structs to zero
- */
- psContextMap[indice].psChannelMap[i].hCard = 0;
- free(psContextMap[indice].psChannelMap[i].readerName);
- psContextMap[indice].psChannelMap[i].readerName = NULL;
+static LONG SCardCleanContext(SCONTEXTMAP * targetContextMap)
+{
+ int list_index;
+ int listSize;
+ CHANNEL_MAP * currentChannelMap;
+
+ targetContextMap->hContext = 0;
+ (void)SHMClientCloseSession(targetContextMap->dwClientID);
+ targetContextMap->dwClientID = 0;
+ (void)SYS_MutexDestroy(targetContextMap->mMutex);
+ free(targetContextMap->mMutex);
+ targetContextMap->mMutex = NULL;
+
+ listSize = list_size(&(targetContextMap->channelMapList));
+ for (list_index = 0; list_index < listSize; list_index++)
+ {
+ currentChannelMap = list_get_at(&(targetContextMap->channelMapList),
+ list_index);
+ if (NULL == currentChannelMap)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_get_at failed for index %d",
+ list_index);
+ continue;
+ }
+ else
+ {
+ free(currentChannelMap->readerName);
+ free(currentChannelMap);
+ }
+
+ }
+ list_destroy(&(targetContextMap->channelMapList));
+ list_index = list_locate(&contextMapList, targetContextMap);
+ if (list_index < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_locate failed with return value: %X", list_index);
+ }
+ else
+ {
+ int lrv;
+
+ lrv = list_delete_at(&contextMapList, list_index);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_delete_at failed with return value: %X", lrv);
+ }
}
return SCARD_S_SUCCESS;
@@ -3397,43 +3500,71 @@
* Functions for managing hCard values returned from SCardConnect.
*/
-static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
+static LONG SCardAddHandle(SCARDHANDLE hCard, SCONTEXTMAP * currentContextMap,
LPCSTR readerName)
{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
- {
- if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
- {
- psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
- psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
- return SCARD_S_SUCCESS;
- }
- }
-
- return SCARD_E_NO_MEMORY;
+ CHANNEL_MAP * newChannelMap;
+ int lrv = -1;
+
+ newChannelMap = malloc(sizeof(CHANNEL_MAP));
+ if (NULL == newChannelMap)
+ return SCARD_E_NO_MEMORY;
+
+ newChannelMap->hCard = hCard;
+ newChannelMap->readerName = strdup(readerName);
+
+ lrv = list_append(&(currentContextMap->channelMapList), newChannelMap);
+ if (lrv < 0)
+ {
+ free(newChannelMap->readerName);
+ free(newChannelMap);
+ Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %X", lrv);
+ return SCARD_E_NO_MEMORY;
+ }
+
+ return SCARD_S_SUCCESS;
}
static LONG SCardRemoveHandle(SCARDHANDLE hCard)
{
- DWORD dwContextIndice, dwChannelIndice;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * currentChannelMap;
+ int list_index = 0;
LONG rv;
- rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
+ rv = SCardGetContextAndChannelFromHandle(hCard, ¤tContextMap,
+ ¤tChannelMap);
if (rv == -1)
return SCARD_E_INVALID_HANDLE;
+
+ free(currentChannelMap->readerName);
+
+ list_index = list_locate(&(currentContextMap->channelMapList),
+ currentChannelMap);
+ if (list_index < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_locate failed with return value: %X", list_index);
+ }
else
{
- psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
- free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
- psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
- return SCARD_S_SUCCESS;
- }
+ int lrv;
+
+ lrv = list_delete_at(&(currentContextMap->channelMapList), list_index);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_delete_at failed with return value: %X", lrv);
+ }
+ }
+
+ free(currentChannelMap);
+
+ return SCARD_S_SUCCESS;
}
-static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard,
- PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
+static LONG SCardGetContextAndChannelFromHandle(SCARDHANDLE hCard,
+ SCONTEXTMAP **targetContextMap, CHANNEL_MAP ** targetChannelMap)
{
LONG rv;
@@ -3441,33 +3572,41 @@
return -1;
(void)SCardLockThread();
- rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
+ rv = SCardGetContextAndChannelFromHandleTH(hCard, targetContextMap, targetChannelMap);
(void)SCardUnlockThread();
return rv;
}
-static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard,
- PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
-{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
- {
- if (psContextMap[i].hContext != 0)
+static LONG SCardGetContextAndChannelFromHandleTH(SCARDHANDLE hCard,
+ SCONTEXTMAP **targetContextMap, CHANNEL_MAP ** targetChannelMap)
+{
+ int listSize;
+ int list_index;
+ SCONTEXTMAP * currentContextMap;
+ CHANNEL_MAP * currentChannelMap;
+
+ /* Best to get the caller a crash early if we fail unsafely */
+ *targetContextMap = NULL;
+ *targetChannelMap = NULL;
+
+ listSize = list_size(&contextMapList);
+
+ for (list_index = 0; list_index < listSize; list_index++)
+ {
+ currentContextMap = list_get_at(&contextMapList, list_index);
+ if (currentContextMap == NULL)
{
- int j;
-
- for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
- {
- if (psContextMap[i].psChannelMap[j].hCard == hCard)
- {
- *pdwContextIndice = i;
- *pdwChannelIndice = j;
- return SCARD_S_SUCCESS;
- }
- }
-
+ Log2(PCSC_LOG_CRITICAL, "list_get_at failed for index %d", list_index);
+ continue;
+ }
+ currentChannelMap = list_seek(&(currentContextMap->channelMapList),
+ &hCard);
+ if (currentChannelMap != NULL)
+ {
+ *targetContextMap = currentContextMap;
+ *targetChannelMap = currentChannelMap;
+ return SCARD_S_SUCCESS;
}
}
@@ -3522,14 +3661,29 @@
if (need_restart)
{
- int i;
-
/* invalid all handles */
(void)SCardLockThread();
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
- if (psContextMap[i].hContext)
- (void)SCardCleanContext(i);
+ while (list_size(&contextMapList) != 0)
+ {
+ int lrv;
+ SCONTEXTMAP * currentContextMap;
+
+ currentContextMap = list_get_at(&contextMapList, 0);
+ if (currentContextMap != NULL)
+ (void)SCardCleanContext(currentContextMap);
+ else
+ Log1(PCSC_LOG_CRITICAL, "list_get_at returned NULL");
+
+ lrv = list_delete_at(&contextMapList, 0);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "list_delete_at failed with return value: %X", lrv);
+ }
+ /* man free says it is OK to call free(NULL) */
+ free(currentContextMap);
+ }
(void)SCardUnlockThread();
@@ -3547,9 +3701,9 @@
return SCARD_S_SUCCESS;
}
-static LONG getReaderStates(LONG dwContextIndex)
-{
- int32_t dwClientID = psContextMap[dwContextIndex].dwClientID;
+static LONG getReaderStates(SCONTEXTMAP * currentContextMap)
+{
+ int32_t dwClientID = currentContextMap->dwClientID;
if (-1 == SHMMessageSendWithHeader(CMD_GET_READERS_STATE, dwClientID, 0,
PCSCLITE_WRITE_TIMEOUT, NULL))
Modified: trunk/PCSC/src/winscard_svc.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_svc.c?rev=4553&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_svc.c (original)
+++ trunk/PCSC/src/winscard_svc.c Tue Nov 17 14:48:46 2009
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <stddef.h>
+#include <stdlib.h>
#include "pcscd.h"
#include "winscard.h"
@@ -36,36 +37,87 @@
#include "thread_generic.h"
#include "readerfactory.h"
#include "eventhandler.h"
+#include "simclist.h"
/**
* @brief Represents an Application Context on the Server side.
*
* An Application Context contains Channels (\c hCard).
*/
-static struct _psContext
+
+static unsigned int contextMaxThreadCounter = PCSC_MAX_CONTEXT_THREADS;
+static unsigned int contextMaxCardHandles = PCSC_MAX_CONTEXT_CARD_HANDLES;
+
+/* Context tracking list */
+static list_t contextsList;
+
+struct _psContext
{
uint32_t hContext;
- uint32_t hCard[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
+ list_t cardsList;
uint32_t dwClientID; /**< Connection ID used to reference the Client. */
PCSCLITE_THREAD_T pthThread; /**< Event polling thread's ID */
int protocol_major, protocol_minor; /**< Protocol number agreed between client and server*/
-} psContext[PCSCLITE_MAX_APPLICATIONS_CONTEXTS];
-
-static LONG MSGCheckHandleAssociation(SCARDHANDLE, DWORD);
-static LONG MSGAddContext(SCARDCONTEXT, DWORD);
-static LONG MSGRemoveContext(SCARDCONTEXT, DWORD);
-static LONG MSGAddHandle(SCARDCONTEXT, SCARDHANDLE, DWORD);
-static LONG MSGRemoveHandle(SCARDHANDLE, DWORD);
-static LONG MSGCleanupClient(DWORD);
+};
+typedef struct _psContext SCONTEXT;
+
+static LONG MSGCheckHandleAssociation(SCARDHANDLE, SCONTEXT *);
+static LONG MSGAddContext(SCARDCONTEXT, SCONTEXT *);
+static LONG MSGRemoveContext(SCARDCONTEXT, SCONTEXT *);
+static LONG MSGAddHandle(SCARDCONTEXT, SCARDHANDLE, SCONTEXT *);
+static LONG MSGRemoveHandle(SCARDHANDLE, SCONTEXT *);
+static LONG MSGCleanupClient(SCONTEXT *);
static void ContextThread(LPVOID pdwIndex);
extern READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
-LONG ContextsInitialize(void)
-{
- memset(psContext, 0, sizeof(struct _psContext)*PCSCLITE_MAX_APPLICATIONS_CONTEXTS);
+static int contextsListhContext_seeker(const void *el, const void *key)
+{
+ const SCONTEXT * currentContext = (SCONTEXT *)el;
+
+ if ((el == NULL) || (key == NULL))
+ {
+ Log3(PCSC_LOG_CRITICAL, "contextsListhContext_seeker called with NULL pointer: el=%X, key=%X", el, key);
+ }
+
+ if (currentContext->hContext == *(uint32_t *)key)
+ return 1;
+ return 0;
+}
+
+LONG ContextsInitialize(unsigned int customMaxThreadCounter, unsigned int customMaxThreadCardHandles)
+{
+ int lrv = 0;
+
+ if (customMaxThreadCounter != 0)
+ contextMaxThreadCounter = customMaxThreadCounter;
+
+ if (customMaxThreadCardHandles != 0)
+ contextMaxCardHandles = customMaxThreadCardHandles;
+
+ lrv = list_init(&contextsList);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %X", lrv);
+ return -1;
+ }
+ lrv = list_attributes_seeker(& contextsList, contextsListhContext_seeker);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_attributes_seeker failed with return value: %X", lrv);
+ return -1;
+ }
+
return 1;
+}
+
+void ContextsDeinitialize(void)
+{
+ int listSize;
+ listSize = list_size(&contextsList);
+ Log2(PCSC_LOG_DEBUG, "remaining threads: %d", listSize);
+ /* This is currently a no-op. It should terminate the threads properly. */
}
/**
@@ -80,37 +132,93 @@
*/
LONG CreateContextThread(uint32_t *pdwClientID)
{
- long i;
int rv;
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
- {
- if (psContext[i].dwClientID == 0)
- {
- psContext[i].dwClientID = *pdwClientID;
- *pdwClientID = 0;
- break;
- }
- }
-
- if (i == PCSCLITE_MAX_APPLICATIONS_CONTEXTS)
- {
- Log2(PCSC_LOG_CRITICAL, "No more context available (max: %d)",
- PCSCLITE_MAX_APPLICATIONS_CONTEXTS);
- return SCARD_F_INTERNAL_ERROR;
- }
-
- rv = SYS_ThreadCreate(&psContext[i].pthThread, THREAD_ATTR_DETACHED,
- (PCSCLITE_THREAD_FUNCTION( )) ContextThread, (LPVOID) i);
+ int lrv;
+ int listSize;
+ SCONTEXT * newContext = NULL;
+
+ listSize = list_size(&contextsList);
+
+ if (listSize >= contextMaxThreadCounter)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Too many context running: %d", listSize);
+ goto error;
+ }
+
+ /* Create the context for this thread. */
+ newContext = malloc(sizeof(*newContext));
+ if (NULL == newContext)
+ {
+ Log1(PCSC_LOG_CRITICAL, "Could not allocate new context");
+ goto error;
+ }
+ memset(newContext, 0, sizeof(*newContext));
+
+ newContext->dwClientID = *pdwClientID;
+
+ /* Initialise the list of card contexts */
+ lrv = list_init(&(newContext->cardsList));
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %X", lrv);
+ goto error;
+ }
+
+ /* request to store copies, and provide the metric function */
+ list_attributes_copy(&(newContext->cardsList), list_meter_int32_t, 1);
+
+ /* Adding a comparator
+ * The stored type is SCARDHANDLE (long) but has only 32 bits
+ * usefull even on a 64-bit CPU since the API between pcscd and
+ * libpcscliter uses "int32_t hCard;"
+ */
+ lrv = list_attributes_comparator(&(newContext->cardsList), list_comparator_int32_t);
+ if (lrv != 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_attributes_comparator failed with return value: %X", lrv);
+ list_destroy(&(newContext->cardsList));
+ goto error;
+ }
+
+ lrv = list_append(&contextsList, newContext);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %X", lrv);
+ list_destroy(&(newContext->cardsList));
+ goto error;
+ }
+
+ rv = SYS_ThreadCreate(&(newContext->pthThread), THREAD_ATTR_DETACHED,
+ (PCSCLITE_THREAD_FUNCTION( )) ContextThread, (LPVOID) newContext);
if (rv)
{
- (void)SYS_CloseFile(psContext[i].dwClientID);
- psContext[i].dwClientID = 0;
+ int list_index;
+
Log2(PCSC_LOG_CRITICAL, "SYS_ThreadCreate failed: %s", strerror(rv));
- return SCARD_E_NO_MEMORY;
+ list_index = list_locate(&contextsList, (const void *) newContext);
+ if (list_index >= 0)
+ {
+ int lrv2 = list_delete_at(&contextsList, list_index);
+ if (lrv2 < 0)
+ Log2(PCSC_LOG_CRITICAL, "list_delete_at() failed with error %X", lrv2);
+ }
+ else
+ {
+ Log3(PCSC_LOG_CRITICAL,
+ "list_locate() failed with error %X when looking for threadContext %X",
+ list_index, newContext);
+ }
+ list_destroy(&(newContext->cardsList));
+ goto error;
}
return SCARD_S_SUCCESS;
+
+error:
+ if (newContext)
+ free(newContext);
+ (void)SYS_CloseFile(*pdwClientID);
+ return SCARD_E_NO_MEMORY;
}
/*
@@ -124,7 +232,7 @@
* For each Client message a new instance of this thread is created.
*
* @param[in] dwIndex Index of an avaiable Application Context slot in
- * \c psContext.
+ * \c SCONTEXT *.
*/
static const char *CommandsText[] = {
"NULL",
@@ -159,13 +267,13 @@
#define WRITE_BODY(v) \
ret = SHMMessageSend(&v, sizeof(v), filedes, PCSCLITE_WRITE_TIMEOUT);
-static void ContextThread(LPVOID dwIndex)
-{
- DWORD dwContextIndex = (DWORD)dwIndex;
- int32_t filedes = psContext[dwContextIndex].dwClientID;
-
- Log2(PCSC_LOG_DEBUG, "Thread is started: %d",
- psContext[dwContextIndex].dwClientID);
+static void ContextThread(LPVOID newContext)
+{
+ SCONTEXT * threadContext = (SCONTEXT *) newContext;
+ int32_t filedes = threadContext->dwClientID;
+
+ Log3(PCSC_LOG_DEBUG, "Thread is started: dwClientID=%d, threadContext @%X",
+ threadContext->dwClientID, threadContext);
while (1)
{
@@ -193,8 +301,8 @@
READ_BODY(veStr)
/* get the client protocol version */
- psContext[dwContextIndex].protocol_major = veStr.major;
- psContext[dwContextIndex].protocol_minor = veStr.minor;
+ threadContext->protocol_major = veStr.major;
+ threadContext->protocol_minor = veStr.minor;
Log3(PCSC_LOG_DEBUG,
"Client is protocol version %d:%d",
@@ -275,7 +383,7 @@
if (esStr.rv == SCARD_S_SUCCESS)
esStr.rv =
- MSGAddContext(esStr.hContext, dwContextIndex);
+ MSGAddContext(esStr.hContext, threadContext);
WRITE_BODY(esStr)
}
@@ -291,7 +399,7 @@
if (reStr.rv == SCARD_S_SUCCESS)
reStr.rv =
- MSGRemoveContext(reStr.hContext, dwContextIndex);
+ MSGRemoveContext(reStr.hContext, threadContext);
WRITE_BODY(reStr)
}
@@ -317,7 +425,7 @@
if (coStr.rv == SCARD_S_SUCCESS)
coStr.rv =
- MSGAddHandle(coStr.hContext, coStr.hCard, dwContextIndex);
+ MSGAddHandle(coStr.hContext, coStr.hCard, threadContext);
WRITE_BODY(coStr)
}
@@ -330,7 +438,7 @@
READ_BODY(rcStr)
- if (MSGCheckHandleAssociation(rcStr.hCard, dwContextIndex))
+ if (MSGCheckHandleAssociation(rcStr.hCard, threadContext))
goto exit;
rcStr.rv = SCardReconnect(rcStr.hCard, rcStr.dwShareMode,
@@ -349,14 +457,14 @@
READ_BODY(diStr)
- rv = MSGCheckHandleAssociation(diStr.hCard, dwContextIndex);
+ rv = MSGCheckHandleAssociation(diStr.hCard, threadContext);
if (0 == rv)
{
diStr.rv = SCardDisconnect(diStr.hCard, diStr.dwDisposition);
if (SCARD_S_SUCCESS == diStr.rv)
diStr.rv =
- MSGRemoveHandle(diStr.hCard, dwContextIndex);
+ MSGRemoveHandle(diStr.hCard, threadContext);
}
WRITE_BODY(diStr)
@@ -370,7 +478,7 @@
READ_BODY(beStr)
- rv = MSGCheckHandleAssociation(beStr.hCard, dwContextIndex);
+ rv = MSGCheckHandleAssociation(beStr.hCard, threadContext);
if (0 == rv)
beStr.rv = SCardBeginTransaction(beStr.hCard);
@@ -385,7 +493,7 @@
READ_BODY(enStr)
- rv = MSGCheckHandleAssociation(enStr.hCard, dwContextIndex);
+ rv = MSGCheckHandleAssociation(enStr.hCard, threadContext);
if (0 == rv)
enStr.rv =
SCardEndTransaction(enStr.hCard, enStr.dwDisposition);
@@ -401,7 +509,7 @@
READ_BODY(caStr)
- rv = MSGCheckHandleAssociation(caStr.hCard, dwContextIndex);
+ rv = MSGCheckHandleAssociation(caStr.hCard, threadContext);
if (0 == rv)
caStr.rv = SCardCancelTransaction(caStr.hCard);
@@ -412,23 +520,17 @@
case SCARD_CANCEL:
{
struct cancel_struct caStr;
- uint32_t fd = 0;
- int i;
-
+ SCONTEXT * psTargetContext = NULL;
READ_BODY(caStr)
/* find the client */
- for (i=0; i<PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
+ psTargetContext = (SCONTEXT *) list_seek(&contextsList,
+ &(caStr.hContext));
+ if (psTargetContext != NULL)
{
- if (psContext[i].hContext == caStr.hContext)
- {
- fd = psContext[i].dwClientID;
- break;
- }
+ uint32_t fd = psTargetContext->dwClientID;
+ caStr.rv = MSGSignalClient(fd, SCARD_E_CANCELLED);
}
-
- if (fd)
- caStr.rv = MSGSignalClient(fd, SCARD_E_CANCELLED);
else
caStr.rv = SCARD_E_INVALID_VALUE;
@@ -443,7 +545,7 @@
READ_BODY(stStr)
- rv = MSGCheckHandleAssociation(stStr.hCard, dwContextIndex);
+ rv = MSGCheckHandleAssociation(stStr.hCard, threadContext);
if (0 == rv)
{
DWORD cchReaderLen;
@@ -491,7 +593,7 @@
READ_BODY(trStr)
- if (MSGCheckHandleAssociation(trStr.hCard, dwContextIndex))
+ if (MSGCheckHandleAssociation(trStr.hCard, threadContext))
goto exit;
/* avoids buffer overflow */
@@ -542,7 +644,7 @@
READ_BODY(ctStr)
- if (MSGCheckHandleAssociation(ctStr.hCard, dwContextIndex))
+ if (MSGCheckHandleAssociation(ctStr.hCard, threadContext))
goto exit;
/* avoids buffer overflow */
@@ -586,7 +688,7 @@
READ_BODY(gsStr)
- if (MSGCheckHandleAssociation(gsStr.hCard, dwContextIndex))
+ if (MSGCheckHandleAssociation(gsStr.hCard, threadContext))
goto exit;
/* avoids buffer overflow */
@@ -610,7 +712,7 @@
READ_BODY(gsStr)
- if (MSGCheckHandleAssociation(gsStr.hCard, dwContextIndex))
+ if (MSGCheckHandleAssociation(gsStr.hCard, threadContext))
goto buffer_overflow;
/* avoids buffer overflow */
@@ -645,7 +747,7 @@
Log2(PCSC_LOG_DEBUG, "Wrong length: %d", filedes);
exit:
(void)SYS_CloseFile(filedes);
- (void)MSGCleanupClient(dwContextIndex);
+ (void)MSGCleanupClient(threadContext);
(void)SYS_ThreadExit((LPVOID) NULL);
}
@@ -662,139 +764,148 @@
return ret;
} /* MSGSignalClient */
-static LONG MSGAddContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
-{
- psContext[dwContextIndex].hContext = hContext;
+static LONG MSGAddContext(SCARDCONTEXT hContext, SCONTEXT * threadContext)
+{
+ threadContext->hContext = hContext;
return SCARD_S_SUCCESS;
}
-static LONG MSGRemoveContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
-{
- int i;
+static LONG MSGRemoveContext(SCARDCONTEXT hContext, SCONTEXT * threadContext)
+{
LONG rv;
-
- if (psContext[dwContextIndex].hContext == hContext)
- {
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ int lrv;
+
+ if (threadContext->hContext != hContext)
+ return SCARD_E_INVALID_VALUE;
+
+ while (list_size(&(threadContext->cardsList)) != 0)
+ {
+ PREADER_CONTEXT rContext = NULL;
+ DWORD dwLockId;
+ SCARDHANDLE hCard;
+ void *ptr;
+
+ /*
+ * Disconnect each of these just in case
+ */
+ ptr = list_get_at(&(threadContext->cardsList), 0);
+ if (NULL == ptr)
+ {
+ Log1(PCSC_LOG_CRITICAL, "list_get_at failed");
+ continue;
+ }
+ hCard = *(int32_t *)ptr;
+
+ /*
+ * Unlock the sharing
+ */
+ rv = RFReaderInfoById(hCard, &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ dwLockId = rContext->dwLockId;
+ rContext->dwLockId = 0;
+
+ if (hCard != dwLockId)
{
/*
- * Disconnect each of these just in case
+ * if the card is locked by someone else we do not reset it
+ * and simulate a card removal
*/
-
- if (psContext[dwContextIndex].hCard[i] != 0)
- {
- PREADER_CONTEXT rContext = NULL;
- DWORD dwLockId;
-
- /*
- * Unlock the sharing
- */
- rv = RFReaderInfoById(psContext[dwContextIndex].hCard[i],
- &rContext);
- if (rv != SCARD_S_SUCCESS)
- return rv;
-
- dwLockId = rContext->dwLockId;
- rContext->dwLockId = 0;
-
- if (psContext[dwContextIndex].hCard[i] != dwLockId)
- {
- /*
- * if the card is locked by someone else we do not reset it
- * and simulate a card removal
- */
- rv = SCARD_W_REMOVED_CARD;
- }
- else
- {
- /*
- * We will use SCardStatus to see if the card has been
- * reset there is no need to reset each time
- * Disconnect is called
- */
- rv = SCardStatus(psContext[dwContextIndex].hCard[i], NULL,
- NULL, NULL, NULL, NULL, NULL);
- }
-
- if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD)
- (void)SCardDisconnect(psContext[dwContextIndex].hCard[i],
- SCARD_LEAVE_CARD);
- else
- (void)SCardDisconnect(psContext[dwContextIndex].hCard[i],
- SCARD_RESET_CARD);
-
- psContext[dwContextIndex].hCard[i] = 0;
- }
- }
-
- psContext[dwContextIndex].hContext = 0;
- return SCARD_S_SUCCESS;
- }
-
- return SCARD_E_INVALID_VALUE;
+ rv = SCARD_W_REMOVED_CARD;
+ }
+ else
+ {
+ /*
+ * We will use SCardStatus to see if the card has been
+ * reset there is no need to reset each time
+ * Disconnect is called
+ */
+ rv = SCardStatus(hCard, NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+
+ if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD)
+ (void)SCardDisconnect(hCard, SCARD_LEAVE_CARD);
+ else
+ (void)SCardDisconnect(hCard, SCARD_RESET_CARD);
+
+ /* Remove entry from the list */
+ lrv = list_delete_at(&(threadContext->cardsList), 0);
+ if (lrv < 0)
+ Log2(PCSC_LOG_CRITICAL,
+ "list_delete_at failed with return value: %X", lrv);
+ }
+ list_destroy(&(threadContext->cardsList)) ;
+
+ /* We only mark the context as no longer in use.
+ * The memory is freed in MSGCleanupCLient() */
+ threadContext->hContext = 0;
+
+ return SCARD_S_SUCCESS;
}
static LONG MSGAddHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard,
- DWORD dwContextIndex)
-{
- int i;
-
- if (psContext[dwContextIndex].hContext == hContext)
- {
-
+ SCONTEXT * threadContext)
+{
+ if (threadContext->hContext == hContext)
+ {
/*
* Find an empty spot to put the hCard value
*/
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
- {
- if (psContext[dwContextIndex].hCard[i] == 0)
- {
- psContext[dwContextIndex].hCard[i] = hCard;
- break;
- }
- }
-
- if (i == PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS)
- {
- return SCARD_F_INTERNAL_ERROR;
- } else
- {
- return SCARD_S_SUCCESS;
- }
-
+ int listLength, lrv;
+
+ listLength = list_size(&(threadContext->cardsList));
+ if (listLength >= contextMaxCardHandles)
+ {
+ Log4(PCSC_LOG_DEBUG, "Too many card handles for thread context @%X: %d (max is %d)"
+ "Restart pcscd with --max-card-handle-per-thread value",
+ threadContext, listLength, contextMaxCardHandles);
+ return SCARD_E_NO_MEMORY;
+ }
+
+ lrv = list_append(&(threadContext->cardsList), &hCard);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %X",
+ lrv);
+ return SCARD_E_NO_MEMORY;
+ }
+ return SCARD_S_SUCCESS;
}
return SCARD_E_INVALID_VALUE;
}
-static LONG MSGRemoveHandle(SCARDHANDLE hCard, DWORD dwContextIndex)
-{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
- {
- if (psContext[dwContextIndex].hCard[i] == hCard)
- {
- psContext[dwContextIndex].hCard[i] = 0;
- return SCARD_S_SUCCESS;
- }
- }
-
+static LONG MSGRemoveHandle(SCARDHANDLE hCard, SCONTEXT * threadContext)
+{
+ int list_index = 0;
+
+ list_index = list_locate(&(threadContext->cardsList), &hCard);
+ if (list_index >= 0)
+ {
+ int lrv;
+
+ lrv = list_delete_at(&(threadContext->cardsList), list_index);
+ if (lrv < 0)
+ Log2(PCSC_LOG_CRITICAL, "list_delete_at() failed with error %X", lrv);
+
+ return SCARD_S_SUCCESS;
+ }
+ else
+ {
+ Log3(PCSC_LOG_CRITICAL, "list_locate() failed with error %X when looking for hCard %X",
+ list_index, hCard);
+ }
return SCARD_E_INVALID_VALUE;
}
-static LONG MSGCheckHandleAssociation(SCARDHANDLE hCard, DWORD dwContextIndex)
-{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
- {
- if (psContext[dwContextIndex].hCard[i] == hCard)
- {
- return 0;
- }
- }
+static LONG MSGCheckHandleAssociation(SCARDHANDLE hCard, SCONTEXT * threadContext)
+{
+ int list_index = 0;
+ list_index = list_locate(&(threadContext->cardsList), &hCard);
+ if (list_index >= 0)
+ return 0;
/* Must be a rogue client, debug log and sleep a couple of seconds */
Log1(PCSC_LOG_ERROR, "Client failed to authenticate");
@@ -803,18 +914,44 @@
return -1;
}
-static LONG MSGCleanupClient(DWORD dwContextIndex)
-{
- if (psContext[dwContextIndex].hContext != 0)
- {
- (void)SCardReleaseContext(psContext[dwContextIndex].hContext);
- (void)MSGRemoveContext(psContext[dwContextIndex].hContext,
- dwContextIndex);
- }
-
- psContext[dwContextIndex].dwClientID = 0;
- psContext[dwContextIndex].protocol_major = 0;
- psContext[dwContextIndex].protocol_minor = 0;
+
+/* Should be called just prior to exiting the thread as it de-allocates
+ * the thread memory strucutres
+ */
+static LONG MSGCleanupClient(SCONTEXT * threadContext)
+{
+ int list_index = 0;
+ if (threadContext->hContext != 0)
+ {
+ (void)SCardReleaseContext(threadContext->hContext);
+ (void)MSGRemoveContext(threadContext->hContext, threadContext);
+ }
+
+ Log3(PCSC_LOG_DEBUG,
+ "Thread is stopping: dwClientID=%d, threadContext @%X",
+ threadContext->dwClientID, threadContext);
+
+ /* Clear the struct to ensure that we detect
+ * access to de-allocated memory
+ * Hopefully the compiler won't optimise it out */
+ memset((void*) threadContext, 0, sizeof(SCONTEXT));
+ Log2(PCSC_LOG_DEBUG, "Freeing SCONTEXT @%X", threadContext);
+ list_index = list_locate(&contextsList, (const void *) threadContext);
+ if (list_index >= 0)
+ {
+ int lrv = list_delete_at(&contextsList, list_index);
+ if (lrv < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "list_delete_at() failed with error %x", lrv);
+ }
+ }
+ else
+ {
+ Log3(PCSC_LOG_CRITICAL, "list_locate() failed with error %X when looking for threadContext %X",
+ list_index, threadContext);
+ }
+
+ free(threadContext);
return 0;
}
Modified: trunk/PCSC/src/winscard_svc.h
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_svc.h?rev=4553&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_svc.h (original)
+++ trunk/PCSC/src/winscard_svc.h Tue Nov 17 14:48:46 2009
@@ -24,7 +24,8 @@
extern "C"
{
#endif
- LONG ContextsInitialize(void);
+ LONG ContextsInitialize(unsigned int, unsigned int);
+ void ContextsDeinitialize(void);
LONG CreateContextThread(uint32_t *);
LONG MSGSignalClient(uint32_t filedes, LONG rv);
#ifdef __cplusplus
More information about the Pcsclite-cvs-commit
mailing list