winscard_svc.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 2001-2004
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  *  Damien Sauveron <damien.sauveron@labri.fr>
00007  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00008  *
00009  * $Id: winscard_svc.c 3031 2008-06-27 07:31:37Z rousseau $
00010  */
00011 
00022 #include "config.h"
00023 #include <time.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 
00027 #include "pcscd.h"
00028 #include "winscard.h"
00029 #include "debuglog.h"
00030 #include "winscard_msg.h"
00031 #include "winscard_svc.h"
00032 #include "sys_generic.h"
00033 #include "thread_generic.h"
00034 #include "readerfactory.h"
00035 
00041 static struct _psContext
00042 {
00043     uint32_t hContext;
00044     uint32_t hCard[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
00045     uint32_t dwClientID;            
00046     PCSCLITE_THREAD_T pthThread;        
00047     sharedSegmentMsg msgStruct;     
00048     int protocol_major, protocol_minor; 
00049 } psContext[PCSCLITE_MAX_APPLICATIONS_CONTEXTS];
00050 
00051 LONG MSGCheckHandleAssociation(SCARDHANDLE, DWORD);
00052 LONG MSGFunctionDemarshall(psharedSegmentMsg, DWORD);
00053 LONG MSGAddContext(SCARDCONTEXT, DWORD);
00054 LONG MSGRemoveContext(SCARDCONTEXT, DWORD);
00055 LONG MSGAddHandle(SCARDCONTEXT, SCARDHANDLE, DWORD);
00056 LONG MSGRemoveHandle(SCARDHANDLE, DWORD);
00057 LONG MSGCleanupClient(DWORD);
00058 
00059 static void ContextThread(LPVOID pdwIndex);
00060 
00061 LONG ContextsInitialize(void)
00062 {
00063     memset(psContext, 0, sizeof(struct _psContext)*PCSCLITE_MAX_APPLICATIONS_CONTEXTS);
00064     return 1;
00065 }
00066 
00077 LONG CreateContextThread(uint32_t *pdwClientID)
00078 {
00079     long i;
00080     int rv;
00081 
00082     for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
00083     {
00084         if (psContext[i].dwClientID == 0)
00085         {
00086             psContext[i].dwClientID = *pdwClientID;
00087             *pdwClientID = 0;
00088             break;
00089         }
00090     }
00091 
00092     if (i == PCSCLITE_MAX_APPLICATIONS_CONTEXTS)
00093     {
00094         Log2(PCSC_LOG_CRITICAL, "No more context available (max: %d)",
00095             PCSCLITE_MAX_APPLICATIONS_CONTEXTS);
00096         return SCARD_F_INTERNAL_ERROR;
00097     }
00098 
00099     rv = SYS_ThreadCreate(&psContext[i].pthThread, THREAD_ATTR_DETACHED,
00100         (PCSCLITE_THREAD_FUNCTION( )) ContextThread, (LPVOID) i);
00101     if (rv)
00102     {
00103         SYS_CloseFile(psContext[i].dwClientID);
00104         psContext[i].dwClientID = 0;
00105         Log2(PCSC_LOG_CRITICAL, "SYS_ThreadCreate failed: %s", strerror(rv));
00106         return SCARD_E_NO_MEMORY;
00107     }
00108 
00109     return SCARD_S_SUCCESS;
00110 }
00111 
00112 /*
00113  * A list of local functions used to keep track of clients and their
00114  * connections
00115  */
00116 
00125 static void ContextThread(LPVOID dwIndex)
00126 {
00127     LONG rv;
00128     sharedSegmentMsg msgStruct;
00129     DWORD dwContextIndex = (DWORD)dwIndex;
00130 
00131     Log2(PCSC_LOG_DEBUG, "Thread is started: %d",
00132         psContext[dwContextIndex].dwClientID);
00133 
00134     while (1)
00135     {
00136         switch (rv = SHMProcessEventsContext(psContext[dwContextIndex].dwClientID, &msgStruct, 0))
00137         {
00138         case 0:
00139             if (msgStruct.mtype == CMD_CLIENT_DIED)
00140             {
00141                 /*
00142                  * Clean up the dead client
00143                  */
00144                 Log2(PCSC_LOG_DEBUG, "Client die: %d",
00145                     psContext[dwContextIndex].dwClientID);
00146                 MSGCleanupClient(dwContextIndex);
00147                 SYS_ThreadExit((LPVOID) NULL);
00148             }
00149             break;
00150 
00151         case 1:
00152             if (msgStruct.mtype == CMD_FUNCTION)
00153             {
00154                 /*
00155                  * Command must be found
00156                  */
00157                 rv = MSGFunctionDemarshall(&msgStruct, dwContextIndex);
00158                 if (rv)
00159                 {
00160                     Log2(PCSC_LOG_DEBUG, "MSGFunctionDemarshall failed: %d",
00161                         rv);
00162                     SHMClientCloseSession(psContext[dwContextIndex].dwClientID);
00163                     MSGCleanupClient(dwContextIndex);
00164                     SYS_ThreadExit((LPVOID) NULL);
00165                 }
00166 
00167                 /* the SCARD_TRANSMIT_EXTENDED anwser is already sent by
00168                  * MSGFunctionDemarshall */
00169                 if ((msgStruct.command != SCARD_TRANSMIT_EXTENDED)
00170                     && (msgStruct.command != SCARD_CONTROL_EXTENDED))
00171                     rv = SHMMessageSend(&msgStruct, sizeof(msgStruct),
00172                         psContext[dwContextIndex].dwClientID,
00173                         PCSCLITE_SERVER_ATTEMPTS);
00174             }
00175             else
00176                 /* pcsc-lite client/server protocol version */
00177                 if (msgStruct.mtype == CMD_VERSION)
00178                 {
00179                     version_struct *veStr;
00180                     veStr = (version_struct *) msgStruct.data;
00181 
00182                     /* get the client protocol version */
00183                     psContext[dwContextIndex].protocol_major = veStr->major;
00184                     psContext[dwContextIndex].protocol_minor = veStr->minor;
00185 
00186                     Log3(PCSC_LOG_DEBUG,
00187                         "Client is protocol version %d:%d",
00188                         veStr->major, veStr->minor);
00189 
00190                     veStr->rv = SCARD_S_SUCCESS;
00191 
00192                     /* client is newer than server */
00193                     if ((veStr->major > PROTOCOL_VERSION_MAJOR)
00194                         || (veStr->major == PROTOCOL_VERSION_MAJOR
00195                             && veStr->minor > PROTOCOL_VERSION_MINOR))
00196                     {
00197                         Log3(PCSC_LOG_CRITICAL,
00198                             "Client protocol is too new %d:%d",
00199                             veStr->major, veStr->minor);
00200                         Log3(PCSC_LOG_CRITICAL,
00201                             "Server protocol is %d:%d",
00202                             PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR);
00203                         veStr->rv = SCARD_E_NO_SERVICE;
00204                     }
00205 
00206                     /* set the server protocol version */
00207                     veStr->major = PROTOCOL_VERSION_MAJOR;
00208                     veStr->minor = PROTOCOL_VERSION_MINOR;
00209 
00210                     /* send back the response */
00211                     rv = SHMMessageSend(&msgStruct, sizeof(msgStruct),
00212                         psContext[dwContextIndex].dwClientID,
00213                         PCSCLITE_SERVER_ATTEMPTS);
00214                 }
00215                 else
00216                     continue;
00217 
00218             break;
00219 
00220         case 2:
00221             /*
00222              * timeout in SHMProcessEventsContext(): do nothing
00223              * this is used to catch the Ctrl-C signal at some time when
00224              * nothing else happens
00225              */
00226             break;
00227 
00228         case -1:
00229             Log1(PCSC_LOG_ERROR, "Error in SHMProcessEventsContext");
00230             break;
00231 
00232         default:
00233             Log2(PCSC_LOG_ERROR,
00234                 "SHMProcessEventsContext unknown retval: %d", rv);
00235             break;
00236         }
00237     }
00238 }
00239 
00255 LONG MSGFunctionDemarshall(psharedSegmentMsg msgStruct, DWORD dwContextIndex)
00256 {
00257     LONG rv;
00258     establish_struct *esStr;
00259     release_struct *reStr;
00260     connect_struct *coStr;
00261     reconnect_struct *rcStr;
00262     disconnect_struct *diStr;
00263     begin_struct *beStr;
00264     cancel_struct *caStr;
00265     end_struct *enStr;
00266     status_struct *stStr;
00267     transmit_struct *trStr;
00268     control_struct *ctStr;
00269     getset_struct *gsStr;
00270 
00271     SCARDCONTEXT hContext;
00272     SCARDHANDLE hCard;
00273     DWORD dwActiveProtocol;
00274 
00275     DWORD cchReaderLen;
00276     DWORD dwState;
00277     DWORD dwProtocol;
00278     DWORD cbAtrLen;
00279     DWORD cbRecvLength;
00280     DWORD dwBytesReturned;
00281     DWORD cbAttrLen;
00282 
00283     SCARD_IO_REQUEST ioSendPci;
00284     SCARD_IO_REQUEST ioRecvPci;
00285 
00286     /*
00287      * Zero out everything
00288      */
00289     rv = 0;
00290     switch (msgStruct->command)
00291     {
00292 
00293     case SCARD_ESTABLISH_CONTEXT:
00294         esStr = ((establish_struct *) msgStruct->data);
00295 
00296         hContext = esStr->phContext;
00297         esStr->rv = SCardEstablishContext(esStr->dwScope, 0, 0, &hContext);
00298         esStr->phContext = hContext;
00299 
00300         if (esStr->rv == SCARD_S_SUCCESS)
00301             esStr->rv =
00302                 MSGAddContext(esStr->phContext, dwContextIndex);
00303         break;
00304 
00305     case SCARD_RELEASE_CONTEXT:
00306         reStr = ((release_struct *) msgStruct->data);
00307         reStr->rv = SCardReleaseContext(reStr->hContext);
00308 
00309         if (reStr->rv == SCARD_S_SUCCESS)
00310             reStr->rv =
00311                 MSGRemoveContext(reStr->hContext, dwContextIndex);
00312 
00313         break;
00314 
00315     case SCARD_CONNECT:
00316         coStr = ((connect_struct *) msgStruct->data);
00317 
00318         hCard = coStr->phCard;
00319         dwActiveProtocol = coStr->pdwActiveProtocol;
00320 
00321         coStr->rv = SCardConnect(coStr->hContext, coStr->szReader,
00322             coStr->dwShareMode, coStr->dwPreferredProtocols,
00323             &hCard, &dwActiveProtocol);
00324 
00325         coStr->phCard = hCard;
00326         coStr->pdwActiveProtocol = dwActiveProtocol;
00327 
00328         if (coStr->rv == SCARD_S_SUCCESS)
00329             coStr->rv =
00330                 MSGAddHandle(coStr->hContext, coStr->phCard, dwContextIndex);
00331 
00332         break;
00333 
00334     case SCARD_RECONNECT:
00335         rcStr = ((reconnect_struct *) msgStruct->data);
00336         rv = MSGCheckHandleAssociation(rcStr->hCard, dwContextIndex);
00337         if (rv != 0) return rv;
00338 
00339         rcStr->rv = SCardReconnect(rcStr->hCard, rcStr->dwShareMode,
00340             rcStr->dwPreferredProtocols,
00341             rcStr->dwInitialization, &dwActiveProtocol);
00342         rcStr->pdwActiveProtocol = dwActiveProtocol;
00343         break;
00344 
00345     case SCARD_DISCONNECT:
00346         diStr = ((disconnect_struct *) msgStruct->data);
00347         rv = MSGCheckHandleAssociation(diStr->hCard, dwContextIndex);
00348         if (rv != 0) return rv;
00349         diStr->rv = SCardDisconnect(diStr->hCard, diStr->dwDisposition);
00350 
00351         if (diStr->rv == SCARD_S_SUCCESS)
00352             diStr->rv =
00353                 MSGRemoveHandle(diStr->hCard, dwContextIndex);
00354         break;
00355 
00356     case SCARD_BEGIN_TRANSACTION:
00357         beStr = ((begin_struct *) msgStruct->data);
00358         rv = MSGCheckHandleAssociation(beStr->hCard, dwContextIndex);
00359         if (rv != 0) return rv;
00360         beStr->rv = SCardBeginTransaction(beStr->hCard);
00361         break;
00362 
00363     case SCARD_END_TRANSACTION:
00364         enStr = ((end_struct *) msgStruct->data);
00365         rv = MSGCheckHandleAssociation(enStr->hCard, dwContextIndex);
00366         if (rv != 0) return rv;
00367         enStr->rv =
00368             SCardEndTransaction(enStr->hCard, enStr->dwDisposition);
00369         break;
00370 
00371     case SCARD_CANCEL_TRANSACTION:
00372         caStr = ((cancel_struct *) msgStruct->data);
00373         rv = MSGCheckHandleAssociation(caStr->hCard, dwContextIndex);
00374         if (rv != 0) return rv;
00375         caStr->rv = SCardCancelTransaction(caStr->hCard);
00376         break;
00377 
00378     case SCARD_STATUS:
00379         stStr = ((status_struct *) msgStruct->data);
00380         rv = MSGCheckHandleAssociation(stStr->hCard, dwContextIndex);
00381         if (rv != 0) return rv;
00382 
00383         cchReaderLen = stStr->pcchReaderLen;
00384         dwState = stStr->pdwState;
00385         dwProtocol = stStr->pdwProtocol;
00386         cbAtrLen = stStr->pcbAtrLen;
00387 
00388         stStr->rv = SCardStatus(stStr->hCard, stStr->mszReaderNames,
00389             &cchReaderLen, &dwState,
00390             &dwProtocol, stStr->pbAtr, &cbAtrLen);
00391 
00392         stStr->pcchReaderLen = cchReaderLen;
00393         stStr->pdwState = dwState;
00394         stStr->pdwProtocol = dwProtocol;
00395         stStr->pcbAtrLen = cbAtrLen;
00396         break;
00397 
00398     case SCARD_TRANSMIT:
00399         trStr = ((transmit_struct *) msgStruct->data);
00400         rv = MSGCheckHandleAssociation(trStr->hCard, dwContextIndex);
00401         if (rv != 0) return rv;
00402 
00403         ioSendPci.dwProtocol = trStr->pioSendPciProtocol;
00404         ioSendPci.cbPciLength = trStr->pioSendPciLength;
00405         ioRecvPci.dwProtocol = trStr->pioRecvPciProtocol;
00406         ioRecvPci.cbPciLength = trStr->pioRecvPciLength;
00407         cbRecvLength = trStr->pcbRecvLength;
00408 
00409         trStr->rv = SCardTransmit(trStr->hCard, &ioSendPci,
00410             trStr->pbSendBuffer, trStr->cbSendLength,
00411             &ioRecvPci, trStr->pbRecvBuffer,
00412             &cbRecvLength);
00413 
00414         trStr->pioSendPciProtocol = ioSendPci.dwProtocol;
00415         trStr->pioSendPciLength = ioSendPci.cbPciLength;
00416         trStr->pioRecvPciProtocol = ioRecvPci.dwProtocol;
00417         trStr->pioRecvPciLength = ioRecvPci.cbPciLength;
00418         trStr->pcbRecvLength = cbRecvLength;
00419 
00420         break;
00421 
00422     case SCARD_CONTROL:
00423         ctStr = ((control_struct *) msgStruct->data);
00424         rv = MSGCheckHandleAssociation(ctStr->hCard, dwContextIndex);
00425         if (rv != 0) return rv;
00426 
00427         dwBytesReturned = ctStr->dwBytesReturned;
00428 
00429         ctStr->rv = SCardControl(ctStr->hCard, ctStr->dwControlCode,
00430             ctStr->pbSendBuffer, ctStr->cbSendLength,
00431             ctStr->pbRecvBuffer, ctStr->cbRecvLength,
00432             &dwBytesReturned);
00433 
00434         ctStr->dwBytesReturned = dwBytesReturned;
00435 
00436         break;
00437 
00438     case SCARD_GET_ATTRIB:
00439         gsStr = ((getset_struct *) msgStruct->data);
00440         rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
00441         if (rv != 0) return rv;
00442 
00443         cbAttrLen = gsStr->cbAttrLen;
00444 
00445         gsStr->rv = SCardGetAttrib(gsStr->hCard, gsStr->dwAttrId,
00446             gsStr->pbAttr, &cbAttrLen);
00447 
00448         gsStr->cbAttrLen = cbAttrLen;
00449 
00450         break;
00451 
00452     case SCARD_SET_ATTRIB:
00453         gsStr = ((getset_struct *) msgStruct->data);
00454         rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
00455         if (rv != 0) return rv;
00456         gsStr->rv = SCardSetAttrib(gsStr->hCard, gsStr->dwAttrId,
00457             gsStr->pbAttr, gsStr->cbAttrLen);
00458         break;
00459 
00460     case SCARD_TRANSMIT_EXTENDED:
00461         {
00462             transmit_struct_extended *treStr;
00463             unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
00464             unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
00465 
00466             treStr = ((transmit_struct_extended *) msgStruct->data);
00467             rv = MSGCheckHandleAssociation(treStr->hCard, dwContextIndex);
00468             if (rv != 0) return rv;
00469 
00470             /* on more block to read? */
00471             if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
00472             {
00473                 /* copy the first APDU part */
00474                 memcpy(pbSendBuffer, treStr->data,
00475                     PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*treStr));
00476 
00477                 /* receive the second block */
00478                 rv = SHMMessageReceive(
00479                     pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*treStr),
00480                     treStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
00481                     psContext[dwContextIndex].dwClientID,
00482                     PCSCLITE_SERVER_ATTEMPTS);
00483                 if (rv)
00484                     Log1(PCSC_LOG_CRITICAL, "reception failed");
00485             }
00486             else
00487                 memcpy(pbSendBuffer, treStr->data, treStr->cbSendLength);
00488 
00489             ioSendPci.dwProtocol = treStr->pioSendPciProtocol;
00490             ioSendPci.cbPciLength = treStr->pioSendPciLength;
00491             ioRecvPci.dwProtocol = treStr->pioRecvPciProtocol;
00492             ioRecvPci.cbPciLength = treStr->pioRecvPciLength;
00493             cbRecvLength = treStr->pcbRecvLength;
00494 
00495             treStr->rv = SCardTransmit(treStr->hCard, &ioSendPci,
00496                 pbSendBuffer, treStr->cbSendLength,
00497                 &ioRecvPci, pbRecvBuffer,
00498                 &cbRecvLength);
00499 
00500             treStr->pioSendPciProtocol = ioSendPci.dwProtocol;
00501             treStr->pioSendPciLength = ioSendPci.cbPciLength;
00502             treStr->pioRecvPciProtocol = ioRecvPci.dwProtocol;
00503             treStr->pioRecvPciLength = ioRecvPci.cbPciLength;
00504             treStr->pcbRecvLength = cbRecvLength;
00505 
00506             treStr->size = sizeof(*treStr) + treStr->pcbRecvLength;
00507             if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
00508             {
00509                 /* two blocks */
00510                 memcpy(treStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
00511                     - sizeof(*treStr));
00512 
00513                 rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
00514                     psContext[dwContextIndex].dwClientID,
00515                     PCSCLITE_SERVER_ATTEMPTS);
00516                 if (rv)
00517                     Log1(PCSC_LOG_CRITICAL, "transmission failed");
00518 
00519                 rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
00520                     - sizeof(*treStr),
00521                     treStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
00522                     psContext[dwContextIndex].dwClientID,
00523                     PCSCLITE_SERVER_ATTEMPTS);
00524                 if (rv)
00525                     Log1(PCSC_LOG_CRITICAL, "transmission failed");
00526             }
00527             else
00528             {
00529                 /* one block only */
00530                 memcpy(treStr->data, pbRecvBuffer, treStr->pcbRecvLength);
00531 
00532                 rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
00533                     psContext[dwContextIndex].dwClientID,
00534                     PCSCLITE_SERVER_ATTEMPTS);
00535                 if (rv)
00536                     Log1(PCSC_LOG_CRITICAL, "transmission failed");
00537             }
00538         }
00539         break;
00540 
00541     case SCARD_CONTROL_EXTENDED:
00542         {
00543             control_struct_extended *cteStr;
00544             unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
00545             unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
00546 
00547             cteStr = ((control_struct_extended *) msgStruct->data);
00548             rv = MSGCheckHandleAssociation(cteStr->hCard, dwContextIndex);
00549             if (rv != 0) return rv;
00550 
00551             /* on more block to read? */
00552             if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
00553             {
00554                 /* copy the first data part */
00555                 memcpy(pbSendBuffer, cteStr->data,
00556                     PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr));
00557 
00558                 /* receive the second block */
00559                 rv = SHMMessageReceive(
00560                     pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr),
00561                     cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
00562                     psContext[dwContextIndex].dwClientID,
00563                     PCSCLITE_SERVER_ATTEMPTS);
00564                 if (rv)
00565                     Log1(PCSC_LOG_CRITICAL, "reception failed");
00566             }
00567             else
00568                 memcpy(pbSendBuffer, cteStr->data, cteStr->cbSendLength);
00569 
00570             dwBytesReturned = cteStr->pdwBytesReturned;
00571 
00572             cteStr->rv = SCardControl(cteStr->hCard, cteStr->dwControlCode,
00573                 pbSendBuffer, cteStr->cbSendLength,
00574                 pbRecvBuffer, cteStr->cbRecvLength,
00575                 &dwBytesReturned);
00576 
00577             cteStr->pdwBytesReturned = dwBytesReturned;
00578 
00579             cteStr->size = sizeof(*cteStr) + cteStr->pdwBytesReturned;
00580             if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
00581             {
00582                 /* two blocks */
00583                 memcpy(cteStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
00584                     - sizeof(*cteStr));
00585 
00586                 rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
00587                     psContext[dwContextIndex].dwClientID,
00588                     PCSCLITE_SERVER_ATTEMPTS);
00589                 if (rv)
00590                     Log1(PCSC_LOG_CRITICAL, "transmission failed");
00591 
00592                 rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
00593                     - sizeof(*cteStr),
00594                     cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
00595                     psContext[dwContextIndex].dwClientID,
00596                     PCSCLITE_SERVER_ATTEMPTS);
00597                 if (rv)
00598                     Log1(PCSC_LOG_CRITICAL, "transmission failed");
00599             }
00600             else
00601             {
00602                 /* one block only */
00603                 memcpy(cteStr->data, pbRecvBuffer, cteStr->pdwBytesReturned);
00604 
00605                 rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
00606                     psContext[dwContextIndex].dwClientID,
00607                     PCSCLITE_SERVER_ATTEMPTS);
00608                 if (rv)
00609                     Log1(PCSC_LOG_CRITICAL, "transmission failed");
00610             }
00611         }
00612         break;
00613 
00614     default:
00615         Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", msgStruct->command);
00616         return -1;
00617     }
00618 
00619     return 0;
00620 }
00621 
00622 LONG MSGAddContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
00623 {
00624     psContext[dwContextIndex].hContext = hContext;
00625     return SCARD_S_SUCCESS;
00626 }
00627 
00628 LONG MSGRemoveContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
00629 {
00630     int i;
00631     LONG rv;
00632 
00633     if (psContext[dwContextIndex].hContext == hContext)
00634     {
00635         for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
00636         {
00637             /*
00638              * Disconnect each of these just in case
00639              */
00640 
00641             if (psContext[dwContextIndex].hCard[i] != 0)
00642             {
00643                 PREADER_CONTEXT rContext = NULL;
00644                 DWORD dwLockId;
00645 
00646                 /*
00647                  * Unlock the sharing
00648                  */
00649                 rv = RFReaderInfoById(psContext[dwContextIndex].hCard[i],
00650                     &rContext);
00651                 if (rv != SCARD_S_SUCCESS)
00652                     return rv;
00653 
00654                 dwLockId = rContext->dwLockId;
00655                 rContext->dwLockId = 0;
00656 
00657                 if (psContext[dwContextIndex].hCard[i] != dwLockId)
00658                 {
00659                     /*
00660                      * if the card is locked by someone else we do not reset it
00661                      * and simulate a card removal
00662                      */
00663                     rv = SCARD_W_REMOVED_CARD;
00664                 }
00665                 else
00666                 {
00667                     /*
00668                      * We will use SCardStatus to see if the card has been
00669                      * reset there is no need to reset each time
00670                      * Disconnect is called
00671                      */
00672                     rv = SCardStatus(psContext[dwContextIndex].hCard[i], NULL,
00673                         NULL, NULL, NULL, NULL, NULL);
00674                 }
00675 
00676                 if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD)
00677                     SCardDisconnect(psContext[dwContextIndex].hCard[i],
00678                         SCARD_LEAVE_CARD);
00679                 else
00680                     SCardDisconnect(psContext[dwContextIndex].hCard[i],
00681                         SCARD_RESET_CARD);
00682 
00683                 psContext[dwContextIndex].hCard[i] = 0;
00684             }
00685         }
00686 
00687         psContext[dwContextIndex].hContext = 0;
00688         return SCARD_S_SUCCESS;
00689     }
00690 
00691     return SCARD_E_INVALID_VALUE;
00692 }
00693 
00694 LONG MSGAddHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard, DWORD dwContextIndex)
00695 {
00696     int i;
00697 
00698     if (psContext[dwContextIndex].hContext == hContext)
00699     {
00700 
00701         /*
00702          * Find an empty spot to put the hCard value
00703          */
00704         for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
00705         {
00706             if (psContext[dwContextIndex].hCard[i] == 0)
00707             {
00708                 psContext[dwContextIndex].hCard[i] = hCard;
00709                 break;
00710             }
00711         }
00712 
00713         if (i == PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS)
00714         {
00715             return SCARD_F_INTERNAL_ERROR;
00716         } else
00717         {
00718             return SCARD_S_SUCCESS;
00719         }
00720 
00721     }
00722 
00723     return SCARD_E_INVALID_VALUE;
00724 }
00725 
00726 LONG MSGRemoveHandle(SCARDHANDLE hCard, DWORD dwContextIndex)
00727 {
00728     int i;
00729 
00730     for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
00731     {
00732         if (psContext[dwContextIndex].hCard[i] == hCard)
00733         {
00734             psContext[dwContextIndex].hCard[i] = 0;
00735             return SCARD_S_SUCCESS;
00736         }
00737     }
00738 
00739     return SCARD_E_INVALID_VALUE;
00740 }
00741 
00742 
00743 LONG MSGCheckHandleAssociation(SCARDHANDLE hCard, DWORD dwContextIndex)
00744 {
00745     int i;
00746 
00747     for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
00748     {
00749         if (psContext[dwContextIndex].hCard[i] == hCard)
00750         {
00751             return 0;
00752         }
00753     }
00754 
00755     /* Must be a rogue client, debug log and sleep a couple of seconds */
00756     Log1(PCSC_LOG_ERROR, "Client failed to authenticate");
00757     SYS_Sleep(2);
00758 
00759     return -1;
00760 }
00761 
00762 LONG MSGCleanupClient(DWORD dwContextIndex)
00763 {
00764     if (psContext[dwContextIndex].hContext != 0)
00765     {
00766         SCardReleaseContext(psContext[dwContextIndex].hContext);
00767         MSGRemoveContext(psContext[dwContextIndex].hContext, dwContextIndex);
00768     }
00769 
00770     psContext[dwContextIndex].dwClientID = 0;
00771     psContext[dwContextIndex].protocol_major = 0;
00772     psContext[dwContextIndex].protocol_minor = 0;
00773 
00774     return 0;
00775 }

Generated on Thu Aug 28 20:14:41 2008 for pcsc-lite by  doxygen 1.5.6