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