예제 #1
0
/**
 * Open a communication channel to the IFD.
 */
LONG IFDOpenIFD(READER_CONTEXT * rContext)
{
	RESPONSECODE rv = 0;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
	RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;

	if (rContext->version == IFD_HVERSION_2_0)
		IFDH_create_channel =
			rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
	else
	{
		IFDH_create_channel =
			rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
		IFDH_create_channel_by_name =
			rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
	}
#endif

	/* LOCK THIS CODE REGION */
	(void)pthread_mutex_lock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	if (rContext->version == IFD_HVERSION_2_0)
	{
		rv = (*IFDH_create_channel) (rContext->slot, rContext->port);
	} else
	{
		/* use device name only if defined */
		if (rContext->device[0] != '\0')
			rv = (*IFDH_create_channel_by_name) (rContext->slot, rContext->device);
		else
			rv = (*IFDH_create_channel) (rContext->slot, rContext->port);
	}
#else
#if defined(IFDHANDLERv2)
	rv = IFDHCreateChannel(rContext->slot, rContext->port);
#else
	{
		/* Use device name only if defined */
		if (rContext->device[0] != '\0')
			rv = IFDHCreateChannelByName(rContext->slot, rContext->device);
		else
			rv = IFDHCreateChannel(rContext->slot, rContext->port);
	}
#endif
#endif

	/* END OF LOCKED REGION */
	(void)pthread_mutex_unlock(rContext->mMutex);

	return rv;
}
예제 #2
0
/**
 * Set the protocol type selection (PTS).
 * This function sets the appropriate protocol to be used on the card.
 */
LONG IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol, UCHAR ucFlags,
	UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
{
	RESPONSECODE rv;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_set_protocol_parameters) (DWORD, DWORD, UCHAR,
		UCHAR, UCHAR, UCHAR) = NULL;

	IFDH_set_protocol_parameters = (RESPONSECODE(*)(DWORD, DWORD, UCHAR,
		UCHAR, UCHAR, UCHAR))
		rContext->psFunctions.psFunctions_v2.pvfSetProtocolParameters;

	if (NULL == IFDH_set_protocol_parameters)
		return SCARD_E_UNSUPPORTED_FEATURE;
#endif

	/*
	 * Locking is done in winscard.c SCardConnect() and SCardReconnect()
	 *
	 * This avoids to renegotiate the protocol and confuse the card
	 * Error returned by CCID driver is: CCID_Receive Procedure byte conflict
	 */

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_set_protocol_parameters) (rContext->slot,
		dwProtocol, ucFlags, ucPTS1, ucPTS2, ucPTS3);
#else
	rv = IFDHSetProtocolParameters(rContext->slot, dwProtocol, ucFlags,
		ucPTS1, ucPTS2, ucPTS3);
#endif

	return rv;
}
예제 #3
0
/**
 * Get's capabilities in the reader.
 * Other functions int this file will call
 * the driver directly to not cause a deadlock.
 */
LONG IFDGetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
	PDWORD pdwLength, PUCHAR pucValue)
{
	RESPONSECODE rv;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, /*@out@*/ PUCHAR) = NULL;

	IFDH_get_capabilities =
		rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
#endif

	/* LOCK THIS CODE REGION */
	(void)pthread_mutex_lock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_get_capabilities) (rContext->slot, dwTag, pdwLength, pucValue);
#else
	rv = IFDHGetCapabilities(rContext->slot, dwTag, pdwLength, pucValue);
#endif

	/* END OF LOCKED REGION */
	(void)pthread_mutex_unlock(rContext->mMutex);

	return rv;
}
예제 #4
0
/**
 * Set capabilities in the reader.
 */
LONG IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
			DWORD dwLength, PUCHAR pucValue)
{
	RESPONSECODE rv;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;

	IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
#endif

	/*
	 * Let the calling function lock this otherwise a deadlock will
	 * result
	 */

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_set_capabilities) (rContext->slot, dwTag,
			dwLength, pucValue);
#else
	rv = IFDHSetCapabilities(rContext->slot, dwTag, dwLength, pucValue);
#endif

	return rv;
}
예제 #5
0
/**
 * Close a communication channel to the IFD.
 */
