static void OS_ThreadWrapper(void) { /* Execute the thread entry point */ current->entry_point(current->arg); /* The thread is finished so we free all the TCB entries */ SYS_ThreadExit(); }
void EHStatusHandlerThread(PREADER_CONTEXT rContext) { LONG rv; LPCSTR lpcReader; DWORD dwStatus, dwReaderSharing; DWORD dwCurrentState; int pageSize = SYS_GetPageSize(); /* * Zero out everything */ dwStatus = 0; dwReaderSharing = 0; dwCurrentState = 0; secdebug("pcscd", "EHStatusHandlerThread: rContext: 0x%p", rContext); lpcReader = rContext->lpcReader; PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(rContext->readerState); DWORD tmpCardAtrLength = MAX_ATR_SIZE; rv = IFDStatusICC(rContext, &dwStatus, rs->xcardAtr(), &tmpCardAtrLength); secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDStatusICC: %d [%04X]", rv, rv); if (dwStatus & SCARD_PRESENT) { tmpCardAtrLength = MAX_ATR_SIZE; rv = IFDPowerICC(rContext, IFD_POWER_UP, rs->xcardAtr(), &tmpCardAtrLength); /* the protocol is unset after a power on */ rs->xcardProtocol(SCARD_PROTOCOL_UNSET); secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDPowerICC: %d [%04X]", rv, rv); if (rv == IFD_SUCCESS) { rs->xcardAtrLength(tmpCardAtrLength); dwStatus |= SCARD_PRESENT; dwStatus &= ~SCARD_ABSENT; dwStatus |= SCARD_POWERED; dwStatus |= SCARD_NEGOTIABLE; dwStatus &= ~SCARD_SPECIFIC; dwStatus &= ~SCARD_SWALLOWED; dwStatus &= ~SCARD_UNKNOWN; if (rs->xcardAtrLength() > 0) { LogXxd(PCSC_LOG_INFO, "Card ATR: ", rs->xcardAtr(), rs->xcardAtrLength()); } else Log1(PCSC_LOG_INFO, "Card ATR: (NULL)"); } else { dwStatus |= SCARD_PRESENT; dwStatus &= ~SCARD_ABSENT; dwStatus |= SCARD_SWALLOWED; dwStatus &= ~SCARD_POWERED; dwStatus &= ~SCARD_NEGOTIABLE; dwStatus &= ~SCARD_SPECIFIC; dwStatus &= ~SCARD_UNKNOWN; Log3(PCSC_LOG_ERROR, "Error powering up card: %d 0x%04X", rv, rv); } dwCurrentState = SCARD_PRESENT; } else { dwStatus |= SCARD_ABSENT; dwStatus &= ~SCARD_PRESENT; dwStatus &= ~SCARD_POWERED; dwStatus &= ~SCARD_NEGOTIABLE; dwStatus &= ~SCARD_SPECIFIC; dwStatus &= ~SCARD_SWALLOWED; dwStatus &= ~SCARD_UNKNOWN; rs->xcardAtrLength(0); rs->xcardProtocol(SCARD_PROTOCOL_UNSET); dwCurrentState = SCARD_ABSENT; } /* * Set all the public attributes to this reader */ rs->xreaderState(dwStatus); dwReaderSharing = rContext->dwContexts; rs->sharing(dwReaderSharing); SYS_MMapSynchronize((void *) rContext->readerState, pageSize); while (1) { dwStatus = 0; // Defensive measure if (!rContext->vHandle) { // Exit and notify the caller secdebug("pcscd", "EHStatusHandlerThread: lost dynamic callbacks ??"); ReaderContextUnlock(rContext); SYS_ThreadDetach(rContext->pthThread); SYS_ThreadExit(0); } DWORD tmpCardAtrLength = MAX_ATR_SIZE; rv = IFDStatusICC(rContext, &dwStatus, rs->xcardAtr(), &tmpCardAtrLength); if (rv != SCARD_S_SUCCESS) { Log2(PCSC_LOG_ERROR, "Error communicating to: %s", lpcReader); /* * Set error status on this reader while errors occur */ DWORD readerStateTmp = rs->xreaderState(); readerStateTmp &= ~SCARD_ABSENT; readerStateTmp &= ~SCARD_PRESENT; readerStateTmp &= ~SCARD_POWERED; readerStateTmp &= ~SCARD_NEGOTIABLE; readerStateTmp &= ~SCARD_SPECIFIC; readerStateTmp &= ~SCARD_SWALLOWED; readerStateTmp |= SCARD_UNKNOWN; rs->xcardAtrLength(0); rs->xcardProtocol(SCARD_PROTOCOL_UNSET); rs->xreaderState(readerStateTmp); dwCurrentState = SCARD_UNKNOWN; SYS_MMapSynchronize((void *) rContext->readerState, pageSize); /* * This code causes race conditions on G4's with USB * insertion */ /* * dwErrorCount += 1; SYS_Sleep(1); */ /* * After 10 seconds of errors, try to reinitialize the reader * This sometimes helps bring readers out of *crazy* states. */ /* * if ( dwErrorCount == 10 ) { RFUnInitializeReader( rContext * ); RFInitializeReader( rContext ); dwErrorCount = 0; } */ /* * End of race condition code block */ } if (dwStatus & SCARD_ABSENT) { if (dwCurrentState == SCARD_PRESENT || dwCurrentState == SCARD_UNKNOWN) { /* * Change the status structure */ Log2(PCSC_LOG_INFO, "Card Removed From %s", lpcReader); /* * Notify the card has been removed */ RFSetReaderEventState(rContext, SCARD_REMOVED); rs->xcardAtrLength(0); rs->xcardProtocol(SCARD_PROTOCOL_UNSET); DWORD readerStateTmp = rs->xreaderState(); readerStateTmp |= SCARD_ABSENT; readerStateTmp &= ~SCARD_UNKNOWN; readerStateTmp &= ~SCARD_PRESENT; readerStateTmp &= ~SCARD_POWERED; readerStateTmp &= ~SCARD_NEGOTIABLE; readerStateTmp &= ~SCARD_SWALLOWED; readerStateTmp &= ~SCARD_SPECIFIC; rs->xreaderState(readerStateTmp); dwCurrentState = SCARD_ABSENT; SYS_MMapSynchronize((void *) rContext->readerState, pageSize); } } else if (dwStatus & SCARD_PRESENT) { if (dwCurrentState == SCARD_ABSENT || dwCurrentState == SCARD_UNKNOWN) { /* * Power and reset the card */ SYS_USleep(PCSCLITE_STATUS_WAIT); DWORD tmpCardAtrLength = MAX_ATR_SIZE; rv = IFDPowerICC(rContext, IFD_POWER_UP, rs->xcardAtr(), &tmpCardAtrLength); /* the protocol is unset after a power on */ rs->xcardProtocol(SCARD_PROTOCOL_UNSET); secdebug("pcscd", "EHStatusHandlerThread: power-and-reset call to IFDPowerICC: %d [%04X]", rv, rv); DWORD readerStateTmp = rs->xreaderState(); if (rv == IFD_SUCCESS) { rs->xcardAtrLength(tmpCardAtrLength); readerStateTmp |= SCARD_PRESENT; readerStateTmp &= ~SCARD_ABSENT; readerStateTmp |= SCARD_POWERED; readerStateTmp |= SCARD_NEGOTIABLE; readerStateTmp &= ~SCARD_SPECIFIC; readerStateTmp &= ~SCARD_UNKNOWN; readerStateTmp &= ~SCARD_SWALLOWED; rs->xreaderState(readerStateTmp); /* * Notify the card has been reset */ RFSetReaderEventState(rContext, SCARD_RESET); } else { readerStateTmp |= SCARD_PRESENT; readerStateTmp &= ~SCARD_ABSENT; readerStateTmp |= SCARD_SWALLOWED; readerStateTmp &= ~SCARD_POWERED; readerStateTmp &= ~SCARD_NEGOTIABLE; readerStateTmp &= ~SCARD_SPECIFIC; readerStateTmp &= ~SCARD_UNKNOWN; rs->xreaderState(readerStateTmp); rs->xcardAtrLength(0); } dwCurrentState = SCARD_PRESENT; SYS_MMapSynchronize((void *) rContext->readerState, pageSize); Log2(PCSC_LOG_INFO, "Card inserted into %s", lpcReader); if (rv == IFD_SUCCESS) { if (rs->xcardAtrLength() > 0) LogXxd(PCSC_LOG_INFO, "Card ATR: ", rs->xcardAtr(), rs->xcardAtrLength()); else Log1(PCSC_LOG_INFO, "Card ATR: (NULL)"); } else Log1(PCSC_LOG_ERROR,"Error powering up card."); } } if (ReaderContextIsLocked(rContext)) { /* * Exit and notify the caller */ secdebug("pcscd", "EHStatusHandlerThread: parent requested shutdown"); ReaderContextUnlock(rContext); SYS_ThreadDetach(rContext->pthThread); SYS_ThreadExit(0); } /* * Sharing may change w/o an event pass it on */ if (dwReaderSharing != (uint32_t)rContext->dwContexts) { dwReaderSharing = rContext->dwContexts; rs->sharing(dwReaderSharing); SYS_MMapSynchronize((void *) rContext->readerState, pageSize); } SYS_USleep(PCSCLITE_STATUS_POLL_RATE); } }