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

Generated on Wed Jul 14 18:43:53 2010 for pcsc-lite by  doxygen 1.4.7