[Pcsclite-cvs-commit] PCSC/src winscard_svc.c,1.13,1.14
sauveron-guest@quantz.debian.org
sauveron-guest@quantz.debian.org
Tue, 16 Dec 2003 23:41:41 +0100
Update of /cvsroot/pcsclite/PCSC/src
In directory quantz:/tmp/cvs-serv3738/src
Modified Files:
winscard_svc.c
Log Message:
Design to handle all the requests in the context
Index: winscard_svc.c
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/winscard_svc.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- winscard_svc.c 23 Oct 2003 21:57:06 -0000 1.13
+++ winscard_svc.c 16 Dec 2003 22:41:39 -0000 1.14
@@ -13,6 +13,7 @@
#include "config.h"
#include <time.h>
#include <stdio.h>
+#include <string.h>
#include "wintypes.h"
#include "pcsclite.h"
@@ -21,24 +22,149 @@
#include "winscard_svc.h"
#include "debuglog.h"
#include "sys_generic.h"
+#include "thread_generic.h"
-static struct _psContext
+struct _psContext
{
SCARDCONTEXT hContext;
SCARDHANDLE hCard[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
DWORD dwClientID;
- DWORD dwHandleID;
+ // DWORD dwHandleID;
+ PCSCLITE_THREAD_T pthThread; /* Event polling thread */
+ sharedSegmentMsg msgStruct;
+};
+
+typedef struct _psContext CONTEXT, *PCONTEXT;
+
+static CONTEXT psContext[PCSCLITE_MAX_APPLICATIONS_CONTEXTS];
+
+static DWORD dwNextContextIndex;
+
+LONG MSGCheckHandleAssociation(SCARDHANDLE, DWORD);
+LONG MSGFunctionDemarshall(psharedSegmentMsg, DWORD);
+LONG MSGAddContext(SCARDCONTEXT, DWORD);
+LONG MSGRemoveContext(SCARDCONTEXT, DWORD);
+LONG MSGAddHandle(SCARDCONTEXT, SCARDHANDLE, DWORD);
+LONG MSGRemoveHandle(SCARDHANDLE, DWORD);
+LONG MSGCleanupClient(DWORD);
+
+static void ContextThread(DWORD* pdwIndex);
+
+LONG ContextsInitialize()
+{
+
+ memset(psContext, 0, sizeof(CONTEXT)*PCSCLITE_MAX_APPLICATIONS_CONTEXTS);
+ return 1;
}
-psContext[PCSCLITE_MAX_APPLICATIONS_CONTEXTS];
-LONG MSGCheckHandleAssociation(DWORD, SCARDHANDLE);
+LONG CreateContextThread(PDWORD pdwClientID)
+{
+
+ int i;
+ LONG 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)
+ {
+ SYS_CloseFile(psContext[i].dwClientID);
+ psContext[i].dwClientID = 0;
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ dwNextContextIndex = i;
+
+ rv = SYS_ThreadCreate(&psContext[i].pthThread, NULL,
+ (LPVOID) ContextThread, (LPVOID) &dwNextContextIndex);
+ if (rv == 1)
+ {
+ return SCARD_S_SUCCESS;
+ }
+ else
+ {
+ SYS_CloseFile(psContext[i].dwClientID);
+ psContext[i].dwClientID = 0;
+ return SCARD_E_NO_MEMORY;
+ }
+
+}
/*
* A list of local functions used to keep track of clients and their
* connections
*/
-LONG MSGFunctionDemarshall(psharedSegmentMsg msgStruct)
+static void ContextThread(DWORD* pdwIndex)
+{
+ LONG rv;
+ sharedSegmentMsg msgStruct;
+ DWORD dwContextIndex = *pdwIndex;
+
+
+ DebugLogB("ContextThread: Thread is started: %d", psContext[dwContextIndex].dwClientID);
+
+ while (1)
+ {
+
+ switch (rv = SHMProcessEventsContext(&psContext[dwContextIndex].dwClientID, &msgStruct, 0))
+ {
+ case 0:
+ if (msgStruct.mtype == CMD_CLIENT_DIED)
+ {
+ /*
+ * Clean up the dead client
+ */
+ DebugLogB("ContextThread: Client die: %d", psContext[dwContextIndex].dwClientID);
+ MSGCleanupClient(dwContextIndex);
+ SYS_ThreadExit((LPVOID) NULL);
+ }
+ break;
+
+ case 1:
+ if (msgStruct.mtype == CMD_FUNCTION)
+ {
+ /*
+ * Command must be found
+ */
+ MSGFunctionDemarshall(&msgStruct, dwContextIndex);
+ rv = SHMMessageSend(&msgStruct, psContext[dwContextIndex].dwClientID,
+ PCSCLITE_SERVER_ATTEMPTS);
+ } else
+ {
+ continue;
+ }
+
+ break;
+
+ case 2:
+ /*
+ * timeout in SHMProcessEventsContext(): do nothing
+ * this is used to catch the Ctrl-C signal at some time when
+ * nothing else happens
+ */
+ break;
+
+ case -1:
+ DebugLogA("ContextThread: Error in SHMProcessEventsContext");
+ break;
+
+ default:
+ DebugLogB("ContextThread: SHMProcessEventsContext unknown retval: %d",
+ rv);
+ break;
+ }
+ }
+}
+
+LONG MSGFunctionDemarshall(psharedSegmentMsg msgStruct, DWORD dwContextIndex)
{
LONG rv;
@@ -68,8 +194,7 @@
if (esStr->rv == SCARD_S_SUCCESS)
esStr->rv =
- MSGAddContext(esStr->phContext, msgStruct->request_id);
-
+ MSGAddContext(esStr->phContext, dwContextIndex);
break;
case SCARD_RELEASE_CONTEXT:
@@ -78,7 +203,7 @@
if (reStr->rv == SCARD_S_SUCCESS)
reStr->rv =
- MSGRemoveContext(reStr->hContext, msgStruct->request_id);
+ MSGRemoveContext(reStr->hContext, dwContextIndex);
break;
@@ -90,14 +215,13 @@
if (coStr->rv == SCARD_S_SUCCESS)
coStr->rv =
- MSGAddHandle(coStr->hContext, msgStruct->request_id,
- coStr->phCard);
+ MSGAddHandle(coStr->hContext, coStr->phCard, dwContextIndex);
break;
case SCARD_RECONNECT:
rcStr = ((reconnect_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(msgStruct->request_id, rcStr->hCard);
+ rv = MSGCheckHandleAssociation(rcStr->hCard, dwContextIndex);
if (rv != 0) return rv;
rcStr->rv = SCardReconnect(rcStr->hCard, rcStr->dwShareMode,
@@ -107,25 +231,25 @@
case SCARD_DISCONNECT:
diStr = ((disconnect_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(msgStruct->request_id, diStr->hCard);
+ rv = MSGCheckHandleAssociation(diStr->hCard, dwContextIndex);
if (rv != 0) return rv;
diStr->rv = SCardDisconnect(diStr->hCard, diStr->dwDisposition);
if (diStr->rv == SCARD_S_SUCCESS)
diStr->rv =
- MSGRemoveHandle(0, msgStruct->request_id, diStr->hCard);
+ MSGRemoveHandle(diStr->hCard, dwContextIndex);
break;
case SCARD_BEGIN_TRANSACTION:
beStr = ((begin_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(msgStruct->request_id, beStr->hCard);
+ rv = MSGCheckHandleAssociation(beStr->hCard, dwContextIndex);
if (rv != 0) return rv;
beStr->rv = SCardBeginTransaction(beStr->hCard);
break;
case SCARD_END_TRANSACTION:
enStr = ((end_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(msgStruct->request_id, enStr->hCard);
+ rv = MSGCheckHandleAssociation(enStr->hCard, dwContextIndex);
if (rv != 0) return rv;
enStr->rv =
SCardEndTransaction(enStr->hCard, enStr->dwDisposition);
@@ -133,14 +257,14 @@
case SCARD_CANCEL_TRANSACTION:
caStr = ((cancel_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(msgStruct->request_id, caStr->hCard);
+ rv = MSGCheckHandleAssociation(caStr->hCard, dwContextIndex);
if (rv != 0) return rv;
caStr->rv = SCardCancelTransaction(caStr->hCard);
break;
case SCARD_STATUS:
stStr = ((status_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(msgStruct->request_id, stStr->hCard);
+ rv = MSGCheckHandleAssociation(stStr->hCard, dwContextIndex);
if (rv != 0) return rv;
stStr->rv = SCardStatus(stStr->hCard, stStr->mszReaderNames,
&stStr->pcchReaderLen, &stStr->pdwState,
@@ -149,7 +273,7 @@
case SCARD_TRANSMIT:
trStr = ((transmit_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(msgStruct->request_id, trStr->hCard);
+ rv = MSGCheckHandleAssociation(trStr->hCard, dwContextIndex);
if (rv != 0) return rv;
trStr->rv = SCardTransmit(trStr->hCard, &trStr->pioSendPci,
trStr->pbSendBuffer, trStr->cbSendLength,
@@ -164,152 +288,104 @@
return 0;
}
-LONG MSGAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
+LONG MSGAddContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
{
- int i;
-
- for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
- {
- if (psContext[i].dwClientID == 0)
- {
- psContext[i].hContext = hContext;
- psContext[i].dwClientID = dwClientID;
- break;
- }
- }
-
- if (i == PCSCLITE_MAX_APPLICATIONS_CONTEXTS)
- {
- return SCARD_F_INTERNAL_ERROR;
- } else
- {
- return SCARD_S_SUCCESS;
- }
-
+ psContext[dwContextIndex].hContext = hContext;
+ return SCARD_S_SUCCESS;
}
-LONG MSGRemoveContext(SCARDCONTEXT hContext, DWORD dwClientID)
+LONG MSGRemoveContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
{
- int i, j;
+ int i;
LONG rv;
- for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
+ if (psContext[dwContextIndex].hContext == hContext)
{
- if (psContext[i].hContext == hContext &&
- psContext[i].dwClientID == dwClientID)
- {
- for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ {
+ /*
+ * Disconnect each of these just in case
+ */
+
+ if (psContext[dwContextIndex].hCard[i] != 0)
{
+
/*
- * Disconnect each of these just in case
+ * We will use SCardStatus to see if the card has been
+ * reset there is no need to reset each time
+ * Disconnect is called
*/
-
- if (psContext[i].hCard[j] != 0)
+
+ rv = SCardStatus(psContext[dwContextIndex].hCard[i], 0, 0, 0, 0, 0, 0);
+
+ if (rv == SCARD_W_RESET_CARD
+ || rv == SCARD_W_REMOVED_CARD)
{
-
- /*
- * 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[i].hCard[j], 0, 0, 0, 0,
- 0, 0);
-
- if (rv == SCARD_W_RESET_CARD
- || rv == SCARD_W_REMOVED_CARD)
- {
- SCardDisconnect(psContext[i].hCard[j],
- SCARD_LEAVE_CARD);
- } else
- {
- SCardDisconnect(psContext[i].hCard[j],
- SCARD_RESET_CARD);
- }
-
- psContext[i].hCard[j] = 0;
+ SCardDisconnect(psContext[dwContextIndex].hCard[i], SCARD_LEAVE_CARD);
+ } else
+ {
+ SCardDisconnect(psContext[dwContextIndex].hCard[i], SCARD_RESET_CARD);
}
+ psContext[dwContextIndex].hCard[i] = 0;
}
- psContext[i].hContext = 0;
- psContext[i].dwClientID = 0;
- SCardReleaseContext(hContext);
- return SCARD_S_SUCCESS;
}
- }
+
+ psContext[dwContextIndex].hContext = 0;
+ return SCARD_S_SUCCESS;
+ }
return SCARD_E_INVALID_VALUE;
}
-LONG MSGAddHandle(SCARDCONTEXT hContext, DWORD dwClientID,
- SCARDHANDLE hCard)
+LONG MSGAddHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard, DWORD dwContextIndex)
{
- int i, j;
+ int i;
- for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
+ if (psContext[dwContextIndex].hContext == hContext)
{
- if (psContext[i].hContext == hContext &&
- psContext[i].dwClientID == dwClientID)
+
+ /*
+ * Find an empty spot to put the hCard value
+ */
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
{
-
- /*
- * Find an empty spot to put the hCard value
- */
- for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
- {
- if (psContext[i].hCard[j] == 0)
- {
- psContext[i].hCard[j] = hCard;
- break;
- }
- }
-
- if (j == PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS)
- {
- return SCARD_F_INTERNAL_ERROR;
- } else
+ if (psContext[dwContextIndex].hCard[i] == 0)
{
- return SCARD_S_SUCCESS;
+ psContext[dwContextIndex].hCard[i] = hCard;
+ break;
}
-
+ }
+
+ if (i == PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS)
+ {
+ return SCARD_F_INTERNAL_ERROR;
+ } else
+ {
+ return SCARD_S_SUCCESS;
}
- } /* End of for */
-
+ }
+
return SCARD_E_INVALID_VALUE;
-
}
-LONG MSGRemoveHandle(SCARDCONTEXT hContext, DWORD dwClientID,
- SCARDHANDLE hCard)
+LONG MSGRemoveHandle(SCARDHANDLE hCard, DWORD dwContextIndex)
{
- int i, j;
+ int i;
- for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
{
- /*
- * I have introduced this verification but it generates a bug
- * when SCardDisconnect is called.
- * Perhaps a modification to do in the future. (D. Sauveron)
- */
- /* if (psContext[i].hContext == hContext && */
- /* psContext[i].dwClientID == dwClientID) */
- if (psContext[i].dwClientID == dwClientID)
+ if (psContext[dwContextIndex].hCard[i] == hCard)
{
- for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
- {
- if (psContext[i].hCard[j] == hCard)
- {
- psContext[i].hCard[j] = 0;
- return SCARD_S_SUCCESS;
- }
- }
+ psContext[dwContextIndex].hCard[i] = 0;
+ return SCARD_S_SUCCESS;
}
}
@@ -317,25 +393,20 @@
}
-LONG MSGCheckHandleAssociation(DWORD dwClientID, SCARDHANDLE hCard)
+LONG MSGCheckHandleAssociation(SCARDHANDLE hCard, DWORD dwContextIndex)
{
- int i, j;
+ int i;
- for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
{
- if (psContext[i].dwClientID == dwClientID)
+ if (psContext[dwContextIndex].hCard[i] == hCard)
{
- for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
- {
- if (psContext[i].hCard[j] == hCard)
- {
- return 0;
- }
- }
+ return 0;
}
}
-
+
/* Must be a rogue client, debug log and sleep a couple of seconds */
DebugLogA("MSGCheckHandleAssociation: Client failed to authenticate\n");
SYS_Sleep(2);
@@ -343,18 +414,16 @@
return -1;
}
-LONG MSGCleanupClient(psharedSegmentMsg msgStruct)
+LONG MSGCleanupClient(DWORD dwContextIndex)
{
- int i;
- for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
- {
- if (psContext[i].dwClientID == msgStruct->request_id)
- {
- MSGRemoveContext(psContext[i].hContext,
- msgStruct->request_id);
- }
- }
+ if (psContext[dwContextIndex].hContext == 0)
+ return 0;
+
+ SCardReleaseContext(psContext[dwContextIndex].hContext);
+ MSGRemoveContext(psContext[dwContextIndex].hContext, dwContextIndex);
+ psContext[dwContextIndex].dwClientID = 0;
+
return 0;
}