回到RFAddReader
237 238 /* asynchronous card movement? */ 239 { 240 RESPONSECODE (*fct)(DWORD) = NULL; 241 242 dwGetSize = sizeof(fct); 243 244 rv = IFDGetCapabilities((sReadersContexts[dwContext]), 245 TAG_IFD_POLLING_THREAD, &dwGetSize, (PUCHAR)&fct); 246 if ((rv != SCARD_S_SUCCESS) || (dwGetSize != sizeof(fct))) 247 { 248 fct = NULL; 249 Log1(PCSC_LOG_INFO, "Using the pcscd polling thread"); 250 } 251 else 252 Log1(PCSC_LOG_INFO, "Using the reader polling thread"); 253 |
244行,查询驱动是否提供fct回调函数地址。接下去启动线程,如果存在,线程运行的上下文中会包含这个fct.
254 rv = EHSpawnEventHandler(sReadersContexts[dwContext], fct); 255 if (rv != SCARD_S_SUCCESS) 256 { 257 Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader); 258 (void)RFRemoveReader(lpcReader, dwPort); 259 return rv; 260 } 261 } |
254行, EHSpawnEventHandler开始启动线程,不断查询读卡器状态了。
EHSpawnEventHandler在eventhandler.c中定义
实现如下:
168 LONG EHSpawnEventHandler(PREADER_CONTEXT rContext, 169 RESPONSECODE (*card_event)(DWORD)) 170 { 171 LONG rv; 172 DWORD dwStatus = 0; 173 int i; 174 UCHAR ucAtr[MAX_ATR_SIZE]; 175 DWORD dwAtrLen = 0; 176 177 rv = IFDStatusICC(rContext, &dwStatus, ucAtr, &dwAtrLen); 178 if (rv != SCARD_S_SUCCESS) 179 { 180 Log2(PCSC_LOG_ERROR, "Initial Check Failed on %s", rContext->lpcReader); 181 return SCARD_F_UNKNOWN_ERROR; 182 } 183 |
177行, IFDStatusICC在ifdwrapper.c实现,
定义如下:
412 LONG IFDStatusICC(PREADER_CONTEXT rContext, PDWORD pdwStatus, 413 PUCHAR pucAtr, PDWORD pdwAtrLen) 414 { 415 RESPONSECODE rv = IFD_SUCCESS; 416 DWORD dwTag = 0, dwCardStatus = 0; 417 SMARTCARD_EXTENSION sSmartCard; 418 UCHAR ucValue[1] = "/x00"; 419 420 #ifndef PCSCLITE_STATIC_DRIVER 421 RESPONSECODE(*IFD_is_icc_present) (void) = NULL; 422 RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL; 423 RESPONSECODE(*IFD_get_capabilities) (DWORD, /*@out@*/ PUCHAR) = NULL; 424 425 if (rContext->dwVersion == IFD_HVERSION_1_0) 426 { 427 IFD_is_icc_present = 428 rContext->psFunctions.psFunctions_v1.pvfICCPresence; 429 IFD_get_capabilities = 430 rContext->psFunctions.psFunctions_v1.pvfGetCapabilities; 431 } 432 else 433 IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence; 434 #endif |
首先,从前面RFBindFunctions初始化好的函数指针变量中获取对应的函数地址。
接着进行调用
435 436 /* LOCK THIS CODE REGION */ 437 (void)SYS_MutexLock(rContext->mMutex); 438 439 #ifndef PCSCLITE_STATIC_DRIVER 440 if (rContext->dwVersion == IFD_HVERSION_1_0) 441 { 442 ucValue[0] = rContext->dwSlot; 443 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue); 444 rv = (*IFD_is_icc_present) (); 445 } 446 else 447 rv = (*IFDH_icc_presence) (rContext->dwSlot); 448 #else 449 if (rContext->dwVersion == IFD_HVERSION_1_0) 450 { 451 ucValue[0] = rContext->dwSlot; 452 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue); 453 rv = IFD_Is_ICC_Present(); 454 } 455 else 456 rv = IFDHICCPresence(rContext->dwSlot); 457 #endif 458 459 /* END OF LOCKED REGION */ 460 (void)SYS_MutexUnLock(rContext->mMutex); |
440~447行,根据版本,调用相应的函数。查询对应读卡器中的卡是否存在。
448~457行,不会被编译。
461 462 if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT) 463 dwCardStatus |= SCARD_PRESENT; 464 else 465 if (rv == IFD_ICC_NOT_PRESENT) 466 dwCardStatus |= SCARD_ABSENT; 467 else 468 { 469 Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv); 470 *pdwStatus = SCARD_UNKNOWN; 471 472 if (rv == IFD_NO_SUCH_DEVICE) 473 { 474 (void)SendHotplugSignal(); 475 return SCARD_E_READER_UNAVAILABLE; 476 } 477 478 return SCARD_E_NOT_TRANSACTED; 479 } |
463行,466行,如果查询结果表示卡存在则标志是 SCARD_PRESENT,
否则是 SCARD_ABSENT
474行, 再查询失败,而且返回 IFD_NO_SUCH_DEVICE的时候,有 SendHotplugSignal
上面分析过了,最主要还是关照了serial版本的读卡器。SendHotplugSignal,里有 HPReCheckSerialReaders(重新检测系统里的serial版本的读卡器,对于这个函数,后面会具体再说)。某个serial读卡器,可能被拔走了。
480 481 /* 482 * Now lets get the ATR and process it if IFD Handler version 1.0. 483 * IFD Handler version 2.0 does this immediately after reset/power up 484 * to conserve resources 485 */ 486 487 if (rContext->dwVersion == IFD_HVERSION_1_0) 488 { 489 if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT) 490 { 491 short ret; 492 493 dwTag = TAG_IFD_ATR; 494 495 /* LOCK THIS CODE REGION */ 496 (void)SYS_MutexLock(rContext->mMutex); 497 498 ucValue[0] = rContext->dwSlot; 499 (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue); 500 501 #ifndef PCSCLITE_STATIC_DRIVER 502 rv = (*IFD_get_capabilities) (dwTag, pucAtr); 503 #else 504 rv = IFD_Get_Capabilities(dwTag, pucAtr); 505 #endif 506 507 /* END OF LOCKED REGION */ 508 (void)SYS_MutexUnLock(rContext->mMutex); 509 510 /* 511 * FIX :: This is a temporary way to return the correct size 512 * of the ATR since most of the drivers return MAX_ATR_SIZE 513 */ 514 515 ret = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE); 516 517 /* 518 * Might be a memory card without an ATR 519 */ 520 if (ret == 0) 521 *pdwAtrLen = 0; 522 else 523 *pdwAtrLen = sSmartCard.ATR.Length; 524 } 525 else 526 { 527 /* 528 * No card is inserted - Atr length is 0 529 */ 530 *pdwAtrLen = 0; 531 } 532 /* 533 * End of FIX 534 */ 535 } 536 537 *pdwStatus = dwCardStatus; 538 539 return SCARD_S_SUCCESS; 540 } |
正如482~485的注释所说的,要特别对待ifdhandler v1版本。
对于v1版本,在此处获取atr.
499行,设置读卡器的当前槽,502行,获取对应的atr.