pcsc-lite
1.8.2
|
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-2011 00007 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00008 * 00009 * $Id: winscard.c 5962 2011-09-24 08:24:34Z 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 00173 LONG SCardEstablishContext(DWORD dwScope, /*@unused@*/ LPCVOID pvReserved1, 00174 /*@unused@*/ LPCVOID pvReserved2, LPSCARDCONTEXT phContext) 00175 { 00176 (void)pvReserved1; 00177 (void)pvReserved2; 00178 00179 if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL && 00180 dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL) 00181 { 00182 *phContext = 0; 00183 return SCARD_E_INVALID_VALUE; 00184 } 00185 00186 /* 00187 * Unique identifier for this server so that it can uniquely be 00188 * identified by clients and distinguished from others 00189 */ 00190 00191 *phContext = (PCSCLITE_SVC_IDENTITY + SYS_RandomInt(1, 65535)); 00192 00193 Log2(PCSC_LOG_DEBUG, "Establishing Context: 0x%lX", *phContext); 00194 00195 return SCARD_S_SUCCESS; 00196 } 00197 00198 LONG SCardReleaseContext(SCARDCONTEXT hContext) 00199 { 00200 /* 00201 * Nothing to do here RPC layer will handle this 00202 */ 00203 00204 Log2(PCSC_LOG_DEBUG, "Releasing Context: 0x%lX", hContext); 00205 00206 return SCARD_S_SUCCESS; 00207 } 00208 00209 LONG SCardConnect(/*@unused@*/ SCARDCONTEXT hContext, LPCSTR szReader, 00210 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, 00211 LPDWORD pdwActiveProtocol) 00212 { 00213 LONG rv; 00214 READER_CONTEXT * rContext = NULL; 00215 uint32_t readerState; 00216 00217 (void)hContext; 00218 PROFILE_START 00219 00220 *phCard = 0; 00221 00222 if ((dwShareMode != SCARD_SHARE_DIRECT) && 00223 !(dwPreferredProtocols & SCARD_PROTOCOL_T0) && 00224 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) && 00225 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) && 00226 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)) 00227 return SCARD_E_PROTO_MISMATCH; 00228 00229 if (dwShareMode != SCARD_SHARE_EXCLUSIVE && 00230 dwShareMode != SCARD_SHARE_SHARED && 00231 dwShareMode != SCARD_SHARE_DIRECT) 00232 return SCARD_E_INVALID_VALUE; 00233 00234 Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %ld", 00235 szReader, dwPreferredProtocols); 00236 00237 rv = RFReaderInfo((LPSTR) szReader, &rContext); 00238 00239 if (rv != SCARD_S_SUCCESS) 00240 { 00241 Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader); 00242 return rv; 00243 } 00244 00245 /* 00246 * Make sure the reader is working properly 00247 */ 00248 rv = RFCheckReaderStatus(rContext); 00249 if (rv != SCARD_S_SUCCESS) 00250 return rv; 00251 00252 /******************************************* 00253 * 00254 * This section checks for simple errors 00255 * 00256 *******************************************/ 00257 00258 /* 00259 * Connect if not exclusive mode 00260 */ 00261 if (rContext->contexts == PCSCLITE_SHARING_EXCLUSIVE_CONTEXT) 00262 { 00263 Log1(PCSC_LOG_ERROR, "Error Reader Exclusive"); 00264 return SCARD_E_SHARING_VIOLATION; 00265 } 00266 00267 /* 00268 * wait until a possible transaction is finished 00269 */ 00270 if (rContext->hLockId != 0) 00271 { 00272 Log1(PCSC_LOG_INFO, "Waiting for release of lock"); 00273 while (rContext->hLockId != 0) 00274 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE); 00275 Log1(PCSC_LOG_INFO, "Lock released"); 00276 } 00277 00278 /******************************************* 00279 * 00280 * This section tries to determine the 00281 * presence of a card or not 00282 * 00283 *******************************************/ 00284 readerState = rContext->readerState->readerState; 00285 00286 if (dwShareMode != SCARD_SHARE_DIRECT) 00287 { 00288 if (!(readerState & SCARD_PRESENT)) 00289 { 00290 Log1(PCSC_LOG_DEBUG, "Card Not Inserted"); 00291 return SCARD_E_NO_SMARTCARD; 00292 } 00293 00294 /* Power on (again) the card if needed */ 00295 (void)pthread_mutex_lock(&rContext->powerState_lock); 00296 if (POWER_STATE_UNPOWERED == rContext->powerState) 00297 { 00298 DWORD dwAtrLen; 00299 00300 dwAtrLen = sizeof(rContext->readerState->cardAtr); 00301 rv = IFDPowerICC(rContext, IFD_POWER_UP, 00302 rContext->readerState->cardAtr, &dwAtrLen); 00303 rContext->readerState->cardAtrLength = dwAtrLen; 00304 00305 if (rv == IFD_SUCCESS) 00306 { 00307 readerState = SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE; 00308 00309 Log1(PCSC_LOG_DEBUG, "power up complete."); 00310 LogXxd(PCSC_LOG_DEBUG, "Card ATR: ", 00311 rContext->readerState->cardAtr, 00312 rContext->readerState->cardAtrLength); 00313 } 00314 else 00315 Log3(PCSC_LOG_ERROR, "Error powering up card: %ld 0x%04lX", 00316 rv, rv); 00317 } 00318 00319 if (! (readerState & SCARD_POWERED)) 00320 { 00321 Log1(PCSC_LOG_ERROR, "Card Not Powered"); 00322 (void)pthread_mutex_unlock(&rContext->powerState_lock); 00323 return SCARD_W_UNPOWERED_CARD; 00324 } 00325 00326 /* the card is now in use */ 00327 rContext->powerState = POWER_STATE_INUSE; 00328 Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_INUSE"); 00329 (void)pthread_mutex_unlock(&rContext->powerState_lock); 00330 } 00331 00332 /******************************************* 00333 * 00334 * This section tries to decode the ATR 00335 * and set up which protocol to use 00336 * 00337 *******************************************/ 00338 if (dwPreferredProtocols & SCARD_PROTOCOL_RAW) 00339 rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW; 00340 else 00341 { 00342 if (dwShareMode != SCARD_SHARE_DIRECT) 00343 { 00344 /* lock here instead in IFDSetPTS() to lock up to 00345 * setting rContext->readerState->cardProtocol */ 00346 (void)pthread_mutex_lock(rContext->mMutex); 00347 00348 /* the protocol is not yet set (no PPS yet) */ 00349 if (SCARD_PROTOCOL_UNDEFINED == rContext->readerState->cardProtocol) 00350 { 00351 int availableProtocols, defaultProtocol; 00352 int ret; 00353 00354 ATRDecodeAtr(&availableProtocols, &defaultProtocol, 00355 rContext->readerState->cardAtr, 00356 rContext->readerState->cardAtrLength); 00357 00358 /* If it is set to ANY let it do any of the protocols */ 00359 if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD) 00360 dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1; 00361 00362 ret = PHSetProtocol(rContext, dwPreferredProtocols, 00363 availableProtocols, defaultProtocol); 00364 00365 /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */ 00366 if (SET_PROTOCOL_PPS_FAILED == ret) 00367 { 00368 (void)pthread_mutex_unlock(rContext->mMutex); 00369 return SCARD_W_UNRESPONSIVE_CARD; 00370 } 00371 00372 if (SET_PROTOCOL_WRONG_ARGUMENT == ret) 00373 { 00374 (void)pthread_mutex_unlock(rContext->mMutex); 00375 return SCARD_E_PROTO_MISMATCH; 00376 } 00377 00378 /* use negotiated protocol */ 00379 rContext->readerState->cardProtocol = ret; 00380 00381 (void)pthread_mutex_unlock(rContext->mMutex); 00382 } 00383 else 00384 { 00385 (void)pthread_mutex_unlock(rContext->mMutex); 00386 00387 if (! (dwPreferredProtocols & rContext->readerState->cardProtocol)) 00388 return SCARD_E_PROTO_MISMATCH; 00389 } 00390 } 00391 } 00392 00393 *pdwActiveProtocol = rContext->readerState->cardProtocol; 00394 00395 if (dwShareMode != SCARD_SHARE_DIRECT) 00396 { 00397 switch (*pdwActiveProtocol) 00398 { 00399 case SCARD_PROTOCOL_T0: 00400 case SCARD_PROTOCOL_T1: 00401 Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d", 00402 (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1); 00403 break; 00404 00405 case SCARD_PROTOCOL_RAW: 00406 Log1(PCSC_LOG_DEBUG, "Active Protocol: RAW"); 00407 break; 00408 00409 default: 00410 Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %ld", 00411 *pdwActiveProtocol); 00412 } 00413 } 00414 else 00415 Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected"); 00416 00417 /* 00418 * Prepare the SCARDHANDLE identity 00419 */ 00420 *phCard = RFCreateReaderHandle(rContext); 00421 00422 Log2(PCSC_LOG_DEBUG, "hCard Identity: %lx", *phCard); 00423 00424 /******************************************* 00425 * 00426 * This section tries to set up the 00427 * exclusivity modes. -1 is exclusive 00428 * 00429 *******************************************/ 00430 00431 if (dwShareMode == SCARD_SHARE_EXCLUSIVE) 00432 { 00433 if (rContext->contexts == PCSCLITE_SHARING_NO_CONTEXT) 00434 { 00435 rContext->contexts = PCSCLITE_SHARING_EXCLUSIVE_CONTEXT; 00436 (void)RFLockSharing(*phCard, rContext); 00437 } 00438 else 00439 { 00440 (void)RFDestroyReaderHandle(*phCard); 00441 *phCard = 0; 00442 return SCARD_E_SHARING_VIOLATION; 00443 } 00444 } 00445 else 00446 { 00447 /* 00448 * Add a connection to the context stack 00449 */ 00450 rContext->contexts += 1; 00451 } 00452 00453 /* 00454 * Add this handle to the handle list 00455 */ 00456 rv = RFAddReaderHandle(rContext, *phCard); 00457 00458 if (rv != SCARD_S_SUCCESS) 00459 { 00460 /* 00461 * Clean up - there is no more room 00462 */ 00463 (void)RFDestroyReaderHandle(*phCard); 00464 if (rContext->contexts == PCSCLITE_SHARING_EXCLUSIVE_CONTEXT) 00465 rContext->contexts = PCSCLITE_SHARING_NO_CONTEXT; 00466 else 00467 if (rContext->contexts > PCSCLITE_SHARING_NO_CONTEXT) 00468 rContext->contexts -= 1; 00469 00470 *phCard = 0; 00471 00472 PROFILE_END 00473 00474 return SCARD_F_INTERNAL_ERROR; 00475 } 00476 00477 /* 00478 * Propagate new state to reader state 00479 */ 00480 rContext->readerState->readerSharing = rContext->contexts; 00481 00482 PROFILE_END 00483 00484 return SCARD_S_SUCCESS; 00485 } 00486 00487 LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, 00488 DWORD dwPreferredProtocols, DWORD dwInitialization, 00489 LPDWORD pdwActiveProtocol) 00490 { 00491 LONG rv; 00492 READER_CONTEXT * rContext = NULL; 00493 00494 Log1(PCSC_LOG_DEBUG, "Attempting reconnect to token."); 00495 00496 if (hCard == 0) 00497 return SCARD_E_INVALID_HANDLE; 00498 00499 /* 00500 * Handle the dwInitialization 00501 */ 00502 if (dwInitialization != SCARD_LEAVE_CARD && 00503 dwInitialization != SCARD_RESET_CARD && 00504 dwInitialization != SCARD_UNPOWER_CARD) 00505 return SCARD_E_INVALID_VALUE; 00506 00507 if (dwShareMode != SCARD_SHARE_SHARED && 00508 dwShareMode != SCARD_SHARE_EXCLUSIVE && 00509 dwShareMode != SCARD_SHARE_DIRECT) 00510 return SCARD_E_INVALID_VALUE; 00511 00512 if ((dwShareMode != SCARD_SHARE_DIRECT) && 00513 !(dwPreferredProtocols & SCARD_PROTOCOL_T0) && 00514 !(dwPreferredProtocols & SCARD_PROTOCOL_T1) && 00515 !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) && 00516 !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)) 00517 return SCARD_E_PROTO_MISMATCH; 00518 00519 /* get rContext corresponding to hCard */ 00520 rv = RFReaderInfoById(hCard, &rContext); 00521 if (rv != SCARD_S_SUCCESS) 00522 return rv; 00523 00524 /* 00525 * Make sure the reader is working properly 00526 */ 00527 rv = RFCheckReaderStatus(rContext); 00528 if (rv != SCARD_S_SUCCESS) 00529 return rv; 00530 00531 rv = RFFindReaderHandle(hCard); 00532 if (rv != SCARD_S_SUCCESS) 00533 return rv; 00534 00535 /* 00536 * Make sure no one has a lock on this reader 00537 */ 00538 rv = RFCheckSharing(hCard, rContext); 00539 if (rv != SCARD_S_SUCCESS) 00540 return rv; 00541 00542 if (dwInitialization == SCARD_RESET_CARD || 00543 dwInitialization == SCARD_UNPOWER_CARD) 00544 { 00545 DWORD dwAtrLen; 00546 00547 /* 00548 * Notify the card has been reset 00549 */ 00550 (void)RFSetReaderEventState(rContext, SCARD_RESET); 00551 00552 /* 00553 * Currently pcsc-lite keeps the card powered constantly 00554 */ 00555 dwAtrLen = sizeof(rContext->readerState->cardAtr); 00556 if (SCARD_RESET_CARD == dwInitialization) 00557 rv = IFDPowerICC(rContext, IFD_RESET, 00558 rContext->readerState->cardAtr, &dwAtrLen); 00559 else 00560 { 00561 IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL); 00562 rv = IFDPowerICC(rContext, IFD_POWER_UP, 00563 rContext->readerState->cardAtr, &dwAtrLen); 00564 } 00565 rContext->readerState->cardAtrLength = dwAtrLen; 00566 00567 /* the protocol is unset after a power on */ 00568 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 00569 00570 /* 00571 * Set up the status bit masks on readerState 00572 */ 00573 if (rv == SCARD_S_SUCCESS) 00574 { 00575 rContext->readerState->cardAtrLength = dwAtrLen; 00576 rContext->readerState->readerState = 00577 SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE; 00578 00579 Log1(PCSC_LOG_DEBUG, "Reset complete."); 00580 LogXxd(PCSC_LOG_DEBUG, "Card ATR: ", 00581 rContext->readerState->cardAtr, 00582 rContext->readerState->cardAtrLength); 00583 } 00584 else 00585 { 00586 rContext->readerState->cardAtrLength = 0; 00587 Log1(PCSC_LOG_ERROR, "Error resetting card."); 00588 00589 if (rv == SCARD_W_REMOVED_CARD) 00590 { 00591 rContext->readerState->readerState = SCARD_ABSENT; 00592 return SCARD_E_NO_SMARTCARD; 00593 } 00594 else 00595 { 00596 rContext->readerState->readerState = 00597 SCARD_PRESENT | SCARD_SWALLOWED; 00598 return SCARD_W_UNRESPONSIVE_CARD; 00599 } 00600 } 00601 } 00602 else 00603 if (dwInitialization == SCARD_LEAVE_CARD) 00604 { 00605 uint32_t readerState = rContext->readerState->readerState; 00606 00607 if (readerState & SCARD_ABSENT) 00608 return SCARD_E_NO_SMARTCARD; 00609 00610 if ((readerState & SCARD_PRESENT) 00611 && (readerState & SCARD_SWALLOWED)) 00612 return SCARD_W_UNRESPONSIVE_CARD; 00613 } 00614 00615 /******************************************* 00616 * 00617 * This section tries to decode the ATR 00618 * and set up which protocol to use 00619 * 00620 *******************************************/ 00621 if (dwPreferredProtocols & SCARD_PROTOCOL_RAW) 00622 rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW; 00623 else 00624 { 00625 if (dwShareMode != SCARD_SHARE_DIRECT) 00626 { 00627 /* lock here instead in IFDSetPTS() to lock up to 00628 * setting rContext->readerState->cardProtocol */ 00629 (void)pthread_mutex_lock(rContext->mMutex); 00630 00631 /* the protocol is not yet set (no PPS yet) */ 00632 if (SCARD_PROTOCOL_UNDEFINED == rContext->readerState->cardProtocol) 00633 { 00634 int availableProtocols, defaultProtocol; 00635 int ret; 00636 00637 ATRDecodeAtr(&availableProtocols, &defaultProtocol, 00638 rContext->readerState->cardAtr, 00639 rContext->readerState->cardAtrLength); 00640 00641 /* If it is set to ANY let it do any of the protocols */ 00642 if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD) 00643 dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1; 00644 00645 ret = PHSetProtocol(rContext, dwPreferredProtocols, 00646 availableProtocols, defaultProtocol); 00647 00648 /* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error */ 00649 if (SET_PROTOCOL_PPS_FAILED == ret) 00650 { 00651 (void)pthread_mutex_unlock(rContext->mMutex); 00652 return SCARD_W_UNRESPONSIVE_CARD; 00653 } 00654 00655 if (SET_PROTOCOL_WRONG_ARGUMENT == ret) 00656 { 00657 (void)pthread_mutex_unlock(rContext->mMutex); 00658 return SCARD_E_PROTO_MISMATCH; 00659 } 00660 00661 /* use negotiated protocol */ 00662 rContext->readerState->cardProtocol = ret; 00663 00664 (void)pthread_mutex_unlock(rContext->mMutex); 00665 } 00666 else 00667 { 00668 (void)pthread_mutex_unlock(rContext->mMutex); 00669 00670 if (! (dwPreferredProtocols & rContext->readerState->cardProtocol)) 00671 return SCARD_E_PROTO_MISMATCH; 00672 } 00673 } 00674 } 00675 00676 *pdwActiveProtocol = rContext->readerState->cardProtocol; 00677 00678 if (dwShareMode != SCARD_SHARE_DIRECT) 00679 { 00680 switch (*pdwActiveProtocol) 00681 { 00682 case SCARD_PROTOCOL_T0: 00683 case SCARD_PROTOCOL_T1: 00684 Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d", 00685 (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1); 00686 break; 00687 00688 case SCARD_PROTOCOL_RAW: 00689 Log1(PCSC_LOG_DEBUG, "Active Protocol: RAW"); 00690 break; 00691 00692 default: 00693 Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %ld", 00694 *pdwActiveProtocol); 00695 } 00696 } 00697 else 00698 Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected"); 00699 00700 if (dwShareMode == SCARD_SHARE_EXCLUSIVE) 00701 { 00702 if (rContext->contexts == PCSCLITE_SHARING_EXCLUSIVE_CONTEXT) 00703 { 00704 /* 00705 * Do nothing - we are already exclusive 00706 */ 00707 } else 00708 { 00709 if (rContext->contexts == PCSCLITE_SHARING_LAST_CONTEXT) 00710 { 00711 rContext->contexts = PCSCLITE_SHARING_EXCLUSIVE_CONTEXT; 00712 (void)RFLockSharing(hCard, rContext); 00713 } else 00714 { 00715 return SCARD_E_SHARING_VIOLATION; 00716 } 00717 } 00718 } else if (dwShareMode == SCARD_SHARE_SHARED) 00719 { 00720 if (rContext->contexts != PCSCLITE_SHARING_EXCLUSIVE_CONTEXT) 00721 { 00722 /* 00723 * Do nothing - in sharing mode already 00724 */ 00725 } else 00726 { 00727 /* 00728 * We are in exclusive mode but want to share now 00729 */ 00730 (void)RFUnlockSharing(hCard, rContext); 00731 rContext->contexts = PCSCLITE_SHARING_LAST_CONTEXT; 00732 } 00733 } else if (dwShareMode == SCARD_SHARE_DIRECT) 00734 { 00735 if (rContext->contexts != PCSCLITE_SHARING_EXCLUSIVE_CONTEXT) 00736 { 00737 /* 00738 * Do nothing - in sharing mode already 00739 */ 00740 } else 00741 { 00742 /* 00743 * We are in exclusive mode but want to share now 00744 */ 00745 (void)RFUnlockSharing(hCard, rContext); 00746 rContext->contexts = PCSCLITE_SHARING_LAST_CONTEXT; 00747 } 00748 } else 00749 return SCARD_E_INVALID_VALUE; 00750 00751 /* 00752 * Clear a previous event to the application 00753 */ 00754 (void)RFClearReaderEventState(rContext, hCard); 00755 00756 /* 00757 * Propagate new state to reader state 00758 */ 00759 rContext->readerState->readerSharing = rContext->contexts; 00760 00761 return SCARD_S_SUCCESS; 00762 } 00763 00764 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) 00765 { 00766 LONG rv; 00767 READER_CONTEXT * rContext = NULL; 00768 00769 if (hCard == 0) 00770 return SCARD_E_INVALID_HANDLE; 00771 00772 /* get rContext corresponding to hCard */ 00773 rv = RFReaderInfoById(hCard, &rContext); 00774 if (rv != SCARD_S_SUCCESS) 00775 return rv; 00776 00777 rv = RFFindReaderHandle(hCard); 00778 if (rv != SCARD_S_SUCCESS) 00779 return rv; 00780 00781 if ((dwDisposition != SCARD_LEAVE_CARD) 00782 && (dwDisposition != SCARD_UNPOWER_CARD) 00783 && (dwDisposition != SCARD_RESET_CARD) 00784 && (dwDisposition != SCARD_EJECT_CARD)) 00785 return SCARD_E_INVALID_VALUE; 00786 00787 /* 00788 * wait until a possible transaction is finished 00789 */ 00790 if ((dwDisposition != SCARD_LEAVE_CARD) && (rContext->hLockId != 0) 00791 && (rContext->hLockId != hCard)) 00792 { 00793 Log1(PCSC_LOG_INFO, "Waiting for release of lock"); 00794 while (rContext->hLockId != 0) 00795 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE); 00796 Log1(PCSC_LOG_INFO, "Lock released"); 00797 } 00798 00799 /* 00800 * Try to unlock any blocks on this context 00801 * 00802 * This may fail with SCARD_E_SHARING_VIOLATION if a transaction is 00803 * on going on another card context and dwDisposition == SCARD_LEAVE_CARD. 00804 * We should not stop. 00805 */ 00806 rv = RFUnlockAllSharing(hCard, rContext); 00807 if (rv != SCARD_S_SUCCESS) 00808 { 00809 if (rv != SCARD_E_SHARING_VIOLATION) 00810 { 00811 return rv; 00812 } 00813 else 00814 { 00815 if (SCARD_LEAVE_CARD != dwDisposition) 00816 return rv; 00817 } 00818 } 00819 00820 Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->contexts); 00821 Log2(PCSC_LOG_DEBUG, "dwDisposition: %ld", dwDisposition); 00822 00823 if (dwDisposition == SCARD_RESET_CARD || 00824 dwDisposition == SCARD_UNPOWER_CARD) 00825 { 00826 DWORD dwAtrLen; 00827 00828 /* 00829 * Notify the card has been reset 00830 */ 00831 (void)RFSetReaderEventState(rContext, SCARD_RESET); 00832 00833 /* 00834 * Currently pcsc-lite keeps the card powered constantly 00835 * unless DISABLE_AUTO_POWER_ON is defined 00836 */ 00837 dwAtrLen = sizeof(rContext->readerState->cardAtr); 00838 if (SCARD_RESET_CARD == dwDisposition) 00839 rv = IFDPowerICC(rContext, IFD_RESET, 00840 rContext->readerState->cardAtr, &dwAtrLen); 00841 else 00842 { 00843 IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL); 00844 00845 #ifdef DISABLE_AUTO_POWER_ON 00846 rContext->powerState = POWER_STATE_UNPOWERED; 00847 Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_UNPOWERED"); 00848 #else 00849 rv = IFDPowerICC(rContext, IFD_POWER_UP, 00850 rContext->readerState->cardAtr, &dwAtrLen); 00851 #endif 00852 } 00853 00854 /* the protocol is unset after a power on */ 00855 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 00856 00857 #ifdef DISABLE_AUTO_POWER_ON 00858 if (SCARD_UNPOWER_CARD == dwDisposition) 00859 { 00860 rContext->readerState->cardAtrLength = 0; 00861 if (rv == SCARD_S_SUCCESS) 00862 rContext->readerState->readerState = SCARD_PRESENT; 00863 else 00864 { 00865 Log3(PCSC_LOG_ERROR, "Error powering down card: %d 0x%04X", 00866 rv, rv); 00867 if (rv == SCARD_W_REMOVED_CARD) 00868 rContext->readerState->readerState = SCARD_ABSENT; 00869 else 00870 rContext->readerState->readerState = 00871 SCARD_PRESENT | SCARD_SWALLOWED; 00872 } 00873 Log1(PCSC_LOG_INFO, "Skip card power on"); 00874 } 00875 else 00876 #endif 00877 { 00878 /* 00879 * Set up the status bit masks on readerState 00880 */ 00881 if (rv == SCARD_S_SUCCESS) 00882 { 00883 rContext->readerState->cardAtrLength = dwAtrLen; 00884 rContext->readerState->readerState = 00885 SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE; 00886 00887 Log1(PCSC_LOG_DEBUG, "Reset complete."); 00888 LogXxd(PCSC_LOG_DEBUG, "Card ATR: ", 00889 rContext->readerState->cardAtr, 00890 rContext->readerState->cardAtrLength); 00891 } 00892 else 00893 { 00894 rContext->readerState->cardAtrLength = 0; 00895 Log1(PCSC_LOG_ERROR, "Error resetting card."); 00896 00897 if (rv == SCARD_W_REMOVED_CARD) 00898 rContext->readerState->readerState = SCARD_ABSENT; 00899 else 00900 rContext->readerState->readerState = 00901 SCARD_PRESENT | SCARD_SWALLOWED; 00902 } 00903 } 00904 } 00905 else if (dwDisposition == SCARD_EJECT_CARD) 00906 { 00907 UCHAR controlBuffer[5]; 00908 UCHAR receiveBuffer[MAX_BUFFER_SIZE]; 00909 DWORD receiveLength; 00910 00911 /* 00912 * Set up the CTBCS command for Eject ICC 00913 */ 00914 controlBuffer[0] = 0x20; 00915 controlBuffer[1] = 0x15; 00916 controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1; 00917 controlBuffer[3] = 0x00; 00918 controlBuffer[4] = 0x00; 00919 receiveLength = 2; 00920 rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer, 00921 &receiveLength); 00922 00923 if (rv == SCARD_S_SUCCESS) 00924 { 00925 if (receiveLength == 2 && receiveBuffer[0] == 0x90) 00926 { 00927 Log1(PCSC_LOG_DEBUG, "Card ejected successfully."); 00928 /* 00929 * Successful 00930 */ 00931 } 00932 else 00933 Log1(PCSC_LOG_ERROR, "Error ejecting card."); 00934 } 00935 else 00936 Log1(PCSC_LOG_ERROR, "Error ejecting card."); 00937 00938 } 00939 else if (dwDisposition == SCARD_LEAVE_CARD) 00940 { 00941 /* 00942 * Do nothing 00943 */ 00944 } 00945 00946 /* 00947 * Remove and destroy this handle 00948 */ 00949 (void)RFRemoveReaderHandle(rContext, hCard); 00950 (void)RFDestroyReaderHandle(hCard); 00951 00952 /* 00953 * For exclusive connection reset it to no connections 00954 */ 00955 if (rContext->contexts == PCSCLITE_SHARING_EXCLUSIVE_CONTEXT) 00956 rContext->contexts = PCSCLITE_SHARING_NO_CONTEXT; 00957 else 00958 { 00959 /* 00960 * Remove a connection from the context stack 00961 */ 00962 rContext->contexts -= 1; 00963 00964 if (rContext->contexts < 0) 00965 rContext->contexts = 0; 00966 } 00967 00968 if (PCSCLITE_SHARING_NO_CONTEXT == rContext->contexts) 00969 { 00970 RESPONSECODE (*fct)(DWORD) = NULL; 00971 DWORD dwGetSize; 00972 00973 (void)pthread_mutex_lock(&rContext->powerState_lock); 00974 /* Switch to POWER_STATE_GRACE_PERIOD unless the card was not 00975 * powered */ 00976 if (POWER_STATE_POWERED <= rContext->powerState) 00977 { 00978 #ifdef DISABLE_AUTO_POWER_ON 00979 if (SCARD_RESET_CARD == dwDisposition) 00980 { 00981 rContext->powerState = POWER_STATE_GRACE_PERIOD; 00982 Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_GRACE_PERIOD"); 00983 } 00984 #else 00985 rContext->powerState = POWER_STATE_GRACE_PERIOD; 00986 Log1(PCSC_LOG_DEBUG, "powerState: POWER_STATE_GRACE_PERIOD"); 00987 #endif 00988 } 00989 00990 (void)pthread_mutex_unlock(&rContext->powerState_lock); 00991 00992 /* ask to stop the "polling" thread so it can be restarted using 00993 * the correct timeout */ 00994 dwGetSize = sizeof(fct); 00995 rv = IFDGetCapabilities(rContext, TAG_IFD_STOP_POLLING_THREAD, 00996 &dwGetSize, (PUCHAR)&fct); 00997 00998 if ((IFD_SUCCESS == rv) && (dwGetSize == sizeof(fct))) 00999 { 01000 Log1(PCSC_LOG_INFO, "Stoping polling thread"); 01001 fct(rContext->slot); 01002 } 01003 } 01004 01005 /* 01006 * Propagate new state to reader state 01007 */ 01008 rContext->readerState->readerSharing = rContext->contexts; 01009 01010 return SCARD_S_SUCCESS; 01011 } 01012 01013 LONG SCardBeginTransaction(SCARDHANDLE hCard) 01014 { 01015 LONG rv; 01016 READER_CONTEXT * rContext; 01017 01018 if (hCard == 0) 01019 return SCARD_E_INVALID_HANDLE; 01020 01021 /* get rContext corresponding to hCard */ 01022 rv = RFReaderInfoById(hCard, &rContext); 01023 if (rv != SCARD_S_SUCCESS) 01024 return rv; 01025 01026 /* 01027 * Make sure the reader is working properly 01028 */ 01029 rv = RFCheckReaderStatus(rContext); 01030 if (rv != SCARD_S_SUCCESS) 01031 return rv; 01032 01033 rv = RFFindReaderHandle(hCard); 01034 if (rv != SCARD_S_SUCCESS) 01035 return rv; 01036 01037 /* 01038 * Make sure some event has not occurred 01039 */ 01040 rv = RFCheckReaderEventState(rContext, hCard); 01041 if (rv != SCARD_S_SUCCESS) 01042 return rv; 01043 01044 rv = RFLockSharing(hCard, rContext); 01045 01046 /* if the transaction is not yet ready we sleep a bit so the client 01047 * do not retry immediately */ 01048 if (SCARD_E_SHARING_VIOLATION == rv) 01049 (void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE); 01050 01051 Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv); 01052 01053 return rv; 01054 } 01055 01056 LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition) 01057 { 01058 LONG rv; 01059 READER_CONTEXT * rContext = NULL; 01060 01061 /* 01062 * Ignoring dwDisposition for now 01063 */ 01064 if (hCard == 0) 01065 return SCARD_E_INVALID_HANDLE; 01066 01067 if ((dwDisposition != SCARD_LEAVE_CARD) 01068 && (dwDisposition != SCARD_UNPOWER_CARD) 01069 && (dwDisposition != SCARD_RESET_CARD) 01070 && (dwDisposition != SCARD_EJECT_CARD)) 01071 return SCARD_E_INVALID_VALUE; 01072 01073 /* get rContext corresponding to hCard */ 01074 rv = RFReaderInfoById(hCard, &rContext); 01075 if (rv != SCARD_S_SUCCESS) 01076 return rv; 01077 01078 rv = RFFindReaderHandle(hCard); 01079 if (rv != SCARD_S_SUCCESS) 01080 return rv; 01081 01082 /* 01083 * Make sure some event has not occurred 01084 */ 01085 rv = RFCheckReaderEventState(rContext, hCard); 01086 if (rv != SCARD_S_SUCCESS) 01087 return rv; 01088 01089 if (dwDisposition == SCARD_RESET_CARD || 01090 dwDisposition == SCARD_UNPOWER_CARD) 01091 { 01092 DWORD dwAtrLen; 01093 01094 /* 01095 * Currently pcsc-lite keeps the card always powered 01096 */ 01097 dwAtrLen = sizeof(rContext->readerState->cardAtr); 01098 if (SCARD_RESET_CARD == dwDisposition) 01099 rv = IFDPowerICC(rContext, IFD_RESET, 01100 rContext->readerState->cardAtr, &dwAtrLen); 01101 else 01102 { 01103 IFDPowerICC(rContext, IFD_POWER_DOWN, NULL, NULL); 01104 rv = IFDPowerICC(rContext, IFD_POWER_UP, 01105 rContext->readerState->cardAtr, &dwAtrLen); 01106 } 01107 01108 /* the protocol is unset after a power on */ 01109 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 01110 01111 /* 01112 * Notify the card has been reset 01113 */ 01114 (void)RFSetReaderEventState(rContext, SCARD_RESET); 01115 01116 /* 01117 * Set up the status bit masks on readerState 01118 */ 01119 if (rv == SCARD_S_SUCCESS) 01120 { 01121 rContext->readerState->cardAtrLength = dwAtrLen; 01122 rContext->readerState->readerState = 01123 SCARD_PRESENT | SCARD_POWERED | SCARD_NEGOTIABLE; 01124 01125 Log1(PCSC_LOG_DEBUG, "Reset complete."); 01126 LogXxd(PCSC_LOG_DEBUG, "Card ATR: ", 01127 rContext->readerState->cardAtr, 01128 rContext->readerState->cardAtrLength); 01129 } 01130 else 01131 { 01132 rContext->readerState->cardAtrLength = 0; 01133 Log1(PCSC_LOG_ERROR, "Error resetting card."); 01134 01135 if (rv == SCARD_W_REMOVED_CARD) 01136 rContext->readerState->readerState = SCARD_ABSENT; 01137 else 01138 rContext->readerState->readerState = 01139 SCARD_PRESENT | SCARD_SWALLOWED; 01140 } 01141 } 01142 else if (dwDisposition == SCARD_EJECT_CARD) 01143 { 01144 UCHAR controlBuffer[5]; 01145 UCHAR receiveBuffer[MAX_BUFFER_SIZE]; 01146 DWORD receiveLength; 01147 01148 /* 01149 * Set up the CTBCS command for Eject ICC 01150 */ 01151 controlBuffer[0] = 0x20; 01152 controlBuffer[1] = 0x15; 01153 controlBuffer[2] = (rContext->slot & 0x0000FFFF) + 1; 01154 controlBuffer[3] = 0x00; 01155 controlBuffer[4] = 0x00; 01156 receiveLength = 2; 01157 rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer, 01158 &receiveLength); 01159 01160 if (rv == SCARD_S_SUCCESS) 01161 { 01162 if (receiveLength == 2 && receiveBuffer[0] == 0x90) 01163 { 01164 Log1(PCSC_LOG_DEBUG, "Card ejected successfully."); 01165 /* 01166 * Successful 01167 */ 01168 } 01169 else 01170 Log1(PCSC_LOG_ERROR, "Error ejecting card."); 01171 } 01172 else 01173 Log1(PCSC_LOG_ERROR, "Error ejecting card."); 01174 01175 } 01176 else if (dwDisposition == SCARD_LEAVE_CARD) 01177 { 01178 /* 01179 * Do nothing 01180 */ 01181 } 01182 01183 /* 01184 * Unlock any blocks on this context 01185 */ 01186 (void)RFUnlockSharing(hCard, rContext); 01187 01188 Log2(PCSC_LOG_DEBUG, "Status: 0x%08lX", rv); 01189 01190 return rv; 01191 } 01192 01193 LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames, 01194 LPDWORD pcchReaderLen, LPDWORD pdwState, 01195 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) 01196 { 01197 LONG rv; 01198 READER_CONTEXT * rContext = NULL; 01199 01200 /* These parameters are not used by the client 01201 * Client side code uses readerStates[] instead */ 01202 (void)mszReaderNames; 01203 (void)pcchReaderLen; 01204 (void)pdwState; 01205 (void)pdwProtocol; 01206 (void)pbAtr; 01207 (void)pcbAtrLen; 01208 01209 if (hCard == 0) 01210 return SCARD_E_INVALID_HANDLE; 01211 01212 /* get rContext corresponding to hCard */ 01213 rv = RFReaderInfoById(hCard, &rContext); 01214 if (rv != SCARD_S_SUCCESS) 01215 return rv; 01216 01217 /* 01218 * Make sure no one has a lock on this reader 01219 */ 01220 rv = RFCheckSharing(hCard, rContext); 01221 if (rv != SCARD_S_SUCCESS) 01222 return rv; 01223 01224 if (rContext->readerState->cardAtrLength > MAX_ATR_SIZE) 01225 return SCARD_F_INTERNAL_ERROR; 01226 01227 /* 01228 * This is a client side function however the server maintains the 01229 * list of events between applications so it must be passed through to 01230 * obtain this event if it has occurred 01231 */ 01232 01233 /* 01234 * Make sure some event has not occurred 01235 */ 01236 rv = RFCheckReaderEventState(rContext, hCard); 01237 if (rv != SCARD_S_SUCCESS) 01238 return rv; 01239 01240 /* 01241 * Make sure the reader is working properly 01242 */ 01243 rv = RFCheckReaderStatus(rContext); 01244 if (rv != SCARD_S_SUCCESS) 01245 return rv; 01246 01247 return rv; 01248 } 01249 01250 LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, 01251 LPCVOID pbSendBuffer, DWORD cbSendLength, 01252 LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned) 01253 { 01254 LONG rv; 01255 READER_CONTEXT * rContext = NULL; 01256 01257 /* 0 bytes returned by default */ 01258 *lpBytesReturned = 0; 01259 01260 if (0 == hCard) 01261 return SCARD_E_INVALID_HANDLE; 01262 01263 /* get rContext corresponding to hCard */ 01264 rv = RFReaderInfoById(hCard, &rContext); 01265 if (rv != SCARD_S_SUCCESS) 01266 return rv; 01267 01268 /* 01269 * Make sure no one has a lock on this reader 01270 */ 01271 rv = RFCheckSharing(hCard, rContext); 01272 if (rv != SCARD_S_SUCCESS) 01273 return rv; 01274 01275 if (IFD_HVERSION_2_0 == rContext->version) 01276 if (NULL == pbSendBuffer || 0 == cbSendLength) 01277 return SCARD_E_INVALID_PARAMETER; 01278 01279 /* 01280 * Make sure the reader is working properly 01281 */ 01282 rv = RFCheckReaderStatus(rContext); 01283 if (rv != SCARD_S_SUCCESS) 01284 return rv; 01285 01286 rv = RFFindReaderHandle(hCard); 01287 if (rv != SCARD_S_SUCCESS) 01288 return rv; 01289 01290 if (IFD_HVERSION_2_0 == rContext->version) 01291 { 01292 /* we must wrap a API 3.0 client in an API 2.0 driver */ 01293 *lpBytesReturned = cbRecvLength; 01294 return IFDControl_v2(rContext, (PUCHAR)pbSendBuffer, 01295 cbSendLength, pbRecvBuffer, lpBytesReturned); 01296 } 01297 else 01298 if (IFD_HVERSION_3_0 == rContext->version) 01299 return IFDControl(rContext, dwControlCode, pbSendBuffer, 01300 cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned); 01301 else 01302 return SCARD_E_UNSUPPORTED_FEATURE; 01303 } 01304 01305 LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, 01306 LPBYTE pbAttr, LPDWORD pcbAttrLen) 01307 { 01308 LONG rv; 01309 READER_CONTEXT * rContext = NULL; 01310 01311 if (0 == hCard) 01312 return SCARD_E_INVALID_HANDLE; 01313 01314 /* get rContext corresponding to hCard */ 01315 rv = RFReaderInfoById(hCard, &rContext); 01316 if (rv != SCARD_S_SUCCESS) 01317 return rv; 01318 01319 /* 01320 * Make sure no one has a lock on this reader 01321 */ 01322 rv = RFCheckSharing(hCard, rContext); 01323 if (rv != SCARD_S_SUCCESS) 01324 return rv; 01325 01326 /* 01327 * Make sure the reader is working properly 01328 */ 01329 rv = RFCheckReaderStatus(rContext); 01330 if (rv != SCARD_S_SUCCESS) 01331 return rv; 01332 01333 rv = RFFindReaderHandle(hCard); 01334 if (rv != SCARD_S_SUCCESS) 01335 return rv; 01336 01337 /* 01338 * Make sure some event has not occurred 01339 */ 01340 rv = RFCheckReaderEventState(rContext, hCard); 01341 if (rv != SCARD_S_SUCCESS) 01342 return rv; 01343 01344 rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr); 01345 switch(rv) 01346 { 01347 case IFD_SUCCESS: 01348 rv = SCARD_S_SUCCESS; 01349 break; 01350 case IFD_ERROR_TAG: 01351 /* Special case SCARD_ATTR_DEVICE_FRIENDLY_NAME as it is better 01352 * implemented in pcscd (it knows the friendly name) 01353 */ 01354 if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME) 01355 { 01356 unsigned int len = strlen(rContext->readerState->readerName)+1; 01357 01358 *pcbAttrLen = len; 01359 if (len > *pcbAttrLen) 01360 rv = SCARD_E_INSUFFICIENT_BUFFER; 01361 else 01362 { 01363 (void)strlcpy((char *)pbAttr, 01364 rContext->readerState->readerName, *pcbAttrLen); 01365 rv = SCARD_S_SUCCESS; 01366 } 01367 01368 } 01369 else 01370 rv = SCARD_E_UNSUPPORTED_FEATURE; 01371 break; 01372 case IFD_ERROR_INSUFFICIENT_BUFFER: 01373 rv = SCARD_E_INSUFFICIENT_BUFFER; 01374 break; 01375 default: 01376 rv = SCARD_E_NOT_TRANSACTED; 01377 } 01378 01379 return rv; 01380 } 01381 01382 LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, 01383 LPCBYTE pbAttr, DWORD cbAttrLen) 01384 { 01385 LONG rv; 01386 READER_CONTEXT * rContext = NULL; 01387 01388 if (0 == hCard) 01389 return SCARD_E_INVALID_HANDLE; 01390 01391 /* get rContext corresponding to hCard */ 01392 rv = RFReaderInfoById(hCard, &rContext); 01393 if (rv != SCARD_S_SUCCESS) 01394 return rv; 01395 01396 /* 01397 * Make sure no one has a lock on this reader 01398 */ 01399 rv = RFCheckSharing(hCard, rContext); 01400 if (rv != SCARD_S_SUCCESS) 01401 return rv; 01402 01403 /* 01404 * Make sure the reader is working properly 01405 */ 01406 rv = RFCheckReaderStatus(rContext); 01407 if (rv != SCARD_S_SUCCESS) 01408 return rv; 01409 01410 rv = RFFindReaderHandle(hCard); 01411 if (rv != SCARD_S_SUCCESS) 01412 return rv; 01413 01414 /* 01415 * Make sure some event has not occurred 01416 */ 01417 rv = RFCheckReaderEventState(rContext, hCard); 01418 if (rv != SCARD_S_SUCCESS) 01419 return rv; 01420 01421 rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr); 01422 if (rv == IFD_SUCCESS) 01423 return SCARD_S_SUCCESS; 01424 else 01425 if (rv == IFD_ERROR_TAG) 01426 return SCARD_E_UNSUPPORTED_FEATURE; 01427 else 01428 return SCARD_E_NOT_TRANSACTED; 01429 } 01430 01431 LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, 01432 LPCBYTE pbSendBuffer, DWORD cbSendLength, 01433 SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer, 01434 LPDWORD pcbRecvLength) 01435 { 01436 LONG rv; 01437 READER_CONTEXT * rContext = NULL; 01438 SCARD_IO_HEADER sSendPci, sRecvPci; 01439 DWORD dwRxLength, tempRxLength; 01440 01441 dwRxLength = *pcbRecvLength; 01442 *pcbRecvLength = 0; 01443 01444 if (hCard == 0) 01445 return SCARD_E_INVALID_HANDLE; 01446 01447 /* 01448 * Must at least have 2 status words even for SCardControl 01449 */ 01450 if (dwRxLength < 2) 01451 return SCARD_E_INSUFFICIENT_BUFFER; 01452 01453 /* get rContext corresponding to hCard */ 01454 rv = RFReaderInfoById(hCard, &rContext); 01455 if (rv != SCARD_S_SUCCESS) 01456 return rv; 01457 01458 /* 01459 * Make sure no one has a lock on this reader 01460 */ 01461 rv = RFCheckSharing(hCard, rContext); 01462 if (rv != SCARD_S_SUCCESS) 01463 return rv; 01464 01465 /* 01466 * Make sure the reader is working properly 01467 */ 01468 rv = RFCheckReaderStatus(rContext); 01469 if (rv != SCARD_S_SUCCESS) 01470 return rv; 01471 01472 rv = RFFindReaderHandle(hCard); 01473 if (rv != SCARD_S_SUCCESS) 01474 return rv; 01475 01476 /* 01477 * Make sure some event has not occurred 01478 */ 01479 rv = RFCheckReaderEventState(rContext, hCard); 01480 if (rv != SCARD_S_SUCCESS) 01481 return rv; 01482 01483 /* 01484 * Check for some common errors 01485 */ 01486 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW) 01487 { 01488 if (rContext->readerState->readerState & SCARD_ABSENT) 01489 { 01490 return SCARD_E_NO_SMARTCARD; 01491 } 01492 } 01493 01494 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW) 01495 { 01496 if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD) 01497 { 01498 if (pioSendPci->dwProtocol != rContext->readerState->cardProtocol) 01499 { 01500 return SCARD_E_PROTO_MISMATCH; 01501 } 01502 } 01503 } 01504 01505 /* 01506 * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler 01507 * just wants 0 or 1 01508 */ 01509 01510 sSendPci.Protocol = 0; /* protocol T=0 by default */ 01511 01512 if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1) 01513 { 01514 sSendPci.Protocol = 1; 01515 } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW) 01516 { 01517 /* 01518 * This is temporary ...... 01519 */ 01520 sSendPci.Protocol = SCARD_PROTOCOL_RAW; 01521 } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD) 01522 { 01523 /* Fix by Amira (Athena) */ 01524 unsigned long i; 01525 unsigned long prot = rContext->readerState->cardProtocol; 01526 01527 for (i = 0 ; prot != 1 ; i++) 01528 prot >>= 1; 01529 01530 sSendPci.Protocol = i; 01531 } 01532 01533 sSendPci.Length = pioSendPci->cbPciLength; 01534 01535 sRecvPci.Protocol = pioRecvPci->dwProtocol; 01536 sRecvPci.Length = pioRecvPci->cbPciLength; 01537 01538 /* the protocol number is decoded a few lines above */ 01539 Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%ld", sSendPci.Protocol); 01540 01541 tempRxLength = dwRxLength; 01542 01543 if ((pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW) 01544 && (rContext->version == IFD_HVERSION_2_0)) 01545 { 01546 rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength, 01547 pbRecvBuffer, &dwRxLength); 01548 } else 01549 { 01550 rv = IFDTransmit(rContext, sSendPci, (PUCHAR) pbSendBuffer, 01551 cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci); 01552 } 01553 01554 pioRecvPci->dwProtocol = sRecvPci.Protocol; 01555 pioRecvPci->cbPciLength = sRecvPci.Length; 01556 01557 /* 01558 * Check for any errors that might have occurred 01559 */ 01560 01561 if (rv != SCARD_S_SUCCESS) 01562 { 01563 *pcbRecvLength = 0; 01564 Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv); 01565 return rv; 01566 } 01567 01568 /* 01569 * Available is less than received 01570 */ 01571 if (tempRxLength < dwRxLength) 01572 { 01573 *pcbRecvLength = 0; 01574 return SCARD_E_INSUFFICIENT_BUFFER; 01575 } 01576 01577 /* 01578 * Successful return 01579 */ 01580 *pcbRecvLength = dwRxLength; 01581 return SCARD_S_SUCCESS; 01582 } 01583