[Pcsclite-cvs-commit] r4434 - in /trunk/PCSC/src: eventhandler.c pcscd.h.in pcscdaemon.c readerfactory.c winscard.c winscard_clnt.c winscard_msg.c winscard_msg.h winscard_msg_srv.c winscard_svc.c
rousseau at users.alioth.debian.org
rousseau at users.alioth.debian.org
Tue Oct 6 09:37:51 UTC 2009
Author: rousseau
Date: Tue Oct 6 09:37:51 2009
New Revision: 4434
URL: http://svn.debian.org/wsvn/pcsclite/?sc=1&rev=4434
Log:
redesign the client/server communication:
- no more shared memory used (allow pcscd and libpcsclite1.so to be on
different computer and talk over a network)
- no more difference between short and extended APDU
- no more use of a /var/run/pcscd/pcscd.events/ directory. events are
sent through the socket
- simpler command format between client and server
The side effect is that you are not able to mix an old pcscd with a new
libpcsclite1.so or the reverse. SCardEstablishContext() will fail unless
you update both sides of the communication.
Modified:
trunk/PCSC/src/eventhandler.c
trunk/PCSC/src/pcscd.h.in
trunk/PCSC/src/pcscdaemon.c
trunk/PCSC/src/readerfactory.c
trunk/PCSC/src/winscard.c
trunk/PCSC/src/winscard_clnt.c
trunk/PCSC/src/winscard_msg.c
trunk/PCSC/src/winscard_msg.h
trunk/PCSC/src/winscard_msg_srv.c
trunk/PCSC/src/winscard_svc.c
Modified: trunk/PCSC/src/eventhandler.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/eventhandler.c?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/eventhandler.c (original)
+++ trunk/PCSC/src/eventhandler.c Tue Oct 6 09:37:51 2009
@@ -39,7 +39,7 @@
#include "winscard_svc.h"
#include "simclist.h"
-static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
+READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
static list_t ClientsWaitingForEvent; /**< list of client file descriptors */
PCSCLITE_MUTEX_T ClientsWaitingForEvent_lock; /**< lock for the above list */
@@ -104,59 +104,29 @@
LONG EHInitializeEventStructures(void)
{
- int fd, i, pageSize;
- int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
-
- fd = 0;
- i = 0;
- pageSize = 0;
-
- (void)SYS_RemoveFile(PCSCLITE_PUBSHM_FILE);
-
- fd = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDWR | O_CREAT, mode);
- if (fd < 0)
- {
- Log3(PCSC_LOG_CRITICAL, "Cannot create public shared file %s: %s",
- PCSCLITE_PUBSHM_FILE, strerror(errno));
- exit(1);
- }
-
- /* set correct mode even is umask is too restictive */
- (void)SYS_Chmod(PCSCLITE_PUBSHM_FILE, mode);
-
- pageSize = SYS_GetPageSize();
-
- /*
- * Jump to end of file space and allocate zero's
- */
- (void)SYS_SeekFile(fd, pageSize * PCSCLITE_MAX_READERS_CONTEXTS);
- (void)SYS_WriteFile(fd, "", 1);
-
- /*
- * Allocate each reader structure
- */
+ int i;
+
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
- readerStates[i] = (PREADER_STATE)
- SYS_MemoryMap(sizeof(READER_STATE), fd, (i * pageSize));
- if (readerStates[i] == MAP_FAILED)
- {
- Log3(PCSC_LOG_CRITICAL, "Cannot memory map public shared file %s: %s",
- PCSCLITE_PUBSHM_FILE, strerror(errno));
- exit(1);
- }
-
- /*
- * Zero out each value in the struct
- */
- memset((readerStates[i])->readerName, 0, MAX_READERNAME);
- memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
- (readerStates[i])->readerID = 0;
- (readerStates[i])->readerState = 0;
- (readerStates[i])->readerSharing = 0;
- (readerStates[i])->cardAtrLength = 0;
- (readerStates[i])->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
- }
+ /* Zero out each value in the struct */
+ memset(readerStates[i].readerName, 0, MAX_READERNAME);
+ memset(readerStates[i].cardAtr, 0, MAX_ATR_SIZE);
+ readerStates[i].readerID = 0;
+ readerStates[i].readerState = 0;
+ readerStates[i].readerSharing = 0;
+ readerStates[i].cardAtrLength = 0;
+ readerStates[i].cardProtocol = SCARD_PROTOCOL_UNDEFINED;
+ }
+
+ list_init(&ClientsWaitingForEvent);
+
+ /* request to store copies, and provide the metric function */
+ list_attributes_copy(&ClientsWaitingForEvent, list_meter_int32_t, 1);
+
+ /* setting the comparator, so the list can sort, find the min, max etc */
+ list_attributes_comparator(&ClientsWaitingForEvent, list_comparator_int32_t);
+
+ SYS_MutexInit(ClientsWaitingForEvent_lock);
return SCARD_S_SUCCESS;
}
@@ -247,7 +217,7 @@
*/
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
- if ((readerStates[i])->readerID == 0)
+ if (readerStates[i].readerID == 0)
break;
}
@@ -257,7 +227,7 @@
/*
* Set all the attributes to this reader
*/
- rContext->readerState = readerStates[i];
+ rContext->readerState = &readerStates[i];
(void)strlcpy(rContext->readerState->readerName, rContext->lpcReader,
sizeof(rContext->readerState->readerName));
memcpy(rContext->readerState->cardAtr, ucAtr, dwAtrLen);
@@ -377,7 +347,7 @@
rContext->readerState->readerSharing = dwReaderSharing =
rContext->dwContexts;
- (void)StatSynchronize(rContext->readerState);
+ (void)EHSignalEventToClients();
while (1)
{
@@ -408,7 +378,7 @@
dwCurrentState = SCARD_UNKNOWN;
- (void)StatSynchronize(rContext->readerState);
+ (void)EHSignalEventToClients();
}
if (dwStatus & SCARD_ABSENT)
@@ -438,7 +408,7 @@
incrementEventCounter(rContext->readerState);
- (void)StatSynchronize(rContext->readerState);
+ (void)EHSignalEventToClients();
}
}
@@ -485,7 +455,7 @@
incrementEventCounter(rContext->readerState);
- (void)StatSynchronize(rContext->readerState);
+ (void)EHSignalEventToClients();
Log2(PCSC_LOG_INFO, "Card inserted into %s", lpcReader);
@@ -512,7 +482,7 @@
{
dwReaderSharing = rContext->dwContexts;
rContext->readerState->readerSharing = dwReaderSharing;
- (void)StatSynchronize(rContext->readerState);
+ (void)EHSignalEventToClients();
}
if (rContext->pthCardEvent)
@@ -531,7 +501,7 @@
/*
* Exit and notify the caller
*/
- (void)StatSynchronize(rContext->readerState);
+ (void)EHSignalEventToClients();
Log1(PCSC_LOG_INFO, "Die");
rContext->dwLockId = 0;
(void)SYS_ThreadExit(NULL);
Modified: trunk/PCSC/src/pcscd.h.in
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/pcscd.h.in?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/pcscd.h.in (original)
+++ trunk/PCSC/src/pcscd.h.in Tue Oct 6 09:37:51 2009
@@ -30,19 +30,13 @@
#define PCSCLITE_RUN_PID PCSCLITE_IPC_DIR "/pcscd.pid"
#define PCSCLITE_READER_CONFIG PCSCLITE_CONFIG_DIR "/reader.conf"
-#define PCSCLITE_PUBSHM_FILE PCSCLITE_IPC_DIR "/pcscd.pub"
#define PCSCLITE_CSOCK_NAME PCSCLITE_IPC_DIR "/pcscd.comm"
-#define PCSCLITE_EVENTS_DIR PCSCLITE_IPC_DIR "/pcscd.events"
#define PCSCLITE_SVC_IDENTITY 0x01030000 /**< Service ID */
-
-#define PCSCLITE_INFINITE_TIMEOUT 4320000 /**< 50 day infinite t/o */
#define PCSCLITE_VERSION_NUMBER "@VERSION@" /**< Current version */
#define PCSCLITE_WRITE_TIMEOUT 1000 /**< write timeout */
#define PCSCLITE_READ_TIMEOUT 120*1000 /**< read timeout */
-#define PCSCLITE_CLIENT_ATTEMPTS 120 /**< Attempts to reach sv */
-#define PCSCLITE_MCLIENT_ATTEMPTS 20 /**< Attempts to reach sv */
#define PCSCLITE_STATUS_POLL_RATE 400000 /**< Status polling rate */
#define PCSCLITE_LOCK_POLL_RATE 100000 /**< Lock polling rate */
@@ -62,14 +56,7 @@
#define MAX_LIBNAME 100
#define MAX_DEVICENAME 255
-/*
- * The message and buffer sizes must be multiples of 16.
- * The max message size must be at least large enough
- * to accomodate the transmit_struct
- */
-#define PCSCLITE_MAX_MESSAGE_SIZE 2048 /**< Transport msg len */
-#define MAX_BUFFER_SIZE 264 /**< Maximum Tx/Rx Buffer for short APDU */
-#define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3) /**< enhanced (64K + APDU + Lc + Le) Tx/Rx Buffer */
-#define PCSCLITE_SERVER_ATTEMPTS 5 /**< Attempts to reach cl */
+#define MAX_BUFFER_SIZE 264 /**< Maximum Tx/Rx Buffer for get/set attributes */
+#define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3) /**< max APDU (64K + APDU + Lc + Le) Tx/Rx Buffer */
#endif
Modified: trunk/PCSC/src/pcscdaemon.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/pcscdaemon.c?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/pcscdaemon.c (original)
+++ trunk/PCSC/src/pcscdaemon.c Tue Oct 6 09:37:51 2009
@@ -305,10 +305,10 @@
}
/*
- * test the presence of /var/run/pcscd/pcsc.pub
- */
-
- rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &fStatBuf);
+ * test the presence of /var/run/pcscd/pcscd.comm
+ */
+
+ rv = SYS_Stat(PCSCLITE_CSOCK_NAME, &fStatBuf);
if (rv == 0)
{
@@ -327,7 +327,7 @@
if (kill(pid, 0) == 0)
{
Log1(PCSC_LOG_CRITICAL,
- "file " PCSCLITE_PUBSHM_FILE " already exists.");
+ "file " PCSCLITE_CSOCK_NAME " already exists.");
Log2(PCSC_LOG_CRITICAL,
"Another pcscd (pid: %d) seems to be running.", pid);
return EXIT_FAILURE;
@@ -346,13 +346,12 @@
}
Log1(PCSC_LOG_CRITICAL,
- "file " PCSCLITE_PUBSHM_FILE " already exists.");
+ "file " PCSCLITE_CSOCK_NAME " already exists.");
Log1(PCSC_LOG_CRITICAL,
"Maybe another pcscd is running?");
Log1(PCSC_LOG_CRITICAL,
"I can't read process pid from " PCSCLITE_RUN_PID);
- Log1(PCSC_LOG_CRITICAL,
- "Remove " PCSCLITE_PUBSHM_FILE " and " PCSCLITE_CSOCK_NAME);
+ Log1(PCSC_LOG_CRITICAL, "Remove " PCSCLITE_CSOCK_NAME);
Log1(PCSC_LOG_CRITICAL,
"if pcscd is not running to clear this message.");
return EXIT_FAILURE;
@@ -429,25 +428,6 @@
else
Log2(PCSC_LOG_CRITICAL, "cannot create " PCSCLITE_RUN_PID ": %s",
strerror(errno));
- }
-
- /*
- * If PCSCLITE_EVENTS does not exist then create it
- */
- rv = SYS_Stat(PCSCLITE_EVENTS_DIR, &fStatBuf);
- if (rv < 0)
- {
- /* 1733 : world writable + sticky bit */
- int mode = S_IRWXU | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH | S_ISVTX;
-
- rv = SYS_Mkdir(PCSCLITE_EVENTS_DIR, mode);
- if (rv != 0)
- {
- Log2(PCSC_LOG_CRITICAL,
- "cannot create " PCSCLITE_EVENTS_DIR ": %s", strerror(errno));
- return EXIT_FAILURE;
- }
- (void)SYS_Chmod(PCSCLITE_EVENTS_DIR, mode);
}
/* cleanly remove /var/run/pcscd/pcsc.* files when exiting */
@@ -540,11 +520,6 @@
{
int rv;
- rv = SYS_RemoveFile(PCSCLITE_PUBSHM_FILE);
- if (rv != 0)
- Log2(PCSC_LOG_ERROR, "Cannot remove " PCSCLITE_PUBSHM_FILE ": %s",
- strerror(errno));
-
rv = SYS_RemoveFile(PCSCLITE_CSOCK_NAME);
if (rv != 0)
Log2(PCSC_LOG_ERROR, "Cannot remove " PCSCLITE_CSOCK_NAME ": %s",
@@ -553,13 +528,6 @@
rv = SYS_RemoveFile(PCSCLITE_RUN_PID);
if (rv != 0)
Log2(PCSC_LOG_ERROR, "Cannot remove " PCSCLITE_RUN_PID ": %s",
- strerror(errno));
-
- (void)StatSynchronize(NULL);
- SYS_Sleep(1);
- rv = SYS_RemoveFile(PCSCLITE_EVENTS_DIR);
- if (rv != 0)
- Log2(PCSC_LOG_ERROR, "Cannot remove " PCSCLITE_EVENTS_DIR ": %s",
strerror(errno));
}
Modified: trunk/PCSC/src/readerfactory.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/readerfactory.c?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/readerfactory.c (original)
+++ trunk/PCSC/src/readerfactory.c Tue Oct 6 09:37:51 2009
@@ -470,7 +470,7 @@
dwNumReadersContexts -= 1;
/* signal an event to clients */
- StatSynchronize(NULL);
+ (void)EHSignalEventToClients();
}
return SCARD_S_SUCCESS;
Modified: trunk/PCSC/src/winscard.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard.c?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/winscard.c (original)
+++ trunk/PCSC/src/winscard.c Tue Oct 6 09:37:51 2009
@@ -499,10 +499,9 @@
}
/*
- * Propagate new state to Shared Memory
+ * Propagate new state to reader state
*/
rContext->readerState->readerSharing = rContext->dwContexts;
- (void)StatSynchronize(rContext->readerState);
PROFILE_END
@@ -812,10 +811,9 @@
(void)RFClearReaderEventState(rContext, hCard);
/*
- * Propagate new state to Shared Memory
+ * Propagate new state to reader state
*/
rContext->readerState->readerSharing = rContext->dwContexts;
- (void)StatSynchronize(rContext->readerState);
return SCARD_S_SUCCESS;
}
@@ -995,10 +993,9 @@
}
/*
- * Propagate new state to Shared Memory
+ * Propagate new state to reader state
*/
rContext->readerState->readerSharing = rContext->dwContexts;
- (void)StatSynchronize(rContext->readerState);
return SCARD_S_SUCCESS;
}
Modified: trunk/PCSC/src/winscard_clnt.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_clnt.c?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_clnt.c (original)
+++ trunk/PCSC/src/winscard_clnt.c Tue Oct 6 09:37:51 2009
@@ -229,12 +229,9 @@
static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
/**
- * Pointers to a memory mapped area used to read status information about the
- * readers.
- * Each element in the vector \ref readerStates makes references to a part of
- * the memory mapped \ref mapAddr.
- */
-static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
+ * Area used to read status information about the readers.
+ */
+static READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 }; /**< Protocol Control Information for T=0 */
PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 }; /**< Protocol Control Information for T=1 */
@@ -258,6 +255,7 @@
LPBYTE pbAttr, LPDWORD pcbAttrLen);
void DESTRUCTOR SCardUnload(void);
+static LONG getReaderStates(LONG dwContextIndex);
/*
* Thread safety functions
@@ -378,7 +376,6 @@
LONG rv;
int i;
establish_struct scEstablishStruct;
- sharedSegmentMsg msgStruct;
uint32_t dwClientID = 0;
(void)pvReserved1;
@@ -397,47 +394,10 @@
*/
if (isExecuted == 0)
{
- int pageSize;
-
/*
* Do any system initilization here
*/
(void)SYS_Initialize();
-
- /*
- * Set up the memory mapped reader stats structures
- */
- mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
- if (mapAddr < 0)
- {
- Log3(PCSC_LOG_CRITICAL, "Cannot open public shared file %s: %s",
- PCSCLITE_PUBSHM_FILE, strerror(errno));
- return SCARD_E_NO_SERVICE;
- }
-
- /* close on exec so that child processes do not inherits the file
- * descriptor. The child process will call SCardEstablishContext()
- * if needed. */
- (void)fcntl(mapAddr, F_SETFD, FD_CLOEXEC);
-
- pageSize = SYS_GetPageSize();
-
- /*
- * Allocate each reader structure in the memory map
- */
- for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
- {
- readerStates[i] =
- (PREADER_STATE)SYS_PublicMemoryMap(sizeof(READER_STATE),
- mapAddr, (i * pageSize));
- if (readerStates[i] == NULL)
- {
- Log2(PCSC_LOG_CRITICAL, "Cannot public memory map: %s",
- strerror(errno));
- (void)SYS_CloseFile(mapAddr); /* Close the memory map file */
- return SCARD_F_INTERNAL_ERROR;
- }
- }
/*
* Initializes the application contexts and all channels for each one
@@ -484,43 +444,32 @@
/* Establishes a connection to the server */
if (SHMClientSetupSession(&dwClientID) != 0)
{
- (void)SYS_CloseFile(mapAddr);
return SCARD_E_NO_SERVICE;
}
{ /* exchange client/server protocol versions */
- version_struct *veStr;
-
- memset(&msgStruct, 0, sizeof(msgStruct));
- msgStruct.mtype = CMD_VERSION;
- msgStruct.user_id = SYS_GetUID();
- msgStruct.group_id = SYS_GetGID();
- msgStruct.command = 0;
- msgStruct.date = time(NULL);
-
- veStr = &msgStruct.veStr;
- veStr->major = PROTOCOL_VERSION_MAJOR;
- veStr->minor = PROTOCOL_VERSION_MINOR;
-
- if (-1 == SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
- PCSCLITE_MCLIENT_ATTEMPTS))
+ version_struct veStr;
+
+ veStr.major = PROTOCOL_VERSION_MAJOR;
+ veStr.minor = PROTOCOL_VERSION_MINOR;
+
+ if (-1 == SHMMessageSendWithHeader(CMD_VERSION, dwClientID, sizeof(veStr),
+ PCSCLITE_WRITE_TIMEOUT, &veStr))
return SCARD_E_NO_SERVICE;
- /*
- * Read a message from the server
- */
- if (-1 == SHMMessageReceive(&msgStruct, sizeof(msgStruct), dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS))
+ /* Read a message from the server */
+ if (-1 == SHMMessageReceive(&veStr, sizeof(veStr), dwClientID,
+ PCSCLITE_READ_TIMEOUT))
{
Log1(PCSC_LOG_CRITICAL, "Your pcscd is too old and does not support CMD_VERSION");
return SCARD_F_COMM_ERROR;
}
Log3(PCSC_LOG_INFO, "Server is protocol version %d:%d",
- veStr->major, veStr->minor);
-
- if (veStr->rv != SCARD_S_SUCCESS)
- return veStr->rv;
+ veStr.major, veStr.minor);
+
+ if (veStr.rv != SCARD_S_SUCCESS)
+ return veStr.rv;
isExecuted = 1;
}
@@ -533,8 +482,8 @@
scEstablishStruct.hContext = 0;
scEstablishStruct.rv = SCARD_S_SUCCESS;
- rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
- sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
+ rv = SHMMessageSendWithHeader(SCARD_ESTABLISH_CONTEXT, dwClientID,
+ sizeof(scEstablishStruct), PCSCLITE_WRITE_TIMEOUT,
(void *) &scEstablishStruct);
if (rv == -1)
@@ -543,12 +492,10 @@
/*
* Read the response from the server
*/
- rv = SHMClientRead(&msgStruct, dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
+ rv = SHMMessageReceive(&scEstablishStruct, sizeof(scEstablishStruct), dwClientID, PCSCLITE_READ_TIMEOUT);
if (rv == -1)
return SCARD_F_COMM_ERROR;
-
- memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
if (scEstablishStruct.rv != SCARD_S_SUCCESS)
return scEstablishStruct.rv;
@@ -594,7 +541,6 @@
{
LONG rv;
release_struct scReleaseStruct;
- sharedSegmentMsg msgStruct;
LONG dwContextIndex;
PROFILE_START
@@ -636,10 +582,10 @@
scReleaseStruct.hContext = hContext;
scReleaseStruct.rv = SCARD_S_SUCCESS;
- rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT,
+ rv = SHMMessageSendWithHeader(SCARD_RELEASE_CONTEXT,
psContextMap[dwContextIndex].dwClientID,
sizeof(scReleaseStruct),
- PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
+ PCSCLITE_WRITE_TIMEOUT, (void *) &scReleaseStruct);
if (rv == -1)
{
@@ -650,9 +596,9 @@
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
- memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
+ rv = SHMMessageReceive(&scReleaseStruct, sizeof(scReleaseStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
if (rv == -1)
{
@@ -757,7 +703,6 @@
{
LONG rv;
connect_struct scConnectStruct;
- sharedSegmentMsg msgStruct;
LONG dwContextIndex;
PROFILE_START
@@ -809,9 +754,9 @@
scConnectStruct.dwActiveProtocol = 0;
scConnectStruct.rv = SCARD_S_SUCCESS;
- rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
sizeof(scConnectStruct),
- PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
+ PCSCLITE_READ_TIMEOUT, (void *) &scConnectStruct);
if (rv == -1)
{
@@ -822,10 +767,9 @@
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
+ rv = SHMMessageReceive(&scConnectStruct, sizeof(scConnectStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
if (rv == -1)
{
@@ -929,7 +873,6 @@
{
LONG rv;
reconnect_struct scReconnectStruct;
- sharedSegmentMsg msgStruct;
int i;
DWORD dwContextIndex, dwChannelIndex;
@@ -959,19 +902,24 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
/* by default r == NULL */
- if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+ if (r && strcmp(r, readerStates[i].readerName) == 0)
break;
}
if (i == PCSCLITE_MAX_READERS_CONTEXTS)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_READER_UNAVAILABLE;
+ rv = SCARD_E_READER_UNAVAILABLE;
+ goto end;
}
do
@@ -983,9 +931,9 @@
scReconnectStruct.dwActiveProtocol = *pdwActiveProtocol;
scReconnectStruct.rv = SCARD_S_SUCCESS;
- rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
sizeof(scReconnectStruct),
- PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
+ PCSCLITE_READ_TIMEOUT, (void *) &scReconnectStruct);
if (rv == -1)
{
@@ -996,25 +944,27 @@
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
+ rv = SHMMessageReceive(&scReconnectStruct,
+ sizeof(scReconnectStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
if (rv == -1)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
+ rv = SCARD_F_COMM_ERROR;
+ goto end;
}
} while (SCARD_E_SHARING_VIOLATION == scReconnectStruct.rv);
*pdwActiveProtocol = scReconnectStruct.dwActiveProtocol;
-
+ rv = scReconnectStruct.rv;
+
+end:
(void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- PROFILE_END(scReconnectStruct.rv)
-
- return scReconnectStruct.rv;
+ PROFILE_END(rv)
+
+ return rv;
}
/**
@@ -1051,7 +1001,6 @@
{
LONG rv;
disconnect_struct scDisconnectStruct;
- sharedSegmentMsg msgStruct;
DWORD dwContextIndex, dwChannelIndex;
PROFILE_START
@@ -1081,9 +1030,9 @@
scDisconnectStruct.dwDisposition = dwDisposition;
scDisconnectStruct.rv = SCARD_S_SUCCESS;
- rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
sizeof(scDisconnectStruct),
- PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
+ PCSCLITE_READ_TIMEOUT, (void *) &scDisconnectStruct);
if (rv == -1)
{
@@ -1094,11 +1043,10 @@
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- memcpy(&scDisconnectStruct, &msgStruct.data,
- sizeof(scDisconnectStruct));
+ rv = SHMMessageReceive(&scDisconnectStruct,
+ sizeof(scDisconnectStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
if (rv == -1)
{
@@ -1156,7 +1104,6 @@
LONG rv;
begin_struct scBeginStruct;
int i;
- sharedSegmentMsg msgStruct;
DWORD dwContextIndex, dwChannelIndex;
PROFILE_START
@@ -1182,19 +1129,24 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
/* by default r == NULL */
- if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+ if (r && strcmp(r, readerStates[i].readerName) == 0)
break;
}
if (i == PCSCLITE_MAX_READERS_CONTEXTS)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_READER_UNAVAILABLE;
+ rv = SCARD_E_READER_UNAVAILABLE;
+ goto end;
}
scBeginStruct.hCard = hCard;
@@ -1207,40 +1159,39 @@
do
{
- rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
sizeof(scBeginStruct),
- PCSCLITE_CLIENT_ATTEMPTS, (void *) &scBeginStruct);
+ PCSCLITE_READ_TIMEOUT, (void *) &scBeginStruct);
if (rv == -1)
{
-
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_NO_SERVICE;
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
}
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- memcpy(&scBeginStruct, &msgStruct.data, sizeof(scBeginStruct));
+ rv = SHMMessageReceive(&scBeginStruct, sizeof(scBeginStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
if (rv == -1)
{
-
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
+ rv = SCARD_F_COMM_ERROR;
+ goto end;
}
}
while (scBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
-
+ rv = scBeginStruct.rv;
+
+end:
(void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- PROFILE_END(scBeginStruct.rv);
-
- return scBeginStruct.rv;
+ PROFILE_END(rv);
+
+ return rv;
}
/**
@@ -1287,7 +1238,6 @@
{
LONG rv;
end_struct scEndStruct;
- sharedSegmentMsg msgStruct;
int randnum, i;
DWORD dwContextIndex, dwChannelIndex;
@@ -1319,48 +1269,52 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
/* by default r == NULL */
- if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+ if (r && strcmp(r, readerStates[i].readerName) == 0)
break;
}
if (i == PCSCLITE_MAX_READERS_CONTEXTS)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_READER_UNAVAILABLE;
+ rv = SCARD_E_READER_UNAVAILABLE;
+ goto end;
}
scEndStruct.hCard = hCard;
scEndStruct.dwDisposition = dwDisposition;
scEndStruct.rv = SCARD_S_SUCCESS;
- rv = WrapSHMWrite(SCARD_END_TRANSACTION,
+ rv = SHMMessageSendWithHeader(SCARD_END_TRANSACTION,
psContextMap[dwContextIndex].dwClientID,
sizeof(scEndStruct),
- PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_NO_SERVICE;
+ PCSCLITE_READ_TIMEOUT, (void *) &scEndStruct);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
}
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
+ rv = SHMMessageReceive(&scEndStruct, sizeof(scEndStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_F_COMM_ERROR;
+ goto end;
}
/*
@@ -1368,12 +1322,14 @@
*/
randnum = SYS_RandomInt(1000, 10000);
(void)SYS_USleep(randnum);
-
+ rv = scEndStruct.rv;
+
+end:
(void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- PROFILE_END(scEndStruct.rv)
-
- return scEndStruct.rv;
+ PROFILE_END(rv)
+
+ return rv;
}
/**
@@ -1385,8 +1341,7 @@
LONG SCardCancelTransaction(SCARDHANDLE hCard)
{
LONG rv;
- cancel_struct scCancelStruct;
- sharedSegmentMsg msgStruct;
+ cancel_transaction_struct scCancelStruct;
int i;
DWORD dwContextIndex, dwChannelIndex;
@@ -1413,53 +1368,59 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
/* by default r == NULL */
- if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+ if (r && strcmp(r, readerStates[i].readerName) == 0)
break;
}
if (i == PCSCLITE_MAX_READERS_CONTEXTS)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_READER_UNAVAILABLE;
+ rv = SCARD_E_READER_UNAVAILABLE;
+ goto end;
}
scCancelStruct.hCard = hCard;
- rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION,
+ rv = SHMMessageSendWithHeader(SCARD_CANCEL_TRANSACTION,
psContextMap[dwContextIndex].dwClientID,
sizeof(scCancelStruct),
- PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_NO_SERVICE;
+ PCSCLITE_READ_TIMEOUT, (void *) &scCancelStruct);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
}
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
- }
-
+ rv = SHMMessageReceive(&scCancelStruct, sizeof(scCancelStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_F_COMM_ERROR;
+ goto end;
+ }
+ rv = scCancelStruct.rv;
+
+end:
(void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- PROFILE_END(scCancelStruct.rv)
-
- return scCancelStruct.rv;
+ PROFILE_END(rv)
+
+ return rv;
}
/**
@@ -1557,7 +1518,6 @@
LONG rv;
int i;
status_struct scStatusStruct;
- sharedSegmentMsg msgStruct;
DWORD dwContextIndex, dwChannelIndex;
char *r;
char *bufReader = NULL;
@@ -1608,11 +1568,16 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
/* by default r == NULL */
- if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+ if (r && strcmp(r, readerStates[i].readerName) == 0)
break;
}
@@ -1630,9 +1595,9 @@
scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
- rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
+ rv = SHMMessageSendWithHeader(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
sizeof(scStatusStruct),
- PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
+ PCSCLITE_READ_TIMEOUT, (void *) &scStatusStruct);
if (rv == -1)
{
@@ -1643,10 +1608,9 @@
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
+ rv = SHMMessageReceive(&scStatusStruct, sizeof(scStatusStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
if (rv == -1)
{
@@ -1668,13 +1632,13 @@
*/
*pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
- *pcbAtrLen = (readerStates[i])->cardAtrLength;
+ *pcbAtrLen = readerStates[i].cardAtrLength;
if (pdwState)
- *pdwState = (readerStates[i])->readerState;
+ *pdwState = readerStates[i].readerState;
if (pdwProtocol)
- *pdwProtocol = (readerStates[i])->cardProtocol;
+ *pdwProtocol = readerStates[i].cardProtocol;
if (SCARD_AUTOALLOCATE == dwReaderLen)
{
@@ -1730,7 +1694,7 @@
if (*pcbAtrLen > dwAtrLen)
rv = SCARD_E_INSUFFICIENT_BUFFER;
- memcpy(bufAtr, (readerStates[i])->cardAtr, min(*pcbAtrLen, dwAtrLen));
+ memcpy(bufAtr, readerStates[i].cardAtr, min(*pcbAtrLen, dwAtrLen));
}
end:
@@ -1739,63 +1703,6 @@
PROFILE_END(rv)
return rv;
-}
-
-static long WaitForPcscdEvent(SCARDCONTEXT hContext, long dwTime)
-{
- char filename[FILENAME_MAX];
- char buf[1];
- int fd, r;
- struct timeval tv, *ptv = NULL;
- struct timeval before, after;
- fd_set read_fd;
-
- if (INFINITE != dwTime)
- {
- if (dwTime < 0)
- return 0;
- gettimeofday(&before, NULL);
- tv.tv_sec = dwTime/1000;
- tv.tv_usec = dwTime*1000 - tv.tv_sec*1000000;
- ptv = &tv;
- }
-
- (void)snprintf(filename, sizeof(filename), "%s/event.%d.%ld",
- PCSCLITE_EVENTS_DIR, SYS_GetPID(), hContext);
- r = mkfifo(filename, 0644);
- if (-1 == r)
- {
- Log2(PCSC_LOG_CRITICAL, "Can't create event fifo: %s", strerror(errno));
- goto exit;
- }
-
- fd = SYS_OpenFile(filename, O_RDONLY | O_NONBLOCK, 0);
-
- /* the file may have been removed between the mkfifo() and open() */
- if (-1 != fd)
- {
- FD_ZERO(&read_fd);
- FD_SET(fd, &read_fd);
-
- (void)select(fd+1, &read_fd, NULL, NULL, ptv);
-
- (void)SYS_ReadFile(fd, buf, 1);
- (void)SYS_CloseFile(fd);
- }
-
- (void)SYS_RemoveFile(filename);
-
- if (INFINITE != dwTime)
- {
- long int diff;
-
- gettimeofday(&after, NULL);
- diff = time_sub(&after, &before);
- dwTime -= diff/1000;
- }
-
-exit:
- return dwTime;
}
/**
@@ -1894,7 +1801,7 @@
{
PSCARD_READERSTATE_A currReader;
PREADER_STATE rContext;
- long dwTime = dwTimeout;
+ long dwTime;
DWORD dwState;
DWORD dwBreakFlag = 0;
int j;
@@ -1952,6 +1859,11 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
/* Clear the event state for all readers */
for (j = 0; j < cReaders; j++)
rgReaderStates[j].dwEventState = 0;
@@ -1963,8 +1875,13 @@
/* Get the initial reader count on the system */
for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
- if ((readerStates[j])->readerID != 0)
+ if (readerStates[j].readerID != 0)
currentReaderCount++;
+
+ if (INFINITE == dwTimeout)
+ dwTime = 60*1000; /* "infinite" timeout */
+ else
+ dwTime = dwTimeout;
j = 0;
do
@@ -1994,7 +1911,7 @@
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
- if (strcmp(lpcReaderName, (readerStates[i])->readerName) == 0)
+ if (strcmp(lpcReaderName, readerStates[i].readerName) == 0)
break;
}
@@ -2007,7 +1924,7 @@
int k, newReaderCount = 0;
for (k=0; k < PCSCLITE_MAX_READERS_CONTEXTS; k++)
- if ((readerStates[k])->readerID != 0)
+ if (readerStates[k].readerID != 0)
newReaderCount++;
if (newReaderCount != currentReaderCount)
@@ -2048,7 +1965,7 @@
/*****************************************************************/
/* Set the reader status structure */
- rContext = readerStates[i];
+ rContext = &readerStates[i];
/* Now we check all the Reader States */
dwState = rContext->readerState;
@@ -2255,7 +2172,80 @@
break;
/* Only sleep once for each cycle of reader checks. */
- dwTime = WaitForPcscdEvent(hContext, dwTime);
+ {
+ struct wait_reader_state_change waitStatusStruct;
+ struct timeval before, after;
+
+ gettimeofday(&before, NULL);
+
+ waitStatusStruct.timeOut = dwTime;
+
+ rv = SHMMessageSendWithHeader(CMD_WAIT_READER_STATE_CHANGE,
+ psContextMap[dwContextIndex].dwClientID,
+ sizeof(waitStatusStruct), PCSCLITE_WRITE_TIMEOUT,
+ &waitStatusStruct);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMMessageReceive(&waitStatusStruct, sizeof(waitStatusStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ dwTime);
+
+ /* timeout */
+ if (-1 == rv)
+ {
+ /* aask server to remove us from the event list */
+ rv = SHMMessageSendWithHeader(CMD_STOP_WAITING_READER_STATE_CHANGE,
+ psContextMap[dwContextIndex].dwClientID,
+ sizeof(waitStatusStruct), PCSCLITE_WRITE_TIMEOUT,
+ &waitStatusStruct);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
+
+ /* Read a message from the server */
+ rv = SHMMessageReceive(&waitStatusStruct, sizeof(waitStatusStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ dwTime);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
+ }
+
+ /* an event occurs or SCardCancel() was called */
+ if (SCARD_S_SUCCESS != waitStatusStruct.rv)
+ {
+ rv = waitStatusStruct.rv;
+ goto end;
+ }
+
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
+ if (INFINITE != dwTimeout)
+ {
+ long int diff;
+
+ gettimeofday(&after, NULL);
+ diff = time_sub(&after, &before);
+ dwTime -= diff/1000;
+ }
+ }
if (dwTimeout != INFINITE)
{
@@ -2341,8 +2331,7 @@
LPDWORD lpBytesReturned)
{
LONG rv;
- control_struct scControlStruct;
- sharedSegmentMsg msgStruct;
+ struct control_struct scControlStruct;
int i;
DWORD dwContextIndex, dwChannelIndex;
@@ -2376,155 +2365,92 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
/* by default r == NULL */
- if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+ if (r && strcmp(r, readerStates[i].readerName) == 0)
break;
}
if (i == PCSCLITE_MAX_READERS_CONTEXTS)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_READER_UNAVAILABLE;
+ rv = SCARD_E_READER_UNAVAILABLE;
+ goto end;
}
if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
|| (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_INSUFFICIENT_BUFFER;
- }
-
- if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
- {
- /* extended control */
- unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
- control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
- sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
-
- scControlStructExtended->hCard = hCard;
- scControlStructExtended->dwControlCode = dwControlCode;
- scControlStructExtended->cbSendLength = cbSendLength;
- scControlStructExtended->cbRecvLength = cbRecvLength;
- scControlStructExtended->dwBytesReturned = 0;
- scControlStructExtended->rv = SCARD_S_SUCCESS;
- /* The size of data to send is the size of
- * struct control_struct_extended WITHOUT the data[] field
- * plus the effective data[] size
- */
- scControlStructExtended->size = sizeof(*scControlStructExtended)
- - (sizeof(control_struct_extended) - offsetof(control_struct_extended, data))
- + cbSendLength;
- memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
-
- rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
+ rv = SCARD_E_INSUFFICIENT_BUFFER;
+ goto end;
+ }
+
+ scControlStruct.hCard = hCard;
+ scControlStruct.dwControlCode = dwControlCode;
+ scControlStruct.cbSendLength = cbSendLength;
+ scControlStruct.cbRecvLength = cbRecvLength;
+
+ rv = SHMMessageSendWithHeader(SCARD_CONTROL,
+ psContextMap[dwContextIndex].dwClientID,
+ sizeof(scControlStruct), PCSCLITE_READ_TIMEOUT, &scControlStruct);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
+
+ /* write the sent buffer */
+ rv = SHMMessageSend((char *)pbSendBuffer, cbSendLength,
+ psContextMap[dwContextIndex].dwClientID, PCSCLITE_WRITE_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMMessageReceive(&scControlStruct, sizeof(scControlStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_F_COMM_ERROR;
+ goto end;
+ }
+
+ if (SCARD_S_SUCCESS == scControlStruct.rv)
+ {
+ /* read the received buffer */
+ rv = SHMMessageReceive(pbRecvBuffer, scControlStruct.dwBytesReturned,
psContextMap[dwContextIndex].dwClientID,
- scControlStructExtended->size,
- PCSCLITE_CLIENT_ATTEMPTS, buffer);
+ PCSCLITE_READ_TIMEOUT);
if (rv == -1)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_NO_SERVICE;
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
}
- /*
- * Read a message from the server
- */
- /* read the first block */
- rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg),
- psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
- }
-
- /* we receive a sharedSegmentMsg and not a control_struct_extended */
- scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
-
- /* a second block is present */
- if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
- {
- rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
- scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
- psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
- }
- }
-
- if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
- {
- /*
- * Copy and zero it so any secret information is not leaked
- */
- memcpy(pbRecvBuffer, scControlStructExtended -> data,
- scControlStructExtended -> dwBytesReturned);
- memset(scControlStructExtended -> data, 0x00,
- scControlStructExtended -> dwBytesReturned);
- }
-
- if (NULL != lpBytesReturned)
- *lpBytesReturned = scControlStructExtended -> dwBytesReturned;
-
- rv = scControlStructExtended -> rv;
- }
- else
- {
- scControlStruct.hCard = hCard;
- scControlStruct.dwControlCode = dwControlCode;
- scControlStruct.cbSendLength = cbSendLength;
- scControlStruct.cbRecvLength = cbRecvLength;
- memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
-
- rv = WrapSHMWrite(SCARD_CONTROL,
- psContextMap[dwContextIndex].dwClientID,
- sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_NO_SERVICE;
- }
-
- /*
- * Read a message from the server
- */
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
- }
-
- memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
-
- if (NULL != lpBytesReturned)
- *lpBytesReturned = scControlStruct.dwBytesReturned;
-
- if (scControlStruct.rv == SCARD_S_SUCCESS)
- {
- /*
- * Copy and zero it so any secret information is not leaked
- */
- memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
- scControlStruct.cbRecvLength);
- memset(scControlStruct.pbRecvBuffer, 0x00,
- sizeof(scControlStruct.pbRecvBuffer));
- }
-
- rv = scControlStruct.rv;
- }
-
+ }
+
+ if (NULL != lpBytesReturned)
+ *lpBytesReturned = scControlStruct.dwBytesReturned;
+
+ rv = scControlStruct.rv;
+
+end:
(void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
PROFILE_END(rv)
@@ -2728,8 +2654,7 @@
LPBYTE pbAttr, LPDWORD pcbAttrLen)
{
LONG rv;
- getset_struct scGetSetStruct;
- sharedSegmentMsg msgStruct;
+ struct getset_struct scGetSetStruct;
int i;
DWORD dwContextIndex, dwChannelIndex;
@@ -2754,25 +2679,30 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
/* by default r == NULL */
- if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+ if (r && strcmp(r, readerStates[i].readerName) == 0)
break;
}
if (i == PCSCLITE_MAX_READERS_CONTEXTS)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_READER_UNAVAILABLE;
+ rv = SCARD_E_READER_UNAVAILABLE;
+ goto end;
}
if (*pcbAttrLen > MAX_BUFFER_SIZE)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_INSUFFICIENT_BUFFER;
+ rv = SCARD_E_INSUFFICIENT_BUFFER;
+ goto end;
}
scGetSetStruct.hCard = hCard;
@@ -2783,29 +2713,28 @@
if (SCARD_SET_ATTRIB == command)
memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
- rv = WrapSHMWrite(command,
+ rv = SHMMessageSendWithHeader(command,
psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
- PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_NO_SERVICE;
+ PCSCLITE_READ_TIMEOUT, &scGetSetStruct);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
}
/*
* Read a message from the server
*/
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
- }
-
- memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
+ rv = SHMMessageReceive(&scGetSetStruct, sizeof(scGetSetStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_F_COMM_ERROR;
+ goto end;
+ }
if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
{
@@ -2825,10 +2754,12 @@
memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
}
-
+ rv = scGetSetStruct.rv;
+
+end:
(void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return scGetSetStruct.rv;
+ return rv;
}
/**
@@ -2897,6 +2828,7 @@
LONG rv;
int i;
DWORD dwContextIndex, dwChannelIndex;
+ struct transmit_struct scTransmitStruct;
PROFILE_START
@@ -2929,200 +2861,109 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
/* by default r == NULL */
- if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+ if (r && strcmp(r, readerStates[i].readerName) == 0)
break;
}
if (i == PCSCLITE_MAX_READERS_CONTEXTS)
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_READER_UNAVAILABLE;
+ rv = SCARD_E_READER_UNAVAILABLE;
+ goto end;
}
if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
|| (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
{
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_INSUFFICIENT_BUFFER;
- }
-
- if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
- {
- /* extended APDU */
- unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
- transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
- sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
-
- scTransmitStructExtended->hCard = hCard;
- scTransmitStructExtended->cbSendLength = cbSendLength;
- scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
- /* The size of data to send is the size of
- * struct control_struct_extended WITHOUT the data[] field
- * plus the effective data[] size
- */
- scTransmitStructExtended->size = sizeof(*scTransmitStructExtended)
- - (sizeof(transmit_struct_extended) - offsetof(transmit_struct_extended, data))
- + cbSendLength;
- scTransmitStructExtended->ioSendPciProtocol = pioSendPci->dwProtocol;
- scTransmitStructExtended->ioSendPciLength = pioSendPci->cbPciLength;
- memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
- scTransmitStructExtended->rv = SCARD_S_SUCCESS;
+ rv = SCARD_E_INSUFFICIENT_BUFFER;
+ goto end;
+ }
+
+ scTransmitStruct.hCard = hCard;
+ scTransmitStruct.cbSendLength = cbSendLength;
+ scTransmitStruct.pcbRecvLength = *pcbRecvLength;
+ scTransmitStruct.ioSendPciProtocol = pioSendPci->dwProtocol;
+ scTransmitStruct.ioSendPciLength = pioSendPci->cbPciLength;
+ scTransmitStruct.rv = SCARD_S_SUCCESS;
+
+ if (pioRecvPci)
+ {
+ scTransmitStruct.ioRecvPciProtocol = pioRecvPci->dwProtocol;
+ scTransmitStruct.ioRecvPciLength = pioRecvPci->cbPciLength;
+ }
+ else
+ {
+ scTransmitStruct.ioRecvPciProtocol = SCARD_PROTOCOL_ANY;
+ scTransmitStruct.ioRecvPciLength = sizeof(SCARD_IO_REQUEST);
+ }
+
+ rv = SHMMessageSendWithHeader(SCARD_TRANSMIT,
+ psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
+ PCSCLITE_WRITE_TIMEOUT, (void *) &scTransmitStruct);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
+
+ /* write the sent buffer */
+ rv = SHMMessageSend((void *)pbSendBuffer, cbSendLength,
+ psContextMap[dwContextIndex].dwClientID, PCSCLITE_WRITE_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMMessageReceive(&scTransmitStruct, sizeof(scTransmitStruct),
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_F_COMM_ERROR;
+ goto end;
+ }
+
+ if (SCARD_S_SUCCESS == scTransmitStruct.rv)
+ {
+ /* read the received buffer */
+ rv = SHMMessageReceive(pbRecvBuffer, scTransmitStruct.pcbRecvLength,
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_READ_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
if (pioRecvPci)
{
- scTransmitStructExtended->ioRecvPciProtocol = pioRecvPci->dwProtocol;
- scTransmitStructExtended->ioRecvPciLength = pioRecvPci->cbPciLength;
+ pioRecvPci->dwProtocol = scTransmitStruct.ioRecvPciProtocol;
+ pioRecvPci->cbPciLength = scTransmitStruct.ioRecvPciLength;
}
- else
- {
- scTransmitStructExtended->ioRecvPciProtocol = SCARD_PROTOCOL_ANY;
- scTransmitStructExtended->ioRecvPciLength = sizeof(SCARD_IO_REQUEST);
- }
-
- rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
- psContextMap[dwContextIndex].dwClientID,
- scTransmitStructExtended->size,
- PCSCLITE_CLIENT_ATTEMPTS, buffer);
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_NO_SERVICE;
- }
-
- /*
- * Read a message from the server
- */
- /* read the first block */
- rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
- }
-
- /* we receive a sharedSegmentMsg and not a transmit_struct_extended */
- scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
-
- /* a second block is present */
- if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
- {
- rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
- scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
- psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
- }
- }
-
- if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
- {
- /*
- * Copy and zero it so any secret information is not leaked
- */
- memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
- scTransmitStructExtended -> pcbRecvLength);
- memset(scTransmitStructExtended -> data, 0x00,
- scTransmitStructExtended -> pcbRecvLength);
-
- if (pioRecvPci)
- {
- pioRecvPci->dwProtocol = scTransmitStructExtended->ioRecvPciProtocol;
- pioRecvPci->cbPciLength = scTransmitStructExtended->ioRecvPciLength;
- }
- }
-
- *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
-
- rv = scTransmitStructExtended -> rv;
- }
- else
- {
- /* short APDU */
- transmit_struct scTransmitStruct;
- sharedSegmentMsg msgStruct;
-
- scTransmitStruct.hCard = hCard;
- scTransmitStruct.cbSendLength = cbSendLength;
- scTransmitStruct.pcbRecvLength = *pcbRecvLength;
- scTransmitStruct.ioSendPciProtocol = pioSendPci->dwProtocol;
- scTransmitStruct.ioSendPciLength = pioSendPci->cbPciLength;
- memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
- memset(scTransmitStruct.pbSendBuffer+cbSendLength, 0, sizeof(scTransmitStruct.pbSendBuffer)-cbSendLength);
- memset(scTransmitStruct.pbRecvBuffer, 0, sizeof(scTransmitStruct.pbRecvBuffer));
- scTransmitStruct.rv = SCARD_S_SUCCESS;
-
- if (pioRecvPci)
- {
- scTransmitStruct.ioRecvPciProtocol = pioRecvPci->dwProtocol;
- scTransmitStruct.ioRecvPciLength = pioRecvPci->cbPciLength;
- }
- else
- {
- scTransmitStruct.ioRecvPciProtocol = SCARD_PROTOCOL_ANY;
- scTransmitStruct.ioRecvPciLength = sizeof(SCARD_IO_REQUEST);
- }
-
- rv = WrapSHMWrite(SCARD_TRANSMIT,
- psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
- PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_E_NO_SERVICE;
- }
-
- /*
- * Read a message from the server
- */
- rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,
- PCSCLITE_CLIENT_ATTEMPTS);
-
- memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
-
- if (rv == -1)
- {
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
- return SCARD_F_COMM_ERROR;
- }
-
- /*
- * Zero it and free it so any secret information cannot be leaked
- */
- memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
-
- if (scTransmitStruct.rv == SCARD_S_SUCCESS)
- {
- /*
- * Copy and zero it so any secret information is not leaked
- */
- memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
- scTransmitStruct.pcbRecvLength);
- memset(scTransmitStruct.pbRecvBuffer, 0x00,
- scTransmitStruct.pcbRecvLength);
-
- if (pioRecvPci)
- {
- pioRecvPci->dwProtocol = scTransmitStruct.ioRecvPciProtocol;
- pioRecvPci->cbPciLength = scTransmitStruct.ioRecvPciLength;
- }
- }
-
- *pcbRecvLength = scTransmitStruct.pcbRecvLength;
- (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
-
- rv = scTransmitStruct.rv;
- }
+ }
+
+ *pcbRecvLength = scTransmitStruct.pcbRecvLength;
+ rv = scTransmitStruct.rv;
+
+end:
+ (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
PROFILE_END(rv)
@@ -3180,7 +3021,7 @@
LONG SCardListReaders(SCARDCONTEXT hContext, /*@unused@*/ LPCSTR mszGroups,
LPSTR mszReaders, LPDWORD pcchReaders)
{
- DWORD dwReadersLen;
+ DWORD dwReadersLen = 0;
int i;
LONG dwContextIndex;
LONG rv = SCARD_S_SUCCESS;
@@ -3219,10 +3060,15 @@
* -> so the mMutex has been unlocked */
return SCARD_E_INVALID_HANDLE;
+ /* synchronize reader states with daemon */
+ rv = getReaderStates(dwContextIndex);
+ if (rv != SCARD_S_SUCCESS)
+ goto end;
+
dwReadersLen = 0;
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
- if ((readerStates[i])->readerID != 0)
- dwReadersLen += strlen((readerStates[i])->readerName) + 1;
+ if (readerStates[i].readerID != 0)
+ dwReadersLen += strlen(readerStates[i].readerName) + 1;
/* for the last NULL byte */
dwReadersLen += 1;
@@ -3265,13 +3111,13 @@
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
{
- if ((readerStates[i])->readerID != 0)
+ if (readerStates[i].readerID != 0)
{
/*
* Build the multi-string
*/
- strcpy(buf, (readerStates[i])->readerName);
- buf += strlen((readerStates[i])->readerName)+1;
+ strcpy(buf, readerStates[i].readerName);
+ buf += strlen(readerStates[i].readerName)+1;
}
}
*buf = '\0'; /* Add the last null */
@@ -3477,9 +3323,14 @@
{
LONG dwContextIndex;
LONG rv = SCARD_S_SUCCESS;
+ uint32_t dwClientID = 0;
+ struct cancel_struct scCancelStruct;
PROFILE_START
+ /*
+ * Make sure this context has been opened
+ */
dwContextIndex = SCardGetContextIndice(hContext);
if (dwContextIndex == -1)
return SCARD_E_INVALID_HANDLE;
@@ -3490,9 +3341,44 @@
*/
psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
- if (StatSynchronizeContext(hContext))
- rv = SCARD_F_INTERNAL_ERROR;
-
+ /* create a new connection to the server */
+ if (SHMClientSetupSession(&dwClientID) != 0)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto error;
+ }
+
+ scCancelStruct.hContext = hContext;
+ scCancelStruct.rv = SCARD_S_SUCCESS;
+
+ rv = SHMMessageSendWithHeader(SCARD_CANCEL,
+ dwClientID,
+ sizeof(scCancelStruct), PCSCLITE_READ_TIMEOUT, (void *)
+ &scCancelStruct);
+
+ if (rv == -1)
+ {
+ rv = SCARD_E_NO_SERVICE;
+ goto end;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMMessageReceive(&scCancelStruct, sizeof(scCancelStruct),
+ dwClientID, PCSCLITE_READ_TIMEOUT);
+
+ if (rv == -1)
+ {
+ rv = SCARD_F_COMM_ERROR;
+ goto end;
+ }
+
+ rv = scCancelStruct.rv;
+end:
+ SHMClientCloseSession(dwClientID);
+
+error:
PROFILE_END(rv)
return rv;
@@ -3774,11 +3660,11 @@
struct stat statBuffer;
int need_restart = 0;
- rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
+ rv = SYS_Stat(PCSCLITE_CSOCK_NAME, &statBuffer);
if (rv != 0)
{
- Log2(PCSC_LOG_INFO, "PCSC Not Running: " PCSCLITE_PUBSHM_FILE ": %s",
+ Log2(PCSC_LOG_INFO, "PCSC Not Running: " PCSCLITE_CSOCK_NAME ": %s",
strerror(errno));
return SCARD_E_NO_SERVICE;
}
@@ -3819,9 +3705,6 @@
daemon_ctime = 0;
client_pid = 0;
- /* reset the lib */
- SCardUnload();
-
return SCARD_E_INVALID_HANDLE;
}
@@ -3863,3 +3746,19 @@
isExecuted = 0;
}
+static LONG getReaderStates(LONG dwContextIndex)
+{
+ int32_t dwClientID = psContextMap[dwContextIndex].dwClientID;
+
+ if (-1 == SHMMessageSendWithHeader(CMD_GET_READERS_STATE, dwClientID, 0,
+ PCSCLITE_WRITE_TIMEOUT, NULL))
+ return SCARD_E_NO_SERVICE;
+
+ /* Read a message from the server */
+ if (-1 == SHMMessageReceive(&readerStates, sizeof(readerStates), dwClientID,
+ PCSCLITE_READ_TIMEOUT))
+ return SCARD_F_COMM_ERROR;
+
+ return SCARD_S_SUCCESS;
+}
+
Modified: trunk/PCSC/src/winscard_msg.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_msg.c?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_msg.c (original)
+++ trunk/PCSC/src/winscard_msg.c Tue Oct 6 09:37:51 2009
@@ -44,22 +44,6 @@
#include "utils.h"
/**
- * @brief Wrapper for the SHMMessageReceive() function.
- *
- * Called by clients to read the server responses.
- *
- * @param[out] msgStruct Message read.
- * @param[in] dwClientID Client socket handle.
- * @param[in] blockamount Timeout in milliseconds.
- *
- * @return Same error codes as SHMMessageReceive().
- */
-INTERNAL int32_t SHMClientRead(psharedSegmentMsg msgStruct, uint32_t dwClientID, int32_t blockamount)
-{
- return SHMMessageReceive(msgStruct, sizeof(*msgStruct), dwClientID, blockamount);
-}
-
-/**
* @brief Prepares a communication channel for the client to talk to the server.
*
* This is called by the application to create a socket for local IPC with the
@@ -149,28 +133,39 @@
int retval = 0;
/* record the time when we started */
- time_t start = time(0);
+ struct timeval start;
/* how many bytes remains to be written */
size_t remaining = buffer_size;
+
+ gettimeofday(&start, NULL);
/* repeat until all data is written */
while (remaining > 0)
{
fd_set write_fd;
- struct timeval timeout;
+ struct timeval timeout, now;
int selret;
-
- FD_ZERO(&write_fd);
- FD_SET(filedes, &write_fd);
-
- timeout.tv_usec = 0;
- if ((timeout.tv_sec = start + timeOut - time(0)) < 0)
+ long delta;
+
+ gettimeofday(&now, NULL);
+ delta = time_sub(&now, &start);
+
+ if (delta > timeOut*1000)
{
/* we already timed out */
retval = -1;
break;
}
+
+ /* remaining time to wait */
+ delta = timeOut*1000 - delta;
+
+ FD_ZERO(&write_fd);
+ FD_SET(filedes, &write_fd);
+
+ timeout.tv_sec = delta/1000000;
+ timeout.tv_usec = delta - timeout.tv_sec*1000000;
selret = select(filedes + 1, NULL, &write_fd, NULL, &timeout);
@@ -252,29 +247,40 @@
int retval = 0;
/* record the time when we started */
- time_t start = time(0);
+ struct timeval start;
/* how many bytes we must read */
size_t remaining = buffer_size;
+
+ gettimeofday(&start, NULL);
/* repeat until we get the whole message */
while (remaining > 0)
{
fd_set read_fd;
- struct timeval timeout;
+ struct timeval timeout, now;
int selret;
-
- FD_ZERO(&read_fd);
- FD_SET(filedes, &read_fd);
-
- timeout.tv_usec = 0;
- if ((timeout.tv_sec = start + timeOut - time(0)) < 0)
+ long delta;
+
+ gettimeofday(&now, NULL);
+ delta = time_sub(&now, &start);
+
+ if (delta > timeOut*1000)
{
/* we already timed out */
retval = -1;
break;
}
+ /* remaining time to wait */
+ delta = timeOut*1000 - delta;
+
+ FD_ZERO(&read_fd);
+ FD_SET(filedes, &read_fd);
+
+ timeout.tv_sec = delta/1000000;
+ timeout.tv_usec = delta - timeout.tv_sec*1000000;
+
selret = select(filedes + 1, &read_fd, NULL, NULL, &timeout);
/* try to read only when socket is readable */
@@ -297,9 +303,7 @@
remaining -= readed;
} else if (readed == 0)
{
- /*
- * peer closed the socket
- */
+ /* peer closed the socket */
retval = -1;
break;
} else
@@ -327,9 +331,6 @@
break;
}
- /* the command is extra slow so we keep waiting */
- start = time(0);
-
/* you need to set the env variable PCSCLITE_DEBUG=0 since
* this is logged on the client side and not on the pcscd
* side*/
@@ -366,58 +367,19 @@
*
* @return Same error codes as SHMMessageSend().
*/
-INTERNAL int32_t WrapSHMWrite(uint32_t command, uint32_t dwClientID,
+INTERNAL int32_t SHMMessageSendWithHeader(uint32_t command, uint32_t dwClientID,
uint64_t size, uint32_t timeOut, void *data_void)
{
- char *data = data_void;
-
- sharedSegmentMsg msgStruct;
+ struct rxHeader header;
int ret;
- /*
- * Set the appropriate packet parameters
- */
-
- memset(&msgStruct, 0, sizeof(msgStruct));
- msgStruct.mtype = CMD_FUNCTION;
- msgStruct.user_id = SYS_GetUID();
- msgStruct.group_id = SYS_GetGID();
- msgStruct.command = command;
- msgStruct.date = time(NULL);
- if ((SCARD_TRANSMIT_EXTENDED == command)
- || (SCARD_CONTROL_EXTENDED == command))
- {
- /* first block */
- if (size > sizeof(msgStruct.data))
- memcpy(msgStruct.data, data, sizeof(msgStruct.data));
- else
- {
- memcpy(msgStruct.data, data, size);
- memset(msgStruct.data+size, 0, sizeof(msgStruct.data)-size);
- }
-
- ret = SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
- timeOut);
-
- /* do not send an empty second block */
- if ((0 == ret) && (size > sizeof(msgStruct.data)))
- {
- /* second block */
- ret = SHMMessageSend(data+sizeof(msgStruct.data),
- size-sizeof(msgStruct.data), dwClientID, timeOut);
- }
- }
- else
- {
- memcpy(msgStruct.data, data, size);
-
- ret = SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
- timeOut);
- }
-
- if (SCARD_TRANSMIT == command)
- /* clean APDU buffer to remove any possible PIN or secret value */
- memset(msgStruct.data, 0, min(size, sizeof(msgStruct.data)));
+ /* header */
+ header.command = command;
+ header.size = size;
+ ret = SHMMessageSend(&header, sizeof(header), dwClientID, timeOut);
+
+ /* command */
+ ret = SHMMessageSend(data_void, size, dwClientID, timeOut);
return ret;
}
Modified: trunk/PCSC/src/winscard_msg.h
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_msg.h?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_msg.h (original)
+++ trunk/PCSC/src/winscard_msg.h Tue Oct 6 09:37:51 2009
@@ -21,7 +21,7 @@
#include <stdint.h>
/** Major version of the current message protocol */
-#define PROTOCOL_VERSION_MAJOR 3
+#define PROTOCOL_VERSION_MAJOR 4
/** Minor version of the current message protocol */
#define PROTOCOL_VERSION_MINOR 0
@@ -42,44 +42,12 @@
typedef struct version_struct version_struct;
/**
- * @brief General structure for client/serve message data exchange.
- *
- * It is used in the calls of \c SHMMessageSend and \c SHMMessageReceive.
- * The field \c data is interpreted according to the values of the fields
- * \c mtype and \c command. The possible structs the \c data field can
- * represent are: \c version_struct \c client_struct \c establish_struct
- * \c release_struct \c connect_struct \c reconnect_struct
- * \c disconnect_struct \c begin_struct \c end_struct \c cancel_struct
- * \c status_struct \c transmit_struct \c control_struct \c getset_struct
- */
- typedef struct rxSharedSegment
- {
- uint32_t mtype; /** one of the \c pcsc_adm_commands */
- uint32_t user_id;
- uint32_t group_id;
- uint32_t command; /** one of the \c pcsc_msg_commands */
- uint64_t date;
- union
- {
- unsigned char data[PCSCLITE_MAX_MESSAGE_SIZE];
- struct version_struct veStr;
- };
- }
- sharedSegmentMsg, *psharedSegmentMsg;
-
- /**
- * Command types available to use in the field \c sharedSegmentMsg.mtype.
- */
- enum pcsc_adm_commands
- {
- CMD_FUNCTION = 0xF1,
- CMD_FAILED = 0xF2,
- CMD_SERVER_DIED = 0xF3,
- CMD_CLIENT_DIED = 0xF4,
- CMD_READER_EVENT = 0xF5,
- CMD_SYN = 0xF6,
- CMD_ACK = 0xF7,
- CMD_VERSION = 0xF8 /**< version of the IPC */
+ * @brief header structure for client/server message data exchange.
+ */
+ struct rxHeader
+ {
+ uint32_t size; /**< size of the message expluding this header */
+ uint32_t command; /**< one of the \c pcsc_msg_commands */
};
/**
@@ -100,11 +68,13 @@
SCARD_STATUS = 0x0B, /**< used by SCardStatus() */
SCARD_GET_STATUS_CHANGE = 0x0C, /**< used by SCardGetStatusChange() */
SCARD_CANCEL = 0x0D, /**< used by SCardCancel() */
- SCARD_CANCEL_TRANSACTION = 0x0E,
+ SCARD_CANCEL_TRANSACTION = 0x0E, /**< used by SCardCancelTransaction() */
SCARD_GET_ATTRIB = 0x0F, /**< used by SCardGetAttrib() */
SCARD_SET_ATTRIB = 0x10, /**< used by SCardSetAttrib() */
- SCARD_TRANSMIT_EXTENDED = 0x11, /**< used by SCardTransmit() */
- SCARD_CONTROL_EXTENDED = 0x12 /**< used by SCardControl() */
+ CMD_VERSION = 0x11, /**< get the client/server protocol version */
+ CMD_GET_READERS_STATE = 0x12, /**< get the readers state */
+ CMD_WAIT_READER_STATE_CHANGE = 0x13, /**< wait for a reader state change */
+ CMD_STOP_WAITING_READER_STATE_CHANGE = 0x14 /**< stop waiting for a reader state change */
};
struct client_struct
@@ -225,10 +195,22 @@
*/
struct cancel_struct
{
- int32_t hCard;
+ int32_t hContext;
uint32_t rv;
};
typedef struct cancel_struct cancel_struct;
+
+ /**
+ * @brief contained in \ref SCARD_CANCEL_TRANSACTION Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct cancel_transaction_struct
+ {
+ int32_t hCard;
+ uint32_t rv;
+ };
+ typedef struct cancel_transaction_struct cancel_transaction_struct;
/**
* @brief contained in \ref SCARD_STATUS Messages.
@@ -258,35 +240,13 @@
int32_t hCard;
uint32_t ioSendPciProtocol;
uint32_t ioSendPciLength;
- uint8_t pbSendBuffer[MAX_BUFFER_SIZE];
- uint32_t cbSendLength;
- uint32_t ioRecvPciProtocol;
- uint32_t ioRecvPciLength;
- uint8_t pbRecvBuffer[MAX_BUFFER_SIZE];
- uint32_t pcbRecvLength;
- uint32_t rv;
- };
- typedef struct transmit_struct transmit_struct;
-
- /**
- * @brief contained in \ref SCARD_TRANSMIT_EXTENDED Messages.
- *
- * These data are passed throw the field \c sharedSegmentMsg.data.
- */
- struct transmit_struct_extended
- {
- int32_t hCard;
- uint32_t ioSendPciProtocol;
- uint32_t ioSendPciLength;
uint32_t cbSendLength;
uint32_t ioRecvPciProtocol;
uint32_t ioRecvPciLength;
uint32_t pcbRecvLength;
uint32_t rv;
- uint64_t size;
- uint8_t data[1];
- };
- typedef struct transmit_struct_extended transmit_struct_extended;
+ };
+ typedef struct transmit_struct transmit_struct;
/**
* @brief contained in \ref SCARD_CONTROL Messages.
@@ -294,24 +254,6 @@
* These data are passed throw the field \c sharedSegmentMsg.data.
*/
struct control_struct
- {
- int32_t hCard;
- uint32_t dwControlCode;
- uint8_t pbSendBuffer[MAX_BUFFER_SIZE];
- uint32_t cbSendLength;
- uint8_t pbRecvBuffer[MAX_BUFFER_SIZE];
- uint32_t cbRecvLength;
- uint32_t dwBytesReturned;
- uint32_t rv;
- };
- typedef struct control_struct control_struct;
-
- /**
- * @brief contained in \ref SCARD_CONTROL_EXTENDED Messages.
- *
- * These data are passed throw the field \c sharedSegmentMsg.data.
- */
- struct control_struct_extended
{
int32_t hCard;
uint32_t dwControlCode;
@@ -319,8 +261,6 @@
uint32_t cbRecvLength;
uint32_t dwBytesReturned;
uint32_t rv;
- uint64_t size;
- uint8_t data[1];
};
typedef struct control_struct_extended control_struct_extended;
@@ -343,17 +283,15 @@
* Now some function definitions
*/
- int32_t SHMClientRead(psharedSegmentMsg, uint32_t, int32_t);
int32_t SHMClientSetupSession(uint32_t *);
int32_t SHMClientCloseSession(uint32_t);
int32_t SHMInitializeCommonSegment(void);
- int32_t SHMProcessEventsContext(uint32_t, /*@out@*/ psharedSegmentMsg);
int32_t SHMProcessEventsServer(/*@out@*/ uint32_t *);
int32_t SHMMessageSend(void *buffer, uint64_t buffer_size, int32_t filedes,
int32_t blockAmount);
int32_t SHMMessageReceive(/*@out@*/ void *buffer, uint64_t buffer_size,
int32_t filedes, int32_t blockAmount);
- int32_t WrapSHMWrite(uint32_t command, uint32_t dwClientID, uint64_t size,
+ int32_t SHMMessageSendWithHeader(uint32_t command, uint32_t dwClientID, uint64_t size,
uint32_t blockAmount, void *data);
void SHMCleanupSharedSegment(int32_t, const char *);
Modified: trunk/PCSC/src/winscard_msg_srv.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_msg_srv.c?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_msg_srv.c (original)
+++ trunk/PCSC/src/winscard_msg_srv.c Tue Oct 6 09:37:51 2009
@@ -49,29 +49,6 @@
extern char AraKiri;
extern char ReCheckSerialReaders;
-static const char *CommandsText[] = {
- "CMD_VERSION", /* mtype = 0xF8 and command = 0x00 */
- "ESTABLISH_CONTEXT", /* mtype = 0xF1 */
- "RELEASE_CONTEXT",
- "LIST_READERS",
- "CONNECT",
- "RECONNECT",
- "DISCONNECT",
- "BEGIN_TRANSACTION",
- "END_TRANSACTION",
- "TRANSMIT",
- "CONTROL",
- "STATUS",
- "GET_STATUS_CHANGE",
- "CANCEL",
- "CANCEL_TRANSACTION",
- "GET_ATTRIB",
- "SET_ATTRIB",
- "TRANSMIT_EXTENDED",
- "CONTROL_EXTENDED",
- "NULL"
-};
-
/**
* @brief Accepts a Client connection.
*
@@ -82,14 +59,12 @@
* @return Error code.
* @retval 0 Success.
* @retval -1 Can not establish the connection.
- * @retval -1 Can not set the connection to non-blocking mode.
*/
static int SHMProcessCommonChannelRequest(/*@out@*/ uint32_t *pdwClientID)
{
socklen_t clnt_len;
int new_sock;
struct sockaddr_un clnt_addr;
- int one;
clnt_len = sizeof(clnt_addr);
@@ -102,16 +77,6 @@
}
*pdwClientID = new_sock;
-
- one = 1;
- if (ioctl(*pdwClientID, FIONBIO, &one) < 0)
- {
- Log2(PCSC_LOG_CRITICAL, "Error: cannot set socket nonblocking: %s",
- strerror(errno));
- (void)SYS_CloseFile(*pdwClientID);
- *pdwClientID = -1;
- return -1;
- }
return 0;
}
@@ -184,7 +149,7 @@
* @return Error code.
* @retval 0 Success.
* @retval -1 Error accessing the communication channel.
- * @retval -1 Can not set the connection to non-blocking mode.
+ * @retval -2 EINTR
* @retval 2 Timeout.
*/
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
@@ -242,82 +207,14 @@
Log2(PCSC_LOG_ERROR,
"error in SHMProcessCommonChannelRequest: %d", *pdwClientID);
return -1;
- } else
- {
- Log2(PCSC_LOG_DEBUG,
- "SHMProcessCommonChannelRequest detects: %d", *pdwClientID);
- return 0;
}
}
-
- return -1;
+ else
+ return -1;
+
+ Log2(PCSC_LOG_DEBUG,
+ "SHMProcessCommonChannelRequest detects: %d", *pdwClientID);
+
+ return 0;
}
-/**
- * @brief
- *
- * Called by \c ContextThread().
- */
-INTERNAL int32_t SHMProcessEventsContext(uint32_t dwClientID,
- psharedSegmentMsg msgStruct)
-{
- fd_set read_fd;
- int selret, rv;
-#ifdef DO_TIMEOUT
- struct timeval tv;
-
- tv.tv_sec = 1;
- tv.tv_usec = 0;
-#endif
-
- FD_ZERO(&read_fd);
- FD_SET(dwClientID, &read_fd);
-
- selret = select(dwClientID + 1, &read_fd, (fd_set *) NULL,
- (fd_set *) NULL,
-#ifdef DO_TIMEOUT
- &tv
-#else
- NULL
-#endif
- );
-
- if (selret < 0)
- {
- Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
- strerror(errno));
- return -1;
- }
-
- if (selret == 0)
- /* timeout */
- return 2;
-
- if (FD_ISSET(dwClientID, &read_fd))
- {
- /*
- * Return the current handle
- */
- rv = SHMMessageReceive(msgStruct, sizeof(*msgStruct), dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
-
- if (rv == -1)
- { /* The client has died */
- Log2(PCSC_LOG_DEBUG, "Client has disappeared: %d", dwClientID);
- msgStruct->mtype = CMD_CLIENT_DIED;
- msgStruct->command = 0;
- (void)SYS_CloseFile(dwClientID);
-
- return 0;
- }
-
- /*
- * Set the identifier handle
- */
- Log3(PCSC_LOG_DEBUG, "command %s received by client %d", CommandsText[msgStruct->command], dwClientID);
- return 1;
- }
-
- return -1;
-}
-
Modified: trunk/PCSC/src/winscard_svc.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/winscard_svc.c?rev=4434&op=diff
==============================================================================
--- trunk/PCSC/src/winscard_svc.c (original)
+++ trunk/PCSC/src/winscard_svc.c Tue Oct 6 09:37:51 2009
@@ -33,6 +33,7 @@
#include "sys_generic.h"
#include "thread_generic.h"
#include "readerfactory.h"
+#include "eventhandler.h"
/**
* @brief Represents an Application Context on the Server side.
@@ -45,12 +46,10 @@
uint32_t hCard[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
uint32_t dwClientID; /**< Connection ID used to reference the Client. */
PCSCLITE_THREAD_T pthThread; /**< Event polling thread's ID */
- sharedSegmentMsg msgStruct; /**< Msg sent by the Client */
int protocol_major, protocol_minor; /**< Protocol number agreed between client and server*/
} psContext[PCSCLITE_MAX_APPLICATIONS_CONTEXTS];
static LONG MSGCheckHandleAssociation(SCARDHANDLE, DWORD);
-static LONG MSGFunctionDemarshall(psharedSegmentMsg, DWORD);
static LONG MSGAddContext(SCARDCONTEXT, DWORD);
static LONG MSGRemoveContext(SCARDCONTEXT, DWORD);
static LONG MSGAddHandle(SCARDCONTEXT, SCARDHANDLE, DWORD);
@@ -58,6 +57,8 @@
static LONG MSGCleanupClient(DWORD);
static void ContextThread(LPVOID pdwIndex);
+
+extern READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
LONG ContextsInitialize(void)
{
@@ -131,559 +132,525 @@
* @param[in] dwIndex Index of an avaiable Application Context slot in
* \c psContext.
*/
+static const char *CommandsText[] = {
+ "NULL",
+ "ESTABLISH_CONTEXT", /* 0x01 */
+ "RELEASE_CONTEXT",
+ "LIST_READERS",
+ "CONNECT",
+ "RECONNECT", /* 0x05 */
+ "DISCONNECT",
+ "BEGIN_TRANSACTION",
+ "END_TRANSACTION",
+ "TRANSMIT",
+ "CONTROL", /* 0x0A */
+ "STATUS",
+ "GET_STATUS_CHANGE",
+ "CANCEL",
+ "CANCEL_TRANSACTION",
+ "GET_ATTRIB", /* 0x0F */
+ "SET_ATTRIB",
+ "CMD_VERSION",
+ "CMD_GET_READERS_STATE",
+ "CMD_WAIT_READER_STATE_CHANGE",
+ "CMD_STOP_WAITING_READER_STATE_CHANGE", /* 0x14 */
+ "NULL"
+};
+
+#define READ_BODY(v) \
+ if (header.size != sizeof(v)) {printf("%d %d\n", header.size, sizeof(v)); goto wrong_length;} \
+ ret = SHMMessageReceive(&v, sizeof(v), filedes, PCSCLITE_READ_TIMEOUT); \
+ if (-1 == ret) { Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes); goto exit; }
+
+#define WRITE_BODY(v) \
+ ret = SHMMessageSend(&v, sizeof(v), filedes, PCSCLITE_WRITE_TIMEOUT);
+
static void ContextThread(LPVOID dwIndex)
{
- LONG rv;
- sharedSegmentMsg msgStruct;
DWORD dwContextIndex = (DWORD)dwIndex;
+ int32_t filedes = psContext[dwContextIndex].dwClientID;
Log2(PCSC_LOG_DEBUG, "Thread is started: %d",
psContext[dwContextIndex].dwClientID);
while (1)
{
- switch (rv = SHMProcessEventsContext(psContext[dwContextIndex].dwClientID, &msgStruct))
- {
- case 0:
- if (msgStruct.mtype == CMD_CLIENT_DIED)
- {
- /*
- * Clean up the dead client
- */
- Log2(PCSC_LOG_DEBUG, "Client die: %d",
- psContext[dwContextIndex].dwClientID);
- (void)MSGCleanupClient(dwContextIndex);
- (void)SYS_ThreadExit((LPVOID) NULL);
- }
- break;
-
- case 1:
- if (msgStruct.mtype == CMD_FUNCTION)
- {
- /*
- * Command must be found
- */
- rv = MSGFunctionDemarshall(&msgStruct, dwContextIndex);
- if (rv)
+ struct rxHeader header;
+ int32_t ret = SHMMessageReceive(&header, sizeof(header), filedes, PCSCLITE_READ_TIMEOUT);
+
+ if (-1 == ret)
+ {
+ /* Clean up the dead client */
+ Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
+ goto exit;
+ }
+
+ Log2(PCSC_LOG_DEBUG, "Received command: %s", CommandsText[header.command]);
+
+ switch (header.command)
+ {
+ /* pcsc-lite client/server protocol version */
+ case CMD_VERSION:
+ {
+ struct version_struct veStr;
+
+ READ_BODY(veStr)
+
+ /* get the client protocol version */
+ psContext[dwContextIndex].protocol_major = veStr.major;
+ psContext[dwContextIndex].protocol_minor = veStr.minor;
+
+ Log3(PCSC_LOG_DEBUG,
+ "Client is protocol version %d:%d",
+ veStr.major, veStr.minor);
+
+ veStr.rv = SCARD_S_SUCCESS;
+
+ /* client is newer than server */
+ if ((veStr.major > PROTOCOL_VERSION_MAJOR)
+ || (veStr.major == PROTOCOL_VERSION_MAJOR
+ && veStr.minor > PROTOCOL_VERSION_MINOR))
{
- Log2(PCSC_LOG_DEBUG, "MSGFunctionDemarshall failed: %d",
- rv);
- (void)SHMClientCloseSession(psContext[dwContextIndex].dwClientID);
- (void)MSGCleanupClient(dwContextIndex);
- (void)SYS_ThreadExit((LPVOID) NULL);
- }
-
- /* the SCARD_TRANSMIT_EXTENDED anwser is already sent by
- * MSGFunctionDemarshall */
- if ((msgStruct.command != SCARD_TRANSMIT_EXTENDED)
- && (msgStruct.command != SCARD_CONTROL_EXTENDED))
- rv = SHMMessageSend(&msgStruct, sizeof(msgStruct),
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- }
- else
- /* pcsc-lite client/server protocol version */
- if (msgStruct.mtype == CMD_VERSION)
- {
- version_struct *veStr;
- veStr = &msgStruct.veStr;
-
- /* get the client protocol version */
- psContext[dwContextIndex].protocol_major = veStr->major;
- psContext[dwContextIndex].protocol_minor = veStr->minor;
-
- Log3(PCSC_LOG_DEBUG,
- "Client is protocol version %d:%d",
- veStr->major, veStr->minor);
-
- veStr->rv = SCARD_S_SUCCESS;
-
- /* client is newer than server */
- if ((veStr->major > PROTOCOL_VERSION_MAJOR)
- || (veStr->major == PROTOCOL_VERSION_MAJOR
- && veStr->minor > PROTOCOL_VERSION_MINOR))
- {
- Log3(PCSC_LOG_CRITICAL,
+ Log3(PCSC_LOG_CRITICAL,
"Client protocol is too new %d:%d",
- veStr->major, veStr->minor);
- Log3(PCSC_LOG_CRITICAL,
+ veStr.major, veStr.minor);
+ Log3(PCSC_LOG_CRITICAL,
"Server protocol is %d:%d",
PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR);
- veStr->rv = SCARD_E_NO_SERVICE;
+ veStr.rv = SCARD_E_NO_SERVICE;
+ }
+
+ /* set the server protocol version */
+ veStr.major = PROTOCOL_VERSION_MAJOR;
+ veStr.minor = PROTOCOL_VERSION_MINOR;
+
+ /* send back the response */
+ WRITE_BODY(veStr)
+ }
+ break;
+
+ case CMD_GET_READERS_STATE:
+ {
+ /* nothing to read */
+
+ /* dump the readers state */
+ ret = SHMMessageSend(readerStates, sizeof(readerStates), filedes, PCSCLITE_WRITE_TIMEOUT);
+ }
+ break;
+
+ case CMD_WAIT_READER_STATE_CHANGE:
+ {
+ struct wait_reader_state_change waStr;
+
+ READ_BODY(waStr)
+
+ /* add the client fd to the list */
+ EHRegisterClientForEvent(filedes);
+
+ /* We do not send anything here.
+ * Either the client will timeout or the server will
+ * answer if an event occurs */
+ }
+ break;
+
+ case CMD_STOP_WAITING_READER_STATE_CHANGE:
+ {
+ struct wait_reader_state_change waStr;
+
+ READ_BODY(waStr)
+
+ /* add the client fd to the list */
+ waStr.rv = EHUnregisterClientForEvent(filedes);
+
+ WRITE_BODY(waStr)
+ }
+ break;
+
+ case SCARD_ESTABLISH_CONTEXT:
+ {
+ struct establish_struct esStr;
+ SCARDCONTEXT hContext;
+
+ READ_BODY(esStr)
+
+ hContext = esStr.hContext;
+ esStr.rv = SCardEstablishContext(esStr.dwScope, 0, 0, &hContext);
+ esStr.hContext = hContext;
+
+ if (esStr.rv == SCARD_S_SUCCESS)
+ esStr.rv =
+ MSGAddContext(esStr.hContext, dwContextIndex);
+
+ WRITE_BODY(esStr)
+ }
+ break;
+
+ case SCARD_RELEASE_CONTEXT:
+ {
+ struct release_struct reStr;
+
+ READ_BODY(reStr)
+
+ reStr.rv = SCardReleaseContext(reStr.hContext);
+
+ if (reStr.rv == SCARD_S_SUCCESS)
+ reStr.rv =
+ MSGRemoveContext(reStr.hContext, dwContextIndex);
+
+ WRITE_BODY(reStr)
+ }
+ break;
+
+ case SCARD_CONNECT:
+ {
+ struct connect_struct coStr;
+ SCARDHANDLE hCard;
+ DWORD dwActiveProtocol;
+
+ READ_BODY(coStr)
+
+ hCard = coStr.hCard;
+ dwActiveProtocol = coStr.dwActiveProtocol;
+
+ coStr.rv = SCardConnect(coStr.hContext, coStr.szReader,
+ coStr.dwShareMode, coStr.dwPreferredProtocols,
+ &hCard, &dwActiveProtocol);
+
+ coStr.hCard = hCard;
+ coStr.dwActiveProtocol = dwActiveProtocol;
+
+ if (coStr.rv == SCARD_S_SUCCESS)
+ coStr.rv =
+ MSGAddHandle(coStr.hContext, coStr.hCard, dwContextIndex);
+
+ WRITE_BODY(coStr)
+ }
+ break;
+
+ case SCARD_RECONNECT:
+ {
+ struct reconnect_struct rcStr;
+ DWORD dwActiveProtocol;
+
+ READ_BODY(rcStr)
+
+ if (MSGCheckHandleAssociation(rcStr.hCard, dwContextIndex))
+ goto exit;
+
+ rcStr.rv = SCardReconnect(rcStr.hCard, rcStr.dwShareMode,
+ rcStr.dwPreferredProtocols,
+ rcStr.dwInitialization, &dwActiveProtocol);
+ rcStr.dwActiveProtocol = dwActiveProtocol;
+
+ WRITE_BODY(rcStr)
+ }
+ break;
+
+ case SCARD_DISCONNECT:
+ {
+ struct disconnect_struct diStr;
+ LONG rv;
+
+ READ_BODY(diStr)
+
+ rv = MSGCheckHandleAssociation(diStr.hCard, dwContextIndex);
+ if (0 == rv)
+ {
+ diStr.rv = SCardDisconnect(diStr.hCard, diStr.dwDisposition);
+
+ if (SCARD_S_SUCCESS == diStr.rv)
+ diStr.rv =
+ MSGRemoveHandle(diStr.hCard, dwContextIndex);
+ }
+
+ WRITE_BODY(diStr)
+ }
+ break;
+
+ case SCARD_BEGIN_TRANSACTION:
+ {
+ struct begin_struct beStr;
+ LONG rv;
+
+ READ_BODY(beStr)
+
+ rv = MSGCheckHandleAssociation(beStr.hCard, dwContextIndex);
+ if (0 == rv)
+ beStr.rv = SCardBeginTransaction(beStr.hCard);
+
+ WRITE_BODY(beStr)
+ }
+ break;
+
+ case SCARD_END_TRANSACTION:
+ {
+ struct end_struct enStr;
+ LONG rv;
+
+ READ_BODY(enStr)
+
+ rv = MSGCheckHandleAssociation(enStr.hCard, dwContextIndex);
+ if (0 == rv)
+ enStr.rv =
+ SCardEndTransaction(enStr.hCard, enStr.dwDisposition);
+
+ WRITE_BODY(enStr)
+ }
+ break;
+
+ case SCARD_CANCEL_TRANSACTION:
+ {
+ struct cancel_transaction_struct caStr;
+ LONG rv;
+
+ READ_BODY(caStr)
+
+ rv = MSGCheckHandleAssociation(caStr.hCard, dwContextIndex);
+ if (0 == rv)
+ caStr.rv = SCardCancelTransaction(caStr.hCard);
+
+ WRITE_BODY(caStr)
+ }
+ break;
+
+ case SCARD_CANCEL:
+ {
+ struct cancel_struct caStr;
+ uint32_t fd = 0;
+ int i;
+
+ READ_BODY(caStr)
+
+ /* find the client */
+ for (i=0; i<PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
+ {
+ if (psContext[i].hContext == caStr.hContext)
+ {
+ fd = psContext[i].dwClientID;
+ break;
}
-
- /* set the server protocol version */
- veStr->major = PROTOCOL_VERSION_MAJOR;
- veStr->minor = PROTOCOL_VERSION_MINOR;
-
- /* send back the response */
- rv = SHMMessageSend(&msgStruct, sizeof(msgStruct),
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
}
+
+ if (fd)
+ caStr.rv = MSGSignalClient(fd, SCARD_E_CANCELLED);
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:
- Log1(PCSC_LOG_ERROR, "Error in SHMProcessEventsContext");
- break;
-
- default:
- Log2(PCSC_LOG_ERROR,
- "SHMProcessEventsContext unknown retval: %d", rv);
- break;
+ caStr.rv = SCARD_E_INVALID_VALUE;
+
+ WRITE_BODY(caStr)
+ }
+ break;
+
+ case SCARD_STATUS:
+ {
+ struct status_struct stStr;
+ LONG rv;
+
+ READ_BODY(stStr)
+
+ rv = MSGCheckHandleAssociation(stStr.hCard, dwContextIndex);
+ if (0 == rv)
+ {
+ DWORD cchReaderLen;
+ DWORD dwState;
+ DWORD dwProtocol;
+ DWORD cbAtrLen;
+
+ cchReaderLen = stStr.pcchReaderLen;
+ dwState = stStr.dwState;
+ dwProtocol = stStr.dwProtocol;
+ cbAtrLen = stStr.pcbAtrLen;
+
+ /* avoids buffer overflow */
+ if ((cchReaderLen > sizeof(stStr.mszReaderNames))
+ || (cbAtrLen > sizeof(stStr.pbAtr)))
+ {
+ stStr.rv = SCARD_E_INSUFFICIENT_BUFFER ;
+ }
+ else
+ {
+ stStr.rv = SCardStatus(stStr.hCard,
+ stStr.mszReaderNames,
+ &cchReaderLen, &dwState,
+ &dwProtocol, stStr.pbAtr, &cbAtrLen);
+
+ stStr.pcchReaderLen = cchReaderLen;
+ stStr.dwState = dwState;
+ stStr.dwProtocol = dwProtocol;
+ stStr.pcbAtrLen = cbAtrLen;
+ }
+ }
+
+ WRITE_BODY(stStr)
+ }
+ break;
+
+ case SCARD_TRANSMIT:
+ {
+ struct transmit_struct trStr;
+ unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
+ unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
+ SCARD_IO_REQUEST ioSendPci;
+ SCARD_IO_REQUEST ioRecvPci;
+ DWORD cbRecvLength;
+
+ READ_BODY(trStr)
+
+ if (MSGCheckHandleAssociation(trStr.hCard, dwContextIndex))
+ goto exit;
+
+ /* avoids buffer overflow */
+ if ((trStr.pcbRecvLength > sizeof(pbRecvBuffer))
+ || (trStr.cbSendLength > sizeof(pbSendBuffer)))
+ goto exit;
+
+ /* read sent buffer */
+ ret = SHMMessageReceive(pbSendBuffer, trStr.cbSendLength,
+ filedes, PCSCLITE_READ_TIMEOUT);
+ if (-1 == ret)
+ {
+ Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
+ goto exit;
+ }
+
+ ioSendPci.dwProtocol = trStr.ioSendPciProtocol;
+ ioSendPci.cbPciLength = trStr.ioSendPciLength;
+ ioRecvPci.dwProtocol = trStr.ioRecvPciProtocol;
+ ioRecvPci.cbPciLength = trStr.ioRecvPciLength;
+ cbRecvLength = trStr.pcbRecvLength;
+
+ trStr.rv = SCardTransmit(trStr.hCard, &ioSendPci,
+ pbSendBuffer, trStr.cbSendLength, &ioRecvPci,
+ pbRecvBuffer, &cbRecvLength);
+
+ trStr.ioSendPciProtocol = ioSendPci.dwProtocol;
+ trStr.ioSendPciLength = ioSendPci.cbPciLength;
+ trStr.ioRecvPciProtocol = ioRecvPci.dwProtocol;
+ trStr.ioRecvPciLength = ioRecvPci.cbPciLength;
+ trStr.pcbRecvLength = cbRecvLength;
+
+ WRITE_BODY(trStr)
+
+ /* write received buffer */
+ if (SCARD_S_SUCCESS == trStr.rv)
+ ret = SHMMessageSend(pbRecvBuffer, cbRecvLength,
+ filedes, PCSCLITE_WRITE_TIMEOUT);
+ }
+ break;
+
+ case SCARD_CONTROL:
+ {
+ struct control_struct ctStr;
+ unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
+ unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
+ DWORD dwBytesReturned;
+
+ READ_BODY(ctStr)
+
+ if (MSGCheckHandleAssociation(ctStr.hCard, dwContextIndex))
+ goto exit;
+
+ /* avoids buffer overflow */
+ if ((ctStr.cbRecvLength > sizeof(pbRecvBuffer))
+ || (ctStr.cbSendLength > sizeof(pbSendBuffer)))
+ {
+ goto exit;
+ }
+
+ /* read sent buffer */
+ ret = SHMMessageReceive(pbSendBuffer, ctStr.cbSendLength,
+ filedes, PCSCLITE_READ_TIMEOUT);
+ if (-1 == ret)
+ {
+ Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
+ goto exit;
+ }
+
+ dwBytesReturned = ctStr.dwBytesReturned;
+
+ ctStr.rv = SCardControl(ctStr.hCard, ctStr.dwControlCode,
+ pbSendBuffer, ctStr.cbSendLength,
+ pbRecvBuffer, ctStr.cbRecvLength,
+ &dwBytesReturned);
+
+ ctStr.dwBytesReturned = dwBytesReturned;
+
+ WRITE_BODY(ctStr)
+
+ /* write received buffer */
+ if (SCARD_S_SUCCESS == ctStr.rv)
+ ret = SHMMessageSend(pbRecvBuffer, dwBytesReturned,
+ filedes, PCSCLITE_WRITE_TIMEOUT);
+ }
+ break;
+
+ case SCARD_GET_ATTRIB:
+ {
+ struct getset_struct gsStr;
+ DWORD cbAttrLen;
+
+ READ_BODY(gsStr)
+
+ if (MSGCheckHandleAssociation(gsStr.hCard, dwContextIndex))
+ goto exit;
+
+ /* avoids buffer overflow */
+ if (gsStr.cbAttrLen > sizeof(gsStr.pbAttr))
+ goto buffer_overflow;
+
+ cbAttrLen = gsStr.cbAttrLen;
+
+ gsStr.rv = SCardGetAttrib(gsStr.hCard, gsStr.dwAttrId,
+ gsStr.pbAttr, &cbAttrLen);
+
+ gsStr.cbAttrLen = cbAttrLen;
+
+ WRITE_BODY(gsStr)
+ }
+ break;
+
+ case SCARD_SET_ATTRIB:
+ {
+ struct getset_struct gsStr;
+
+ READ_BODY(gsStr)
+
+ if (MSGCheckHandleAssociation(gsStr.hCard, dwContextIndex))
+ goto buffer_overflow;
+
+ /* avoids buffer overflow */
+ if (gsStr.cbAttrLen > sizeof(gsStr.pbAttr))
+ goto buffer_overflow;
+
+ gsStr.rv = SCardSetAttrib(gsStr.hCard, gsStr.dwAttrId,
+ gsStr.pbAttr, gsStr.cbAttrLen);
+
+ WRITE_BODY(gsStr)
+ }
+ break;
+
+ default:
+ Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", header.command);
+ goto exit;
+ }
+
+ /* SHMMessageSend() failed */
+ if (-1 == ret)
+ {
+ /* Clean up the dead client */
+ Log2(PCSC_LOG_DEBUG, "Client die: %d", filedes);
+ goto exit;
}
}
-}
-
-/**
- * @brief Find out which message was sent by the Client and execute the right task.
- *
- * According to the command type sent by the client (\c pcsc_msg_commands),
- * cast the message data to the correct struct so that is can be demarshalled.
- * Then call the appropriate function to handle the request.
- *
- * Possible structs are: \c establish_struct \c release_struct
- * \c connect_struct \c reconnect_struct \c disconnect_struct \c begin_struct
- * \c cancel_struct \c end_struct \c status_struct \c transmit_struct
- * \c control_struct \c getset_struct.
- *
- * @param[in] msgStruct Message to be demarshalled and executed.
- * @param[in] dwContextIndex
- */
-static LONG MSGFunctionDemarshall(psharedSegmentMsg msgStruct,
- DWORD dwContextIndex)
-{
- LONG rv;
- establish_struct *esStr;
- release_struct *reStr;
- connect_struct *coStr;
- reconnect_struct *rcStr;
- disconnect_struct *diStr;
- begin_struct *beStr;
- cancel_struct *caStr;
- end_struct *enStr;
- status_struct *stStr;
- transmit_struct *trStr;
- control_struct *ctStr;
- getset_struct *gsStr;
-
- SCARDCONTEXT hContext;
- SCARDHANDLE hCard;
- DWORD dwActiveProtocol;
-
- DWORD cchReaderLen;
- DWORD dwState;
- DWORD dwProtocol;
- DWORD cbAtrLen;
- DWORD cbRecvLength;
- DWORD dwBytesReturned;
- DWORD cbAttrLen;
-
- SCARD_IO_REQUEST ioSendPci;
- SCARD_IO_REQUEST ioRecvPci;
-
- /*
- * Zero out everything
- */
- rv = 0;
- switch (msgStruct->command)
- {
-
- case SCARD_ESTABLISH_CONTEXT:
- esStr = ((establish_struct *) msgStruct->data);
-
- hContext = esStr->hContext;
- esStr->rv = SCardEstablishContext(esStr->dwScope, 0, 0, &hContext);
- esStr->hContext = hContext;
-
- if (esStr->rv == SCARD_S_SUCCESS)
- esStr->rv =
- MSGAddContext(esStr->hContext, dwContextIndex);
- break;
-
- case SCARD_RELEASE_CONTEXT:
- reStr = ((release_struct *) msgStruct->data);
- reStr->rv = SCardReleaseContext(reStr->hContext);
-
- if (reStr->rv == SCARD_S_SUCCESS)
- reStr->rv =
- MSGRemoveContext(reStr->hContext, dwContextIndex);
-
- break;
-
- case SCARD_CONNECT:
- coStr = ((connect_struct *) msgStruct->data);
-
- hCard = coStr->hCard;
- dwActiveProtocol = coStr->dwActiveProtocol;
-
- coStr->rv = SCardConnect(coStr->hContext, coStr->szReader,
- coStr->dwShareMode, coStr->dwPreferredProtocols,
- &hCard, &dwActiveProtocol);
-
- coStr->hCard = hCard;
- coStr->dwActiveProtocol = dwActiveProtocol;
-
- if (coStr->rv == SCARD_S_SUCCESS)
- coStr->rv =
- MSGAddHandle(coStr->hContext, coStr->hCard, dwContextIndex);
-
- break;
-
- case SCARD_RECONNECT:
- rcStr = ((reconnect_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(rcStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
-
- rcStr->rv = SCardReconnect(rcStr->hCard, rcStr->dwShareMode,
- rcStr->dwPreferredProtocols,
- rcStr->dwInitialization, &dwActiveProtocol);
- rcStr->dwActiveProtocol = dwActiveProtocol;
- break;
-
- case SCARD_DISCONNECT:
- diStr = ((disconnect_struct *) msgStruct->data);
- 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(diStr->hCard, dwContextIndex);
- break;
-
- case SCARD_BEGIN_TRANSACTION:
- beStr = ((begin_struct *) msgStruct->data);
- 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(enStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
- enStr->rv =
- SCardEndTransaction(enStr->hCard, enStr->dwDisposition);
- break;
-
- case SCARD_CANCEL_TRANSACTION:
- caStr = ((cancel_struct *) msgStruct->data);
- 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(stStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
-
- cchReaderLen = stStr->pcchReaderLen;
- dwState = stStr->dwState;
- dwProtocol = stStr->dwProtocol;
- cbAtrLen = stStr->pcbAtrLen;
-
- /* avoids buffer overflow */
- if ((cchReaderLen > sizeof(stStr->mszReaderNames))
- || (cbAtrLen > sizeof(stStr->pbAtr)))
- {
- stStr->rv = SCARD_E_INSUFFICIENT_BUFFER ;
- break;
- }
-
- stStr->rv = SCardStatus(stStr->hCard, stStr->mszReaderNames,
- &cchReaderLen, &dwState,
- &dwProtocol, stStr->pbAtr, &cbAtrLen);
-
- stStr->pcchReaderLen = cchReaderLen;
- stStr->dwState = dwState;
- stStr->dwProtocol = dwProtocol;
- stStr->pcbAtrLen = cbAtrLen;
- break;
-
- case SCARD_TRANSMIT:
- trStr = ((transmit_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(trStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
-
- /* avoids buffer overflow */
- if ((trStr->pcbRecvLength > sizeof(trStr->pbRecvBuffer))
- || (trStr->cbSendLength > sizeof(trStr->pbSendBuffer)))
- {
- trStr->rv = SCARD_E_INSUFFICIENT_BUFFER ;
- break;
- }
-
- ioSendPci.dwProtocol = trStr->ioSendPciProtocol;
- ioSendPci.cbPciLength = trStr->ioSendPciLength;
- ioRecvPci.dwProtocol = trStr->ioRecvPciProtocol;
- ioRecvPci.cbPciLength = trStr->ioRecvPciLength;
- cbRecvLength = trStr->pcbRecvLength;
-
- trStr->rv = SCardTransmit(trStr->hCard, &ioSendPci,
- trStr->pbSendBuffer, trStr->cbSendLength,
- &ioRecvPci, trStr->pbRecvBuffer,
- &cbRecvLength);
-
- trStr->ioSendPciProtocol = ioSendPci.dwProtocol;
- trStr->ioSendPciLength = ioSendPci.cbPciLength;
- trStr->ioRecvPciProtocol = ioRecvPci.dwProtocol;
- trStr->ioRecvPciLength = ioRecvPci.cbPciLength;
- trStr->pcbRecvLength = cbRecvLength;
-
- break;
-
- case SCARD_CONTROL:
- ctStr = ((control_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(ctStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
-
- /* avoids buffer overflow */
- if ((ctStr->cbRecvLength > sizeof(ctStr->pbRecvBuffer))
- || (ctStr->cbSendLength > sizeof(ctStr->pbSendBuffer)))
- {
- ctStr->rv = SCARD_E_INSUFFICIENT_BUFFER;
- break;
- }
-
- dwBytesReturned = ctStr->dwBytesReturned;
-
- ctStr->rv = SCardControl(ctStr->hCard, ctStr->dwControlCode,
- ctStr->pbSendBuffer, ctStr->cbSendLength,
- ctStr->pbRecvBuffer, ctStr->cbRecvLength,
- &dwBytesReturned);
-
- ctStr->dwBytesReturned = dwBytesReturned;
-
- break;
-
- case SCARD_GET_ATTRIB:
- gsStr = ((getset_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
-
- /* avoids buffer overflow */
- if (gsStr->cbAttrLen > sizeof(gsStr->pbAttr))
- {
- gsStr->rv = SCARD_E_INSUFFICIENT_BUFFER ;
- break;
- }
-
- cbAttrLen = gsStr->cbAttrLen;
-
- gsStr->rv = SCardGetAttrib(gsStr->hCard, gsStr->dwAttrId,
- gsStr->pbAttr, &cbAttrLen);
-
- gsStr->cbAttrLen = cbAttrLen;
-
- break;
-
- case SCARD_SET_ATTRIB:
- gsStr = ((getset_struct *) msgStruct->data);
- rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
-
- /* avoids buffer overflow */
- if (gsStr->cbAttrLen <= sizeof(gsStr->pbAttr))
- {
- gsStr->rv = SCARD_E_INSUFFICIENT_BUFFER ;
- break;
- }
-
- gsStr->rv = SCardSetAttrib(gsStr->hCard, gsStr->dwAttrId,
- gsStr->pbAttr, gsStr->cbAttrLen);
- break;
-
- case SCARD_TRANSMIT_EXTENDED:
- {
- transmit_struct_extended *treStr;
- unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
- unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
-
- treStr = ((transmit_struct_extended *) msgStruct->data);
- rv = MSGCheckHandleAssociation(treStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
-
- /* avoids buffer overflow */
- if ((treStr->size > sizeof(pbSendBuffer))
- || (treStr->cbSendLength > sizeof(pbSendBuffer))
- || (treStr->pcbRecvLength > sizeof(pbRecvBuffer)))
- {
- treStr->rv = SCARD_E_INSUFFICIENT_BUFFER;
- break;
- }
-
- /* on more block to read? */
- if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
- {
- /* copy the first APDU part */
- memcpy(pbSendBuffer, treStr->data,
- PCSCLITE_MAX_MESSAGE_SIZE-offsetof(transmit_struct_extended, data));
-
- /* receive the second block */
- rv = SHMMessageReceive(
- pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-offsetof(transmit_struct_extended, data),
- treStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- if (rv)
- Log1(PCSC_LOG_CRITICAL, "reception failed");
- }
- else
- memcpy(pbSendBuffer, treStr->data, treStr->cbSendLength);
-
- ioSendPci.dwProtocol = treStr->ioSendPciProtocol;
- ioSendPci.cbPciLength = treStr->ioSendPciLength;
- ioRecvPci.dwProtocol = treStr->ioRecvPciProtocol;
- ioRecvPci.cbPciLength = treStr->ioRecvPciLength;
- cbRecvLength = treStr->pcbRecvLength;
-
- treStr->rv = SCardTransmit(treStr->hCard, &ioSendPci,
- pbSendBuffer, treStr->cbSendLength,
- &ioRecvPci, pbRecvBuffer,
- &cbRecvLength);
-
- treStr->ioSendPciProtocol = ioSendPci.dwProtocol;
- treStr->ioSendPciLength = ioSendPci.cbPciLength;
- treStr->ioRecvPciProtocol = ioRecvPci.dwProtocol;
- treStr->ioRecvPciLength = ioRecvPci.cbPciLength;
- treStr->pcbRecvLength = cbRecvLength;
-
- treStr->size = offsetof(transmit_struct_extended, data) + treStr->pcbRecvLength;
- if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
- {
- /* two blocks */
- memcpy(treStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
- - offsetof(transmit_struct_extended, data));
-
- rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- if (rv)
- Log1(PCSC_LOG_CRITICAL, "transmission failed");
-
- rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
- - offsetof(transmit_struct_extended, data),
- treStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- if (rv)
- Log1(PCSC_LOG_CRITICAL, "transmission failed");
- }
- else
- {
- /* one block only */
- memcpy(treStr->data, pbRecvBuffer, treStr->pcbRecvLength);
-
- rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- if (rv)
- Log1(PCSC_LOG_CRITICAL, "transmission failed");
- }
- }
- break;
-
- case SCARD_CONTROL_EXTENDED:
- {
- control_struct_extended *cteStr;
- unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
- unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
-
- cteStr = ((control_struct_extended *) msgStruct->data);
- rv = MSGCheckHandleAssociation(cteStr->hCard, dwContextIndex);
- if (rv != 0) return rv;
-
- /* avoids buffer overflow */
- if ((cteStr->size > sizeof(pbSendBuffer))
- || (cteStr->cbSendLength > sizeof(pbSendBuffer))
- || (cteStr->cbRecvLength > sizeof(pbRecvBuffer)))
- {
- cteStr->rv = SCARD_E_INSUFFICIENT_BUFFER;
- break;
- }
-
- /* on more block to read? */
- if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
- {
- /* copy the first data part */
- memcpy(pbSendBuffer, cteStr->data,
- PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr));
-
- /* receive the second block */
- rv = SHMMessageReceive(
- pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr),
- cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- if (rv)
- Log1(PCSC_LOG_CRITICAL, "reception failed");
- }
- else
- memcpy(pbSendBuffer, cteStr->data, cteStr->cbSendLength);
-
- dwBytesReturned = cteStr->dwBytesReturned;
-
- cteStr->rv = SCardControl(cteStr->hCard, cteStr->dwControlCode,
- pbSendBuffer, cteStr->cbSendLength,
- pbRecvBuffer, cteStr->cbRecvLength,
- &dwBytesReturned);
-
- cteStr->dwBytesReturned = dwBytesReturned;
-
- cteStr->size = sizeof(*cteStr) + cteStr->dwBytesReturned;
- if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
- {
- /* two blocks */
- memcpy(cteStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
- - sizeof(*cteStr));
-
- rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- if (rv)
- Log1(PCSC_LOG_CRITICAL, "transmission failed");
-
- rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
- - sizeof(*cteStr),
- cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- if (rv)
- Log1(PCSC_LOG_CRITICAL, "transmission failed");
- }
- else
- {
- /* one block only */
- memcpy(cteStr->data, pbRecvBuffer, cteStr->dwBytesReturned);
-
- rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
- psContext[dwContextIndex].dwClientID,
- PCSCLITE_SERVER_ATTEMPTS);
- if (rv)
- Log1(PCSC_LOG_CRITICAL, "transmission failed");
- }
- }
- break;
-
- default:
- Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", msgStruct->command);
- return -1;
- }
-
- return 0;
+
+buffer_overflow:
+ Log2(PCSC_LOG_DEBUG, "Buffer overflow detected: %d", filedes);
+ goto exit;
+wrong_length:
+ Log2(PCSC_LOG_DEBUG, "Wrong length: %d", filedes);
+exit:
+ (void)SYS_CloseFile(filedes);
+ (void)MSGCleanupClient(dwContextIndex);
+ (void)SYS_ThreadExit((LPVOID) NULL);
}
LONG MSGSignalClient(uint32_t filedes, LONG rv)
More information about the Pcsclite-cvs-commit
mailing list