PCSC那事儿(三十五--PCSCD)

来源:互联网 发布:淘宝口碑好的包包店铺 编辑:程序博客网 时间:2024/05/16 18:41

回到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开始启动线程,不断查询读卡器状态了。

EHSpawnEventHandlereventhandler.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行, IFDStatusICCifdwrapper.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.

515行,对获取的atr进行解码,ATRDecodeAtr 又是一个故事,以后再说。

原创粉丝点击