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