PCSC_API LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) { DWORD Lun = hCard; LONG r; UCHAR Atr[MAX_ATR_SIZE]; DWORD AtrLength = sizeof Atr; struct card *card; SET_R_TEST( handle2card(hCard, &card)); if (!card->usage_counter) { r = SCARD_E_INVALID_HANDLE; goto err; } card->usage_counter--; switch (dwDisposition) { case SCARD_LEAVE_CARD: r = SCARD_S_SUCCESS; break; case SCARD_RESET_CARD: if (card->usage_counter) { r = SCARD_E_CANT_DISPOSE; goto err; } SET_R_TEST( responsecode2long( IFDHPowerICC (Lun, IFD_RESET, Atr, &AtrLength))); break; case SCARD_EJECT_CARD: /* fall through */ case SCARD_UNPOWER_CARD: if (card->usage_counter) { r = SCARD_E_CANT_DISPOSE; goto err; } SET_R_TEST( responsecode2long( IFDHPowerICC (Lun, IFD_POWER_DOWN, Atr, &AtrLength))); break; default: r = SCARD_E_INVALID_PARAMETER; break; } err: return r; }
/** * Power up/down or reset's an ICC located in the IFD. */ LONG IFDPowerICC(PREADER_CONTEXT rContext, DWORD dwAction, const unsigned char *pucAtr, PDWORD pdwAtrLen) { RESPONSECODE rv; short ret; SMARTCARD_EXTENSION sSmartCard; DWORD dwStatus; UCHAR ucValue[1]; #ifndef PCSCLITE_STATIC_DRIVER RESPONSECODE(*IFD_power_icc) (DWORD) = NULL; RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL; #endif /* * Zero out everything */ rv = IFD_SUCCESS; dwStatus = 0; ucValue[0] = 0; /* * Check that the card is inserted first */ (void)IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen); if (dwStatus & SCARD_ABSENT) return SCARD_W_REMOVED_CARD; #ifndef PCSCLITE_STATIC_DRIVER if (rContext->dwVersion == IFD_HVERSION_1_0) IFD_power_icc = rContext->psFunctions.psFunctions_v1.pvfPowerICC; else IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC; #endif /* LOCK THIS CODE REGION */ (void)SYS_MutexLock(rContext->mMutex); #ifndef PCSCLITE_STATIC_DRIVER if (rContext->dwVersion == IFD_HVERSION_1_0) { ucValue[0] = rContext->dwSlot; (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue); rv = (*IFD_power_icc) (dwAction); } else { rv = (*IFDH_power_icc) (rContext->dwSlot, dwAction, (unsigned char *)pucAtr, pdwAtrLen); ret = ATRDecodeAtr(&sSmartCard, pucAtr, *pdwAtrLen); } #else if (rContext->dwVersion == IFD_HVERSION_1_0) { ucValue[0] = rContext->dwSlot; (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue); rv = IFD_Power_ICC(dwAction); } else rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, pdwAtrLen); #endif /* END OF LOCKED REGION */ (void)SYS_MutexUnLock(rContext->mMutex); /* use clean values in case of error */ if (rv != IFD_SUCCESS) { *pdwAtrLen = 0; // pucAtr[0] = '\0'; if (rv == IFD_NO_SUCH_DEVICE) { // (void)SendHotplugSignal(); return SCARD_E_READER_UNAVAILABLE; } return SCARD_E_NOT_TRANSACTED; } /* * Get the ATR and it's length */ if (rContext->dwVersion == IFD_HVERSION_1_0) (void)IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen); return rv; }
/** * Power up/down or reset's an ICC located in the IFD. */ LONG IFDPowerICC(READER_CONTEXT * rContext, DWORD dwAction, PUCHAR pucAtr, PDWORD pdwAtrLen) { RESPONSECODE rv; DWORD dwStatus; UCHAR dummyAtr[MAX_ATR_SIZE]; DWORD dummyAtrLen = sizeof(dummyAtr); #ifndef PCSCLITE_STATIC_DRIVER RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL; #endif /* * Zero out everything */ dwStatus = 0; if (NULL == pucAtr) pucAtr = dummyAtr; if (NULL == pdwAtrLen) pdwAtrLen = &dummyAtrLen; /* * Check that the card is inserted first */ rv = IFDStatusICC(rContext, &dwStatus); if (rv != IFD_SUCCESS) { if (rv == IFD_NO_SUCH_DEVICE) return SCARD_E_READER_UNAVAILABLE; return SCARD_E_NOT_TRANSACTED; } if (dwStatus & SCARD_ABSENT) return SCARD_W_REMOVED_CARD; #ifndef PCSCLITE_STATIC_DRIVER IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC; #endif /* LOCK THIS CODE REGION */ (void)pthread_mutex_lock(rContext->mMutex); #ifndef PCSCLITE_STATIC_DRIVER rv = (*IFDH_power_icc) (rContext->slot, dwAction, pucAtr, pdwAtrLen); #else rv = IFDHPowerICC(rContext->slot, dwAction, pucAtr, pdwAtrLen); #endif /* END OF LOCKED REGION */ (void)pthread_mutex_unlock(rContext->mMutex); /* use clean values in case of error */ if (rv != IFD_SUCCESS) { *pdwAtrLen = 0; pucAtr[0] = '\0'; if (rv == IFD_NO_SUCH_DEVICE) { (void)SendHotplugSignal(); return SCARD_E_READER_UNAVAILABLE; } return SCARD_E_NOT_TRANSACTED; } return rv; }