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

Generated on Tue Feb 6 21:24:44 2007 for pcsc-lite by  doxygen 1.5.1