pcsc-lite 1.5.5
|
00001 /* 00002 * MUSCLE SmartCard Development ( http://www.linuxnet.com ) 00003 * 00004 * Copyright (C) 1999-2004 00005 * David Corcoran <corcoran@linuxnet.com> 00006 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00007 * 00008 * $Id: winscard.c 4332 2009-07-21 10:21:01Z rousseau $ 00009 */ 00010 00081 #include "config.h" 00082 #include <stdlib.h> 00083 #include <sys/time.h> 00084 #include <string.h> 00085 00086 #include "pcscd.h" 00087 #include "winscard.h" 00088 #include "ifdhandler.h" 00089 #include "debuglog.h" 00090 #include "readerfactory.h" 00091 #include "prothandler.h" 00092 #include "ifdwrapper.h" 00093 #include "atrhandler.h" 00094 #include "sys_generic.h" 00095 #include "eventhandler.h" 00096 #include "utils.h" 00097 00098 #undef DO_PROFILE 00099 #ifdef DO_PROFILE 00100 00101 #ifndef FALSE 00102 #define FALSE 0 00103 #define TRUE 1 00104 #endif 00105 00106 #define PROFILE_FILE "/tmp/pcscd_profile" 00107 #include <stdio.h> 00108 #include <sys/time.h> 00109 #include <errno.h> 00110 #include <unistd.h> 00111 00112 struct timeval profile_time_start; 00113 FILE *fd; 00114 char profile_tty; 00115 00116 #define PROFILE_START profile_start(__FUNCTION__); 00117 #define PROFILE_END profile_end(__FUNCTION__, __LINE__); 00118 00119 static void profile_start(const char *f) 00120 { 00121 static char initialized = FALSE; 00122 00123 if (!initialized) 00124 { 00125 initialized = TRUE; 00126 fd = fopen(PROFILE_FILE, "a+"); 00127 if (NULL == fd) 00128 { 00129 fprintf(stderr, "\33[01;31mCan't open %s: %s\33[0m\n", 00130 PROFILE_FILE, strerror(errno)); 00131 exit(-1); 00132 } 00133 fprintf(fd, "\nStart a new profile\n"); 00134 fflush(fd); 00135 00136 if (isatty(fileno(stderr))) 00137 profile_tty = TRUE; 00138 else 00139 profile_tty = FALSE; 00140 } 00141 00142 gettimeofday(&profile_time_start, NULL); 00143 } /* profile_start */ 00144 00145 /* r = a - b */ 00146 static long int time_sub(struct timeval *a, struct timeval *b) 00147 { 00148 struct timeval r; 00149 r.tv_sec = a -> tv_sec - b -> tv_sec; 00150 r.tv_usec = a -> tv_usec - b -> tv_usec; 00151 if (r.tv_usec < 0) 00152 { 00153 r.tv_sec--; 00154 r.tv_usec += 1000000; 00155 } 00156 00157 return r.tv_sec * 1000000 + r.tv_usec; 00158 } /* time_sub */ 00159 00160 00161 static void profile_end(const char *f, int line) 00162 { 00163 struct timeval profile_time_end; 00164 long d; 00165 00166 gettimeofday(&profile_time_end, NULL); 00167 d = time_sub(&profile_time_end, &profile_time_start); 00168 00169 if (profile_tty) 00170 fprintf(stderr, "\33[01;31mRESULT %s \33[35m%ld\33[0m (%d)\n", f, d, 00171 line); 00172 fprintf(fd, "%s %ld\n", f, d); 00173 fflush(fd); 00174 } /* profile_end */ 00175 00176 #else 00177 #define PROFILE_START 00178 #define PROFILE_END 00179 #endif 00180 00182 #define SCARD_PROTOCOL_ANY_OLD 0x1000 00183 00185 #define SCARD_LAST_CONTEXT 1 00186 00187 #define SCARD_NO_CONTEXT 0 00188 00189 #define SCARD_EXCLUSIVE_CONTEXT -1 00190 00191 #define SCARD_NO_LOCK 0 00192 00193 SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(SCARD_IO_REQUEST) }; 00194 SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(SCARD_IO_REQUEST) }; 00195 SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, sizeof(SCARD_IO_REQUEST) }; 00196 00217 LONG SCardEstablishContext(DWORD dwScope, /*@unused@*/ LPCVOID pvReserved1, 00218 /*@unused@*/ LPCVOID pvReserved2, LPSCARDCONTEXT phContext) 00219 { 00220 (void)pvReserved1; 00221 (void)pvReserved2; 00222 /* 00223 * Check for NULL pointer 00224 */ 00225 if (phContext == 0) 00226 return SCARD_E_INVALID_PARAMETER; 00227 00228 if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL && 00229 dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL) 00230 { 00231 *phContext = 0; 00232 return SCARD_E_INVALID_VALUE; 00233 } 00234 00235 /* 00236 * Unique identifier for this server so that it can uniquely be 00237 * identified by clients and distinguished from others 00238 */ 00239 00240 *phContext = (PCSCLITE_SVC_IDENTITY + SYS_RandomInt(1, 65535)); 00241 00242 Log2(PCSC_LOG_DEBUG, "Establishing Context: %d", *phContext); 00243 00244 return SCARD_S_SUCCESS; 00245 } 00246 00247 LONG SCardReleaseContext(SCARDCONTEXT hContext) 00248 { 00249 /* 00250 * Nothing to do here RPC layer will handle this 00251 */ 00252 00253 Log2(PCSC_LOG_DEBUG, "Releasing Context: %d", hContext); 00254 00255 return SCARD_S_SUCCESS; 00256 } 00257 00258 LONG SCardSetTimeout(/*@unused@*/ SCARDCONTEXT hContext, 00259 /*@unused@*/ DWORD dwTimeout) 00260 { 00261 /* 00262 * This is only used at the client side of an RPC call but just in 00263 * case someone calls it here 00264 */ 00265 00266 (void)hContext; 00267 (void)dwTimeout; 00268 return SCARD_E_UNSUPPORTED_FEATURE; 00269 } 00270 00271 LONG SCardConnect(/*@unused@*/ SCARDCONTEXT hContext, LPCSTR szReader, 00272 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, 00273 LPDWORD pdwActiveProtocol) 00274 { 00275 LONG rv; 00276 PREADER_CONTEXT rContext = NULL; 00277 DWORD dwStatus; 00278 00279 (void)hContext; 00280 PROFILE_START 00281 00282 /* 00283 * Check for NULL parameters 00284 */ 00285 if (szReader == NULL || phCard == NULL || pdwActiveProtocol == NULL) 00286 return SCARD_E_INVALID_PARAMETER; 00287 else 00288 *phCard = 0; 00289 00290 if ((dwShareMode != SCARD_SHARE_DIRECT) && 00291 !(dwPreferredProtocols & SCARD_PROTOCOL_T0) && 00292 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) && 00293 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) && 00294 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)) 00295 return SCARD_E_PROTO_MISMATCH; 00296 00297 if (dwShareMode != SCARD_SHARE_EXCLUSIVE && 00298 dwShareMode != SCARD_SHARE_SHARED && 00299 dwShareMode != SCARD_SHARE_DIRECT) 00300 return SCARD_E_INVALID_VALUE; 00301 00302 Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %d", 00303 szReader, dwPreferredProtocols); 00304 00305 rv = RFReaderInfo((LPSTR) szReader, &rContext); 00306 00307 if (rv != SCARD_S_SUCCESS) 00308 { 00309 Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader); 00310 return rv; 00311 } 00312 00313 /* 00314 * Make sure the reader is working properly 00315 */ 00316 rv = RFCheckReaderStatus(rContext); 00317 if (rv != SCARD_S_SUCCESS) 00318 return rv; 00319 00320 /******************************************* 00321 * 00322 * This section checks for simple errors 00323 * 00324 *******************************************/ 00325 00326 /* 00327 * Connect if not exclusive mode 00328 */ 00329 if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT) 00330 { 00331 Log1(PCSC_LOG_ERROR, "Error Reader Exclusive"); 00332 return SCARD_E_SHARING_VIOLATION; 00333 } 00334 00335 /* 00336 * wait until a possible transaction is finished 00337 */ 00338 if (rContext->dwLockId != 0) 00339 { 00340 Log1(PCSC_LOG_INFO, "Waiting for release of lock"); 00341 while (rContext->dwLockId != 0) 00342 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE); 00343 Log1(PCSC_LOG_INFO, "Lock released"); 00344 } 00345 00346 /* the reader has been removed while we were waiting */ 00347 if (NULL == rContext->readerState) 00348 return SCARD_E_NO_SMARTCARD; 00349 00350 /******************************************* 00351 * 00352 * This section tries to determine the 00353 * presence of a card or not 00354 * 00355 *******************************************/ 00356 dwStatus = rContext->readerState->readerState; 00357 00358 if (dwShareMode != SCARD_SHARE_DIRECT) 00359 { 00360 if (!(dwStatus & SCARD_PRESENT)) 00361 { 00362 Log1(PCSC_LOG_ERROR, "Card Not Inserted"); 00363 return SCARD_E_NO_SMARTCARD; 00364 } 00365 00366 if (dwStatus & SCARD_SWALLOWED) 00367 { 00368 Log1(PCSC_LOG_ERROR, "Card Not Powered"); 00369 return SCARD_W_UNPOWERED_CARD; 00370 } 00371 } 00372 00373 00374 /******************************************* 00375 * 00376 * This section tries to decode the ATR 00377 * and set up which protocol to use 00378 * 00379 *******************************************/ 00380 if (dwPreferredProtocols & SCARD_PROTOCOL_RAW) 00381 rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW; 00382 else 00383 { 00384 if (dwShareMode != SCARD_SHARE_DIRECT) 00385 { 00386 /* lock here instead in IFDSetPTS() to lock up to 00387 * setting rContext->readerState->cardProtocol */ 00388 (void)SYS_MutexLock(rContext->mMutex); 00389 00390 /* the protocol is not yet set (no PPS yet) */ 00391 if (SCARD_PROTOCOL_UNDEFINED == rContext->readerState->cardProtocol) 00392 { 00393 UCHAR ucAvailable, ucDefault; 00394 int ret; 00395 00396 ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr, 00397 rContext->readerState->cardAtrLength); 00398 ucAvailable = 00399 PHGetAvailableProtocols(rContext->readerState->cardAtr, 00400 rContext->readerState->cardAtrLength); 00401 00402 /* 00403 * If it is set to ANY let it do any of the protocols 00404 */ 00405 if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD) 00406 dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1; 00407 00408 ret = PHSetProtocol(rContext, dwPreferredProtocols, 00409 ucAvailable, ucDefault); 00410 00411 /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */ 00412 if (SET_PROTOCOL_PPS_FAILED == ret) 00413 { 00414 (void)SYS_MutexUnLock(rContext->mMutex); 00415 return SCARD_W_UNRESPONSIVE_CARD; 00416 } 00417 00418 if (SET_PROTOCOL_WRONG_ARGUMENT == ret) 00419 { 00420 (void)SYS_MutexUnLock(rContext->mMutex); 00421 return SCARD_E_PROTO_MISMATCH; 00422 } 00423 00424 /* use negociated protocol */ 00425 rContext->readerState->cardProtocol = ret; 00426 00427 (void)SYS_MutexUnLock(rContext->mMutex); 00428 } 00429 else 00430 { 00431 (void)SYS_MutexUnLock(rContext->mMutex); 00432 00433 if (! (dwPreferredProtocols & rContext->readerState->cardProtocol)) 00434 return SCARD_E_PROTO_MISMATCH; 00435 } 00436 } 00437 else 00438 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 00439 } 00440 00441 *pdwActiveProtocol = rContext->readerState->cardProtocol; 00442 00443 if (dwShareMode != SCARD_SHARE_DIRECT) 00444 { 00445 if ((*pdwActiveProtocol != SCARD_PROTOCOL_T0) 00446 && (*pdwActiveProtocol != SCARD_PROTOCOL_T1)) 00447 Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %d", 00448 *pdwActiveProtocol); 00449 else 00450 Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d", 00451 (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1); 00452 } 00453 else 00454 Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected"); 00455 00456 /* 00457 * Prepare the SCARDHANDLE identity 00458 */ 00459 *phCard = RFCreateReaderHandle(rContext); 00460 00461 Log2(PCSC_LOG_DEBUG, "hCard Identity: %x", *phCard); 00462 00463 /******************************************* 00464 * 00465 * This section tries to set up the 00466 * exclusivity modes. -1 is exclusive 00467 * 00468 *******************************************/ 00469 00470 if (dwShareMode == SCARD_SHARE_EXCLUSIVE) 00471 { 00472 if (rContext->dwContexts == SCARD_NO_CONTEXT) 00473 { 00474 rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT; 00475 (void)RFLockSharing(*phCard); 00476 } 00477 else 00478 { 00479 (void)RFDestroyReaderHandle(*phCard); 00480 *phCard = 0; 00481 return SCARD_E_SHARING_VIOLATION; 00482 } 00483 } 00484 else 00485 { 00486 /* 00487 * Add a connection to the context stack 00488 */ 00489 rContext->dwContexts += 1; 00490 } 00491 00492 /* 00493 * Add this handle to the handle list 00494 */ 00495 rv = RFAddReaderHandle(rContext, *phCard); 00496 00497 if (rv != SCARD_S_SUCCESS) 00498 { 00499 /* 00500 * Clean up - there is no more room 00501 */ 00502 (void)RFDestroyReaderHandle(*phCard); 00503 if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT) 00504 rContext->dwContexts = SCARD_NO_CONTEXT; 00505 else 00506 if (rContext->dwContexts > SCARD_NO_CONTEXT) 00507 rContext->dwContexts -= 1; 00508 00509 *phCard = 0; 00510 00511 PROFILE_END 00512 00513 return SCARD_F_INTERNAL_ERROR; 00514 } 00515 00516 /* 00517 * Propagate new state to Shared Memory 00518 */ 00519 rContext->readerState->readerSharing = rContext->dwContexts; 00520 (void)StatSynchronize(rContext->readerState); 00521 00522 PROFILE_END 00523 00524 return SCARD_S_SUCCESS; 00525 } 00526 00527 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, 00528 DWORD dwPreferredProtocols, DWORD dwInitialization, 00529 LPDWORD pdwActiveProtocol) 00530 { 00531 LONG rv; 00532 PREADER_CONTEXT rContext = NULL; 00533 00534 Log1(PCSC_LOG_DEBUG, "Attempting reconnect to token."); 00535 00536 if (hCard == 0) 00537 return SCARD_E_INVALID_HANDLE; 00538 00539 /* 00540 * Handle the dwInitialization 00541 */ 00542 if (dwInitialization != SCARD_LEAVE_CARD && 00543 dwInitialization != SCARD_RESET_CARD && 00544 dwInitialization != SCARD_UNPOWER_CARD) 00545 return SCARD_E_INVALID_VALUE; 00546 00547 if (dwShareMode != SCARD_SHARE_SHARED && 00548 dwShareMode != SCARD_SHARE_EXCLUSIVE && 00549 dwShareMode != SCARD_SHARE_DIRECT) 00550 return SCARD_E_INVALID_VALUE; 00551 00552 if ((dwShareMode != SCARD_SHARE_DIRECT) && 00553 !(dwPreferredProtocols & SCARD_PROTOCOL_T0) && 00554 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) && 00555 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) && 00556 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)) 00557 return SCARD_E_PROTO_MISMATCH; 00558 00559 if (pdwActiveProtocol == NULL) 00560 return SCARD_E_INVALID_PARAMETER; 00561 00562 rv = RFReaderInfoById(hCard, &rContext); 00563 if (rv != SCARD_S_SUCCESS) 00564 return rv; 00565 00566 /* 00567 * Make sure the reader is working properly 00568 */ 00569 rv = RFCheckReaderStatus(rContext); 00570 if (rv != SCARD_S_SUCCESS) 00571 return rv; 00572 00573 rv = RFFindReaderHandle(hCard); 00574 if (rv != SCARD_S_SUCCESS) 00575 return rv; 00576 00577 /* 00578 * Make sure no one has a lock on this reader 00579 */ 00580 rv = RFCheckSharing(hCard); 00581 if (rv != SCARD_S_SUCCESS) 00582 return rv; 00583 00584 /* 00585 * RFUnblockReader( rContext ); FIX - this doesn't work 00586 */ 00587 00588 if (dwInitialization == SCARD_RESET_CARD || 00589 dwInitialization == SCARD_UNPOWER_CARD) 00590 { 00591 DWORD dwAtrLen; 00592 /* 00593 * Currently pcsc-lite keeps the card powered constantly 00594 */ 00595 dwAtrLen = rContext->readerState->cardAtrLength; 00596 if (SCARD_RESET_CARD == dwInitialization) 00597 rv = IFDPowerICC(rContext, IFD_RESET, 00598 rContext->readerState->cardAtr, 00599 &dwAtrLen); 00600 else 00601 { 00602 rv = IFDPowerICC(rContext, IFD_POWER_DOWN, 00603 rContext->readerState->cardAtr, 00604 &dwAtrLen); 00605 rv = IFDPowerICC(rContext, IFD_POWER_UP, 00606 rContext->readerState->cardAtr, 00607 &dwAtrLen); 00608 } 00609 rContext->readerState->cardAtrLength = dwAtrLen; 00610 00611 /* the protocol is unset after a power on */ 00612 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 00613 00614 /* 00615 * Notify the card has been reset 00616 * Not doing this could result in deadlock 00617 */ 00618 rv = RFCheckReaderEventState(rContext, hCard); 00619 switch(rv) 00620 { 00621 /* avoid deadlock */ 00622 case SCARD_W_RESET_CARD: 00623 break; 00624 00625 case SCARD_W_REMOVED_CARD: 00626 Log1(PCSC_LOG_ERROR, "card removed"); 00627 return SCARD_W_REMOVED_CARD; 00628 00629 /* invalid EventStatus */ 00630 case SCARD_E_INVALID_VALUE: 00631 Log1(PCSC_LOG_ERROR, "invalid EventStatus"); 00632 return SCARD_F_INTERNAL_ERROR; 00633 00634 /* invalid hCard, but hCard was widely used some lines above :( */ 00635 case SCARD_E_INVALID_HANDLE: 00636 Log1(PCSC_LOG_ERROR, "invalid handle"); 00637 return SCARD_F_INTERNAL_ERROR; 00638 00639 case SCARD_S_SUCCESS: 00640 /* 00641 * Notify the card has been reset 00642 */ 00643 (void)RFSetReaderEventState(rContext, SCARD_RESET); 00644 00645 /* 00646 * Set up the status bit masks on dwStatus 00647 */ 00648 if (rv == SCARD_S_SUCCESS) 00649 { 00650 rContext->readerState->readerState |= SCARD_PRESENT; 00651 rContext->readerState->readerState &= ~SCARD_ABSENT; 00652 rContext->readerState->readerState |= SCARD_POWERED; 00653 rContext->readerState->readerState |= SCARD_NEGOTIABLE; 00654 rContext->readerState->readerState &= ~SCARD_SPECIFIC; 00655 rContext->readerState->readerState &= ~SCARD_SWALLOWED; 00656 rContext->readerState->readerState &= ~SCARD_UNKNOWN; 00657 } 00658 else 00659 { 00660 rContext->readerState->readerState |= SCARD_PRESENT; 00661 rContext->readerState->readerState &= ~SCARD_ABSENT; 00662 rContext->readerState->readerState |= SCARD_SWALLOWED; 00663 rContext->readerState->readerState &= ~SCARD_POWERED; 00664 rContext->readerState->readerState &= ~SCARD_NEGOTIABLE; 00665 rContext->readerState->readerState &= ~SCARD_SPECIFIC; 00666 rContext->readerState->readerState &= ~SCARD_UNKNOWN; 00667 rContext->readerState->cardAtrLength = 0; 00668 } 00669 00670 if (rContext->readerState->cardAtrLength > 0) 00671 { 00672 Log1(PCSC_LOG_DEBUG, "Reset complete."); 00673 LogXxd(PCSC_LOG_DEBUG, "Card ATR: ", 00674 rContext->readerState->cardAtr, 00675 rContext->readerState->cardAtrLength); 00676 } 00677 else 00678 { 00679 DWORD dwStatus, dwAtrLen2; 00680 UCHAR ucAtr[MAX_ATR_SIZE]; 00681 00682 Log1(PCSC_LOG_ERROR, "Error resetting card."); 00683 (void)IFDStatusICC(rContext, &dwStatus, ucAtr, &dwAtrLen2); 00684 if (dwStatus & SCARD_PRESENT) 00685 return SCARD_W_UNRESPONSIVE_CARD; 00686 else 00687 return SCARD_E_NO_SMARTCARD; 00688 } 00689 break; 00690 00691 default: 00692 Log2(PCSC_LOG_ERROR, 00693 "invalid retcode from RFCheckReaderEventState (%X)", rv); 00694 return SCARD_F_INTERNAL_ERROR; 00695 break; 00696 } 00697 } 00698 else 00699 if (dwInitialization == SCARD_LEAVE_CARD) 00700 { 00701 /* 00702 * Do nothing 00703 */ 00704 } 00705 00706 /******************************************* 00707 * 00708 * This section tries to decode the ATR 00709 * and set up which protocol to use 00710 * 00711 *******************************************/ 00712 if (dwPreferredProtocols & SCARD_PROTOCOL_RAW) 00713 rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW; 00714 else 00715 { 00716 if (dwShareMode != SCARD_SHARE_DIRECT) 00717 { 00718 /* lock here instead in IFDSetPTS() to lock up to 00719 * setting rContext->readerState->cardProtocol */ 00720 (void)SYS_MutexLock(rContext->mMutex); 00721 00722 /* the protocol is not yet set (no PPS yet) */ 00723 if (SCARD_PROTOCOL_UNDEFINED == rContext->readerState->cardProtocol) 00724 { 00725 UCHAR ucAvailable, ucDefault; 00726 int ret; 00727 00728 ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr, 00729 rContext->readerState->cardAtrLength); 00730 ucAvailable = 00731 PHGetAvailableProtocols(rContext->readerState->cardAtr, 00732 rContext->readerState->cardAtrLength); 00733 00734 /* If it is set to ANY let it do any of the protocols */ 00735 if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD) 00736 dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1; 00737 00738 ret = PHSetProtocol(rContext, dwPreferredProtocols, 00739 ucAvailable, ucDefault); 00740 00741 /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */ 00742 if (SET_PROTOCOL_PPS_FAILED == ret) 00743 { 00744 (void)SYS_MutexUnLock(rContext->mMutex); 00745 return SCARD_W_UNRESPONSIVE_CARD; 00746 } 00747 00748 if (SET_PROTOCOL_WRONG_ARGUMENT == ret) 00749 { 00750 (void)SYS_MutexUnLock(rContext->mMutex); 00751 return SCARD_E_PROTO_MISMATCH; 00752 } 00753 00754 /* use negociated protocol */ 00755 rContext->readerState->cardProtocol = ret; 00756 00757 (void)SYS_MutexUnLock(rContext->mMutex); 00758 } 00759 else 00760 { 00761 (void)SYS_MutexUnLock(rContext->mMutex); 00762 00763 if (! (dwPreferredProtocols & rContext->readerState->cardProtocol)) 00764 return SCARD_E_PROTO_MISMATCH; 00765 } 00766 } 00767 else 00768 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 00769 } 00770 00771 *pdwActiveProtocol = rContext->readerState->cardProtocol; 00772 00773 if (dwShareMode == SCARD_SHARE_EXCLUSIVE) 00774 { 00775 if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT) 00776 { 00777 /* 00778 * Do nothing - we are already exclusive 00779 */ 00780 } else 00781 { 00782 if (rContext->dwContexts == SCARD_LAST_CONTEXT) 00783 { 00784 rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT; 00785 (void)RFLockSharing(hCard); 00786 } else 00787 { 00788 return SCARD_E_SHARING_VIOLATION; 00789 } 00790 } 00791 } else if (dwShareMode == SCARD_SHARE_SHARED) 00792 { 00793 if (rContext->dwContexts != SCARD_EXCLUSIVE_CONTEXT) 00794 { 00795 /* 00796 * Do nothing - in sharing mode already 00797 */ 00798 } else 00799 { 00800 /* 00801 * We are in exclusive mode but want to share now 00802 */ 00803 (void)RFUnlockSharing(hCard); 00804 rContext->dwContexts = SCARD_LAST_CONTEXT; 00805 } 00806 } else if (dwShareMode == SCARD_SHARE_DIRECT) 00807 { 00808 if (rContext->dwContexts != SCARD_EXCLUSIVE_CONTEXT) 00809 { 00810 /* 00811 * Do nothing - in sharing mode already 00812 */ 00813 } else 00814 { 00815 /* 00816 * We are in exclusive mode but want to share now 00817 */ 00818 (void)RFUnlockSharing(hCard); 00819 rContext->dwContexts = SCARD_LAST_CONTEXT; 00820 } 00821 } else 00822 return SCARD_E_INVALID_VALUE; 00823 00824 /* 00825 * Clear a previous event to the application 00826 */ 00827 (void)RFClearReaderEventState(rContext, hCard); 00828 00829 /* 00830 * Propagate new state to Shared Memory 00831 */ 00832 rContext->readerState->readerSharing = rContext->dwContexts; 00833 (void)StatSynchronize(rContext->readerState); 00834 00835 return SCARD_S_SUCCESS; 00836 } 00837 00838 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) 00839 { 00840 LONG rv; 00841 PREADER_CONTEXT rContext = NULL; 00842 DWORD dwAtrLen; 00843 00844 if (hCard == 0) 00845 return SCARD_E_INVALID_HANDLE; 00846 00847 rv = RFReaderInfoById(hCard, &rContext); 00848 if (rv != SCARD_S_SUCCESS) 00849 return rv; 00850 00851 rv = RFFindReaderHandle(hCard); 00852 if (rv != SCARD_S_SUCCESS) 00853 return rv; 00854 00855 if ((dwDisposition != SCARD_LEAVE_CARD) 00856 && (dwDisposition != SCARD_UNPOWER_CARD) 00857 && (dwDisposition != SCARD_RESET_CARD) 00858 && (dwDisposition != SCARD_EJECT_CARD)) 00859 return SCARD_E_INVALID_VALUE; 00860 00861 /* 00862 * wait until a possible transaction is finished 00863 */ 00864 if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->dwLockId != 0) 00865 && (rContext->dwLockId != hCard)) 00866 { 00867 Log1(PCSC_LOG_INFO, "Waiting for release of lock"); 00868 while (rContext->dwLockId != 0) 00869 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE); 00870 Log1(PCSC_LOG_INFO, "Lock released"); 00871 } 00872 00873 /* the reader has been removed while we were waiting */ 00874 if (NULL == rContext->readerState) 00875 return SCARD_E_NO_SMARTCARD; 00876 00877 /* 00878 * Unlock any blocks on this context 00879 */ 00880 rv = RFUnlockAllSharing(hCard); 00881 if (rv != SCARD_S_SUCCESS) 00882 return rv; 00883 00884 Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->dwContexts); 00885 00886 if (dwDisposition == SCARD_RESET_CARD || 00887 dwDisposition == SCARD_UNPOWER_CARD) 00888 { 00889 /* 00890 * Currently pcsc-lite keeps the card powered constantly 00891 */ 00892 dwAtrLen = rContext->readerState->cardAtrLength; 00893 if (SCARD_RESET_CARD == dwDisposition) 00894 rv = IFDPowerICC(rContext, IFD_RESET, 00895 rContext->readerState->cardAtr, 00896 &dwAtrLen); 00897 else 00898 { 00899 rv = IFDPowerICC(rContext, IFD_POWER_DOWN, 00900 rContext->readerState->cardAtr, 00901 &dwAtrLen); 00902 rv = IFDPowerICC(rContext, IFD_POWER_UP, 00903 rContext->readerState->cardAtr, 00904 &dwAtrLen); 00905 } 00906 rContext->readerState->cardAtrLength = dwAtrLen; 00907 00908 /* the protocol is unset after a power on */ 00909 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 00910 00911 /* 00912 * Notify the card has been reset 00913 */ 00914 (void)RFSetReaderEventState(rContext, SCARD_RESET); 00915 00916 /* 00917 * Set up the status bit masks on dwStatus 00918 */ 00919 if (rv == SCARD_S_SUCCESS) 00920 { 00921 rContext->readerState->readerState |= SCARD_PRESENT; 00922 rContext->readerState->readerState &= ~SCARD_ABSENT; 00923 rContext->readerState->readerState |= SCARD_POWERED; 00924 rContext->readerState->readerState |= SCARD_NEGOTIABLE; 00925 rContext->readerState->readerState &= ~SCARD_SPECIFIC; 00926 rContext->readerState->readerState &= ~SCARD_SWALLOWED; 00927 rContext->readerState->readerState &= ~SCARD_UNKNOWN; 00928 } 00929 else 00930 { 00931 if (rContext->readerState->readerState & SCARD_ABSENT) 00932 rContext->readerState->readerState &= ~SCARD_PRESENT; 00933 else 00934 rContext->readerState->readerState |= SCARD_PRESENT; 00935 /* SCARD_ABSENT flag is already set */ 00936 rContext->readerState->readerState |= SCARD_SWALLOWED; 00937 rContext->readerState->readerState &= ~SCARD_POWERED; 00938 rContext->readerState->readerState &= ~SCARD_NEGOTIABLE; 00939 rContext->readerState->readerState &= ~SCARD_SPECIFIC; 00940 rContext->readerState->readerState &= ~SCARD_UNKNOWN; 00941 rContext->readerState->cardAtrLength = 0; 00942 } 00943 00944 if (rContext->readerState->cardAtrLength > 0) 00945 Log1(PCSC_LOG_DEBUG, "Reset complete."); 00946 else 00947 Log1(PCSC_LOG_ERROR, "Error resetting card."); 00948 } 00949 else if (dwDisposition == SCARD_EJECT_CARD) 00950 { 00951 UCHAR controlBuffer[5]; 00952 UCHAR receiveBuffer[MAX_BUFFER_SIZE]; 00953 DWORD receiveLength; 00954 00955 /* 00956 * Set up the CTBCS command for Eject ICC 00957 */ 00958 controlBuffer[0] = 0x20; 00959 controlBuffer[1] = 0x15; 00960 controlBuffer[2] = (rContext->dwSlot & 0x0000FFFF) + 1; 00961 controlBuffer[3] = 0x00; 00962 controlBuffer[4] = 0x00; 00963 receiveLength = 2; 00964 rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer, 00965 &receiveLength); 00966 00967 if (rv == SCARD_S_SUCCESS) 00968 { 00969 if (receiveLength == 2 && receiveBuffer[0] == 0x90) 00970 { 00971 Log1(PCSC_LOG_DEBUG, "Card ejected successfully."); 00972 /* 00973 * Successful 00974 */ 00975 } 00976 else 00977 Log1(PCSC_LOG_ERROR, "Error ejecting card."); 00978 } 00979 else 00980 Log1(PCSC_LOG_ERROR, "Error ejecting card."); 00981 00982 } 00983 else if (dwDisposition == SCARD_LEAVE_CARD) 00984 { 00985 /* 00986 * Do nothing 00987 */ 00988 } 00989 00990 /* 00991 * Remove and destroy this handle 00992 */ 00993 (void)RFRemoveReaderHandle(rContext, hCard); 00994 (void)RFDestroyReaderHandle(hCard); 00995 00996 /* 00997 * For exclusive connection reset it to no connections 00998 */ 00999 if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT) 01000 rContext->dwContexts = SCARD_NO_CONTEXT; 01001 else 01002 { 01003 /* 01004 * Remove a connection from the context stack 01005 */ 01006 rContext->dwContexts -= 1; 01007 01008 if (rContext->dwContexts < 0) 01009 rContext->dwContexts = 0; 01010 } 01011 01012 /* 01013 * Propagate new state to Shared Memory 01014 */ 01015 rContext->readerState->readerSharing = rContext->dwContexts; 01016 (void)StatSynchronize(rContext->readerState); 01017 01018 return SCARD_S_SUCCESS; 01019 } 01020 01021 LONG SCardBeginTransaction(SCARDHANDLE hCard) 01022 { 01023 LONG rv; 01024 PREADER_CONTEXT rContext; 01025 01026 if (hCard == 0) 01027 return SCARD_E_INVALID_HANDLE; 01028 01029 rv = RFReaderInfoById(hCard, &rContext); 01030 01031 /* 01032 * Cannot find the hCard in this context 01033 */ 01034 if (rv != SCARD_S_SUCCESS) 01035 return rv; 01036 01037 /* 01038 * Make sure the reader is working properly 01039 */ 01040 rv = RFCheckReaderStatus(rContext); 01041 if (rv != SCARD_S_SUCCESS) 01042 return rv; 01043 01044 rv = RFFindReaderHandle(hCard); 01045 if (rv != SCARD_S_SUCCESS) 01046 return rv; 01047 01048 /* 01049 * Make sure some event has not occurred 01050 */ 01051 if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS) 01052 return rv; 01053 01054 rv = RFLockSharing(hCard); 01055 01056 /* if the transaction is not yet ready we sleep a bit so the client 01057 * do not retry immediately */ 01058 if (SCARD_E_SHARING_VIOLATION == rv) 01059 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE); 01060 01061 Log2(PCSC_LOG_DEBUG, "Status: 0x%08X", rv); 01062 01063 return rv; 01064 } 01065 01066 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition) 01067 { 01068 LONG rv; 01069 PREADER_CONTEXT rContext = NULL; 01070 DWORD dwAtrLen; 01071 01072 /* 01073 * Ignoring dwDisposition for now 01074 */ 01075 if (hCard == 0) 01076 return SCARD_E_INVALID_HANDLE; 01077 01078 if ((dwDisposition != SCARD_LEAVE_CARD) 01079 && (dwDisposition != SCARD_UNPOWER_CARD) 01080 && (dwDisposition != SCARD_RESET_CARD) 01081 && (dwDisposition != SCARD_EJECT_CARD)) 01082 return SCARD_E_INVALID_VALUE; 01083 01084 rv = RFReaderInfoById(hCard, &rContext); 01085 01086 /* 01087 * Cannot find the hCard in this context 01088 */ 01089 if (rv != SCARD_S_SUCCESS) 01090 return rv; 01091 01092 rv = RFFindReaderHandle(hCard); 01093 if (rv != SCARD_S_SUCCESS) 01094 return rv; 01095 01096 /* 01097 * Make sure some event has not occurred 01098 */ 01099 if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS) 01100 return rv; 01101 01102 if (dwDisposition == SCARD_RESET_CARD || 01103 dwDisposition == SCARD_UNPOWER_CARD) 01104 { 01105 /* 01106 * Currently pcsc-lite keeps the card always powered 01107 */ 01108 dwAtrLen = rContext->readerState->cardAtrLength; 01109 if (SCARD_RESET_CARD == dwDisposition) 01110 rv = IFDPowerICC(rContext, IFD_RESET, 01111 rContext->readerState->cardAtr, 01112 &dwAtrLen); 01113 else 01114 { 01115 rv = IFDPowerICC(rContext, IFD_POWER_DOWN, 01116 rContext->readerState->cardAtr, 01117 &dwAtrLen); 01118 rv = IFDPowerICC(rContext, IFD_POWER_UP, 01119 rContext->readerState->cardAtr, 01120 &dwAtrLen); 01121 } 01122 rContext->readerState->cardAtrLength = dwAtrLen; 01123 01124 /* the protocol is unset after a power on */ 01125 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 01126 01127 /* 01128 * Notify the card has been reset 01129 */ 01130 (void)RFSetReaderEventState(rContext, SCARD_RESET); 01131 01132 /* 01133 * Set up the status bit masks on dwStatus 01134 */ 01135 if (rv == SCARD_S_SUCCESS) 01136 { 01137 rContext->readerState->readerState |= SCARD_PRESENT; 01138 rContext->readerState->readerState &= ~SCARD_ABSENT; 01139 rContext->readerState->readerState |= SCARD_POWERED; 01140 rContext->readerState->readerState |= SCARD_NEGOTIABLE; 01141 rContext->readerState->readerState &= ~SCARD_SPECIFIC; 01142 rContext->readerState->readerState &= ~SCARD_SWALLOWED; 01143 rContext->readerState->readerState &= ~SCARD_UNKNOWN; 01144 } 01145 else 01146 { 01147 if (rContext->readerState->readerState & SCARD_ABSENT) 01148 rContext->readerState->readerState &= ~SCARD_PRESENT; 01149 else 01150 rContext->readerState->readerState |= SCARD_PRESENT; 01151 /* SCARD_ABSENT flag is already set */ 01152 rContext->readerState->readerState |= SCARD_SWALLOWED; 01153 rContext->readerState->readerState &= ~SCARD_POWERED; 01154 rContext->readerState->readerState &= ~SCARD_NEGOTIABLE; 01155 rContext->readerState->readerState &= ~SCARD_SPECIFIC; 01156 rContext->readerState->readerState &= ~SCARD_UNKNOWN; 01157 rContext->readerState->cardAtrLength = 0; 01158 } 01159 01160 if (rContext->readerState->cardAtrLength > 0) 01161 Log1(PCSC_LOG_DEBUG, "Reset complete."); 01162 else 01163 Log1(PCSC_LOG_ERROR, "Error resetting card."); 01164 01165 } 01166 else if (dwDisposition == SCARD_EJECT_CARD) 01167 { 01168 UCHAR controlBuffer[5]; 01169 UCHAR receiveBuffer[MAX_BUFFER_SIZE]; 01170 DWORD receiveLength; 01171 01172 /* 01173 * Set up the CTBCS command for Eject ICC 01174 */ 01175 controlBuffer[0] = 0x20; 01176 controlBuffer[1] = 0x15; 01177 controlBuffer[2] = (rContext->dwSlot & 0x0000FFFF) + 1; 01178 controlBuffer[3] = 0x00; 01179 controlBuffer[4] = 0x00; 01180 receiveLength = 2; 01181 rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer, 01182 &receiveLength); 01183 01184 if (rv == SCARD_S_SUCCESS) 01185 { 01186 if (receiveLength == 2 && receiveBuffer[0] == 0x90) 01187 { 01188 Log1(PCSC_LOG_DEBUG, "Card ejected successfully."); 01189 /* 01190 * Successful 01191 */ 01192 } 01193 else 01194 Log1(PCSC_LOG_ERROR, "Error ejecting card."); 01195 } 01196 else 01197 Log1(PCSC_LOG_ERROR, "Error ejecting card."); 01198 01199 } 01200 else if (dwDisposition == SCARD_LEAVE_CARD) 01201 { 01202 /* 01203 * Do nothing 01204 */ 01205 } 01206 01207 /* 01208 * Unlock any blocks on this context 01209 */ 01210 (void)RFUnlockSharing(hCard); 01211 01212 Log2(PCSC_LOG_DEBUG, "Status: 0x%08X", rv); 01213 01214 return rv; 01215 } 01216 01217 LONG SCardCancelTransaction(SCARDHANDLE hCard) 01218 { 01219 LONG rv; 01220 PREADER_CONTEXT rContext = NULL; 01221 01222 /* 01223 * Ignoring dwDisposition for now 01224 */ 01225 if (hCard == 0) 01226 return SCARD_E_INVALID_HANDLE; 01227 01228 rv = RFReaderInfoById(hCard, &rContext); 01229 01230 /* 01231 * Cannot find the hCard in this context 01232 */ 01233 if (rv != SCARD_S_SUCCESS) 01234 return rv; 01235 01236 rv = RFFindReaderHandle(hCard); 01237 if (rv != SCARD_S_SUCCESS) 01238 return rv; 01239 01240 /* 01241 * Make sure some event has not occurred 01242 */ 01243 if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS) 01244 return rv; 01245 01246 rv = RFUnlockSharing(hCard); 01247 01248 Log2(PCSC_LOG_DEBUG, "Status: 0x%08X", rv); 01249 01250 return rv; 01251 } 01252 01253 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames, 01254 LPDWORD pcchReaderLen, LPDWORD pdwState, 01255 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) 01256 { 01257 LONG rv; 01258 PREADER_CONTEXT rContext = NULL; 01259 01260 if (hCard == 0) 01261 return SCARD_E_INVALID_HANDLE; 01262 01263 rv = RFReaderInfoById(hCard, &rContext); 01264 01265 /* 01266 * Cannot find the hCard in this context 01267 */ 01268 if (rv != SCARD_S_SUCCESS) 01269 return rv; 01270 01271 if (strlen(rContext->lpcReader) > MAX_BUFFER_SIZE 01272 || rContext->readerState->cardAtrLength > MAX_ATR_SIZE) 01273 return SCARD_F_INTERNAL_ERROR; 01274 01275 /* 01276 * This is a client side function however the server maintains the 01277 * list of events between applications so it must be passed through to 01278 * obtain this event if it has occurred 01279 */ 01280 01281 /* 01282 * Make sure some event has not occurred 01283 */ 01284 if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS) 01285 return rv; 01286 01287 /* 01288 * Make sure the reader is working properly 01289 */ 01290 rv = RFCheckReaderStatus(rContext); 01291 if (rv != SCARD_S_SUCCESS) 01292 return rv; 01293 01294 if (mszReaderNames) 01295 { /* want reader name */ 01296 if (pcchReaderLen) 01297 { /* & present reader name length */ 01298 if (*pcchReaderLen >= strlen(rContext->lpcReader)) 01299 { /* & enough room */ 01300 *pcchReaderLen = strlen(rContext->lpcReader); 01301 strncpy(mszReaderNames, rContext->lpcReader, MAX_READERNAME); 01302 } 01303 else 01304 { /* may report only reader name len */ 01305 *pcchReaderLen = strlen(rContext->lpcReader); 01306 rv = SCARD_E_INSUFFICIENT_BUFFER; 01307 } 01308 } 01309 else 01310 { /* present buf & no buflen */ 01311 return SCARD_E_INVALID_PARAMETER; 01312 } 01313 } 01314 else 01315 { 01316 if (pcchReaderLen) 01317 { /* want reader len only */ 01318 *pcchReaderLen = strlen(rContext->lpcReader); 01319 } 01320 else 01321 { 01322 /* nothing todo */ 01323 } 01324 } 01325 01326 if (pdwState) 01327 *pdwState = rContext->readerState->readerState; 01328 01329 if (pdwProtocol) 01330 *pdwProtocol = rContext->readerState->cardProtocol; 01331 01332 if (pbAtr) 01333 { /* want ATR */ 01334 if (pcbAtrLen) 01335 { /* & present ATR length */ 01336 if (*pcbAtrLen >= rContext->readerState->cardAtrLength) 01337 { /* & enough room */ 01338 *pcbAtrLen = rContext->readerState->cardAtrLength; 01339 memcpy(pbAtr, rContext->readerState->cardAtr, 01340 rContext->readerState->cardAtrLength); 01341 } 01342 else 01343 { /* may report only ATR len */ 01344 *pcbAtrLen = rContext->readerState->cardAtrLength; 01345 rv = SCARD_E_INSUFFICIENT_BUFFER; 01346 } 01347 } 01348 else 01349 { /* present buf & no buflen */ 01350 return SCARD_E_INVALID_PARAMETER; 01351 } 01352 } 01353 else 01354 { 01355 if (pcbAtrLen) 01356 { /* want ATR len only */ 01357 *pcbAtrLen = rContext->readerState->cardAtrLength; 01358 } 01359 else 01360 { 01361 /* nothing todo */ 01362 } 01363 } 01364 01365 return rv; 01366 } 01367 01368 LONG SCardGetStatusChange(/*@unused@*/ SCARDCONTEXT hContext, 01369 /*@unused@*/ DWORD dwTimeout, 01370 /*@unused@*/ LPSCARD_READERSTATE_A rgReaderStates, 01371 /*@unused@*/ DWORD cReaders) 01372 { 01373 /* 01374 * Client side function 01375 */ 01376 (void)hContext; 01377 (void)dwTimeout; 01378 (void)rgReaderStates; 01379 (void)cReaders; 01380 return SCARD_S_SUCCESS; 01381 } 01382 01383 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, 01384 LPCVOID pbSendBuffer, DWORD cbSendLength, 01385 LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned) 01386 { 01387 LONG rv; 01388 PREADER_CONTEXT rContext = NULL; 01389 01390 /* 0 bytes returned by default */ 01391 *lpBytesReturned = 0; 01392 01393 if (0 == hCard) 01394 return SCARD_E_INVALID_HANDLE; 01395 01396 /* 01397 * Make sure no one has a lock on this reader 01398 */ 01399 if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS) 01400 return rv; 01401 01402 rv = RFReaderInfoById(hCard, &rContext); 01403 if (rv != SCARD_S_SUCCESS) 01404 return rv; 01405 01406 if (IFD_HVERSION_2_0 == rContext->dwVersion) 01407 if (NULL == pbSendBuffer || 0 == cbSendLength) 01408 return SCARD_E_INVALID_PARAMETER; 01409 01410 /* 01411 * Make sure the reader is working properly 01412 */ 01413 rv = RFCheckReaderStatus(rContext); 01414 if (rv != SCARD_S_SUCCESS) 01415 return rv; 01416 01417 rv = RFFindReaderHandle(hCard); 01418 if (rv != SCARD_S_SUCCESS) 01419 return rv; 01420 01421 /* 01422 * Make sure some event has not occurred 01423 */ 01424 if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS) 01425 return rv; 01426 01427 if (IFD_HVERSION_2_0 == rContext->dwVersion) 01428 { 01429 /* we must wrap a API 3.0 client in an API 2.0 driver */ 01430 *lpBytesReturned = cbRecvLength; 01431 return IFDControl_v2(rContext, (PUCHAR)pbSendBuffer, 01432 cbSendLength, pbRecvBuffer, lpBytesReturned); 01433 } 01434 else 01435 if (IFD_HVERSION_3_0 == rContext->dwVersion) 01436 return IFDControl(rContext, dwControlCode, pbSendBuffer, 01437 cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned); 01438 else 01439 return SCARD_E_UNSUPPORTED_FEATURE; 01440 } 01441 01442 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, 01443 LPBYTE pbAttr, LPDWORD pcbAttrLen) 01444 { 01445 LONG rv; 01446 PREADER_CONTEXT rContext = NULL; 01447 01448 if (0 == hCard) 01449 return SCARD_E_INVALID_HANDLE; 01450 01451 /* 01452 * Make sure no one has a lock on this reader 01453 */ 01454 if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS) 01455 return rv; 01456 01457 rv = RFReaderInfoById(hCard, &rContext); 01458 if (rv != SCARD_S_SUCCESS) 01459 return rv; 01460 01461 /* 01462 * Make sure the reader is working properly 01463 */ 01464 rv = RFCheckReaderStatus(rContext); 01465 if (rv != SCARD_S_SUCCESS) 01466 return rv; 01467 01468 rv = RFFindReaderHandle(hCard); 01469 if (rv != SCARD_S_SUCCESS) 01470 return rv; 01471 01472 /* 01473 * Make sure some event has not occurred 01474 */ 01475 if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS) 01476 return rv; 01477 01478 rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr); 01479 if (rv == IFD_SUCCESS) 01480 return SCARD_S_SUCCESS; 01481 else 01482 if (rv == IFD_ERROR_TAG) 01483 return SCARD_E_UNSUPPORTED_FEATURE; 01484 else 01485 return SCARD_E_NOT_TRANSACTED; 01486 } 01487 01488 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, 01489 LPCBYTE pbAttr, DWORD cbAttrLen) 01490 { 01491 LONG rv; 01492 PREADER_CONTEXT rContext = NULL; 01493 01494 if (0 == hCard) 01495 return SCARD_E_INVALID_HANDLE; 01496 01497 /* 01498 * Make sure no one has a lock on this reader 01499 */ 01500 if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS) 01501 return rv; 01502 01503 rv = RFReaderInfoById(hCard, &rContext); 01504 if (rv != SCARD_S_SUCCESS) 01505 return rv; 01506 01507 /* 01508 * Make sure the reader is working properly 01509 */ 01510 rv = RFCheckReaderStatus(rContext); 01511 if (rv != SCARD_S_SUCCESS) 01512 return rv; 01513 01514 rv = RFFindReaderHandle(hCard); 01515 if (rv != SCARD_S_SUCCESS) 01516 return rv; 01517 01518 /* 01519 * Make sure some event has not occurred 01520 */ 01521 if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS) 01522 return rv; 01523 01524 rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr); 01525 if (rv == IFD_SUCCESS) 01526 return SCARD_S_SUCCESS; 01527 else 01528 if (rv == IFD_ERROR_TAG) 01529 return SCARD_E_UNSUPPORTED_FEATURE; 01530 else 01531 return SCARD_E_NOT_TRANSACTED; 01532 } 01533 01534 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, 01535 LPCBYTE pbSendBuffer, DWORD cbSendLength, 01536 LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, 01537 LPDWORD pcbRecvLength) 01538 { 01539 LONG rv; 01540 PREADER_CONTEXT rContext = NULL; 01541 SCARD_IO_HEADER sSendPci, sRecvPci; 01542 DWORD dwRxLength, tempRxLength; 01543 01544 if (pcbRecvLength == 0) 01545 return SCARD_E_INVALID_PARAMETER; 01546 01547 dwRxLength = *pcbRecvLength; 01548 *pcbRecvLength = 0; 01549 01550 if (hCard == 0) 01551 return SCARD_E_INVALID_HANDLE; 01552 01553 if (pbSendBuffer == NULL || pbRecvBuffer == NULL || pioSendPci == NULL) 01554 return SCARD_E_INVALID_PARAMETER; 01555 01556 /* 01557 * Must at least send a 4 bytes APDU 01558 */ 01559 if (cbSendLength < 4) 01560 return SCARD_E_INVALID_PARAMETER; 01561 01562 /* 01563 * Must at least have 2 status words even for SCardControl 01564 */ 01565 if (dwRxLength < 2) 01566 return SCARD_E_INSUFFICIENT_BUFFER; 01567 01568 /* 01569 * Make sure no one has a lock on this reader 01570 */ 01571 if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS) 01572 return rv; 01573 01574 rv = RFReaderInfoById(hCard, &rContext); 01575 if (rv != SCARD_S_SUCCESS) 01576 return rv; 01577 01578 /* 01579 * Make sure the reader is working properly 01580 */ 01581 rv = RFCheckReaderStatus(rContext); 01582 if (rv != SCARD_S_SUCCESS) 01583 return rv; 01584 01585 rv = RFFindReaderHandle(hCard); 01586 if (rv != SCARD_S_SUCCESS) 01587 return rv; 01588 01589 /* 01590 * Make sure some event has not occurred 01591 */ 01592 if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS) 01593 return rv; 01594 01595 /* 01596 * Check for some common errors 01597 */ 01598 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW) 01599 { 01600 if (rContext->readerState->readerState & SCARD_ABSENT) 01601 { 01602 return SCARD_E_NO_SMARTCARD; 01603 } 01604 } 01605 01606 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW) 01607 { 01608 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD) 01609 { 01610 if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol) 01611 { 01612 return SCARD_E_PROTO_MISMATCH; 01613 } 01614 } 01615 } 01616 01617 /* 01618 * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler 01619 * just wants 0 or 1 01620 */ 01621 01622 sSendPci.Protocol = 0; /* protocol T=0 by default */ 01623 01624 if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1) 01625 { 01626 sSendPci.Protocol = 1; 01627 } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW) 01628 { 01629 /* 01630 * This is temporary ...... 01631 */ 01632 sSendPci.Protocol = SCARD_PROTOCOL_RAW; 01633 } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD) 01634 { 01635 /* Fix by Amira (Athena) */ 01636 unsigned long i; 01637 unsigned long prot = rContext->readerState->cardProtocol; 01638 01639 for (i = 0 ; prot != 1 ; i++) 01640 prot >>= 1; 01641 01642 sSendPci.Protocol = i; 01643 } 01644 01645 sSendPci.Length = pioSendPci->cbPciLength; 01646 01647 sRecvPci.Protocol = pioRecvPci->dwProtocol; 01648 sRecvPci.Length = pioRecvPci->cbPciLength; 01649 01650 /* the protocol number is decoded a few lines above */ 01651 Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%d", sSendPci.Protocol); 01652 01653 tempRxLength = dwRxLength; 01654 01655 if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW) 01656 { 01657 rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength, 01658 pbRecvBuffer, &dwRxLength); 01659 } else 01660 { 01661 rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer, 01662 cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci); 01663 } 01664 01665 pioRecvPci->dwProtocol = sRecvPci.Protocol; 01666 pioRecvPci->cbPciLength = sRecvPci.Length; 01667 01668 /* 01669 * Check for any errors that might have occurred 01670 */ 01671 01672 if (rv != SCARD_S_SUCCESS) 01673 { 01674 *pcbRecvLength = 0; 01675 Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv); 01676 return rv; 01677 } 01678 01679 /* 01680 * Available is less than received 01681 */ 01682 if (tempRxLength < dwRxLength) 01683 { 01684 *pcbRecvLength = 0; 01685 return SCARD_E_INSUFFICIENT_BUFFER; 01686 } 01687 01688 /* 01689 * Successful return 01690 */ 01691 *pcbRecvLength = dwRxLength; 01692 return SCARD_S_SUCCESS; 01693 } 01694 01695 LONG SCardListReaders(/*@unused@*/ SCARDCONTEXT hContext, 01696 /*@unused@*/ LPCSTR mszGroups, 01697 /*@unused@*/ LPSTR mszReaders, 01698 /*@unused@*/ LPDWORD pcchReaders) 01699 { 01700 /* 01701 * Client side function 01702 */ 01703 (void)hContext; 01704 (void)mszGroups; 01705 (void)mszReaders; 01706 (void)pcchReaders; 01707 return SCARD_S_SUCCESS; 01708 } 01709 01710 LONG SCardCancel(/*@unused@*/ SCARDCONTEXT hContext) 01711 { 01712 /* 01713 * Client side function 01714 */ 01715 (void)hContext; 01716 return SCARD_S_SUCCESS; 01717 } 01718