PCSC那事儿(二十--SCardTransmit)

 

SCardTransmit

245 SCardTransmit 定义在 winscard_clnt.c

实现如下:

2915 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,

2916         LPCBYTE pbSendBuffer, DWORD cbSendLength,

2917         LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,

 

2918         LPDWORD pcbRecvLength)

2919 {

 

 

 

问:为什么从代码解说开始,每个函数 API 都不说明参数和用法?

答案是, 这些 API 都是符合 PCSC 规范的。第一章的各卷部分都对应做了说明了。所以不再重复。或者也可以看看源代码的这些函数实现的注释部分,这些参数都有注释说明。注释格式符合 Doxygen 要求。

如果这里重复说明,也就是重复昨天的故事,很罗曼蒂克。一可以增加篇幅,二可以增加工作量,三可以倍显所谓的耐心和专业精神。但此时此地,还是不要。

2920         LONG rv;

2921         int i;

2922         DWORD dwContextIndex, dwChannelIndex;

2923

2924         PROFILE_START

2925

2926         if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||

2927                         pcbRecvLength == NULL || pioSendPci == NULL)

2928                 return SCARD_E_INVALID_PARAMETER;

2929

 

 

 

2920~2929 常规检查。

 

问:上面提到了很多 API 了,实现的前部都有检查。能不能不检查?

答案是,在 c 的世界里,不检查意味着崩溃。意味着用彻夜的调试来消耗生命。不过

目前看,生命没有房价值钱,是吧?在 metaprogram 中可以实现这个想法。如果不接受

检查,那么赶快投入 metaprogram 的怀抱,把运行期的错误转移到编译期。

把一个人的温暖转移到另一个人的胸膛

 

2934         /*

2935          * Make sure this handle has been opened

2936          */

2937         rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);

2938         if (rv == -1)

2939         {

2940                 *pcbRecvLength = 0;

2941                 return SCARD_E_INVALID_HANDLE;

2942         }

2943

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

2945

2946         /* check the handle is still valid */

 

2947         rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);

2948         if (rv == -1)

2949                 /* the handle is now invalid

2950                   * -> another thread may have called SCardReleaseContext

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

2952                 return SCARD_E_INVALID_HANDLE;

2953

 

 

 

 

2934~2953 行,前面讲过了?似乎?是讲解过类似的片段,讲了 n 次。

但这个片段不太一样。

找出以前的片段对比对比。有对比才有发现,有攀比才有仇富,有发现才会警醒。

1872 LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,

1873          LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)

 

...

1918         dwContextIndex = SCardGetContextIndice(hContext);

1919         if (dwContextIndex == -1)

1920                 return SCARD_E_INVALID_HANDLE;

1921

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

1923

1924         /* check the context is still opened */

1925         dwContextIndex = SCardGetContextIndice(hContext);

1926         if (dwContextIndex == -1)

1927                 /* the context is now invalid

1928                  * -> another thread may have called SCardReleaseContext

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

1930                   return SCARD_E_INVALID_HANDLE;

 

 

 

重要差别在

一个是

2937         rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);

 

另一个是

 

 

1925         dwContextIndex = SCardGetContextIndice(hContext);

 

 

 

SCardGetContextIndice 上面讲解过了,从 APPLICATION 大佬的 psContextMap 数组

那里获得索引号。

SCardGetIndicesFromHandle 做什么呢?

 

3740 static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard,

3741         PDWORD pdwContextIndice, PDWORD pdwChannelIndice)

3742 {

3743         LONG rv;

3744

3745         if (0 == hCard)

3746                  return -1;

3747

3748         (void)SCardLockThread();

3749         rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);

3750         (void)SCardUnlockThread();

3751

3752         return rv;

3753 }

 

 

 

SCardGetIndicesFromHandle SCardGetIndicesFromHandleTH 加锁并做 wrapper.

还是看看 SCardGetIndicesFromHandleTH.

3755 static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard,

3756         PDWORD pdwContextIndice, PDWORD pdwChannelIndice)

3757 {

3758         int i;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值