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

RFLoadReader定义在readerfactory.c

实现如下:

 736 LONG RFLoadReader(PREADER_CONTEXT rContext)

 737 {

 738         if (rContext->vHandle != 0)

 739         {

 740                 Log2(PCSC_LOG_INFO, "Reusing already loaded driver for %s",

 741                         rContext->lpcLibrary);

 742                 /* Another reader exists with this library loaded */

 743                 return SCARD_S_SUCCESS;

 744         }

 745

 746         return DYN_LoadLibrary(&rContext->vHandle, rContext->lpcLibrary);

 747 }

 

很清楚的,

736~747行,通过调用DYN_LoadLibrary 初始化了rContextvHandle成员。

vHandle代表所打开的动态库的句柄。

 749 LONG RFBindFunctions(PREADER_CONTEXT rContext)

 750 {

 751         int rv1, rv2, rv3;

 752         void *f;

 753

 754         /*

 755          * Use this function as a dummy to determine the IFD Handler version

 756          * type  1.0/2.0/3.0.  Suppress error messaging since it can't be 1.0,

 757          * 2.0 and 3.0.

 758          */

 759

 760         DebugLogSuppress(DEBUGLOG_IGNORE_ENTRIES);

 761

 762         rv1 = DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");

 763         rv2 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannel");

 764         rv3 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannelByName");

 765

 766         DebugLogSuppress(DEBUGLOG_LOG_ENTRIES);

 767

 768         if (rv1 != SCARD_S_SUCCESS && rv2 != SCARD_S_SUCCESS && rv3 != SCARD_S_SUCCESS)

 769         {

 770                 /* Neither version of the IFD Handler was found - exit */

 771                 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");

 772

 773                 exit(1);

 774         } else if (rv1 == SCARD_S_SUCCESS)

 775         {

 776                 /* Ifd Handler 1.0 found */

 777                 rContext->dwVersion = IFD_HVERSION_1_0;

 778         } else if (rv3 == SCARD_S_SUCCESS)

 779         {

 780                 /* Ifd Handler 3.0 found */

 781                 rContext->dwVersion = IFD_HVERSION_3_0;

 782         }

 783         else

 784         {

 785                 /* Ifd Handler 2.0 found */

 786                 rContext->dwVersion = IFD_HVERSION_2_0;

 787         }

762~764行,先进行摸底。摸摸驱动库到底是什么版本的。因为ifdhandler已经有3个版本,

而且对于每一个版本API都不一样。难道这就是独创性。

比如对于CreateChannel函数,版本1api IO_Create_Channel

版本2apiFDHCreateChannel,版本3api IFDHCreateChannelByName.

所以,这里先探测那个版本的可用。并根据实际探测情况,初始化传入参数也就是

reader上下文的dwVersion字段。如果3个版本都没有探测到,则直接退出。坚决如铁。

接下来做什么,当然是根据版本号做相应的动态库函数加载处理。

 788

 789         /* The following binds version 1.0 of the IFD Handler specs */

 790         if (rContext->dwVersion == IFD_HVERSION_1_0)

 791         {

 792                 Log1(PCSC_LOG_INFO, "Loading IFD Handler 1.0");

 793

 794 #define GET_ADDRESS_OPTIONALv1(field, function, code) /

 795 { /

 796         void *f1 = NULL; /

 797         if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFD_" #function)) /

 798         { /

 799                 code /

 800         } /

 801         rContext->psFunctions.psFunctions_v1.pvf ## field = f1; /

 802 }

 803

 804 #define GET_ADDRESSv1(field, function) /

 805         GET_ADDRESS_OPTIONALv1(field, function, /

 806                 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #function ); /

 807                 exit(1); )

 

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

reader上下文中的psFunctions.psFunctions_v1.pvf##field.

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

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

 808

 809                 (void)DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");

 810                 rContext->psFunctions.psFunctions_v1.pvfCreateChannel = f;

 811

 812                 if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f,

 813                         "IO_Close_Channel"))

 814                 {

 815                         Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");

 816                         exit(1);

 817                 }

 818                 rContext->psFunctions.psFunctions_v1.pvfCloseChannel = f;

 819

 820                 GET_ADDRESSv1(GetCapabilities, Get_Capabilities)

 821                 GET_ADDRESSv1(SetCapabilities, Set_Capabilities)

 822                 GET_ADDRESSv1(PowerICC, Power_ICC)

 823                 GET_ADDRESSv1(TransmitToICC, Transmit_to_ICC)

 824                 GET_ADDRESSv1(ICCPresence, Is_ICC_Present)

 825

 826                 GET_ADDRESS_OPTIONALv1(SetProtocolParameters, Set_Protocol_Parameters, )

 827         }

