SCardDisconnect
SCardDisconnect 定义在 winscard_clnt.c
实现如下:
1030 LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) 1031 { 1032 LONG rv; 1033 disconnect_struct scDisconnectStruct; 1034 sharedSegmentMsg msgStruct; 1035 DWORD dwContextIndex, dwChannelIndex; 1036 1037 PROFILE_START 1038 1039 rv = SCardCheckDaemonAvailability(); 1040 if (rv != SCARD_S_SUCCESS) 1041 return rv; 1042 1043 /* 1044 * Make sure this handle has been opened 1045 */ 1046 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex); 1047 if (rv == -1) 1048 return SCARD_E_INVALID_HANDLE; 1049 1050 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex); 1051
1052 /* check the handle is still valid */ 1053 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex); 1054 if (rv == -1) 1055 /* the handle is now invalid 1056 * -> another thread may have called SCardReleaseContext 1057 * -> so the mMutex has been unlocked */ 1058 return SCARD_E_INVALID_HANDLE; 1030~1058 行, ...
1059 1060 scDisconnectStruct.hCard = hCard; 1061 scDisconnectStruct.dwDisposition = dwDisposition; 1062 scDisconnectStruct.rv = SCARD_S_SUCCESS; 1063 1064 rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID, 1065 sizeof(scDisconnectStruct), 1066 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct); 1067 1068 if (rv == -1) 1069 { 1070 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex); 1071 return SCARD_E_NO_SERVICE; 1072 } 1073 1074 /* 1075 * Read a message from the server 1076 */ 1077 rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, 1078 PCSCLITE_CLIENT_ATTEMPTS); 1079 1080 memcpy(&scDisconnectStruct, &msgStruct.data, 1081 sizeof(scDisconnectStruct)); 1082 1083 if (rv == -1) 1084 { 1085 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex); 1086 return SCARD_F_COMM_ERROR; 1087 } |
1059~1081 行,这个 ... 通过分析了 SCardStatus , SCardGetSetAttrib , SCardTransmit 和 SCardControl 之后,仅仅从客户端这边,应该能够理解了。还是那个招式。
几乎一致的算法,处理不一样的数据结构。
发送采用 disconnect_struct 结构,接收采用 sharedSegmentMsg 结构, data 域内嵌 disconnect_struct 结构。
1088 1089 (void) SCardRemoveHandle (hCard); 1090 1091 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex); 1092 1093 PROFILE_END(scDisconnectStruct.rv) 1094 1095 return scDisconnectStruct.rv; 1096 } |
SCardRemoveHandle 在 winscard_clnt.c 定义
实现如下:
3723 static LONG SCardRemoveHandle(SCARDHANDLE hCard) 3724 { 3725 DWORD dwContextIndice, dwChannelIndice; 3726 LONG rv; 3727 3728 rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice); 3729 if (rv == -1) 3730 return SCARD_E_INVALID_HANDLE; 3731 else 3732 { 3733 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0; 3734 free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName); 3735 psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL; 3736 return SCARD_S_SUCCESS; 3737 } 3738 } |
3723~3738 行,既然前面与服务端通讯了,告诉服务端,要断开连接。接着当然是处理
本地和这个连接 Channel 有关的上下文结构了。回收对应的 psContextMap[dwContextIndice].psChannelMap 就可以了。
SCardDisconnect 解说结束。
接着回到 testpcsc.c
391 (void)SCardReleaseContext(hContext); |
SCardReleaseContext ,提过了。
继续 ...
393 394 printf("Press enter: "); 395 (void)getchar(); 396 printf("Testing SCardReconnect/t/t: "); 397 rv = SCardReconnect(hCard, SCARD_SHARE_SHARED, 398 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref); 399 test_rv(rv, hContext, PANIC); |