LONG IFDCloseIFD(PREADER_CONTEXT rContext)
{
	RESPONSECODE rv = IFD_SUCCESS;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IO_close_channel) (void) = NULL;
	RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;

	if (rContext->dwVersion == IFD_HVERSION_1_0)
		IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
	else
		IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
#endif

	/* LOCK THIS CODE REGION */
	(void)SYS_MutexLock(rContext->mMutex);
#ifndef PCSCLITE_STATIC_DRIVER
	if (rContext->dwVersion == IFD_HVERSION_1_0)

		rv = (*IO_close_channel) ();
	else
		rv = (*IFDH_close_channel) (rContext->dwSlot);
#else
	if (rContext->dwVersion == IFD_HVERSION_1_0)
		rv = IO_Close_Channel();
	else
		rv = IFDHCloseChannel(rContext->dwSlot);
#endif

	/* END OF LOCKED REGION */
	(void)SYS_MutexUnLock(rContext->mMutex);

	return rv;
}
예제 #6
0
LONG IFDControl(READER_CONTEXT * rContext, DWORD ControlCode,
	LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
	LPDWORD BytesReturned)
{
	RESPONSECODE rv = IFD_SUCCESS;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
#endif

	if (rContext->version < IFD_HVERSION_3_0)
		return SCARD_E_UNSUPPORTED_FEATURE;

#ifndef PCSCLITE_STATIC_DRIVER
	IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
#endif

	/* LOCK THIS CODE REGION */
	(void)pthread_mutex_lock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_control) (rContext->slot, ControlCode, TxBuffer,
		TxLength, RxBuffer, RxLength, BytesReturned);
#elif defined(IFDHANDLERv3)
	rv = IFDHControl(rContext->slot, ControlCode, TxBuffer,
		TxLength, RxBuffer, RxLength, BytesReturned);
#endif

	/* END OF LOCKED REGION */
	(void)pthread_mutex_unlock(rContext->mMutex);

	if (rv == IFD_SUCCESS)
		return SCARD_S_SUCCESS;
	else
	{
		Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
		Log3(PCSC_LOG_DEBUG, "ControlCode: 0x%.8lX BytesReturned: %ld",
			ControlCode, *BytesReturned);
		LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
		LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *BytesReturned);

		if (rv == IFD_NO_SUCH_DEVICE)
		{
			(void)SendHotplugSignal();
			return SCARD_E_READER_UNAVAILABLE;
		}

		if ((IFD_ERROR_NOT_SUPPORTED == rv) || (IFD_NOT_SUPPORTED == rv))
			return SCARD_E_UNSUPPORTED_FEATURE;

        if (IFD_ERROR_INSUFFICIENT_BUFFER ==rv)
            return SCARD_E_INSUFFICIENT_BUFFER;

		return SCARD_E_NOT_TRANSACTED;
	}
}
예제 #7
0
/**
 * Transmit an APDU to the ICC.
 */
LONG IFDTransmit(READER_CONTEXT * rContext, SCARD_IO_HEADER pioTxPci,
	PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
	PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
{
	RESPONSECODE rv;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
		DWORD, /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
#endif

	/* log the APDU */
	DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);

#ifndef PCSCLITE_STATIC_DRIVER
	IFDH_transmit_to_icc =
		rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
#endif

	/* LOCK THIS CODE REGION */
	(void)pthread_mutex_lock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_transmit_to_icc) (rContext->slot, pioTxPci, (LPBYTE)
		pucTxBuffer, dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
#else
	rv = IFDHTransmitToICC(rContext->slot, pioTxPci,
		(LPBYTE) pucTxBuffer, dwTxLength,
		pucRxBuffer, pdwRxLength, pioRxPci);
#endif

	/* END OF LOCKED REGION */
	(void)pthread_mutex_unlock(rContext->mMutex);

	/* log the returned status word */
	DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);

	if (rv == IFD_SUCCESS)
		return SCARD_S_SUCCESS;
	else
	{
		Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);

		if (rv == IFD_NO_SUCH_DEVICE)
		{
			(void)SendHotplugSignal();
			return SCARD_E_READER_UNAVAILABLE;
		}

		return SCARD_E_NOT_TRANSACTED;
	}
}
예제 #8
0
/**
 * Get's capabilities in the reader.
 * Other functions int this file will call
 * the driver directly to not cause a deadlock.
 */
