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