PCSC那事儿(十六--SCardListReaders)
来源:互联网 发布:java 字符串搜索 编辑:程序博客网 时间:2024/05/29 02:54
SCardListReaders
SCardListReaders做了什么?
定义在winscard_clnt.c
实现如下:
3202 LONG SCardListReaders(SCARDCONTEXT hContext, /*@unused@*/ LPCSTR mszGroups,
3203 LPSTR mszReaders, LPDWORD pcchReaders)
3204 {
3205 DWORD dwReadersLen;
3206 int i;
3207 LONG dwContextIndex;
3208 LONG rv = SCARD_S_SUCCESS;
3209 char *buf = NULL;
3210
3211 (void)mszGroups;
3212 PROFILE_START
3213
3214 /*
3215 * Check for NULL parameters
3216 */
3217 if (pcchReaders == NULL)
3218 return SCARD_E_INVALID_PARAMETER;
3219
3220 rv = SCardCheckDaemonAvailability();
3221 if (rv != SCARD_S_SUCCESS)
3222 return rv;
3223
3224 /*
3225 * Make sure this context has been opened
3226 */
3227 dwContextIndex = SCardGetContextIndice(hContext);
3228 if (dwContextIndex == -1)
3229 return SCARD_E_INVALID_HANDLE;
3230
3231 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
3232
3233 /* check the context is still opened */
3234 dwContextIndex = SCardGetContextIndice(hContext);
3235 if (dwContextIndex == -1)
3236 /* the context is now invalid
3237 * -> another thread may have called SCardReleaseContext
3238 * -> so the mMutex has been unlocked */
3239 return SCARD_E_INVALID_HANDLE;
3240
3241 dwReadersLen = 0;
3242 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
3243 if ((readerStates[i])->readerID != 0)
3244 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
3245
3246 /* for the last NULL byte */
3247 dwReadersLen += 1;
3248
3249 if (1 == dwReadersLen)
3250 {
3251 rv = SCARD_E_NO_READERS_AVAILABLE;
3252 goto end;
3253 }
3254
3255 if (SCARD_AUTOALLOCATE == *pcchReaders)
3256 {
3257 buf = malloc(dwReadersLen);
3258 if (NULL == buf)
3259 {
3260 rv = SCARD_E_NO_MEMORY;
3261 goto end;
3262 }
3263 if (NULL == mszReaders)
3264 {
3265 rv = SCARD_E_INVALID_PARAMETER;
3266 goto end;
3267 }
3268 *(char **)mszReaders = buf;
3269 }
3270 else
3271 {
3272 buf = mszReaders;
3273
3274 /* not enough place to store the reader names */
3275 if ((NULL != mszReaders) && (*pcchReaders < dwReadersLen))
3276 {
3277 rv = SCARD_E_INSUFFICIENT_BUFFER;
3278 goto end;
3279 }
3280 }
3281
3282 if (mszReaders == NULL) /* text array not allocated */
3283 goto end;
3284
3285 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
3286 {
3287 if ((readerStates[i])->readerID != 0)
3288 {
3289 /*
3290 * Build the multi-string
3291 */
3292 strcpy(buf, (readerStates[i])->readerName);
3293 buf += strlen((readerStates[i])->readerName)+1;
3294 }
3295 }
3296 *buf = '/0'; /* Add the last null */
3297
3298 end:
3299 /* set the reader names length */
3300 *pcchReaders = dwReadersLen;
3301
3302 (void)SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
3303
3304 PROFILE_END(rv)
3305
3306 return rv;
3307 }
上面又出现了
3227 dwContextIndex = SCardGetContextIndice(hContext);
3228 if (dwContextIndex == -1)
3229 return SCARD_E_INVALID_HANDLE;
3230
3231 (void)SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
3232
3233 /* check the context is still opened */
3234 dwContextIndex = SCardGetContextIndice(hContext);
3235 if (dwContextIndex == -1)
3236 /* the context is now invalid
3237 * -> another thread may have called SCardReleaseContext
3238 * -> so the mMutex has been unlocked */
3239 return SCARD_E_INVALID_HANDLE;
已经解释过了。以后这样的片段不再解释了。
3242 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
3243 if ((readerStates[i])->readerID != 0)
3244 dwReadersLen += strlen((readerStates[i])->readerName) + 1;
这里出现了readerStates这个在哪里初始化过?
依然记得,在前面的SCardEstablishContextTH
411 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
412 {
413 readerStates[i] =
414 (PREADER_STATE)SYS_PublicMemoryMap(sizeof(READER_STATE),
415 mapAddr, (i * pageSize));
416 if (readerStates[i] == NULL)
417 {
418 Log2(PCSC_LOG_CRITICAL, "Cannot public memory map: %s",
419 strerror(errno));
420 (void)SYS_CloseFile(mapAddr); /* Close the memory map file */
421 return SCARD_F_INTERNAL_ERROR;
422 }
423 }
I got it.
这里初始化过了。
通过共享内存,动态获得了系统中读卡器的状态。
看看 READER_STATE的定义,再看一次
typedef struct pubReaderStatesList
{
int32_t readerID;
char readerName[MAX_READERNAME];
uint32_t readerState;
int32_t readerSharing;
UCHAR cardAtr[MAX_ATR_SIZE];
uint32_t cardAtrLength;
uint32_t cardProtocol;
}
READER_STATE, *PREADER_STATE;
这里有 readerName,太好了。
这样的话, SCardListReaders只要收集 READER_STATE数组提供的 readerName,就实现了获取读卡器列表。
3285~3294行,从共享内存中获得了读卡器列表
3285 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
3286 {
3287 if ((readerStates[i])->readerID != 0)
3288 {
3289 /*
3290 * Build the multi-string
3291 */
3292 strcpy(buf, (readerStates[i])->readerName);
3293 buf += strlen((readerStates[i])->readerName)+1;
3294 }
3295 }
3296 *buf = '/0'; /* Add the last null */
特别又列了一次这个片段,是为了说明读卡器列表字符串的格式是:每个读卡器名字都是以'/0'作为间隔,字符串的最后是两个'/0'。和读卡器组列表字符串的格式(已经提过)一样。
而且读卡器列表的内存分配方式也分为是SCardListReaders分配,还是APPLICATION自己分配两种。
回到testpcsc.c 146行
146 if (SCARD_E_NO_READERS_AVAILABLE == rv)
147 {
148 printf("Testing SCardGetStatusChange /n");
149 printf("Please insert a working reader/t: ");
150 (void)fflush(stdout);
151 rgReaderStates[0].szReader = "////?PnP?//Notification";
152 rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;
153
154 rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
155 test_rv(rv, hContext, PANIC);
156 }
如果144行SCardListReaders没有找到任何读卡器,则146判断成立,
提示插入读卡器,
"////?PnP?//Notification"还有SCardGetStatusChange都是做些什么的?
别着急,慢慢说。
- PCSC那事儿(十六--SCardListReaders)
- PCSC那事儿(二十六--SCardReconnect)
- PCSC那事儿(一)
- PCSC那事儿(二)
- PCSC那事儿(三)
- PCSC那事儿(四)
- PCSC那事儿(五)
- PCSC那事儿(六)
- PCSC那事儿(七)
- PCSC那事儿(八--SCardEstablishContext)
- PCSC那事儿(九--SCardEstablishContext)
- PCSC那事儿(十--SCardEstablishContext)
- PCSC那事儿(十一--SCardEstablishContext)
- PCSC那事儿(十二--SCardIsValidContext)
- PCSC那事儿(十三--SCardListReaderGroups)
- PCSC那事儿(十四--SCardReleaseContext)
- PCSC那事儿(十五--SCardFreeMemory)
- PCSC那事儿(十七--SCardGetStatusChange)
- Unicode详解
- PCSC那事儿(十五--SCardFreeMemory)
- 公司看不起女程序员吗?
- 第二章 C#基本概念
- java 字符大小写(中文)转换
- PCSC那事儿(十六--SCardListReaders)
- 100Base-T,100Base-TX等的含义与区别
- 主从表设计和编程的几种实现办法
- PCSC那事儿(十七--SCardGetStatusChange)
- 人生感悟
- WCF 通信
- 移植 u-boot 1.1.6 到 S3C2440 (nand 启动)
- XML 解析c++源码(头文件)
- 职场