LONG IFDGetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
	PDWORD pdwLength, PUCHAR pucValue)
{
	RESPONSECODE rv = IFD_SUCCESS;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFD_get_capabilities) (DWORD, /*@out@*/ PUCHAR) = NULL;
	RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, /*@out@*/ PUCHAR) = NULL;

	if (rContext->dwVersion == IFD_HVERSION_1_0)
		IFD_get_capabilities =
			rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
	else
		IFDH_get_capabilities =
			rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
#endif

	/* LOCK THIS CODE REGION */
	(void)SYS_MutexLock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	if (rContext->dwVersion == IFD_HVERSION_1_0)
		rv = (*IFD_get_capabilities) (dwTag, pucValue);
	else
		rv = (*IFDH_get_capabilities) (rContext->dwSlot, dwTag,
			pdwLength, pucValue);
#else
	if (rContext->dwVersion == IFD_HVERSION_1_0)
		rv = IFD_Get_Capabilities(dwTag, pucValue);
	else
		rv = IFDHGetCapabilities(rContext->dwSlot, dwTag, pdwLength,
			pucValue);
#endif

	/* END OF LOCKED REGION */
	(void)SYS_MutexUnLock(rContext->mMutex);

	return rv;
}
예제 #9
0
LONG IFDControl(PREADER_CONTEXT rContext, DWORD ControlCode,
	LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
	LPDWORD BytesReturned)
{
	RESPONSECODE rv = IFD_SUCCESS;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
#endif

	if (rContext->dwVersion < IFD_HVERSION_3_0)
		return SCARD_E_UNSUPPORTED_FEATURE;

#ifndef PCSCLITE_STATIC_DRIVER
	IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
#endif

	/* LOCK THIS CODE REGION */
	(void)SYS_MutexLock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_control) (rContext->dwSlot, ControlCode, TxBuffer,
		TxLength, RxBuffer, RxLength, BytesReturned);
#else
	rv = IFDHControl(rContext->dwSlot, ControlCode, TxBuffer,
		TxLength, RxBuffer, RxLength, BytesReturned);
#endif

	/* END OF LOCKED REGION */
	(void)SYS_MutexUnLock(rContext->mMutex);

	if (rv == IFD_SUCCESS)
		return SCARD_S_SUCCESS;
	else
	{
		Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
		Log3(PCSC_LOG_DEBUG, "ControlCode: 0x%.8LX BytesReturned: %ld",
			ControlCode, *BytesReturned);
		LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
		LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *BytesReturned);

		if (rv == IFD_NO_SUCH_DEVICE)
		{
//			(void)SendHotplugSignal();
			return SCARD_E_READER_UNAVAILABLE;
		}

		return SCARD_E_NOT_TRANSACTED;
	}
}
예제 #10
0
/**
 * Set capabilities in the reader.
 */
LONG IFDSetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
			DWORD dwLength, PUCHAR pucValue)
{
	RESPONSECODE rv = IFD_SUCCESS;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFD_set_capabilities) (DWORD, PUCHAR) = NULL;
	RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;

	if (rContext->dwVersion == IFD_HVERSION_1_0)
		IFD_set_capabilities = rContext->psFunctions.psFunctions_v1.pvfSetCapabilities;
	else
		IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
#endif

	/*
	 * Let the calling function lock this otherwise a deadlock will
	 * result
	 */

#ifndef PCSCLITE_STATIC_DRIVER
	if (rContext->dwVersion == IFD_HVERSION_1_0)
		rv = (*IFD_set_capabilities) (dwTag, pucValue);
	else
		rv = (*IFDH_set_capabilities) (rContext->dwSlot, dwTag,
			dwLength, pucValue);
#else
	if (rContext->dwVersion == IFD_HVERSION_1_0)
		rv = IFD_Set_Capabilities(dwTag, pucValue);
	else
		rv = IFDHSetCapabilities(rContext->dwSlot, dwTag, dwLength,
			pucValue);
#endif

	return rv;
}
예제 #11
0
/**
 * Close a communication channel to the IFD.
 */
LONG IFDCloseIFD(PREADER_CONTEXT rContext)
{
	RESPONSECODE rv = IFD_SUCCESS;
	int repeat;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IO_close_channel) (void) = NULL;
	RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;

	if (rContext->dwVersion == IFD_HVERSION_1_0)
		IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
	else
		IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
