PCSC那事儿(十九--SCardConnect)

 

SCardConnect

214 行, SCardConnect 定义在 winscard_clnt.c

实现如下:

  734 LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,

  735         DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,

  736         LPDWORD pdwActiveProtocol)

 

  737 {

  738         LONG rv;

  739         connect_struct scConnectStruct;

  740         sharedSegmentMsg msgStruct;

  741         LONG dwContextIndex;

  742

  743         PROFILE_START

  744

  745         /*

  746          * Check for NULL parameters

  747          */

  748         if (phCard == NULL || pdwActiveProtocol == NULL)

  749                 return SCARD_E_INVALID_PARAMETER;

  750         else

  751                 *phCard = 0;

  752

  753          if (szReader == NULL)

  754                 return SCARD_E_UNKNOWN_READER;

  755

  756         /*

  757          * Check for uninitialized strings

  758          */

  759         if (strlen(szReader) > MAX_READERNAME)

  760                 return SCARD_E_INVALID_VALUE;

  761

  762         rv = SCardCheckDaemonAvailability();

  763         if (rv != SCARD_S_SUCCESS)

  764                 return rv;

  765

  766         /*

  767          * Make sure this context has been opened

  768          */

  769         dwContextIndex = SCardGetContextIndice(hContext);

  770         if (dwContextIndex == -1)

  771                 return SCARD_E_INVALID_HANDLE;

  772

  773         (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);

  774

  775         /* check the context is still opened */

  776         dwContextIndex = SCardGetContextIndice(hContext);

  777         if (dwContextIndex == -1)

  778                 /* the context is now invalid

  779                  * -> another thread may have called SCardReleaseContext

 

 

  780                   * -> so the mMutex has been unlocked */

  781                 return SCARD_E_INVALID_HANDLE;

  782

  783         strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);

  784

  785         scConnectStruct.hContext = hContext;

  786         scConnectStruct.dwShareMode = dwShareMode;

  787         scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;

  788         scConnectStruct.hCard = 0;

  789         scConnectStruct.dwActiveProtocol = 0;

  790         scConnectStruct.rv = SCARD_S_SUCCESS;

  791

  792         rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,

  793                 sizeof(scConnectStruct),

  794                 PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);

  795

  796         if (rv == -1)

  797          {

  798                 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);

  799                 return SCARD_E_NO_SERVICE;

  800         }

  801

  802         /*

  803          * Read a message from the server

  804          */

  805         rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID,

  806                 PCSCLITE_CLIENT_ATTEMPTS);

  807

  808         memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));

  809

  810         if (rv == -1)

  811         {

  812                  (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);

  813                 return SCARD_F_COMM_ERROR;

  814         }

  815

  816         *phCard = scConnectStruct.hCard;

  817         *pdwActiveProtocol = scConnectStruct.dwActiveProtocol;

  818

  819         if (scConnectStruct.rv == SCARD_S_SUCCESS)

  820         {

 

  821                 /*

  822                  * Keep track of the handle locally

  823                  */

  824                 rv = SCardAddHandle(*phCard, dwContextIndex, szReader);

  825                 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);

  826

  827                 PROFILE_END(rv)

  828

  829                 return rv;

  830         }

  831

  832         (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);

  833

  834         PROFILE_END(scConnectStruct.rv)

  835

  836         return scConnectStruct.rv;

  837 }

 

 

 

SCardConnect 与参数 szReader 指定的读卡器进行通讯。

737~760 行,进行常规检查。

761~781 行,解释过 n 次了。

782~790 行,构造 connect_struct 结构体,初始化成员,准备和 pcscd 通讯,进行连接。

 

791~814 行,向 pcscd 发请求,收取回应。

问: SCardConnect 到底要从 pcscd 获取什么?

答案是,获取 SCARDHANDLE, 获取可用的通讯协议。

 

816         *phCard = scConnectStruct.hCard;

817         *pdwActiveProtocol = scConnectStruct.dwActiveProtocol;

 

 

 

可以看出, SCardConnect 的用心。

  818

  819         if (scConnectStruct.rv == SCARD_S_SUCCESS)

  820         {

  821                 /*

  822                  * Keep track of the handle locally

  823                  */

  824                 rv = SCardAddHandle(*phCard, dwContextIndex, szReader);

  825                 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);

 

  826

  827                 PROFILE_END(rv)

  828

  829                 return rv;

  830         }

 

 

 

SCardAddHandle 定义在 winscard_clnt.c

实现如下:

3705 static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,

3706         LPCSTR readerName)

3707 {

3708         int i;

3709

3710         for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)

3711         {

3712                 if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)

3713                 {

3714                         psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;

3715                         psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);

3716                         return SCARD_S_SUCCESS;

3717                 }

3718         }

3719

3720         return SCARD_E_NO_MEMORY;

3721 }

 

 

很早很早以前,就说过了, psContextMap 中有两个重要的句柄,它们都是 long 类型。

psContextMap 管。毫无疑问, SCardAddHandle 把得来的 hCard 注册入 psContextMap

. 应用上下文, APPLICATION 大爷。 SCardAddHandle 把得来的 hCard 进贡给这个大佬。

上面提过了,实际上,分析服务端代码,就可以知道 hContext 是一个随机索引,用于获取

客户端的应用上下文和服务端的应用上下文,而 hCard 用于获取客户端和服务端维护的一个 channel 也就是在一个应用上下文中的一个连接 ( 一个应用上下文可以有多个连接 )

 

SCardConnect 结束。

 

218

219         switch(dwPref)

220         {

221                 case SCARD_PROTOCOL_T0:

222                         pioSendPci = *SCARD_PCI_T0;

 

223                         break;

224                 case SCARD_PROTOCOL_T1:

225                         pioSendPci = *SCARD_PCI_T1;

226                         break;

227                 case SCARD_PROTOCOL_RAW:

228                         pioSendPci = *SCARD_PCI_RAW;

229                         break;

230                  default:

231                         printf("Unknown protocol/n");

232                         return -1;

233          }

 

 

 

218~233 行说明对 根据 SCardConnect 返回的协议类型对 pioSendPci 赋值。

234

235         /* APDU select file */

236         printf("Select file:");

237         send_length = 7;

238         memcpy(bSendBuffer, "/x00/xA4/x00/x00/x02/x3F/x00", send_length);

239         for (i=0; i<send_length; i++)

240                 printf(" %02X", bSendBuffer[i]);

241         printf("/n");

242          length = sizeof(bRecvBuffer);

 

 

 

234~242 做什么?

选择文件,而且是选择 MF(SMART CARD 的主文件 ). bSendBuffer 中填充选择 MF 命令字符串。

 

243

244         printf("Testing SCardTransmit/t/t: ");

245         rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,

246                  &pioRecvPci, bRecvBuffer, &length);

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值