PCSC那事儿(三十三--PCSCD)

 

 859         else if (rContext->dwVersion == IFD_HVERSION_3_0)

 860         {

 861                 /* The following binds version 3.0 of the IFD Handler specs */

 862 #define GET_ADDRESS_OPTIONALv3(s, code) /

 863 { /

 864         void *f1 = NULL; /

 865         if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s)) /

 866         { /

 867                 code /

 868         } /

 869         rContext->psFunctions.psFunctions_v3.pvf ## s = f1; /

 870 }

 871

 872 #define GET_ADDRESSv3(s) /

 873         GET_ADDRESS_OPTIONALv3(s, /

 874                 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); /

 875                 exit(1); )

862行,定义了一个宏,目的是加载动态库中的s函数,执行code代码,并初始化

reader上下文中的psFunctions.psFunctions_v3.pvf##s.

872行,定义了另一个宏,是上面一个宏的wrapper,仅仅具现化了code.

有了这两个helper宏,则对于v3版本的ifdhandler的动态库函数加载很是方便。

 876

 877                 Log1(PCSC_LOG_INFO, "Loading IFD Handler 3.0");

 878

 879                 GET_ADDRESSv2(CreateChannel)

 880                 GET_ADDRESSv2(CloseChannel)

 881                 GET_ADDRESSv2(GetCapabilities)

 882                 GET_ADDRESSv2(SetCapabilities)

 883                 GET_ADDRESSv2(PowerICC)

 884                 GET_ADDRESSv2(TransmitToICC)

 885                 GET_ADDRESSv2(ICCPresence)

 886                 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )

 887

 888                 GET_ADDRESSv3(CreateChannelByName)

 889                 GET_ADDRESSv3(Control)

 890         }

876890行,使用了上面的两个宏,进一步初始化了psFunctions.psFunctions_v3各字段。

必选的函数对应的各字段,

psFunctions.psFunctions_v3.pvfCreateChannel

psFunctions.psFunctions_v3.pvfCloseChannel

psFunctions.psFunctions_v3.pvfGetCapabilities

psFunctions.psFunctions_v3.pvfSetCapabilities

psFunctions.psFunctions_v3.pvfPowerICC

psFunctions.psFunctions_v3.pvfTransmitToICC

psFunctions.psFunctions_v3.pvfICCPresence

psFunctions.psFunctions_v3.pvfControl

psFunctions.psFunctions_v3.pvfCreateChannelByName

可选的函数对应的各字段,

psFunctions.psFunctions_v3.pvfSetProtocolParameters

好了,接下来是v4版本,有吗?现在还没有v4版本。

 891         else

 892         {

 893                 /* Who knows what could have happenned for it to get here. */

 894                 Log1(PCSC_LOG_CRITICAL, "IFD Handler not 1.0/2.0 or 3.0");

 895                 exit(1);

 896         }

 897

 898         return SCARD_S_SUCCESS;

 899 }

891~899行,正如注释所说,因为前面已经进行了版本的判断,如果不是3个版本之一,

则直接退出。所以这里的else显的有些多余。

或许,也不算多余。可以表达现实。版本1,2,3代表权,钱,势。else进一步强调了,如果

没有拥有3者之一,那么命运将是坎坷的。被安排到最后一个else给人家垫背,最后还exit.

几千年的历史,基本都在重复这样的故事。

也请先行记住,有些高版本存在的函数,在低版本中并不存在。

 

好了。继续看IFDOpenIFD

定义在ifdwrapper.c

实现如下:

112 LONG IFDOpenIFD(PREADER_CONTEXT rContext)

113 {

114         RESPONSECODE rv = 0;

115

116 #ifndef PCSCLITE_STATIC_DRIVER

117         RESPONSECODE(*IO_create_channel) (DWORD) = NULL;

118         RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;

119         RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;

120

121         if (rContext->dwVersion == IFD_HVERSION_1_0)

122                 IO_create_channel =

123                         rContext->psFunctions.psFunctions_v1.pvfCreateChannel;

124         else

125                 if (rContext->dwVersion == IFD_HVERSION_2_0)

126                         IFDH_create_channel =

127                                 rContext->psFunctions.psFunctions_v2.pvfCreateChannel;

128                 else

129                 {

130                         IFDH_create_channel =

131                                 rContext->psFunctions.psFunctions_v3.pvfCreateChannel;

132                         IFDH_create_channel_by_name =

133                                 rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;

134                 }

135 #endif

136

137         /* LOCK THIS CODE REGION */

138         (void)SYS_MutexLock(rContext->mMutex);

139

140 #ifndef PCSCLITE_STATIC_DRIVER

141         if (rContext->dwVersion == IFD_HVERSION_1_0)

142         {

143                 rv = (*IO_create_channel) (rContext->dwPort);

144         } else if (rContext->dwVersion == IFD_HVERSION_2_0)

145         {

146                 rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);

147         } else