#endif

	/* TRY TO LOCK THIS CODE REGION */
	repeat = 5;
again:
	rv = SYS_MutexTryLock(rContext->mMutex);
	if (EBUSY == rv)
	{
		Log1(PCSC_LOG_ERROR, "Locking failed");
		repeat--;
		if (repeat)
		{
			(void)SYS_USleep(100*1000);	/* 100 ms */
			goto again;
		}
	}

#ifndef PCSCLITE_STATIC_DRIVER
	if (rContext->dwVersion == IFD_HVERSION_1_0)

		rv = (*IO_close_channel) ();
	else
		rv = (*IFDH_close_channel) (rContext->dwSlot);
#else
	if (rContext->dwVersion == IFD_HVERSION_1_0)
		rv = IO_Close_Channel();
	else
		rv = IFDHCloseChannel(rContext->dwSlot);
#endif

	/* END OF LOCKED REGION */
	(void)SYS_MutexUnLock(rContext->mMutex);

	return rv;
}
예제 #12
0
/**
 * Provide statistical information about the IFD and ICC including insertions,
 * atr, powering status/etc.
 */
LONG IFDStatusICC(READER_CONTEXT * rContext, PDWORD pdwStatus)
{
	RESPONSECODE rv;
	DWORD dwCardStatus = 0;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;

	IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
#endif

	/* LOCK THIS CODE REGION */
	(void)pthread_mutex_lock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_icc_presence) (rContext->slot);
#else
	rv = IFDHICCPresence(rContext->slot);
#endif

	/* END OF LOCKED REGION */
	(void)pthread_mutex_unlock(rContext->mMutex);

	if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
		dwCardStatus |= SCARD_PRESENT;
	else
		if (rv == IFD_ICC_NOT_PRESENT)
			dwCardStatus |= SCARD_ABSENT;
		else
		{
			Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
			*pdwStatus = SCARD_UNKNOWN;

			if (rv == IFD_NO_SUCH_DEVICE)
			{
				(void)SendHotplugSignal();
				return SCARD_E_READER_UNAVAILABLE;
			}

			return SCARD_E_NOT_TRANSACTED;
		}

	*pdwStatus = dwCardStatus;

	return SCARD_S_SUCCESS;
}
예제 #13
0
LONG IFDControl_v2(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
	DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
{
	RESPONSECODE rv = IFD_SUCCESS;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, /*@out@*/ PUCHAR,
		PDWORD);
#endif

	if (rContext->dwVersion != IFD_HVERSION_2_0)
		return SCARD_E_UNSUPPORTED_FEATURE;

#ifndef PCSCLITE_STATIC_DRIVER
	IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
#endif

	/* LOCK THIS CODE REGION */
	(void)SYS_MutexLock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_control_v2) (rContext->dwSlot, TxBuffer, TxLength,
		RxBuffer, RxLength);
#else
	rv = IFDHControl_v2(rContext->dwSlot, TxBuffer, TxLength,
		RxBuffer, RxLength);
#endif

	/* END OF LOCKED REGION */
	(void)SYS_MutexUnLock(rContext->mMutex);

	if (rv == IFD_SUCCESS)
		return SCARD_S_SUCCESS;
	else
	{
		Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
		LogXxd(PCSC_LOG_DEBUG, "TxBuffer ", TxBuffer, TxLength);
		LogXxd(PCSC_LOG_DEBUG, "RxBuffer ", RxBuffer, *RxLength);
		return SCARD_E_NOT_TRANSACTED;
	}
}
예제 #14
0
/**
 * Close a communication channel to the IFD.
 */
LONG IFDCloseIFD(READER_CONTEXT * rContext)
{
	RESPONSECODE rv;
	int repeat;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;

	IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
#endif

	/* TRY TO LOCK THIS CODE REGION */
	repeat = 5;
again:
	rv = pthread_mutex_trylock(rContext->mMutex);
	if (EBUSY == rv)
	{
		Log1(PCSC_LOG_ERROR, "Locking failed");
		repeat--;
		if (repeat)
		{
			(void)SYS_USleep(100*1000);	/* 100 ms */
			goto again;
		}
	}

#ifndef PCSCLITE_STATIC_DRIVER
	rv = (*IFDH_close_channel) (rContext->slot);
#else
	rv = IFDHCloseChannel(rContext->slot);
#endif

	/* END OF LOCKED REGION */
	(void)pthread_mutex_unlock(rContext->mMutex);

	return rv;
}
예제 #15
0
/**
 * Transmit an APDU to the ICC.
 */
