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

Generated on Wed Apr 30 17:11:41 2008 for pcsc-lite by  doxygen 1.5.5