464 /* 465 * Allocate memory for reader structures 466 */ 467 (void)RFAllocateReaderSpace(); 468 |
RFAllocateReaderSpace 定义在 readerfactory.c
实现如下:
55 LONG RFAllocateReaderSpace(void) 56 { 57 int i; /* Counter */ 58 59 /* Allocate each reader structure */ 60 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++) 61 { 62 sReadersContexts[i] = malloc(sizeof(READER_CONTEXT)); 63 (sReadersContexts[i])->vHandle = NULL; 64 (sReadersContexts[i])->readerState = NULL; 65 } 66 67 /* Create public event structures */ 68 return EHInitializeEventStructures(); 69 }
|
60~65 行,初始化读卡器上下文 ReadersContexts 。
EHInitializeEventStructures 则是创建共享内存。
44 LONG EHInitializeEventStructures(void) 45 { 46 int fd, i, pageSize; 47 int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 48 49 fd = 0; 50 i = 0; 51 pageSize = 0; 52 53 (void)SYS_RemoveFile(PCSCLITE_PUBSHM_FILE); 54 55 fd = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDWR | O_CREAT, mode); 56 if (fd < 0) 57 { 58 Log3(PCSC_LOG_CRITICAL, "Cannot create public shared file %s: %s", 59 PCSCLITE_PUBSHM_FILE, strerror(errno)); 60 exit(1); 61 } 62 63 /* set correct mode even is umask is too restictive */ 64 (void)SYS_Chmod(PCSCLITE_PUBSHM_FILE, mode); 65 66 pageSize = SYS_GetPageSize(); 67 68 /* 69 * Jump to end of file space and allocate zero's 70 */ 71 (void)SYS_SeekFile(fd, pageSize * PCSCLITE_MAX_READERS_CONTEXTS); 72 (void)SYS_WriteFile(fd, "", 1); 73 74 /* 75 * Allocate each reader structure 76 */ 77 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++) 78 { 79 readerStates[i] = (PREADER_STATE) 80 SYS_MemoryMap(sizeof(READER_STATE), fd, (i * pageSize)); 81 if (readerStates[i] == MAP_FAILED) 82 { 83 Log3(PCSC_LOG_CRITICAL, "Cannot memory map public shared file %s: %s", 84 PCSCLITE_PUBSHM_FILE, strerror(errno)); 85 exit(1); 86 } 87 88 /* 89 * Zero out each value in the struct 90 */ 91 memset((readerStates[i])->readerName, 0, MAX_READERNAME); 92 memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE); 93 (readerStates[i])->readerID = 0; 94 (readerStates[i])->readerState = 0; 95 (readerStates[i])->readerSharing = 0; 96 (readerStates[i])->cardAtrLength = 0; 97 (readerStates[i])->cardProtocol = SCARD_PROTOCOL_UNDEFINED; 98 } 99 100 return SCARD_S_SUCCESS; 101 } |
LONG EHInitializeEventStructures(void)
45~101 行,
创建共享内存文件,映射文件到内存 readerStates 数组,并初始化数组各成员。
回到 pcscdaemon.c
469 /* 470 * Grab the information from the reader.conf 471 */ 472 if (newReaderConfig) 473 { 474 rv = RFStartSerialReaders(newReaderConfig); 475 if (rv != 0) 476 { 477 Log3(PCSC_LOG_CRITICAL, "invalid file %s: %s", newReaderConfig, 478 strerror(errno)); 479 ExitValue = EXIT_FAILURE; 480 at_exit(); 481 } 482 } 483 else 484 { 485 rv = RFStartSerialReaders(PCSCLITE_READER_CONFIG); 486 487 #if 0 488 if (rv == 1) 489 { 490 Log1(PCSC_LOG_INFO, 491 "warning: no " PCSCLITE_READER_CONFIG " found"); 492 /* 493 * Token error in file 494 */ 495 } 496 else 497 #endif 498 if (rv == -1) 499 { 500 ExitValue = EXIT_FAILURE; 501 at_exit(); 502 } 503 } 504 |
如果 main 的命令行参数有指定 serial 或 PCMCIA 类型的读卡器配置文件路径,则读取该配置文件
RFStartSerialReaders 定义在 readerfactory.c
实现如下:
1299 int RFStartSerialReaders(const char *readerconf) 1300 { 1301 SerialReader *reader_list; 1302 int i, rv; 1303 1304 /* remember the configuration filename for RFReCheckReaderConf() */ 1305 ConfigFile = strdup(readerconf); 1306 1307 rv = DBGetReaderList(readerconf, &reader_list); 1308 1309 /* the list is empty */ 1310 if (NULL == reader_list) 1311 return rv; 1312 1313 for (i=0; reader_list[i].pcFriendlyname; i++) 1314 { 1315 int j; 1316 1317 (void)RFAddReader(reader_list[i].pcFriendlyname, 1318 reader_list[i].dwChannelId, 1319 reader_list[i].pcLibpath, reader_list[i].pcDevicename); 1320 1321 /* update the ConfigFileCRC (this false "CRC" is very weak) */ 1322 for (j=0; j<reader_list[i].pcFriendlyname[j]; j++) 1323 ConfigFileCRC += reader_list[i].pcFriendlyname[j]; 1324 for (j=0; j<reader_list[i].pcLibpath[j]; j++) 1325 ConfigFileCRC += reader_list[i].pcLibpath[j]; 1326 for (j=0; j<reader_list[i].pcDevicename[j]; j++) 1327 ConfigFileCRC += reader_list[i].pcDevicename[j]; 1328 1329 /* free strings allocated by DBGetReaderList() */ 1330 free(reader_list[i].pcFriendlyname); 1331 free(reader_list[i].pcLibpath); 1332 free(reader_list[i].pcDevicename); 1333 } 1334 free(reader_list); 1335 1336 return rv; 1337 } |
1307 行, DBGetReaderList 定义在 configfile.c
实现如下:
1932 int DBGetReaderList(const char *readerconf, SerialReader **caller_reader_list) 1933 { 1934 FILE *configFile = NULL; 1935 1936 *caller_reader_list = NULL; /* no list by default */ 1937 1938 configFile = fopen(readerconf, "r"); 1939 1940 if (configFile == NULL) 1941 return 1; 1942 1943 yyin = configFile; 1944 1945 /* (re)start with a clean state */ 1946 iLinenumber = 1; 1947 iOldLinenumber = -1; 1948 reader_list = NULL; 1949 reader_list_size = 0; 1950 pcFriendlyname = NULL; 1951 pcDevicename = NULL; 1952 pcLibpath = NULL; 1953 pcChannelid = NULL; 1954 pcPrevious = NULL; 1955 pcCurrent = NULL; 1956 badError = 0; 1957 1958 do 1959 { 1960 (void)yylex(); 1961 } 1962 while (!feof(configFile)); 1963 1964 (void)fclose(configFile); 1965 1966 *caller_reader_list = reader_list; 1967 1968 if (badError == 1) 1969 return -1; 1970 else 1971 return 0; 1972 } /* End of configfile.c */ |
1932~1972 行,解析 reader.conf 文件,构造 reader_list.
解析过程采用 flex. flex 又是另外的故事,请参考相关书籍。不是服务端重点,不做深入解说。
实际上只要记住 caller_reader_list
根据配置文件 reader.conf 解析出读卡器列表。
1313~1320 行,遍历读卡器列表,
RFAddReader 定义在 readerfacotry.c
实现如下:
71 LONG RFAddReader(LPSTR lpcReader, DWORD dwPort, LPSTR lpcLibrary, LPSTR lpcDevice) 72 { 73 DWORD dwContext = 0, dwGetSize; 74 UCHAR ucGetData[1], ucThread[1]; 75 LONG rv, parentNode; 76 int i, j; 77 78 if ((lpcReader == NULL) || (lpcLibrary == NULL) || (lpcDevice == NULL)) 79 return SCARD_E_INVALID_VALUE; 80 81 /* Reader name too long? also count " 00 00"*/ 82 if (strlen(lpcReader) > MAX_READERNAME - sizeof(" 00 00")) 83 { 84 Log3(PCSC_LOG_ERROR, "Reader name too long: %d chars instead of max %d", 85 strlen(lpcReader), MAX_READERNAME - sizeof(" 00 00")); 86 return SCARD_E_INVALID_VALUE; 87 } 88 89 /* Library name too long? */ 90 if (strlen(lpcLibrary) >= MAX_LIBNAME) 91 { 92 Log3(PCSC_LOG_ERROR, "Library name too long: %d chars instead of max %d", 93 strlen(lpcLibrary), MAX_LIBNAME); 94 printf("%s/n %d/n",lpcLibrary,MAX_LIBNAME); 95 return SCARD_E_INVALID_VALUE; 96 } 97 98 /* Device name too long? */ 99 if (strlen(lpcDevice) >= MAX_DEVICENAME) 100 { 101 Log3(PCSC_LOG_ERROR, "Device name too long: %d chars instead of max %d", 102 strlen(lpcDevice), MAX_DEVICENAME); 103 return SCARD_E_INVALID_VALUE; 104 } 105 |
72~105 行,在函数入口处进行检查。分别对读卡器,库文件名字,设备名。
参数 dwPort(DWORD, 前面提过了,也就是 unsigned long, 具体的类型长度,根据体系结构而定 ) 分两种情况,一种是表示串行读卡器的编号 COM1 等,另一种用于 usb 读卡器,
实际是一种上下文编号 (hotplug_libusb.c) ,这种情况下,这个编号的高 16 位 (31~16bit) 是 PCSCLITE_HP_BASE_PORT
106 /* Same name, same port - duplicate reader cannot be used */ 107 if (dwNumReadersContexts != 0) 108 { 109 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++) 110 { 111 if ((sReadersContexts[i])->vHandle != 0) 112 { 113 char lpcStripReader[MAX_READERNAME]; 114 int tmplen; 115 116 /* get the reader name without the reader and slot numbers */ 117 strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader, 118 sizeof(lpcStripReader)); 119 tmplen = strlen(lpcStripReader); 120 lpcStripReader[tmplen - 6] = 0; |
111 行, vhandle ,从后面的分析可以知道,这个表示所打开动态库的句柄。
如果 vhandle==0, 则表示对应的读卡器上下文未被使用。
如果被使用,则比较要加入的读卡器的读卡器名字和上下文中已经存在的读卡器名字。