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 初始化了rContext的vHandle成员。
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函数,版本1的api是 IO_Create_Channel,
版本2的api是FDHCreateChannel,版本3的api是 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_Channel,IO_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_OPTIONALv1把code,具现化为空,即使不存在这个函数也
不退出。所以可以处理可选函数。如果可选也退出,那么和必选有什么不同。
“那不是我想要的结果,的结果...”
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
接着处理ifdhandler的v3版本