LONG IFDTransmit(PREADER_CONTEXT rContext, SCARD_IO_HEADER pioTxPci,
	PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
	PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
{
	RESPONSECODE rv = IFD_SUCCESS;
	UCHAR ucValue[1] = "\x00";

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFD_transmit_to_icc) (SCARD_IO_HEADER, PUCHAR, DWORD,
		/*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
	RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
		DWORD, /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
#endif

	/* log the APDU */
	DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);

#ifndef PCSCLITE_STATIC_DRIVER
	if (rContext->dwVersion == IFD_HVERSION_1_0)
		IFD_transmit_to_icc =
			rContext->psFunctions.psFunctions_v1.pvfTransmitToICC;
	else
		IFDH_transmit_to_icc =
			rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
#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_transmit_to_icc) (pioTxPci, (LPBYTE) pucTxBuffer,
			dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
	}
	else
		rv = (*IFDH_transmit_to_icc) (rContext->dwSlot, pioTxPci,
			(LPBYTE) pucTxBuffer, dwTxLength,
			pucRxBuffer, pdwRxLength, pioRxPci);
#else
	if (rContext->dwVersion == IFD_HVERSION_1_0)
	{
		ucValue[0] = rContext->dwSlot;
		(void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
		rv = IFD_Transmit_to_ICC(pioTxPci, (LPBYTE) pucTxBuffer,
			dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
	}
	else
		rv = IFDHTransmitToICC(rContext->dwSlot, pioTxPci,
			(LPBYTE) pucTxBuffer, dwTxLength,
			pucRxBuffer, pdwRxLength, pioRxPci);
#endif

	/* END OF LOCKED REGION */
	(void)SYS_MutexUnLock(rContext->mMutex);

	/* log the returned status word */
	DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);

	if (rv == IFD_SUCCESS)
		return SCARD_S_SUCCESS;
	else
	{
		Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);

		if (rv == IFD_NO_SUCH_DEVICE)
		{
	//		(void)SendHotplugSignal();
			return SCARD_E_READER_UNAVAILABLE;
		}

		return SCARD_E_NOT_TRANSACTED;
	}
}
예제 #16
0
/**
 * Set the protocol type selection (PTS).
 * This function sets the appropriate protocol to be used on the card.
 */
LONG IFDSetPTS(PREADER_CONTEXT rContext, DWORD dwProtocol, UCHAR ucFlags,
	UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
{
	RESPONSECODE rv = IFD_SUCCESS;
	UCHAR ucValue[1];

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFD_set_protocol_parameters) (DWORD, UCHAR, UCHAR,
		UCHAR, UCHAR) = NULL;
	RESPONSECODE(*IFDH_set_protocol_parameters) (DWORD, DWORD, UCHAR,
		UCHAR, UCHAR, UCHAR) = NULL;

	if (rContext->dwVersion == IFD_HVERSION_1_0)
	{
		IFD_set_protocol_parameters = (RESPONSECODE(*)(DWORD, UCHAR, UCHAR,
			UCHAR, UCHAR)) rContext->psFunctions.psFunctions_v1.pvfSetProtocolParameters;

		if (NULL == IFD_set_protocol_parameters)
			return SCARD_E_UNSUPPORTED_FEATURE;
	}
	else
	{
		IFDH_set_protocol_parameters = (RESPONSECODE(*)(DWORD, DWORD, UCHAR,
			UCHAR, UCHAR, UCHAR))
			rContext->psFunctions.psFunctions_v2.pvfSetProtocolParameters;

		if (NULL == IFDH_set_protocol_parameters)
			return SCARD_E_UNSUPPORTED_FEATURE;
	}
#endif

	/*
	 * Locking is done in winscard.c SCardConnect() and SCardReconnect()
	 *
	 * This avoids renegotiating the protocol and confusing the card
	 * Error returned by CCID driver is: CCID_Receive Procedure byte conflict
	 */

	ucValue[0] = rContext->dwSlot;

#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_set_protocol_parameters) (dwProtocol,
			ucFlags, ucPTS1, ucPTS2, ucPTS3);
	}
	else
	{
		rv = (*IFDH_set_protocol_parameters) (rContext->dwSlot,
						      dwProtocol,
						      ucFlags, ucPTS1,
						      ucPTS2, ucPTS3);
	}
