PCSC那事儿(十四--SCardReleaseContext)

 

SCardReleaseContext

看看 SCardReleaseContext 发生了什么。

  576 LONG SCardReleaseContext(SCARDCONTEXT hContext)

  577 {

  578         LONG rv;

  579         release_struct scReleaseStruct;

  580         sharedSegmentMsg msgStruct;

  581         LONG dwContextIndex;

  582

  583         PROFILE_START

  584

  585         /*

  586          * Make sure this context has been opened

  587          * and get dwContextIndex

  588          */

  589         dwContextIndex = SCardGetContextIndice(hContext);

  590         if (dwContextIndex == -1)

  591                 return SCARD_E_INVALID_HANDLE;

  592

  593         rv = SCardCheckDaemonAvailability();

 

  594         if (rv != SCARD_S_SUCCESS)

  595         {

  596                 /*

  597                  * Remove the local context from the stack

  598                  */

  599                 (void)SCardLockThread();

  600                 (void)SCardRemoveContext(hContext);

  601                 (void)SCardUnlockThread();

  602

  603                  return rv;

  604         }

  605

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

  607

  608         /* check the context is still opened */

  609         dwContextIndex = SCardGetContextIndice(hContext);

  610         if (dwContextIndex == -1)

  611                 /* the context is now invalid

  612                  * -> another thread may have called SCardReleaseContext

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

  614                 return SCARD_E_INVALID_HANDLE;

  615

  616         scReleaseStruct.hContext = hContext;

  617         scReleaseStruct.rv = SCARD_S_SUCCESS;

  618

  619         rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT,

  620                 psContextMap[dwContextIndex].dwClientID,

  621                 sizeof(scReleaseStruct),

  622                 PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);

  623

  624         if (rv == -1)

  625         {

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

  627                 return SCARD_E_NO_SERVICE;

  628         }

  629

  630         /*

  631          * Read a message from the server

  632          */

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

  634                 PCSCLITE_CLIENT_ATTEMPTS);

  635         memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));

  636

 

  637         if (rv == -1)

  638         {

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

  640                 return SCARD_F_COMM_ERROR;

  641         }

  642

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

  644

  645         /*

  646          * Remove the local context from the stack

  647          */

  648         (void)SCardLockThread();

  649         (void)SCardRemoveContext(hContext);

  650         (void)SCardUnlockThread();

  651

  652         PROFILE_END(scReleaseStruct.rv)

  653

  654         return scReleaseStruct.rv;

  655 }

 

 

589~593 行,前面都提了 n 次。

  599                 (void)SCardLockThread();

  600                 (void)SCardRemoveContext(hContext);

  601                 (void)SCardUnlockThread();

 

 

 

SCardRemoveContext

600 行,做了些什么, SCardRemoveContext

定义在 winscard_clnt.c

实现如下:

3665 static LONG SCardRemoveContext(SCARDCONTEXT hContext)

3666 {

3667         LONG  retIndice;

3668

3669         retIndice = SCardGetContextIndiceTH(hContext);

3670

3671         if (retIndice == -1)

3672                 return SCARD_E_INVALID_HANDLE;

3673         else

3674                 return SCardCleanContext(retIndice);

3675 }

 

 

 

SCardGetContextIndiceTH 做了些什么?

上面提过了。那么看 SCardCleanContext 了。

SCardCleanContext 定义在 winscard_clnt.c

实现如下:

3677 static LONG SCardCleanContext(LONG indice)

3678 {

3679         int i;

3680

3681         psContextMap[indice].hContext = 0;

3682         (void)SHMClientCloseSession(psContextMap[indice].dwClientID);

3683         psContextMap[indice].dwClientID = 0;

3684         free(psContextMap[indice].mMutex);

3685         psContextMap[indice].mMutex = NULL;

3686         psContextMap[indice].contextBlockStatus = BLOCK_STATUS_RESUME;

3687

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

3689         {

3690                 /*

3691                  * Reset the /c hCard structs to zero

3692                  */

3693                 psContextMap[indice].psChannelMap[i].hCard = 0;

3694                 free(psContextMap[indice].psChannelMap[i].readerName);

3695                 psContextMap[indice].psChannelMap[i].readerName = NULL;

3696         }

3697

3698         return SCARD_S_SUCCESS;

3699 }

 

 

一层又一层, 所以说 SCardRemoveContext 实际是清除上下文数组和

这个函数的参数 hContext 相关的结构内容,上面说了, SCardEstablishContext

是注册,那么这个就是注销了。对于不再使用的上下文,被 SCardRemoveContext

剔除。没有利用价值就被剔除,有价值就被利用。很容易理解的。

 

关注下  psContextMap[indice].hContext = 0;

 

              psContextMap[indice].dwClientID = 0;

 

曾经在 SCardEstablishContext 中获取的,都失去了。

刘德华唱到 短短一生太多的变化 ... 终于失去她 ...”

醒醒,回到 606 行,能活到这行的,说明了 pcscd 还活着。

 

606~643 行, pcscd 还活着,当然 hContext 被剔除之前,就要告诉 pcscd ,让它收回原来分配来的对应的那份 hContext 上下文。很自然,不是吗?虽然这种做法,有些罗嗦。客户端和服务端在维护为了同一个目的的两个 stuff, 不是吗?

怎么通讯?

构造 release_struct ,然后通过前面提到的 WrapSHMWrite 发送这个数据包, SHMClientRead 接收响应包。

 

SCardReleaseContext 结束了。

 

 

回到 SCardListReaderGroups

3429         if (SCARD_AUTOALLOCATE == *pcchGroups)

 

 

说明如果对应 *pcchGroups 的参数传入 SCARD_AUTOALLOCATE ,则要求在这个

函数内部给读卡器组列表分配内存。

 

接着只需要返回 "SCard$DefaultReaders/0" 就可以了。

3405         const char ReaderGroup[] = "SCard$DefaultReaders/0";

 

 

这个说明了, pcsc-lite 版本 (1.5.5) 仅仅支持默认组。

 

回头,回头,回到 testpcsc.c

 

109 #ifdef USE_AUTOALLOCATE

110         dwGroups = SCARD_AUTOALLOCATE;

111         rv = SCardListReaderGroups(hContext, (LPSTR)&mszGroups, &dwGroups);

112 #else

113         rv = SCardListReaderGroups(hContext, NULL, &dwGroups);

114         test_rv(rv, hContext, PANIC);

115

116         printf("Testing SCardListReaderGroups/t: ");

117         mszGroups = calloc(dwGroups, sizeof(char));

118         rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups);

119 # endif

 

 

尝试了 SCardListReaderGroups 的两种调用方式,一种是 SCardListReaderGroups 内部自动分配内存,一种是 APPLICATION 自己分配内存。

133 #ifdef USE_AUTOALLOCATE

134         printf("Testing SCardFreeMemory/t/t: ");

135         rv = SCardFreeMemory(hContext, mszGroups);

136         test_rv(rv, hContext, PANIC);

137 #else

138         free(mszGroups);

139 #endif

 

 

说明了,如果是 SCardListReaderGroups 分配了内存,那么你必须调用 SCardFreeMemory 来释放这些内存。如果是 APPLICATION 调用了内存,则需要 free.

看看这个做了些什么?

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值