Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
		}

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

		return SCARD_E_NOT_TRANSACTED;
	}
}
Exemplo n.º 3
0
static LONG HPRemoveHotPluggable(int reader_index)
{
	SYS_MutexLock(&usbNotifierMutex);

	Log3(PCSC_LOG_INFO, "Removing USB device[%d]: %s", reader_index,
		readerTracker[reader_index].bus_device);

	RFRemoveReader(readerTracker[reader_index].fullName,
		PCSCLITE_HP_BASE_PORT + reader_index);
	free(readerTracker[reader_index].fullName);
	readerTracker[reader_index].status = READER_ABSENT;
	readerTracker[reader_index].bus_device[0] = '\0';
	readerTracker[reader_index].fullName = NULL;

	SYS_MutexUnLock(&usbNotifierMutex);

	return 1;
}	/* End of function */
Exemplo n.º 4
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;
	}
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
static LONG HPAddHotPluggable(struct usb_device *dev, const char bus_device[],
	struct _driverTracker *driver)
{
	int i;
	char deviceName[MAX_DEVICENAME];

	Log2(PCSC_LOG_INFO, "Adding USB device: %s", bus_device);

	snprintf(deviceName, sizeof(deviceName), "usb:%04x/%04x:libusb:%s",
		dev->descriptor.idVendor, dev->descriptor.idProduct, bus_device);
	deviceName[sizeof(deviceName) -1] = '\0';

	SYS_MutexLock(&usbNotifierMutex);

	/* find a free entry */
	for (i=0; i<PCSCLITE_MAX_READERS_CONTEXTS; i++)
	{
		if (readerTracker[i].fullName == NULL)
			break;
	}

	if (i==PCSCLITE_MAX_READERS_CONTEXTS)
	{
		Log2(PCSC_LOG_ERROR,
			"Not enough reader entries. Already found %d readers", i);
		SYS_MutexUnLock(&usbNotifierMutex);
		return 0;
	}

	strncpy(readerTracker[i].bus_device, bus_device,
		sizeof(readerTracker[i].bus_device));
	readerTracker[i].bus_device[sizeof(readerTracker[i].bus_device) - 1] = '\0';

#ifdef ADD_SERIAL_NUMBER
	if (dev->descriptor.iSerialNumber)
	{
		usb_dev_handle *device;
		char serialNumber[MAX_READERNAME];
		char fullname[MAX_READERNAME];
		int ret;

		device = usb_open(dev);
		ret = usb_get_string_simple(device, dev->descriptor.iSerialNumber,
			serialNumber, MAX_READERNAME);
		usb_close(device);

		if (ret < 0)
		{
			Log2(PCSC_LOG_ERROR, "usb_get_string_simple failed: %s",
				usb_strerror());
			readerTracker[i].fullName = strdup(driver->readerName);
		}
		else
		{
			snprintf(fullname, sizeof(fullname), "%s (%s)",
				driver->readerName, serialNumber);
			readerTracker[i].fullName = strdup(fullname);
		}
	}
	else
#endif
		readerTracker[i].fullName = strdup(driver->readerName);

	if (RFAddReader(readerTracker[i].fullName, PCSCLITE_HP_BASE_PORT + i,
		driver->libraryPath, deviceName) == SCARD_S_SUCCESS)
		readerTracker[i].status = READER_PRESENT;
	else
	{
		readerTracker[i].status = READER_FAILED;

		(void)CheckForOpenCT();
	}

	SYS_MutexUnLock(&usbNotifierMutex);