#else
	if (rContext->dwVersion == IFD_HVERSION_1_0)
	{
	        ucValue[0] = rContext->dwSlot;
	        (void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
		rv = IFD_Set_Protocol_Parameters(dwProtocol, ucFlags, ucPTS1,
			ucPTS2, ucPTS3);
	}
	else
	{
		rv = IFDHSetProtocolParameters(rContext->dwSlot, dwProtocol,
			ucFlags, ucPTS1, ucPTS2, ucPTS3);
	}
#endif

	return rv;
}
예제 #17
0
/**
 * 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;
}
예제 #18
0
/**
 * Provide statistical information about the IFD and ICC including insertions,
 * atr, powering status/etc.
 */
LONG IFDStatusICC(PREADER_CONTEXT rContext, PDWORD pdwStatus,
	const unsigned char *pucAtr, PDWORD pdwAtrLen)
{
	RESPONSECODE rv = IFD_SUCCESS;
	DWORD dwTag = 0, dwCardStatus = 0;
	SMARTCARD_EXTENSION sSmartCard;
	UCHAR ucValue[1] = "\x00";

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IFD_is_icc_present) (void) = NULL;
	RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
	RESPONSECODE(*IFD_get_capabilities) (DWORD, /*@out@*/ PUCHAR) = NULL;

	if (rContext->dwVersion == IFD_HVERSION_1_0)
	{
		IFD_is_icc_present =
			rContext->psFunctions.psFunctions_v1.pvfICCPresence;
		IFD_get_capabilities =
			rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
	}
	else
	{
		IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
		// Defensive measure
		if (!IFDH_icc_presence)
			return SCARD_E_SYSTEM_CANCELLED;
	}
#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_is_icc_present) ();
	}
	else
		rv = (*IFDH_icc_presence) (rContext->dwSlot);
#else
	if (rContext->dwVersion == IFD_HVERSION_1_0)
	{
		ucValue[0] = rContext->dwSlot;
		(void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
		rv = IFD_Is_ICC_Present();
	}
	else
		rv = IFDHICCPresence(rContext->dwSlot);
#endif

	/* END OF LOCKED REGION */
	(void)SYS_MutexUnLock(rContext->mMutex);

	if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
		dwCardStatus |= SCARD_PRESENT;
	else
		if (rv == IFD_ICC_NOT_PRESENT)
			dwCardStatus |= SCARD_ABSENT;
		else
		{
			Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
			*pdwStatus = SCARD_UNKNOWN;

			if (rv == IFD_NO_SUCH_DEVICE)
			{
			//	(void)SendHotplugSignal();
				return SCARD_E_READER_UNAVAILABLE;
			}

			return SCARD_E_NOT_TRANSACTED;
		}

	/*
	 * Now lets get the ATR and process it if IFD Handler version 1.0.
	 * IFD Handler version 2.0 does this immediately after reset/power up
	 * to conserve resources
	 */

	if (rContext->dwVersion == IFD_HVERSION_1_0)
	{
		if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
		{
			short ret;

			dwTag = TAG_IFD_ATR;

			/* LOCK THIS CODE REGION */
			(void)SYS_MutexLock(rContext->mMutex);

			ucValue[0] = rContext->dwSlot;
			(void)IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);

#ifndef PCSCLITE_STATIC_DRIVER
			rv = (*IFD_get_capabilities) (dwTag, (unsigned char *)pucAtr);
#else
			rv = IFD_Get_Capabilities(dwTag, pucAtr);
#endif

			/* END OF LOCKED REGION */
			(void)SYS_MutexUnLock(rContext->mMutex);

			/*
			 * FIX :: This is a temporary way to return the correct size
			 * of the ATR since most of the drivers return MAX_ATR_SIZE
			 */

			ret = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);

			/*
			 * Might be a memory card without an ATR
			 */
			if (ret == 0)
				*pdwAtrLen = 0;
			else
				*pdwAtrLen = sSmartCard.ATR.Length;
		}
		else
		{
			/*
			 * No card is inserted - Atr length is 0
			 */
			*pdwAtrLen = 0;
		}
		/*
		 * End of FIX
		 */
	}

	*pdwStatus = dwCardStatus;

	return SCARD_S_SUCCESS;
}
예제 #19
0
/**
 * 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;
}
예제 #20
0
LONG EHDestroyEventHandler(READER_CONTEXT * rContext)
{
	int rv;
	DWORD dwGetSize;
	UCHAR ucGetData[1];

	if ('\0' == rContext->readerState->readerName[0])
	{
		Log1(PCSC_LOG_INFO, "Thread already stomped.");
		return SCARD_S_SUCCESS;
	}

	/*
	 * Set the thread to 0 to exit thread
	 */
	rContext->hLockId = 0xFFFF;

	Log1(PCSC_LOG_INFO, "Stomping thread.");

	/* kill the "polling" thread */
	dwGetSize = sizeof(ucGetData);
	rv = IFDGetCapabilities(rContext, TAG_IFD_POLLING_THREAD_KILLABLE,
		&dwGetSize, ucGetData);