809~810行,没办法,创建通道的函数没有以IFD_开头,所以用不了刚才定义的宏,只能单独处理。 只有IO_Create_ChannelIO_Close_Channel 特殊处理。

初始化 psFunctions.psFunctions_v1.pvfCreateChannel psFunctions.psFunctions_v1.pvfCloseChannel

 

剩下的必选ifdhandler函数采用宏GET_ADDRESSv1处理。

可选的ifdhandler函数采用 GET_ADDRESS_OPTIONALv1处理。

这两个宏之间的差别就在于GET_ADDRESSv1会处理宏参数code,而具现化的code

中包含exit调用。这样,如果不存在这个必选函数,则整个程序退出。

这里初始化了reader上下文中的如下各字段

psFunctions.psFunctions_v1.pvfGetCapabilities

psFunctions.psFunctions_v1.pvfSetCapabilities

psFunctions.psFunctions_v1.pvfPowerICC

psFunctions.psFunctions_v1.pvfTransmitToICC

psFunctions.psFunctions_v1.pvfICCPresence

psFunctions.psFunctions_v1.pvfSetProtocolParameters

 

 

此处调用的GET_ADDRESS_OPTIONALv1code,具现化为空,即使不存在这个函数也

不退出。所以可以处理可选函数。如果可选也退出,那么和必选有什么不同。

那不是我想要的结果,的结果...”

 826                 GET_ADDRESS_OPTIONALv1(SetProtocolParameters, Set_Protocol_Parameters, ) //这里有个,

 

接下来就是v2版本的处理了。

思路是一样的。

 

 828         else if (rContext->dwVersion == IFD_HVERSION_2_0)

 829         {

 830                 /* The following binds version 2.0 of the IFD Handler specs */

 831 #define GET_ADDRESS_OPTIONALv2(s, code) /

 832 { /

 833         void *f1 = NULL; /

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

 835         { /

 836                 code /

 837         } /

 838         rContext->psFunctions.psFunctions_v2.pvf ## s = f1; /

 839 }

 840

 841 #define GET_ADDRESSv2(s) /

 842         GET_ADDRESS_OPTIONALv2(s, /

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

 844                 exit(1); )

 845

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

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

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

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

 845

 846                 Log1(PCSC_LOG_INFO, "Loading IFD Handler 2.0");

 847

 848                 GET_ADDRESSv2(CreateChannel)

 849                 GET_ADDRESSv2(CloseChannel)

 850                 GET_ADDRESSv2(GetCapabilities)

 851                 GET_ADDRESSv2(SetCapabilities)

 852                 GET_ADDRESSv2(PowerICC)

 853                 GET_ADDRESSv2(TransmitToICC)

 854                 GET_ADDRESSv2(ICCPresence)

 855                 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )

 856

 857                 GET_ADDRESSv2(Control)

 858         }

845~858行,使用了上面的两个宏,进一步初始化了psFunctions.psFunctions_v2各字段。

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

psFunctions.psFunctions_v2.pvfCreateChannel

psFunctions.psFunctions_v2.pvfCloseChannel

psFunctions.psFunctions_v2.pvfGetCapabilities

psFunctions.psFunctions_v2.pvfSetCapabilities

psFunctions.psFunctions_v2.pvfPowerICC

psFunctions.psFunctions_v2.pvfTransmitToICC

psFunctions.psFunctions_v2.pvfICCPresence

psFunctions.psFunctions_v2.pvfControl

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

psFunctions.psFunctions_v2.pvfSetProtocolParameters

 

接着处理ifdhandlerv3版本

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值