/* * Sets up callbacks for device hotplug events. */ ULONG HPRegisterForHotplugEvents(void) { ThreadCreate(&sHotplugWatcherThread, THREAD_ATTR_DEFAULT, (PCSCLITE_THREAD_FUNCTION( )) HPDeviceNotificationThread, NULL); return 0; }
LONG EHSpawnEventHandler(PREADER_CONTEXT rContext) { LONG rv; DWORD dwStatus = 0; int i; UCHAR ucAtr[MAX_ATR_SIZE]; DWORD dwAtrLen = 0; secdebug("pcscd", "EHSpawnEventHandler: rContext: 0x%p", rContext); rv = IFDStatusICC(rContext, &dwStatus, ucAtr, &dwAtrLen); if (rv != SCARD_S_SUCCESS) { Log2(PCSC_LOG_ERROR, "Initial Check Failed on %s", rContext->lpcReader); return SCARD_F_UNKNOWN_ERROR; } /* * Find an empty reader slot and insert the new reader */ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++) { PCSCD::SharedReaderState *rstmp = PCSCD::SharedReaderState::overlay(readerStates[i]); if (rstmp->xreaderID() == 0) break; } if (i == PCSCLITE_MAX_READERS_CONTEXTS) return SCARD_F_INTERNAL_ERROR; /* * Set all the attributes to this reader */ PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(readerStates[i]); rContext->readerState = readerStates[i]; rs->xreaderName(rContext->lpcReader); rs->xcardAtr(ucAtr, dwAtrLen); // also sets cardAtrLength rs->xreaderID(i + 100); rs->xreaderState(dwStatus); rs->sharing(rContext->dwContexts); rs->xcardProtocol(SCARD_PROTOCOL_UNSET); rv = SYS_ThreadCreate(&rContext->pthThread, THREAD_ATTR_DETACHED, (PCSCLITE_THREAD_FUNCTION( ))EHStatusHandlerThread, (LPVOID) rContext); secdebug("pcscd", "EHSpawnEventHandler after thread create: %d [%04X]", rv, rv); if (rv == 1) return SCARD_S_SUCCESS; else return SCARD_E_NO_MEMORY; }
LONG HPSearchHotPluggables(void) { int i; for (i=0; i<PCSCLITE_MAX_READERS_CONTEXTS; i++) { readerTracker[i].status = READER_ABSENT; readerTracker[i].bus_device[0] = '\0'; readerTracker[i].fullName = NULL; } if (HPReadBundleValues()) SYS_ThreadCreate(&usbNotifyThread, THREAD_ATTR_DETACHED, (PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, NULL); return 0; }
LONG HPSearchHotPluggables(void) { int i, j; for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++) { bundleTracker[i].productID = 0; bundleTracker[i].manuID = 0; for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++) bundleTracker[i].deviceNumber[j].id = 0; } HPReadBundleValues(); SYS_ThreadCreate(&usbNotifyThread, THREAD_ATTR_DETACHED, (PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, 0); return 0; }
LONG EHSpawnEventHandler(READER_CONTEXT * rContext) { LONG rv; DWORD dwStatus = 0; rv = IFDStatusICC(rContext, &dwStatus); if (rv != SCARD_S_SUCCESS) { Log2(PCSC_LOG_ERROR, "Initial Check Failed on %s", rContext->readerState->readerName); return SCARD_F_UNKNOWN_ERROR; } rv = ThreadCreate(&rContext->pthThread, 0, (PCSCLITE_THREAD_FUNCTION( ))EHStatusHandlerThread, (LPVOID) rContext); if (rv) { Log2(PCSC_LOG_ERROR, "ThreadCreate failed: %s", strerror(rv)); return SCARD_E_NO_MEMORY; } else return SCARD_S_SUCCESS; }
/** * @brief Creates threads to handle messages received from Clients. * * @param[in] pdwClientID Connection ID used to reference the Client. * * @return Error code. * @retval SCARD_S_SUCCESS Success. * @retval SCARD_F_INTERNAL_ERROR Exceded the maximum number of simultaneous Application Contexts. * @retval SCARD_E_NO_MEMORY Error creating the Context Thread. */ LONG CreateContextThread(uint32_t *pdwClientID) { int rv; int lrv; int listSize; SCONTEXT * newContext = NULL; LONG retval = SCARD_E_NO_MEMORY; (void)pthread_mutex_lock(&contextsList_lock); listSize = list_size(&contextsList); if (listSize >= contextMaxThreadCounter) { Log2(PCSC_LOG_CRITICAL, "Too many context running: %d", listSize); goto out; } /* Create the context for this thread. */ newContext = malloc(sizeof(*newContext)); if (NULL == newContext) { Log1(PCSC_LOG_CRITICAL, "Could not allocate new context"); goto out; } memset(newContext, 0, sizeof(*newContext)); newContext->dwClientID = *pdwClientID; /* Initialise the list of card contexts */ lrv = list_init(&newContext->cardsList); if (lrv < 0) { Log2(PCSC_LOG_CRITICAL, "list_init failed with return value: %d", lrv); goto out; } /* request to store copies, and provide the metric function */ list_attributes_copy(&newContext->cardsList, list_meter_int32_t, 1); /* Adding a comparator * The stored type is SCARDHANDLE (long) but has only 32 bits * usefull even on a 64-bit CPU since the API between pcscd and * libpcscliter uses "int32_t hCard;" */ lrv = list_attributes_comparator(&newContext->cardsList, list_comparator_int32_t); if (lrv != 0) { Log2(PCSC_LOG_CRITICAL, "list_attributes_comparator failed with return value: %d", lrv); list_destroy(&newContext->cardsList); goto out; } (void)pthread_mutex_init(&newContext->cardsList_lock, NULL); lrv = list_append(&contextsList, newContext); if (lrv < 0) { Log2(PCSC_LOG_CRITICAL, "list_append failed with return value: %d", lrv); list_destroy(&newContext->cardsList); goto out; } rv = ThreadCreate(&newContext->pthThread, THREAD_ATTR_DETACHED, (PCSCLITE_THREAD_FUNCTION( )) ContextThread, (LPVOID) newContext); if (rv) { int lrv2; Log2(PCSC_LOG_CRITICAL, "ThreadCreate failed: %s", strerror(rv)); lrv2 = list_delete(&contextsList, newContext); if (lrv2 < 0) Log2(PCSC_LOG_CRITICAL, "list_delete failed with error %d", lrv2); list_destroy(&newContext->cardsList); goto out; } /* disable any suicide alarm */ if (AutoExit) alarm(0); retval = SCARD_S_SUCCESS; out: (void)pthread_mutex_unlock(&contextsList_lock); if (retval != SCARD_S_SUCCESS) { if (newContext) free(newContext); (void)close(*pdwClientID); } return retval; }