00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00017 #include "config.h"
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <errno.h>
00025 #include <fcntl.h>
00026
00027 #include "misc.h"
00028 #include "pcscd.h"
00029 #include "ifdhandler.h"
00030 #include "debuglog.h"
00031 #include "thread_generic.h"
00032 #include "readerfactory.h"
00033 #include "dyn_generic.h"
00034 #include "sys_generic.h"
00035 #include "eventhandler.h"
00036 #include "ifdwrapper.h"
00037 #include "hotplug.h"
00038 #include "strlcpycat.h"
00039 #include "configfile.h"
00040
00041 #ifndef TRUE
00042 #define TRUE 1
00043 #define FALSE 0
00044 #endif
00045
00046 static PREADER_CONTEXT sReadersContexts[PCSCLITE_MAX_READERS_CONTEXTS];
00047 static DWORD dwNumReadersContexts = 0;
00048 static char *ConfigFile = NULL;
00049 static int ConfigFileCRC = 0;
00050
00051 #define IDENTITY_SHIFT 16
00052
00053 LONG RFAllocateReaderSpace(void)
00054 {
00055 int i;
00056
00057
00058
00059
00060 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00061 {
00062 sReadersContexts[i] = malloc(sizeof(READER_CONTEXT));
00063 (sReadersContexts[i])->vHandle = NULL;
00064 (sReadersContexts[i])->readerState = NULL;
00065 }
00066
00067
00068
00069
00070 return EHInitializeEventStructures();
00071 }
00072
00073 LONG RFAddReader(LPSTR lpcReader, DWORD dwPort, LPSTR lpcLibrary, LPSTR lpcDevice)
00074 {
00075 DWORD dwContext = 0, dwGetSize;
00076 UCHAR ucGetData[1], ucThread[1];
00077 LONG rv, parentNode;
00078 int i, j;
00079
00080 if ((lpcReader == NULL) || (lpcLibrary == NULL) || (lpcDevice == NULL))
00081 return SCARD_E_INVALID_VALUE;
00082
00083
00084 if (strlen(lpcReader) > MAX_READERNAME - sizeof(" 00 00"))
00085 {
00086 Log3(PCSC_LOG_ERROR, "Reader name too long: %d chars instead of max %d",
00087 strlen(lpcReader), MAX_READERNAME - sizeof(" 00 00"));
00088 return SCARD_E_INVALID_VALUE;
00089 }
00090
00091
00092 if (strlen(lpcLibrary) >= MAX_LIBNAME)
00093 {
00094 Log3(PCSC_LOG_ERROR, "Library name too long: %d chars instead of max %d",
00095 strlen(lpcLibrary), MAX_LIBNAME);
00096 return SCARD_E_INVALID_VALUE;
00097 }
00098
00099
00100 if (strlen(lpcDevice) >= MAX_DEVICENAME)
00101 {
00102 Log3(PCSC_LOG_ERROR, "Device name too long: %d chars instead of max %d",
00103 strlen(lpcDevice), MAX_DEVICENAME);
00104 return SCARD_E_INVALID_VALUE;
00105 }
00106
00107
00108
00109
00110 if (dwNumReadersContexts != 0)
00111 {
00112 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00113 {
00114 if ((sReadersContexts[i])->vHandle != 0)
00115 {
00116 char lpcStripReader[MAX_READERNAME];
00117 int tmplen;
00118
00119
00120 strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
00121 sizeof(lpcStripReader));
00122 tmplen = strlen(lpcStripReader);
00123 lpcStripReader[tmplen - 6] = 0;
00124
00125 if ((strcmp(lpcReader, lpcStripReader) == 0) &&
00126 (dwPort == (sReadersContexts[i])->dwPort))
00127 {
00128 Log1(PCSC_LOG_ERROR, "Duplicate reader found.");
00129 return SCARD_E_DUPLICATE_READER;
00130 }
00131 }
00132 }
00133 }
00134
00135
00136
00137
00138 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00139 {
00140 if ((sReadersContexts[i])->vHandle == 0)
00141 {
00142 dwContext = i;
00143 break;
00144 }
00145 }
00146
00147 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00148 {
00149
00150
00151
00152 return SCARD_E_NO_MEMORY;
00153 }
00154
00155
00156
00157
00158 parentNode = RFSetReaderName(sReadersContexts[dwContext], lpcReader,
00159 lpcLibrary, dwPort, 0);
00160 if (parentNode < -1)
00161 return SCARD_E_NO_MEMORY;
00162
00163 strlcpy((sReadersContexts[dwContext])->lpcLibrary, lpcLibrary,
00164 sizeof((sReadersContexts[dwContext])->lpcLibrary));
00165 strlcpy((sReadersContexts[dwContext])->lpcDevice, lpcDevice,
00166 sizeof((sReadersContexts[dwContext])->lpcDevice));
00167 (sReadersContexts[dwContext])->dwVersion = 0;
00168 (sReadersContexts[dwContext])->dwPort = dwPort;
00169 (sReadersContexts[dwContext])->mMutex = NULL;
00170 (sReadersContexts[dwContext])->dwBlockStatus = 0;
00171 (sReadersContexts[dwContext])->dwContexts = 0;
00172 (sReadersContexts[dwContext])->pthThread = 0;
00173 (sReadersContexts[dwContext])->dwLockId = 0;
00174 (sReadersContexts[dwContext])->LockCount = 0;
00175 (sReadersContexts[dwContext])->vHandle = NULL;
00176 (sReadersContexts[dwContext])->pdwFeeds = NULL;
00177 (sReadersContexts[dwContext])->pdwMutex = NULL;
00178 (sReadersContexts[dwContext])->dwIdentity =
00179 (dwContext + 1) << IDENTITY_SHIFT;
00180 (sReadersContexts[dwContext])->readerState = NULL;
00181
00182 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
00183 (sReadersContexts[dwContext])->psHandles[i].hCard = 0;
00184
00185
00186
00187
00188 if (parentNode >= 0 && parentNode < PCSCLITE_MAX_READERS_CONTEXTS)
00189 {
00190 (sReadersContexts[dwContext])->pdwFeeds =
00191 (sReadersContexts[parentNode])->pdwFeeds;
00192 *(sReadersContexts[dwContext])->pdwFeeds += 1;
00193 (sReadersContexts[dwContext])->vHandle =
00194 (sReadersContexts[parentNode])->vHandle;
00195 (sReadersContexts[dwContext])->mMutex =
00196 (sReadersContexts[parentNode])->mMutex;
00197 (sReadersContexts[dwContext])->pdwMutex =
00198 (sReadersContexts[parentNode])->pdwMutex;
00199
00200
00201
00202
00203 dwGetSize = sizeof(ucThread);
00204 rv = IFDGetCapabilities((sReadersContexts[parentNode]),
00205 TAG_IFD_THREAD_SAFE, &dwGetSize, ucThread);
00206
00207 if (rv == IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
00208 {
00209 Log1(PCSC_LOG_INFO, "Driver is thread safe");
00210 (sReadersContexts[dwContext])->mMutex = NULL;
00211 (sReadersContexts[dwContext])->pdwMutex = NULL;
00212 }
00213 else
00214 *(sReadersContexts[dwContext])->pdwMutex += 1;
00215 }
00216
00217 if ((sReadersContexts[dwContext])->pdwFeeds == NULL)
00218 {
00219 (sReadersContexts[dwContext])->pdwFeeds = malloc(sizeof(DWORD));
00220
00221
00222
00223
00224
00225
00226 *(sReadersContexts[dwContext])->pdwFeeds = 1;
00227 }
00228
00229 if ((sReadersContexts[dwContext])->mMutex == 0)
00230 {
00231 (sReadersContexts[dwContext])->mMutex =
00232 malloc(sizeof(PCSCLITE_MUTEX));
00233 SYS_MutexInit((sReadersContexts[dwContext])->mMutex);
00234 }
00235
00236 if ((sReadersContexts[dwContext])->pdwMutex == NULL)
00237 {
00238 (sReadersContexts[dwContext])->pdwMutex = malloc(sizeof(DWORD));
00239
00240 *(sReadersContexts[dwContext])->pdwMutex = 1;
00241 }
00242
00243 dwNumReadersContexts += 1;
00244
00245 rv = RFInitializeReader(sReadersContexts[dwContext]);
00246 if (rv != SCARD_S_SUCCESS)
00247 {
00248
00249 Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);
00250 RFRemoveReader(lpcReader, dwPort);
00251 return rv;
00252 }
00253
00254
00255
00256
00257 {
00258 RESPONSECODE (*fct)(DWORD) = NULL;
00259
00260 dwGetSize = sizeof(fct);
00261
00262 rv = IFDGetCapabilities((sReadersContexts[dwContext]),
00263 TAG_IFD_POLLING_THREAD, &dwGetSize, (PUCHAR)&fct);
00264 if ((rv != SCARD_S_SUCCESS) || (dwGetSize != sizeof(fct)))
00265 {
00266 fct = NULL;
00267 Log1(PCSC_LOG_INFO, "Using the pcscd polling thread");
00268 }
00269 else
00270 Log1(PCSC_LOG_INFO, "Using the reader polling thread");
00271
00272 rv = EHSpawnEventHandler(sReadersContexts[dwContext], fct);
00273 if (rv != SCARD_S_SUCCESS)
00274 {
00275 Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);
00276 RFRemoveReader(lpcReader, dwPort);
00277 return rv;
00278 }
00279 }
00280
00281
00282
00283
00284
00285 dwGetSize = sizeof(ucGetData);
00286 rv = IFDGetCapabilities((sReadersContexts[dwContext]),
00287 TAG_IFD_SLOTS_NUMBER, &dwGetSize, ucGetData);
00288
00289 if (rv != IFD_SUCCESS || dwGetSize != 1 || ucGetData[0] == 0)
00290
00291
00292
00293
00294 return SCARD_S_SUCCESS;
00295
00296 if (rv == IFD_SUCCESS && dwGetSize == 1 && ucGetData[0] == 1)
00297
00298
00299
00300 return SCARD_S_SUCCESS;
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 for (j = 1; j < ucGetData[0]; j++)
00312 {
00313 char *tmpReader = NULL;
00314 DWORD dwContextB = 0;
00315 RESPONSECODE (*fct)(DWORD) = NULL;
00316
00317
00318
00319
00320
00321 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00322 {
00323 if ((sReadersContexts[i])->vHandle == 0)
00324 {
00325 dwContextB = i;
00326 break;
00327 }
00328 }
00329
00330 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00331 {
00332
00333
00334
00335 rv = RFRemoveReader(lpcReader, dwPort);
00336 return SCARD_E_NO_MEMORY;
00337 }
00338
00339
00340
00341
00342 tmpReader = sReadersContexts[dwContextB]->lpcReader;
00343 strlcpy(tmpReader, sReadersContexts[dwContext]->lpcReader,
00344 sizeof(sReadersContexts[dwContextB]->lpcReader));
00345 sprintf(tmpReader + strlen(tmpReader) - 2, "%02X", j);
00346
00347 strlcpy((sReadersContexts[dwContextB])->lpcLibrary, lpcLibrary,
00348 sizeof((sReadersContexts[dwContextB])->lpcLibrary));
00349 strlcpy((sReadersContexts[dwContextB])->lpcDevice, lpcDevice,
00350 sizeof((sReadersContexts[dwContextB])->lpcDevice));
00351 (sReadersContexts[dwContextB])->dwVersion =
00352 (sReadersContexts[dwContext])->dwVersion;
00353 (sReadersContexts[dwContextB])->dwPort =
00354 (sReadersContexts[dwContext])->dwPort;
00355 (sReadersContexts[dwContextB])->vHandle =
00356 (sReadersContexts[dwContext])->vHandle;
00357 (sReadersContexts[dwContextB])->mMutex =
00358 (sReadersContexts[dwContext])->mMutex;
00359 (sReadersContexts[dwContextB])->pdwMutex =
00360 (sReadersContexts[dwContext])->pdwMutex;
00361 sReadersContexts[dwContextB]->dwSlot =
00362 sReadersContexts[dwContext]->dwSlot + j;
00363
00364
00365
00366
00367
00368
00369 (sReadersContexts[dwContextB])->pdwFeeds =
00370 (sReadersContexts[dwContext])->pdwFeeds;
00371
00372
00373 *(sReadersContexts[dwContextB])->pdwFeeds += 1;
00374
00375 (sReadersContexts[dwContextB])->dwBlockStatus = 0;
00376 (sReadersContexts[dwContextB])->dwContexts = 0;
00377 (sReadersContexts[dwContextB])->dwLockId = 0;
00378 (sReadersContexts[dwContextB])->LockCount = 0;
00379 (sReadersContexts[dwContextB])->readerState = NULL;
00380 (sReadersContexts[dwContextB])->dwIdentity =
00381 (dwContextB + 1) << IDENTITY_SHIFT;
00382
00383 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
00384 (sReadersContexts[dwContextB])->psHandles[i].hCard = 0;
00385
00386
00387
00388
00389
00390 dwGetSize = sizeof(ucThread);
00391 rv = IFDGetCapabilities((sReadersContexts[dwContext]),
00392 TAG_IFD_SLOT_THREAD_SAFE, &dwGetSize, ucThread);
00393
00394 if (rv == IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
00395 {
00396 (sReadersContexts[dwContextB])->mMutex =
00397 malloc(sizeof(PCSCLITE_MUTEX));
00398 SYS_MutexInit((sReadersContexts[dwContextB])->mMutex);
00399
00400 (sReadersContexts[dwContextB])->pdwMutex = malloc(sizeof(DWORD));
00401 *(sReadersContexts[dwContextB])->pdwMutex = 1;
00402 }
00403 else
00404 *(sReadersContexts[dwContextB])->pdwMutex += 1;
00405
00406 dwNumReadersContexts += 1;
00407
00408 rv = RFInitializeReader(sReadersContexts[dwContextB]);
00409 if (rv != SCARD_S_SUCCESS)
00410 {
00411
00412 RFRemoveReader(lpcReader, dwPort);
00413 return rv;
00414 }
00415
00416
00417 dwGetSize = sizeof(fct);
00418
00419 rv = IFDGetCapabilities((sReadersContexts[dwContextB]),
00420 TAG_IFD_POLLING_THREAD, &dwGetSize, (PUCHAR)&fct);
00421 if ((rv != SCARD_S_SUCCESS) || (dwGetSize != sizeof(fct)))
00422 {
00423 fct = NULL;
00424 Log1(PCSC_LOG_INFO, "Using the pcscd polling thread");
00425 }
00426 else
00427 Log1(PCSC_LOG_INFO, "Using the reader polling thread");
00428
00429 rv = EHSpawnEventHandler(sReadersContexts[dwContextB], fct);
00430 if (rv != SCARD_S_SUCCESS)
00431 {
00432 Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);
00433 RFRemoveReader(lpcReader, dwPort);
00434 return rv;
00435 }
00436 }
00437
00438 return SCARD_S_SUCCESS;
00439 }
00440
00441 LONG RFRemoveReader(LPSTR lpcReader, DWORD dwPort)
00442 {
00443 LONG rv;
00444 PREADER_CONTEXT sContext;
00445
00446 if (lpcReader == 0)
00447 return SCARD_E_INVALID_VALUE;
00448
00449 while ((rv = RFReaderInfoNamePort(dwPort, lpcReader, &sContext))
00450 == SCARD_S_SUCCESS)
00451 {
00452 int i;
00453
00454
00455
00456
00457 rv = EHDestroyEventHandler(sContext);
00458
00459 rv = RFUnInitializeReader(sContext);
00460 if (rv != SCARD_S_SUCCESS)
00461 return rv;
00462
00463
00464
00465
00466 if ((NULL == sContext->pdwMutex) || (NULL == sContext->pdwFeeds))
00467 {
00468 Log1(PCSC_LOG_ERROR,
00469 "Trying to remove an already removed driver");
00470 return SCARD_E_INVALID_VALUE;
00471 }
00472
00473 if (*sContext->pdwMutex == 1)
00474 {
00475 SYS_MutexDestroy(sContext->mMutex);
00476 free(sContext->mMutex);
00477 }
00478
00479 *sContext->pdwMutex -= 1;
00480
00481 if (*sContext->pdwMutex == 0)
00482 {
00483 free(sContext->pdwMutex);
00484 sContext->pdwMutex = NULL;
00485 }
00486
00487 *sContext->pdwFeeds -= 1;
00488
00489
00490
00491 if (*sContext->pdwFeeds == 0)
00492 {
00493 free(sContext->pdwFeeds);
00494 sContext->pdwFeeds = NULL;
00495 }
00496
00497 sContext->lpcDevice[0] = 0;
00498 sContext->dwVersion = 0;
00499 sContext->dwPort = 0;
00500 sContext->mMutex = NULL;
00501 sContext->dwBlockStatus = 0;
00502 sContext->dwContexts = 0;
00503 sContext->dwSlot = 0;
00504 sContext->dwLockId = 0;
00505 sContext->LockCount = 0;
00506 sContext->vHandle = NULL;
00507 sContext->dwIdentity = 0;
00508 sContext->readerState = NULL;
00509
00510 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
00511 sContext->psHandles[i].hCard = 0;
00512
00513 dwNumReadersContexts -= 1;
00514 }
00515
00516 return SCARD_S_SUCCESS;
00517 }
00518
00519 LONG RFSetReaderName(PREADER_CONTEXT rContext, LPSTR readerName,
00520 LPSTR libraryName, DWORD dwPort, DWORD dwSlot)
00521 {
00522 LONG parent = -1;
00523 DWORD valueLength;
00524 int currentDigit = -1;
00525 int supportedChannels = 0;
00526 int usedDigits[PCSCLITE_MAX_READERS_CONTEXTS];
00527 int i;
00528
00529
00530
00531
00532 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00533 usedDigits[i] = FALSE;
00534
00535 if ((0 == dwSlot) && (dwNumReadersContexts != 0))
00536 {
00537 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00538 {
00539 if ((sReadersContexts[i])->vHandle != 0)
00540 {
00541 if (strcmp((sReadersContexts[i])->lpcLibrary, libraryName) == 0)
00542 {
00543 UCHAR tagValue[1];
00544 LONG ret;
00545
00546
00547
00548
00549 valueLength = sizeof(tagValue);
00550 ret = IFDGetCapabilities((sReadersContexts[i]),
00551 TAG_IFD_SIMULTANEOUS_ACCESS,
00552 &valueLength, tagValue);
00553
00554 if ((ret == IFD_SUCCESS) && (valueLength == 1) &&
00555 (tagValue[0] > 1))
00556 {
00557 supportedChannels = tagValue[0];
00558 Log2(PCSC_LOG_INFO,
00559 "Support %d simultaneous readers", tagValue[0]);
00560 }
00561 else
00562 supportedChannels = 1;
00563
00564
00565
00566
00567
00568 if (((((sReadersContexts[i])->dwPort & 0xFFFF0000) ==
00569 PCSCLITE_HP_BASE_PORT)
00570 && ((sReadersContexts[i])->dwPort != dwPort))
00571 || (supportedChannels > 1))
00572 {
00573 char *lpcReader = sReadersContexts[i]->lpcReader;
00574
00575
00576
00577
00578
00579
00580 parent = i;
00581
00582
00583
00584
00585
00586
00587 currentDigit = strtol(lpcReader + strlen(lpcReader) - 5, NULL, 16);
00588
00589
00590
00591
00592 usedDigits[currentDigit] = TRUE;
00593 }
00594 }
00595 }
00596 }
00597
00598 }
00599
00600
00601 i = 0;
00602
00603
00604 if (currentDigit != -1)
00605 {
00606 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00607 {
00608
00609 if (usedDigits[i] == FALSE)
00610 break;
00611 }
00612
00613 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
00614 {
00615 Log2(PCSC_LOG_ERROR, "Max number of readers reached: %d", PCSCLITE_MAX_READERS_CONTEXTS);
00616 return -2;
00617 }
00618
00619 if (i >= supportedChannels)
00620 {
00621 Log3(PCSC_LOG_ERROR, "Driver %s does not support more than "
00622 "%d reader(s). Maybe the driver should support "
00623 "TAG_IFD_SIMULTANEOUS_ACCESS", libraryName, supportedChannels);
00624 return -2;
00625 }
00626 }
00627
00628 sprintf(rContext->lpcReader, "%s %02X %02lX", readerName, i, dwSlot);
00629
00630
00631
00632
00633 rContext->dwSlot = (i << 16) + dwSlot;
00634
00635 return parent;
00636 }
00637
00638 #if 0
00639 LONG RFListReaders(LPSTR lpcReaders, LPDWORD pdwReaderNum)
00640 {
00641 DWORD dwCSize;
00642 LPSTR lpcTReaders;
00643 int i, p;
00644
00645 if (dwNumReadersContexts == 0)
00646 return SCARD_E_READER_UNAVAILABLE;
00647
00648
00649
00650
00651 dwCSize = 0;
00652 p = 0;
00653
00654 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00655 {
00656 if ((sReadersContexts[i])->vHandle != 0)
00657 {
00658 dwCSize += strlen((sReadersContexts[i])->lpcReader) + 1;
00659 p += 1;
00660 }
00661 }
00662
00663 if (p > dwNumReadersContexts)
00664
00665
00666
00667
00668
00669
00670 return SCARD_F_UNKNOWN_ERROR;
00671
00672
00673
00674
00675 dwCSize += 1;
00676
00677
00678
00679
00680
00681
00682
00683 if (lpcReaders == 0)
00684 {
00685 *pdwReaderNum = dwCSize;
00686 return SCARD_S_SUCCESS;
00687 }
00688
00689 if (*pdwReaderNum < dwCSize)
00690 return SCARD_E_INSUFFICIENT_BUFFER;
00691
00692 *pdwReaderNum = dwCSize;
00693 lpcTReaders = lpcReaders;
00694 p = 0;
00695
00696
00697
00698
00699 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00700 {
00701 if ((sReadersContexts[i])->vHandle != 0)
00702 {
00703 strcpy(&lpcTReaders[p], (sReadersContexts[i])->lpcReader);
00704 p += strlen((sReadersContexts[i])->lpcReader);
00705 lpcTReaders[p] = 0;
00706 p += 1;
00707 }
00708 }
00709
00710 lpcTReaders[p] = 0;
00711
00712 return SCARD_S_SUCCESS;
00713 }
00714 #endif
00715
00716 LONG RFReaderInfo(LPSTR lpcReader, PREADER_CONTEXT * sReader)
00717 {
00718 int i;
00719
00720 if (lpcReader == 0)
00721 return SCARD_E_UNKNOWN_READER;
00722
00723 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00724 {
00725 if ((sReadersContexts[i])->vHandle != 0)
00726 {
00727 if (strcmp(lpcReader, (sReadersContexts[i])->lpcReader) == 0)
00728 {
00729 *sReader = sReadersContexts[i];
00730 return SCARD_S_SUCCESS;
00731 }
00732 }
00733 }
00734
00735 return SCARD_E_UNKNOWN_READER;
00736 }
00737
00738 LONG RFReaderInfoNamePort(DWORD dwPort, LPSTR lpcReader,
00739 PREADER_CONTEXT * sReader)
00740 {
00741 char lpcStripReader[MAX_READERNAME];
00742 int i;
00743
00744 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00745 {
00746 if ((sReadersContexts[i])->vHandle != 0)
00747 {
00748 int tmplen;
00749
00750 strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
00751 sizeof(lpcStripReader));
00752 tmplen = strlen(lpcStripReader);
00753 lpcStripReader[tmplen - 6] = 0;
00754
00755 if ((strcmp(lpcReader, lpcStripReader) == 0) &&
00756 (dwPort == (sReadersContexts[i])->dwPort))
00757 {
00758 *sReader = sReadersContexts[i];
00759 return SCARD_S_SUCCESS;
00760 }
00761 }
00762 }
00763
00764 return SCARD_E_INVALID_VALUE;
00765 }
00766
00767 LONG RFReaderInfoById(DWORD dwIdentity, PREADER_CONTEXT * sReader)
00768 {
00769 int i;
00770
00771
00772
00773
00774 dwIdentity = dwIdentity >> IDENTITY_SHIFT;
00775 dwIdentity = dwIdentity << IDENTITY_SHIFT;
00776
00777 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
00778 {
00779 if (dwIdentity == (sReadersContexts[i])->dwIdentity)
00780 {
00781 *sReader = sReadersContexts[i];
00782 return SCARD_S_SUCCESS;
00783 }
00784 }
00785
00786 return SCARD_E_INVALID_VALUE;
00787 }
00788
00789 LONG RFLoadReader(PREADER_CONTEXT rContext)
00790 {
00791 if (rContext->vHandle != 0)
00792 {
00793 Log2(PCSC_LOG_INFO, "Reusing already loaded driver for %s",
00794 rContext->lpcLibrary);
00795
00796
00797
00798 return SCARD_S_SUCCESS;
00799 }
00800
00801 return DYN_LoadLibrary(&rContext->vHandle, rContext->lpcLibrary);
00802 }
00803
00804 LONG RFBindFunctions(PREADER_CONTEXT rContext)
00805 {
00806 int rv1, rv2, rv3;
00807 void *f;
00808
00809
00810
00811
00812
00813
00814
00815 DebugLogSuppress(DEBUGLOG_IGNORE_ENTRIES);
00816
00817 rv1 = DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");
00818 rv2 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannel");
00819 rv3 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannelByName");
00820
00821 DebugLogSuppress(DEBUGLOG_LOG_ENTRIES);
00822
00823 if (rv1 != SCARD_S_SUCCESS && rv2 != SCARD_S_SUCCESS && rv3 != SCARD_S_SUCCESS)
00824 {
00825
00826
00827
00828 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
00829
00830 exit(1);
00831 } else if (rv1 == SCARD_S_SUCCESS)
00832 {
00833
00834
00835
00836 rContext->dwVersion = IFD_HVERSION_1_0;
00837 } else if (rv3 == SCARD_S_SUCCESS)
00838 {
00839
00840
00841
00842 rContext->dwVersion = IFD_HVERSION_3_0;
00843 }
00844 else
00845 {
00846
00847
00848
00849 rContext->dwVersion = IFD_HVERSION_2_0;
00850 }
00851
00852
00853
00854
00855
00856 if (rContext->dwVersion == IFD_HVERSION_1_0)
00857 {
00858 Log1(PCSC_LOG_INFO, "Loading IFD Handler 1.0");
00859
00860 #define GET_ADDRESS_OPTIONALv1(field, function, code) \
00861 { \
00862 void *f1 = NULL; \
00863 if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFD_" #function)) \
00864 { \
00865 code \
00866 } \
00867 rContext->psFunctions.psFunctions_v1.pvf ## field = f1; \
00868 }
00869
00870 #define GET_ADDRESSv1(field, function) \
00871 GET_ADDRESS_OPTIONALv1(field, function, \
00872 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #function ); \
00873 exit(1); )
00874
00875 DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");
00876 rContext->psFunctions.psFunctions_v1.pvfCreateChannel = f;
00877
00878 if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f,
00879 "IO_Close_Channel"))
00880 {
00881 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
00882 exit(1);
00883 }
00884 rContext->psFunctions.psFunctions_v1.pvfCloseChannel = f;
00885
00886 GET_ADDRESSv1(GetCapabilities, Get_Capabilities)
00887 GET_ADDRESSv1(SetCapabilities, Set_Capabilities)
00888 GET_ADDRESSv1(PowerICC, Power_ICC)
00889 GET_ADDRESSv1(TransmitToICC, Transmit_to_ICC)
00890 GET_ADDRESSv1(ICCPresence, Is_ICC_Present)
00891
00892 GET_ADDRESS_OPTIONALv1(SetProtocolParameters, Set_Protocol_Parameters, )
00893 }
00894 else if (rContext->dwVersion == IFD_HVERSION_2_0)
00895 {
00896
00897
00898
00899
00900 #define GET_ADDRESS_OPTIONALv2(s, code) \
00901 { \
00902 void *f1 = NULL; \
00903 if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s)) \
00904 { \
00905 code \
00906 } \
00907 rContext->psFunctions.psFunctions_v2.pvf ## s = f1; \
00908 }
00909
00910 #define GET_ADDRESSv2(s) \
00911 GET_ADDRESS_OPTIONALv2(s, \
00912 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
00913 exit(1); )
00914
00915 Log1(PCSC_LOG_INFO, "Loading IFD Handler 2.0");
00916
00917 GET_ADDRESSv2(CreateChannel)
00918 GET_ADDRESSv2(CloseChannel)
00919 GET_ADDRESSv2(GetCapabilities)
00920 GET_ADDRESSv2(SetCapabilities)
00921 GET_ADDRESSv2(PowerICC)
00922 GET_ADDRESSv2(TransmitToICC)
00923 GET_ADDRESSv2(ICCPresence)
00924 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
00925
00926 GET_ADDRESSv2(Control)
00927 }
00928 else if (rContext->dwVersion == IFD_HVERSION_3_0)
00929 {
00930
00931
00932
00933
00934 #define GET_ADDRESS_OPTIONALv3(s, code) \
00935 { \
00936 void *f1 = NULL; \
00937 if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s)) \
00938 { \
00939 code \
00940 } \
00941 rContext->psFunctions.psFunctions_v3.pvf ## s = f1; \
00942 }
00943
00944 #define GET_ADDRESSv3(s) \
00945 GET_ADDRESS_OPTIONALv3(s, \
00946 Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
00947 exit(1); )
00948
00949 Log1(PCSC_LOG_INFO, "Loading IFD Handler 3.0");
00950
00951 GET_ADDRESSv2(CreateChannel)
00952 GET_ADDRESSv2(CloseChannel)
00953 GET_ADDRESSv2(GetCapabilities)
00954 GET_ADDRESSv2(SetCapabilities)
00955 GET_ADDRESSv2(PowerICC)
00956 GET_ADDRESSv2(TransmitToICC)
00957 GET_ADDRESSv2(ICCPresence)
00958 GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
00959
00960 GET_ADDRESSv3(CreateChannelByName)
00961 GET_ADDRESSv3(Control)
00962 }
00963 else
00964 {
00965
00966
00967
00968 Log1(PCSC_LOG_CRITICAL, "IFD Handler not 1.0/2.0 or 3.0");
00969 exit(1);
00970 }
00971
00972 return SCARD_S_SUCCESS;
00973 }
00974
00975 LONG RFUnBindFunctions(PREADER_CONTEXT rContext)
00976 {
00977
00978
00979
00980
00981 memset(&rContext->psFunctions, 0, sizeof(rContext->psFunctions));
00982
00983 return SCARD_S_SUCCESS;
00984 }
00985
00986 LONG RFUnloadReader(PREADER_CONTEXT rContext)
00987 {
00988
00989
00990
00991
00992 if (*rContext->pdwFeeds == 1)
00993 {
00994 Log1(PCSC_LOG_INFO, "Unloading reader driver.");
00995 DYN_CloseLibrary(&rContext->vHandle);
00996 }
00997
00998 rContext->vHandle = NULL;
00999
01000 return SCARD_S_SUCCESS;
01001 }
01002
01003 LONG RFCheckSharing(DWORD hCard)
01004 {
01005 LONG rv;
01006 PREADER_CONTEXT rContext = NULL;
01007
01008 rv = RFReaderInfoById(hCard, &rContext);
01009
01010 if (rv != SCARD_S_SUCCESS)
01011 return rv;
01012
01013 if (rContext->dwLockId == 0 || rContext->dwLockId == hCard)
01014 return SCARD_S_SUCCESS;
01015 else
01016 return SCARD_E_SHARING_VIOLATION;
01017
01018 }
01019
01020 LONG RFLockSharing(DWORD hCard)
01021 {
01022 PREADER_CONTEXT rContext = NULL;
01023
01024 RFReaderInfoById(hCard, &rContext);
01025
01026 if (RFCheckSharing(hCard) == SCARD_S_SUCCESS)
01027 {
01028 rContext->LockCount += 1;
01029 rContext->dwLockId = hCard;
01030 }
01031 else
01032 return SCARD_E_SHARING_VIOLATION;
01033
01034 return SCARD_S_SUCCESS;
01035 }
01036
01037 LONG RFUnlockSharing(DWORD hCard)
01038 {
01039 PREADER_CONTEXT rContext = NULL;
01040 LONG rv;
01041
01042 rv = RFReaderInfoById(hCard, &rContext);
01043 if (rv != SCARD_S_SUCCESS)
01044 return rv;
01045
01046 rv = RFCheckSharing(hCard);
01047 if (rv != SCARD_S_SUCCESS)
01048 return rv;
01049
01050 if (rContext->LockCount > 0)
01051 rContext->LockCount -= 1;
01052 if (0 == rContext->LockCount)
01053 rContext->dwLockId = 0;
01054
01055 return SCARD_S_SUCCESS;
01056 }
01057
01058 LONG RFUnblockContext(SCARDCONTEXT hContext)
01059 {
01060 int i;
01061
01062 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01063 (sReadersContexts[i])->dwBlockStatus = hContext;
01064
01065 return SCARD_S_SUCCESS;
01066 }
01067
01068 LONG RFUnblockReader(PREADER_CONTEXT rContext)
01069 {
01070 rContext->dwBlockStatus = BLOCK_STATUS_RESUME;
01071 return SCARD_S_SUCCESS;
01072 }
01073
01074 LONG RFInitializeReader(PREADER_CONTEXT rContext)
01075 {
01076 LONG rv;
01077
01078
01079
01080
01081 Log3(PCSC_LOG_INFO, "Attempting startup of %s using %s",
01082 rContext->lpcReader, rContext->lpcLibrary);
01083
01084
01085
01086
01087
01088
01089 rv = RFLoadReader(rContext);
01090 if (rv != SCARD_S_SUCCESS)
01091 {
01092 Log2(PCSC_LOG_ERROR, "RFLoadReader failed: %X", rv);
01093 return rv;
01094 }
01095
01096
01097
01098
01099
01100
01101 rv = RFBindFunctions(rContext);
01102
01103 if (rv != SCARD_S_SUCCESS)
01104 {
01105 Log2(PCSC_LOG_ERROR, "RFBindFunctions failed: %X", rv);
01106 RFUnloadReader(rContext);
01107 return rv;
01108 }
01109
01110
01111
01112
01113
01114
01115
01116 rv = IFDOpenIFD(rContext);
01117
01118 if (rv != IFD_SUCCESS)
01119 {
01120 Log3(PCSC_LOG_CRITICAL, "Open Port %X Failed (%s)",
01121 rContext->dwPort, rContext->lpcDevice);
01122 RFUnBindFunctions(rContext);
01123 RFUnloadReader(rContext);
01124 return SCARD_E_INVALID_TARGET;
01125 }
01126
01127 return SCARD_S_SUCCESS;
01128 }
01129
01130 LONG RFUnInitializeReader(PREADER_CONTEXT rContext)
01131 {
01132 Log2(PCSC_LOG_INFO, "Attempting shutdown of %s.",
01133 rContext->lpcReader);
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 IFDCloseIFD(rContext);
01146 RFUnBindFunctions(rContext);
01147 RFUnloadReader(rContext);
01148
01149 return SCARD_S_SUCCESS;
01150 }
01151
01152 SCARDHANDLE RFCreateReaderHandle(PREADER_CONTEXT rContext)
01153 {
01154 USHORT randHandle;
01155
01156
01157
01158
01159
01160 randHandle = SYS_RandomInt(10, 65000);
01161
01162 while (1)
01163 {
01164 int i;
01165
01166 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01167 {
01168 if ((sReadersContexts[i])->vHandle != 0)
01169 {
01170 int j;
01171
01172 for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
01173 {
01174 if ((rContext->dwIdentity + randHandle) ==
01175 (sReadersContexts[i])->psHandles[j].hCard)
01176 {
01177
01178
01179
01180 randHandle = SYS_RandomInt(10, 65000);
01181 continue;
01182 }
01183 }
01184 }
01185 }
01186
01187
01188
01189
01190
01191
01192 if (i == PCSCLITE_MAX_READERS_CONTEXTS)
01193 break;
01194 }
01195
01196 return rContext->dwIdentity + randHandle;
01197 }
01198
01199 LONG RFFindReaderHandle(SCARDHANDLE hCard)
01200 {
01201 int i;
01202
01203 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01204 {
01205 if ((sReadersContexts[i])->vHandle != 0)
01206 {
01207 int j;
01208
01209 for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
01210 {
01211 if (hCard == (sReadersContexts[i])->psHandles[j].hCard)
01212 return SCARD_S_SUCCESS;
01213 }
01214 }
01215 }
01216
01217 return SCARD_E_INVALID_HANDLE;
01218 }
01219
01220 LONG RFDestroyReaderHandle(SCARDHANDLE hCard)
01221 {
01222 return SCARD_S_SUCCESS;
01223 }
01224
01225 LONG RFAddReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01226 {
01227 int i;
01228
01229 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01230 {
01231 if (rContext->psHandles[i].hCard == 0)
01232 {
01233 rContext->psHandles[i].hCard = hCard;
01234 rContext->psHandles[i].dwEventStatus = 0;
01235 break;
01236 }
01237 }
01238
01239 if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01240
01241 return SCARD_E_INSUFFICIENT_BUFFER;
01242
01243 return SCARD_S_SUCCESS;
01244 }
01245
01246 LONG RFRemoveReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01247 {
01248 int i;
01249
01250 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01251 {
01252 if (rContext->psHandles[i].hCard == hCard)
01253 {
01254 rContext->psHandles[i].hCard = 0;
01255 rContext->psHandles[i].dwEventStatus = 0;
01256 break;
01257 }
01258 }
01259
01260 if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01261
01262 return SCARD_E_INVALID_HANDLE;
01263
01264 return SCARD_S_SUCCESS;
01265 }
01266
01267 LONG RFSetReaderEventState(PREADER_CONTEXT rContext, DWORD dwEvent)
01268 {
01269 int i;
01270
01271
01272
01273
01274 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01275 {
01276 if (rContext->psHandles[i].hCard != 0)
01277 rContext->psHandles[i].dwEventStatus = dwEvent;
01278 }
01279
01280 if (SCARD_REMOVED == dwEvent)
01281 {
01282
01283 rContext->dwLockId = 0;
01284 rContext->LockCount = 0;
01285 }
01286
01287 return SCARD_S_SUCCESS;
01288 }
01289
01290 LONG RFCheckReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01291 {
01292 int i;
01293
01294 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01295 {
01296 if (rContext->psHandles[i].hCard == hCard)
01297 {
01298 if (rContext->psHandles[i].dwEventStatus == SCARD_REMOVED)
01299 return SCARD_W_REMOVED_CARD;
01300 else
01301 {
01302 if (rContext->psHandles[i].dwEventStatus == SCARD_RESET)
01303 return SCARD_W_RESET_CARD;
01304 else
01305 {
01306 if (rContext->psHandles[i].dwEventStatus == 0)
01307 return SCARD_S_SUCCESS;
01308 else
01309 return SCARD_E_INVALID_VALUE;
01310 }
01311 }
01312 }
01313 }
01314
01315 return SCARD_E_INVALID_HANDLE;
01316 }
01317
01318 LONG RFClearReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
01319 {
01320 int i;
01321
01322 for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
01323 {
01324 if (rContext->psHandles[i].hCard == hCard)
01325 rContext->psHandles[i].dwEventStatus = 0;
01326 }
01327
01328 if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
01329
01330 return SCARD_E_INVALID_HANDLE;
01331
01332 return SCARD_S_SUCCESS;
01333 }
01334
01335 LONG RFCheckReaderStatus(PREADER_CONTEXT rContext)
01336 {
01337 if ((rContext->readerState == NULL)
01338 || (rContext->readerState->readerState & SCARD_UNKNOWN))
01339 return SCARD_E_READER_UNAVAILABLE;
01340 else
01341 return SCARD_S_SUCCESS;
01342 }
01343
01344 void RFCleanupReaders(int shouldExit)
01345 {
01346 int i;
01347
01348 Log1(PCSC_LOG_INFO, "entering cleaning function");
01349 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01350 {
01351 if (sReadersContexts[i]->vHandle != 0)
01352 {
01353 LONG rv;
01354 char lpcStripReader[MAX_READERNAME];
01355
01356 Log2(PCSC_LOG_INFO, "Stopping reader: %s",
01357 sReadersContexts[i]->lpcReader);
01358
01359 strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
01360 sizeof(lpcStripReader));
01361
01362
01363
01364 lpcStripReader[strlen(lpcStripReader) - 6] = '\0';
01365
01366 rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->dwPort);
01367
01368 if (rv != SCARD_S_SUCCESS)
01369 Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08X", rv);
01370 }
01371 }
01372
01373
01374
01375
01376
01377 if (shouldExit)
01378 exit(0);
01379 }
01380
01381 int RFStartSerialReaders(const char *readerconf)
01382 {
01383 SerialReader *reader_list;
01384 int i, rv;
01385
01386
01387 ConfigFile = strdup(readerconf);
01388
01389 rv = DBGetReaderList(readerconf, &reader_list);
01390
01391
01392 if (NULL == reader_list)
01393 return rv;
01394
01395 for (i=0; reader_list[i].pcFriendlyname; i++)
01396 {
01397 int j;
01398
01399 RFAddReader(reader_list[i].pcFriendlyname, reader_list[i].dwChannelId,
01400 reader_list[i].pcLibpath, reader_list[i].pcDevicename);
01401
01402
01403 for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
01404 ConfigFileCRC += reader_list[i].pcFriendlyname[j];
01405 for (j=0; j<reader_list[i].pcLibpath[j]; j++)
01406 ConfigFileCRC += reader_list[i].pcLibpath[j];
01407 for (j=0; j<reader_list[i].pcDevicename[j]; j++)
01408 ConfigFileCRC += reader_list[i].pcDevicename[j];
01409
01410
01411 free(reader_list[i].pcFriendlyname);
01412 free(reader_list[i].pcLibpath);
01413 free(reader_list[i].pcDevicename);
01414 }
01415 free(reader_list);
01416
01417 return rv;
01418 }
01419
01420 void RFReCheckReaderConf(void)
01421 {
01422 SerialReader *reader_list;
01423 int i, crc;
01424
01425 DBGetReaderList(ConfigFile, &reader_list);
01426
01427
01428 if (NULL == reader_list)
01429 return;
01430
01431 crc = 0;
01432 for (i=0; reader_list[i].pcFriendlyname; i++)
01433 {
01434 int j;
01435
01436
01437 for (j=0; j<reader_list[i].pcFriendlyname[j]; j++)
01438 crc += reader_list[i].pcFriendlyname[j];
01439 for (j=0; j<reader_list[i].pcLibpath[j]; j++)
01440 crc += reader_list[i].pcLibpath[j];
01441 for (j=0; j<reader_list[i].pcDevicename[j]; j++)
01442 crc += reader_list[i].pcDevicename[j];
01443 }
01444
01445
01446 if (crc != ConfigFileCRC)
01447 {
01448 Log2(PCSC_LOG_CRITICAL,
01449 "configuration file: %s has been modified. Recheck canceled",
01450 ConfigFile);
01451 return;
01452 }
01453
01454 for (i=0; reader_list[i].pcFriendlyname; i++)
01455 {
01456 int r;
01457 char present = FALSE;
01458
01459 Log2(PCSC_LOG_DEBUG, "refresh reader: %s",
01460 reader_list[i].pcFriendlyname);
01461
01462
01463 for (r = 0; r < PCSCLITE_MAX_READERS_CONTEXTS; r++)
01464 {
01465 if (sReadersContexts[r]->vHandle != 0)
01466 {
01467 char lpcStripReader[MAX_READERNAME];
01468 int tmplen;
01469
01470
01471 strncpy(lpcStripReader, sReadersContexts[i]->lpcReader,
01472 sizeof(lpcStripReader));
01473 tmplen = strlen(lpcStripReader);
01474 lpcStripReader[tmplen - 6] = 0;
01475
01476 if ((strcmp(reader_list[i].pcFriendlyname, lpcStripReader) == 0)
01477 && (reader_list[r].dwChannelId == sReadersContexts[i]->dwPort))
01478 {
01479 DWORD dwStatus = 0, dwAtrLen = 0;
01480 UCHAR ucAtr[MAX_ATR_SIZE];
01481
01482
01483 present = TRUE;
01484
01485
01486 if (IFDStatusICC(sReadersContexts[r], &dwStatus, ucAtr,
01487 &dwAtrLen) != SCARD_S_SUCCESS)
01488 {
01489 Log2(PCSC_LOG_INFO, "Reader %s disappeared",
01490 reader_list[i].pcFriendlyname);
01491 RFRemoveReader(reader_list[i].pcFriendlyname,
01492 reader_list[r].dwChannelId);
01493 }
01494 }
01495 }
01496 }
01497
01498
01499 if (!present)
01500
01501 RFAddReader(reader_list[i].pcFriendlyname,
01502 reader_list[i].dwChannelId, reader_list[i].pcLibpath,
01503 reader_list[i].pcDevicename);
01504
01505
01506 free(reader_list[i].pcFriendlyname);
01507 free(reader_list[i].pcLibpath);
01508 free(reader_list[i].pcDevicename);
01509 }
01510 free(reader_list);
01511 }
01512
01513 void RFSuspendAllReaders(void)
01514 {
01515 int i;
01516
01517 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01518 {
01519 if ((sReadersContexts[i])->vHandle != 0)
01520 {
01521 EHDestroyEventHandler(sReadersContexts[i]);
01522 IFDCloseIFD(sReadersContexts[i]);
01523 }
01524 }
01525
01526 }
01527
01528 void RFAwakeAllReaders(void)
01529 {
01530 LONG rv = IFD_SUCCESS;
01531 int i;
01532 int initFlag;
01533
01534 initFlag = 0;
01535
01536 for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
01537 {
01538
01539 if ( ((sReadersContexts[i])->vHandle != 0) &&
01540 ((sReadersContexts[i])->pthThread == 0) )
01541 {
01542 int j;
01543
01544 for (j=0; j < i; j++)
01545 {
01546 if (((sReadersContexts[j])->vHandle == (sReadersContexts[i])->vHandle)&&
01547 ((sReadersContexts[j])->dwPort == (sReadersContexts[i])->dwPort))
01548 {
01549 initFlag = 1;
01550 }
01551 }
01552
01553 if (initFlag == 0)
01554 rv = IFDOpenIFD(sReadersContexts[i]);
01555 else
01556 initFlag = 0;
01557
01558 if (rv != IFD_SUCCESS)
01559 {
01560 Log3(PCSC_LOG_ERROR, "Open Port %X Failed (%s)",
01561 (sReadersContexts[i])->dwPort, (sReadersContexts[i])->lpcDevice);
01562 }
01563
01564
01565 EHSpawnEventHandler(sReadersContexts[i], NULL);
01566 RFSetReaderEventState(sReadersContexts[i], SCARD_RESET);
01567 }
01568 }
01569 }
01570