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