StatSynchronize做了两件事情,同步共享内存,往pipe写入'/0'.
319行, StatSynchronize的入口参数rContext->readerState,在执行StatSynchronize之前已经做了足够的初始化。现在通过同步共享内存,并通过pipe告知客户端,状态readerState发生了变化。使得客户端根据共享内存获得最新的状态。
321 while (1) 322 { 323 dwStatus = 0; 324 325 dwAtrLen = rContext->readerState->cardAtrLength; 326 rv = IFDStatusICC(rContext, &dwStatus, 327 rContext->readerState->cardAtr, 328 &dwAtrLen); 329 rContext->readerState->cardAtrLength = dwAtrLen; 330 331 if (rv != SCARD_S_SUCCESS) 332 { 333 Log2(PCSC_LOG_ERROR, "Error communicating to: %s", lpcReader); 334 335 /* 336 * Set error status on this reader while errors occur 337 */ 338 rContext->readerState->readerState &= ~SCARD_ABSENT; 339 rContext->readerState->readerState &= ~SCARD_PRESENT; 340 rContext->readerState->readerState &= ~SCARD_POWERED; 341 rContext->readerState->readerState &= ~SCARD_NEGOTIABLE; 342 rContext->readerState->readerState &= ~SCARD_SPECIFIC; 343 rContext->readerState->readerState &= ~SCARD_SWALLOWED; 344 rContext->readerState->readerState |= SCARD_UNKNOWN; 345 rContext->readerState->cardAtrLength = 0; 346 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 347 348 dwCurrentState = SCARD_UNKNOWN; 349 350 (void)StatSynchronize(rContext->readerState); 351 } |
321行,一个while大循环。重点当然在 IFDStatusICC,不过在进入while之前,已经有
有一个 IFDStatusICC.之前的这个 IFDStatusICC明显不可靠。因为
283 else |
处理了 SCARD_PRESENT之外的所有状态。
并统一宣称
299 dwStatus |= SCARD_ABSENT; |
并刷新了一次共享内存,还通知了APPLICATION.
而实际上IFDStatusICC有可能返回设备不存在的情况。不过整体来说,紧接着的while
很快就报告了真实的情况。
283行,仅仅不妥,并非是bug.
332~351行,说明读卡器已经通讯不上,或者被拔出等等,在
344行,设置了重要的标志SCARD_UNKNOWN.并在
350行,进行了 StatSynchronize,通知了所有的APPLICATIONs.
352 353 if (dwStatus & SCARD_ABSENT) 354 { 355 if (dwCurrentState == SCARD_PRESENT || 356 dwCurrentState == SCARD_UNKNOWN) 357 { 358 /* 359 * Change the status structure 360 */ 361 Log2(PCSC_LOG_INFO, "Card Removed From %s", lpcReader); 362 /* 363 * Notify the card has been removed 364 */ 365 (void)RFSetReaderEventState(rContext, SCARD_REMOVED); 366 367 rContext->readerState->cardAtrLength = 0; 368 rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 369 rContext->readerState->readerState |= SCARD_ABSENT; 370 rContext->readerState->readerState &= ~SCARD_UNKNOWN; 371 rContext->readerState->readerState &= ~SCARD_PRESENT; 372 rContext->readerState->readerState &= ~SCARD_POWERED; 373 rContext->readerState->readerState &= ~SCARD_NEGOTIABLE; 374 rContext->readerState->readerState &= ~SCARD_SWALLOWED; 375 rContext->readerState->readerState &= ~SCARD_SPECIFIC; 376 dwCurrentState = SCARD_ABSENT; 377 378 incrementEventCounter(rContext->readerState); 379 380 (void)StatSynchronize(rContext->readerState); 381 } 382 383 } |
352~383行,卡被拔出,或卡本来就不存在的情况。
365行, RFSetReaderEventState
定义在readerfactory.c
实现如下:
1191 LONG RFSetReaderEventState(PREADER_CONTEXT rContext, DWORD dwEvent) 1192 { 1193 int i; 1194 1195 /* Set all the handles for that reader to the event */ 1196 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++) 1197 { 1198 if (rContext->psHandles[i].hCard != 0) 1199 rContext->psHandles[i].dwEventStatus = dwEvent; 1200 } 1201 1202 if (SCARD_REMOVED == dwEvent) 1203 { 1204 /* unlock the card */ 1205 rContext->dwLockId = 0; 1206 rContext->LockCount = 0; 1207 } 1208 1209 return SCARD_S_SUCCESS; 1210 } |
重点在1198行, rContext->psHandles[i].hCard这个代表读卡器对应通道的一个连接句柄。
也对应APPLICATION.
不得不提rContext的结构了
定义在readerfactory.h
105 struct ReaderContext 106 { 107 char lpcReader[MAX_READERNAME]; /**< Reader Name */ 108 char lpcLibrary[MAX_LIBNAME]; /**< Library Path */ 109 char lpcDevice[MAX_DEVICENAME]; /**< Device Name */ 110 PCSCLITE_THREAD_T pthThread; /**< Event polling thread */ 111 RESPONSECODE (*pthCardEvent)(DWORD); /**< Card Event sync */ 112 PCSCLITE_MUTEX_T mMutex; /**< Mutex for this connection */ 113 RDR_CLIHANDLES psHandles[PCSCLITE_MAX_READER_CONTEXT_CHANNELS]; 114 /**< Structure of connected handles */ 115 union 116 { 117 FCT_MAP_V1 psFunctions_v1; /**< API V1.0 */ 118 FCT_MAP_V2 psFunctions_v2; /**< API V2.0 */ 119 FCT_MAP_V3 psFunctions_v3; /**< API V3.0 */ 120 } psFunctions; /**< driver functions */ 121 122 LPVOID vHandle; /**< Dlopen handle */ 123 DWORD dwVersion; /**< IFD Handler version number */ 124 DWORD dwPort; /**< Port ID */ 125 DWORD dwSlot; /**< Current Reader Slot */ 126 DWORD dwBlockStatus; /**< Current blocking status */ 127 DWORD dwLockId; /**< Lock Id */ 128 DWORD dwIdentity; /**< Shared ID High Nibble */ 129 int LockCount; /**< number of recursive locks */ 130 int32_t dwContexts; /**< Number of open contexts */ 131 PDWORD pdwFeeds; /**< Number of shared client to lib */ 132 PDWORD pdwMutex; /**< Number of client to mutex */ 133 134 struct pubReaderStatesList *readerState; /**< link to the reader state */ 135 /* we can't use PREADER_STATE here since eventhandler.h can't be 136 * included because of circular dependencies */ 137 }; |
注意113行, 出现RDR_CLIHANDLES
97 struct RdrCliHandles 98 { 99 SCARDHANDLE hCard; /**< hCard for this connection */ 100 DWORD dwEventStatus; /**< Recent event that must be sent */ 101 }; 102 103 typedef struct RdrCliHandles RDR_CLIHANDLES, *PRDR_CLIHANDLES; |
看到了吧。99行hCard的类型是 SCARDHANDLE.这个在谈APPLICATION的时候,常常出现,而且多次说明过了。代表一个连接,与卡通讯的连接。
好,回到1199行。
rContext代表读卡器(实际上,对应一个特定的读卡器的一个特定的槽), rContext->psHandles[i].hCard代表和卡的一个连接。当然,你可以和卡建立n个连接。
连接数n不能超过 PCSCLITE_MAX_READER_CONTEXT_CHANNELS.