148         {

149                 /* use device name only if defined */

150                 if (rContext->lpcDevice[0] != '/0')

151                         rv = (*IFDH_create_channel_by_name) (rContext->dwSlot, rContext->lpcDevice);

152                 else

153                         rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);

154         }

155 #else

156         if (rContext->dwVersion == IFD_HVERSION_1_0)

157         {

158                 rv = IO_Create_Channel(rContext->dwPort);

159         } else if (rContext->dwVersion == IFD_HVERSION_2_0)

160         {

161                 rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);

162         } else

163         {

164                 /* Use device name only if defined */

165                 if (rContext->lpcDevice[0] != '/0')

166                         rv = IFDHCreateChannelByName(rContext->dwSlot, rContext->lpcDevice);

167                 else

168                         rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);

169         }

170 #endif

171

172         /* END OF LOCKED REGION */

173         (void)SYS_MutexUnLock(rContext->mMutex);

174

175         return rv;

176 }

 

原来这个函数的目的是调用3个版本之一的create channel.

 30 #undef PCSCLITE_STATIC_DRIVER

所以说155~170没有真正编译。

117~119定义了函数指针。

120135行,根据版本,正确初始化函数指针。

136~154行,调用函数指针所在的函数。

RFInitializeReader解说完成。

回到readerfatory.c

 229         rv = RFInitializeReader(sReadersContexts[dwContext]);

 230         if (rv != SCARD_S_SUCCESS)

 231         {

 232                 /* Cannot connect to reader. Exit gracefully */

 233                 Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);

 234                 (void)RFRemoveReader(lpcReader, dwPort);

 235                 return rv;

 236         }

 

234行,RFRemoveReader.想想,它做什么,难道是从reader上下文数组中踢出不要的元素。

RFRemoveReader定义在readerfactory.c.少不了一个遍历。

实现如下:

 402 LONG RFRemoveReader(LPSTR lpcReader, DWORD dwPort)

 403 {

 404         LONG rv;

 405         PREADER_CONTEXT sContext;

 406

 407         if (lpcReader == 0)

 408                 return SCARD_E_INVALID_VALUE;

 409

 410         while (SCARD_S_SUCCESS ==

 411                 RFReaderInfoNamePort(dwPort, lpcReader, &sContext))

 412         {

 413                 int i;

 414

 415                 /* Try to destroy the thread */

 416                 rv = EHDestroyEventHandler(sContext);

 417

 418                 rv = RFUnInitializeReader(sContext);

 419                 if (rv != SCARD_S_SUCCESS)

 420                         return rv;

 421

411行, RFReaderInfoNamePort根据dwPortlpcReaderreader上下文数组中去寻找对应的元素。无论是否共用一个驱动,从RFAddReader前部,可以知道无法加入名字和端口都一样的reader.

 

 

RFReaderInfoNamePort定义在readerfactory.c

实现如下:

 687 LONG RFReaderInfoNamePort(DWORD dwPort, LPSTR lpcReader,

 688         PREADER_CONTEXT * sReader)

 689 {

 690         char lpcStripReader[MAX_READERNAME];

 691         int i;

 692

 693         for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)

 694         {

 695                 if ((sReadersContexts[i])->vHandle != 0)

 696                 {

 697                         int tmplen;

 698

 699                         strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,

 700                                 sizeof(lpcStripReader));

 701                         tmplen = strlen(lpcStripReader);

 702                         lpcStripReader[tmplen - 6] = 0;

 703

 704                         if ((strcmp(lpcReader, lpcStripReader) == 0) &&

 705                                 (dwPort == (sReadersContexts[i])->dwPort))

 706                         {

 707                                 *sReader = sReadersContexts[i];

 708                                 return SCARD_S_SUCCESS;

 709                         }

 710                 }

 711         }

 712

693712行,根据读卡器名字(不包括读卡器编号和槽号)和端口号,搜索读卡器上下文。

 

回到RFRemoveReader

416行,

EHDestroyEventHandler定义在eventhandler.c

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值