#ifdef HAVE_PTHREAD_CANCEL
	if ((IFD_SUCCESS == rv) && (1 == dwGetSize) && ucGetData[0])
	{
		Log1(PCSC_LOG_INFO, "Killing polling thread");
		(void)pthread_cancel(rContext->pthThread);
	}
	else
#endif
	{
		/* ask to stop the "polling" thread */
		RESPONSECODE (*fct)(DWORD) = NULL;

		dwGetSize = sizeof(fct);
		rv = IFDGetCapabilities(rContext, TAG_IFD_STOP_POLLING_THREAD,
			&dwGetSize, (PUCHAR)&fct);

		if ((IFD_SUCCESS == rv) && (dwGetSize == sizeof(fct)))
		{
			Log1(PCSC_LOG_INFO, "Request stoping of polling thread");
			fct(rContext->slot);
		}
		else
			Log1(PCSC_LOG_INFO, "Waiting polling thread");
	}

	/* wait for the thread to finish */
	rv = pthread_join(rContext->pthThread, NULL);
	if (rv)
		Log2(PCSC_LOG_ERROR, "pthread_join failed: %s", strerror(rv));

	/* Zero the thread */
	rContext->pthThread = 0;

	Log1(PCSC_LOG_INFO, "Thread stomped.");

	return SCARD_S_SUCCESS;
}
예제 #21
0
/**
 * Open a communication channel to the IFD.
 */
LONG IFDOpenIFD(PREADER_CONTEXT rContext)
{
	RESPONSECODE rv = 0;

#ifndef PCSCLITE_STATIC_DRIVER
	RESPONSECODE(*IO_create_channel) (DWORD) = NULL;
	RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
	RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;

	if (rContext->dwVersion == IFD_HVERSION_1_0)
		IO_create_channel =
			rContext->psFunctions.psFunctions_v1.pvfCreateChannel;
	else
		if (rContext->dwVersion == IFD_HVERSION_2_0)
			IFDH_create_channel =
				rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
		else
		{
			IFDH_create_channel =
				rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
			IFDH_create_channel_by_name =
				rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
		}
#endif

	/* LOCK THIS CODE REGION */
	(void)SYS_MutexLock(rContext->mMutex);

#ifndef PCSCLITE_STATIC_DRIVER
	if (rContext->dwVersion == IFD_HVERSION_1_0)
	{
		rv = (*IO_create_channel) (rContext->dwPort);
	} else if (rContext->dwVersion == IFD_HVERSION_2_0)
	{
		rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
	} else
	{
		/* use device name only if defined */
		if (rContext->lpcDevice[0] != '\0')
			rv = (*IFDH_create_channel_by_name) (rContext->dwSlot, rContext->lpcDevice);
		else
			rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
	}
#else
	if (rContext->dwVersion == IFD_HVERSION_1_0)
	{
		rv = IO_Create_Channel(rContext->dwPort);
	} else if (rContext->dwVersion == IFD_HVERSION_2_0)
	{
		rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
	} else
	{
		/* Use device name only if defined */
		if (rContext->lpcDevice[0] != '\0')
			rv = IFDHCreateChannelByName(rContext->dwSlot, rContext->lpcDevice);
		else
			rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
	}
#endif

	/* END OF LOCKED REGION */
	(void)SYS_MutexUnLock(rContext->mMutex);

	return rv;
}