	return 1;
}	/* End of function */
Exemplo n.º 7
0
static void HPEstablishUSBNotifications(void)
{

	int i, j, usbDeviceStatus;
	DIR *dir, *dirB;
	struct dirent *entry, *entryB;
	int deviceNumber;
	int suspectDeviceNumber;
	char dirpath[FILENAME_MAX];
	char filename[FILENAME_MAX];
	int fd, ret;
	struct usb_device_descriptor usbDescriptor;

	usbDeviceStatus = 0;
	suspectDeviceNumber = 0;

	while (1)
	{
		for (i = 0; i < bundleSize; i++)
		{
			usbDeviceStatus     = 0;
			suspectDeviceNumber = 0;

			for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
				/* clear rollcall */
				bundleTracker[i].deviceNumber[j].status = 0;

			dir = NULL;
			dir = opendir(PCSCLITE_USB_PATH);
			if (dir == NULL)
			{
				Log1(PCSC_LOG_ERROR,
					"Cannot open USB path directory: " PCSCLITE_USB_PATH);
				return;
			}

			entry = NULL;
			while ((entry = readdir(dir)) != 0)
			{

				/*
				 * Skip anything starting with a
				 */
				if (entry->d_name[0] == '.')
					continue;
				if (!strchr("0123456789",
						entry->d_name[strlen(entry->d_name) - 1]))
				{
					continue;
				}

				sprintf(dirpath, "%s/%s", PCSCLITE_USB_PATH, entry->d_name);

				dirB = opendir(dirpath);

				if (dirB == NULL)
				{
					Log2(PCSC_LOG_ERROR,
						"USB path seems to have disappeared %s", dirpath);
					closedir(dir);
					return;
				}

				while ((entryB = readdir(dirB)) != NULL)
				{
					/*
					 * Skip anything starting with a
					 */
					if (entryB->d_name[0] == '.')
						continue;

					/* Get the device number so we can distinguish
					   multiple readers */
					sprintf(filename, "%s/%s", dirpath, entryB->d_name);
					sscanf(entryB->d_name, "%d", &deviceNumber);

					fd = open(filename, O_RDONLY);
					if (fd < 0)
						continue;

					ret = read(fd, (void *) &usbDescriptor,
						sizeof(usbDescriptor));

					close(fd);

					if (ret < 0)
						continue;

					/*
					 * Device is found and we don't know about it
					 */

					if (usbDescriptor.idVendor == bundleTracker[i].manuID &&
						usbDescriptor.idProduct == bundleTracker[i].productID &&
						usbDescriptor.idVendor !=0 &&
						usbDescriptor.idProduct != 0)
					{
						for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
						{
							if (bundleTracker[i].deviceNumber[j].id == deviceNumber &&
								bundleTracker[i].deviceNumber[j].id != 0)
							{
								bundleTracker[i].deviceNumber[j].status = 1; /* i'm here */
								break;
							}
						}

						if (j == PCSCLITE_MAX_READERS_CONTEXTS)
						{
							usbDeviceStatus = 1;
							suspectDeviceNumber = deviceNumber;
						}
					}

				} /* End of while */

				closedir(dirB);

			} /* End of while */


			if (usbDeviceStatus == 1)
			{
				SYS_MutexLock(&usbNotifierMutex);

				for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
				{
					if (bundleTracker[i].deviceNumber[j].id == 0)
						break;
				}

				if (j == PCSCLITE_MAX_READERS_CONTEXTS)
					Log1(PCSC_LOG_ERROR,
						"Too many identical readers plugged in");
				else
				{
					HPAddHotPluggable(i, j+1);
					bundleTracker[i].deviceNumber[j].id = suspectDeviceNumber;
				}

				SYS_MutexUnLock(&usbNotifierMutex);
			}
			else
				if (usbDeviceStatus == 0)
				{

					for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
					{
						if (bundleTracker[i].deviceNumber[j].id != 0 &&
							bundleTracker[i].deviceNumber[j].status == 0)
						{
							SYS_MutexLock(&usbNotifierMutex);
							HPRemoveHotPluggable(i, j+1);
							bundleTracker[i].deviceNumber[j].id = 0;
							SYS_MutexUnLock(&usbNotifierMutex);
						}
					}
				}
				else
				{
					/*
					 * Do nothing - no USB devices found
					 */
				}

			if (dir)
				closedir(dir);

		}	/* End of for..loop */

		SYS_Sleep(1);
		if (AraKiriHotPlug)
		{
			int retval;

			Log1(PCSC_LOG_INFO, "Hotplug stopped");
			pthread_exit(&retval);
		}

	}	/* End of while loop */
}
Exemplo n.º 8
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;
	}
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
LONG SCardConnect(/*@unused@*/ SCARDCONTEXT hContext, LPCSTR szReader,
	DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
	LPDWORD pdwActiveProtocol)
{
	LONG rv;
	PREADER_CONTEXT rContext = NULL;
	DWORD dwStatus;

	(void)hContext;
	PROFILE_START

	/*
	 * Check for NULL parameters
	 */
	if (szReader == NULL || phCard == NULL || pdwActiveProtocol == NULL)
		return SCARD_E_INVALID_PARAMETER;
	else
		*phCard = 0;

	if ((dwShareMode != SCARD_SHARE_DIRECT) &&
			!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
			!(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
			!(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
			!(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
		return SCARD_E_PROTO_MISMATCH;

	if (dwShareMode != SCARD_SHARE_EXCLUSIVE &&
			dwShareMode != SCARD_SHARE_SHARED &&
			dwShareMode != SCARD_SHARE_DIRECT)
		return SCARD_E_INVALID_VALUE;

	Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %d",
		szReader, dwPreferredProtocols);

	rv = RFReaderInfo((LPSTR) szReader, &rContext);

	if (rv != SCARD_S_SUCCESS)
	{
		Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader);
		return rv;
	}

	/*
	 * Make sure the reader is working properly
	 */
	rv = RFCheckReaderStatus(rContext);
	if (rv != SCARD_S_SUCCESS)
		return rv;

	/*******************************************
	 *
	 * This section checks for simple errors
	 *
	 *******************************************/

	/*
	 * Connect if not exclusive mode
	 */
	if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
	{
		Log1(PCSC_LOG_ERROR, "Error Reader Exclusive");
		return SCARD_E_SHARING_VIOLATION;
	}

	/*
	 * wait until a possible transaction is finished
	 */
	if (rContext->dwLockId != 0)
	{
		Log1(PCSC_LOG_INFO, "Waiting for release of lock");
		while (rContext->dwLockId != 0)
			(void)SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
		Log1(PCSC_LOG_INFO, "Lock released");
	}

	/* the reader has been removed while we were waiting */
	if (NULL == rContext->readerState)
		return SCARD_E_NO_SMARTCARD;

	/*******************************************
	 *
	 * This section tries to determine the
	 * presence of a card or not
	 *
	 *******************************************/
	dwStatus = rContext->readerState->readerState;

	if (dwShareMode != SCARD_SHARE_DIRECT)
	{
		if (!(dwStatus & SCARD_PRESENT))
		{
			Log1(PCSC_LOG_ERROR, "Card Not Inserted");
			return SCARD_E_NO_SMARTCARD;
		}

		if (dwStatus & SCARD_SWALLOWED)
		{
			Log1(PCSC_LOG_ERROR, "Card Not Powered");
			return SCARD_W_UNPOWERED_CARD;
		}
	}


	/*******************************************
	 *
	 * This section tries to decode the ATR
	 * and set up which protocol to use
	 *
	 *******************************************/
	if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
		rContext->readerState->cardProtocol = SCARD_PROTOCOL_RAW;
	else
	{
		if (dwShareMode != SCARD_SHARE_DIRECT)
		{
			/* lock here instead in IFDSetPTS() to lock up to
			 * setting rContext->readerState->cardProtocol */
			(void)SYS_MutexLock(rContext->mMutex);

			/* the protocol is not yet set (no PPS yet) */
			if (SCARD_PROTOCOL_UNDEFINED == rContext->readerState->cardProtocol)
			{
				UCHAR ucAvailable, ucDefault;
				int ret;

				ucDefault = PHGetDefaultProtocol(rContext->readerState->cardAtr,
					rContext->readerState->cardAtrLength);
				ucAvailable =
					PHGetAvailableProtocols(rContext->readerState->cardAtr,
							rContext->readerState->cardAtrLength);

				/*
				 * If it is set to ANY let it do any of the protocols
				 */
				if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
					dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;

				ret = PHSetProtocol(rContext, dwPreferredProtocols,
					ucAvailable, ucDefault);

				/* keep cardProtocol = SCARD_PROTOCOL_UNDEFINED in case of error  */
				if (SET_PROTOCOL_PPS_FAILED == ret)
				{
					(void)SYS_MutexUnLock(rContext->mMutex);
					return SCARD_W_UNRESPONSIVE_CARD;
				}

				if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
				{
					(void)SYS_MutexUnLock(rContext->mMutex);
					return SCARD_E_PROTO_MISMATCH;
				}

				/* use negotiated protocol */
				rContext->readerState->cardProtocol = ret;

				(void)SYS_MutexUnLock(rContext->mMutex);
			}
			else
			{
				(void)SYS_MutexUnLock(rContext->mMutex);

				if (! (dwPreferredProtocols & rContext->readerState->cardProtocol))
					return SCARD_E_PROTO_MISMATCH;
			}
		}
		else
			rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
	}

	*pdwActiveProtocol = rContext->readerState->cardProtocol;

	if (dwShareMode != SCARD_SHARE_DIRECT)
	{
		if ((*pdwActiveProtocol != SCARD_PROTOCOL_T0)
			&& (*pdwActiveProtocol != SCARD_PROTOCOL_T1))
			Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %d",
				*pdwActiveProtocol);
		else
			Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
				(*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
	}
	else
		Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");

	/*
	 * Prepare the SCARDHANDLE identity
	 */
	*phCard = RFCreateReaderHandle(rContext);

	Log2(PCSC_LOG_DEBUG, "hCard Identity: %x", *phCard);

	/*******************************************
	 *
	 * This section tries to set up the
	 * exclusivity modes. -1 is exclusive
	 *
	 *******************************************/

	if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
	{
		if (rContext->dwContexts == SCARD_NO_CONTEXT)
		{
			rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT;
			(void)RFLockSharing(*phCard);
		}
		else
		{
			(void)RFDestroyReaderHandle(*phCard);
			*phCard = 0;
			return SCARD_E_SHARING_VIOLATION;
		}
	}
	else
	{
		/*
		 * Add a connection to the context stack
		 */
		rContext->dwContexts += 1;
	}

	/*
	 * Add this handle to the handle list
	 */
	rv = RFAddReaderHandle(rContext, *phCard);

	if (rv != SCARD_S_SUCCESS)
	{
		/*
		 * Clean up - there is no more room
		 */
		(void)RFDestroyReaderHandle(*phCard);
		if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
			rContext->dwContexts = SCARD_NO_CONTEXT;
		else
			if (rContext->dwContexts > SCARD_NO_CONTEXT)
				rContext->dwContexts -= 1;

		*phCard = 0;

		PROFILE_END

		return SCARD_F_INTERNAL_ERROR;
	}