[Pcsclite-cvs-commit] PCSC/src winscard_svc.c,1.19,1.20 winscard_msg.h,1.8,1.9 winscard_clnt.c,1.30,1.31 winscard.h,1.8,1.9 winscard.c,1.21,1.22 ifdwrapper.h,1.5,1.6 ifdwrapper.c,1.12,1.13

rousseau@haydn.debian.org rousseau@haydn.debian.org


Update of /cvsroot/pcsclite/PCSC/src
In directory haydn:/tmp/cvs-serv4982

Modified Files:
	winscard_svc.c winscard_msg.h winscard_clnt.c winscard.h 
	winscard.c ifdwrapper.h ifdwrapper.c 
Log Message:
add support of the new IFDHControl() API


Index: winscard_svc.c
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/winscard_svc.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- winscard_svc.c	15 Apr 2004 08:43:33 -0000	1.19
+++ winscard_svc.c	16 Apr 2004 15:27:21 -0000	1.20
@@ -190,6 +190,7 @@
 	end_struct *enStr;
 	status_struct *stStr;
 	transmit_struct *trStr;
+	control_struct *ctStr;
 
 	/*
 	 * Zero out everything 
@@ -291,6 +292,16 @@
 			trStr->pbSendBuffer, trStr->cbSendLength,
 			&trStr->pioRecvPci, trStr->pbRecvBuffer,
 			&trStr->pcbRecvLength);
+		break;
+
+	case SCARD_CONTROL:
+		ctStr = ((control_struct *) msgStruct->data);
+		rv = MSGCheckHandleAssociation(ctStr->hCard, dwContextIndex);
+		if (rv != 0) return rv;
+		ctStr->rv = SCardControl(ctStr->hCard, ctStr->dwControlCode,
+			ctStr->pbSendBuffer, ctStr->cbSendLength,
+			ctStr->pbRecvBuffer, ctStr->cbRecvLength,
+			&ctStr->dwBytesReturned);
 		break;
 
 	default:

Index: winscard_msg.h
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/winscard_msg.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- winscard_msg.h	15 Apr 2004 08:43:33 -0000	1.8
+++ winscard_msg.h	16 Apr 2004 15:27:21 -0000	1.9
@@ -175,6 +175,19 @@
 	};
 	typedef struct transmit_struct transmit_struct;
 
+	struct control_struct
+	{
+		SCARDHANDLE hCard;
+		DWORD dwControlCode;
+		UCHAR pbSendBuffer[MAX_BUFFER_SIZE];
+		DWORD cbSendLength;
+		UCHAR pbRecvBuffer[MAX_BUFFER_SIZE];
+		DWORD cbRecvLength;
+		DWORD dwBytesReturned;
+		LONG rv;
+	};
+	typedef struct control_struct control_struct;
+
 	/*
 	 * Now some function definitions 
 	 */

Index: winscard_clnt.c
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/winscard_clnt.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- winscard_clnt.c	15 Apr 2004 08:43:33 -0000	1.30
+++ winscard_clnt.c	16 Apr 2004 15:27:21 -0000	1.31
@@ -1524,16 +1524,108 @@
 	return SCARD_S_SUCCESS;
 }
 
-LONG SCardControl(SCARDHANDLE hCard, LPCBYTE pbSendBuffer,
-	DWORD cbSendLength, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
+LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
+	DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
+	LPDWORD lpBytesReturned)
 {
-	SCARD_IO_REQUEST pioSendPci, pioRecvPci;
+	LONG rv;
+	control_struct scControlStruct;
+	sharedSegmentMsg msgStruct;
+	int i;
+	DWORD dwContextIndex, dwChannelIndex;
 
-	pioSendPci.dwProtocol = SCARD_PROTOCOL_RAW;
-	pioRecvPci.dwProtocol = SCARD_PROTOCOL_RAW;
+	/*
+	 * Zero out everything
+	 */
+	rv = 0;
+	i = 0;
 
-	return SCardTransmit(hCard, &pioSendPci, pbSendBuffer, cbSendLength,
-		&pioRecvPci, pbRecvBuffer, pcbRecvLength);
+	/* 0 bytes received by default */
+	if (NULL != lpBytesReturned)
+		*lpBytesReturned = 0;
+
+	if (pbSendBuffer == 0)
+		return SCARD_E_INVALID_PARAMETER;
+
+	if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+		return SCARD_E_NO_SERVICE;
+
+	/*
+	 * Make sure this handle has been opened
+	 */
+	rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+	if (rv == -1)
+		return SCARD_E_INVALID_HANDLE;
+
+	SYS_MutexLock(psContextMap[dwContextIndex].mMutex);	
+
+	for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+	{
+		char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+
+		/* by default r == NULL */
+		if (r && strcmp(r, (readerStates[i])->readerName) == 0)
+			break;
+	}
+
+	if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+	{
+		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+		return SCARD_E_READER_UNAVAILABLE;
+	}
+
+	if (cbSendLength > MAX_BUFFER_SIZE)
+	{
+		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+		return SCARD_E_INSUFFICIENT_BUFFER;
+	}
+
+	scControlStruct.hCard = hCard;
+	scControlStruct.dwControlCode = dwControlCode;
+	scControlStruct.cbSendLength = cbSendLength;
+	scControlStruct.cbRecvLength = cbRecvLength;
+	memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
+
+	rv = WrapSHMWrite(SCARD_CONTROL, psContextMap[dwContextIndex].dwClientID,
+		sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
+
+	if (rv == -1)
+	{
+		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+		return SCARD_E_NO_SERVICE;
+	}
+
+	/*
+	 * Read a message from the server
+	 */
+	rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
+
+	if (rv == -1)
+	{
+		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+		return SCARD_F_COMM_ERROR;
+	}
+
+	memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
+
+	if (NULL != lpBytesReturned)
+		*lpBytesReturned = scControlStruct.dwBytesReturned;
+
+	if (scControlStruct.rv == SCARD_S_SUCCESS)
+	{
+		/*
+		 * Copy and zero it so any secret information is not leaked
+		 */
+		memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
+			scControlStruct.cbRecvLength);
+		memset(scControlStruct.pbRecvBuffer, 0x00,
+			sizeof(scControlStruct.pbRecvBuffer));
+	}
+
+	SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+		
+	return scControlStruct.rv;
 }
 
 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,

Index: winscard.h
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/winscard.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- winscard.h	31 Mar 2004 09:42:01 -0000	1.8
+++ winscard.h	16 Apr 2004 15:27:21 -0000	1.9
@@ -60,9 +60,9 @@
 		DWORD dwTimeout,
 		LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders);
 
-	LONG SCardControl(SCARDHANDLE hCard,
-		LPCBYTE pbSendBuffer, DWORD cbSendLength,
-		LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
+	LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
+		LPCVOID pbSendBuffer, DWORD cbSendLength,
+		LPVOID pbRecvBuffer, DWORD cbRecvLength, DWORD *lpBytesReturned);
 
 	LONG SCardTransmit(SCARDHANDLE hCard,
 		LPCSCARD_IO_REQUEST pioSendPci,

Index: winscard.c
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/winscard.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- winscard.c	6 Apr 2004 06:56:22 -0000	1.21
+++ winscard.c	16 Apr 2004 15:27:21 -0000	1.22
@@ -724,7 +724,7 @@
 		controlBuffer[3] = 0x00;
 		controlBuffer[4] = 0x00;
 		receiveLength = 2;
-		rv = IFDControl(rContext, controlBuffer, 5, receiveBuffer,
+		rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
 			&receiveLength);
 
 		if (rv == SCARD_S_SUCCESS)
@@ -950,7 +950,7 @@
 		controlBuffer[3] = 0x00;
 		controlBuffer[4] = 0x00;
 		receiveLength = 2;
-		rv = IFDControl(rContext, controlBuffer, 5, receiveBuffer,
+		rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer,
 			&receiveLength);
 
 		if (rv == SCARD_S_SUCCESS)
@@ -1156,15 +1156,60 @@
 	return SCARD_S_SUCCESS;
 }
 
-LONG SCardControl(SCARDHANDLE hCard, LPCBYTE pbSendBuffer,
-	DWORD cbSendLength, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
+LONG SCardControl(SCARDHANDLE hCard, DWORD dwControlCode,
+	LPCVOID pbSendBuffer, DWORD cbSendLength,
+	LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned)
 {
+	LONG rv;
+	PREADER_CONTEXT rContext;
+
 	/*
-	 * This is not used.  SCardControl is passed through SCardTransmit.
-	 * This is here to make the compiler happy. 
+	 * Zero out everything 
 	 */
+	rv = 0;
+	rContext = 0;
 
-	return SCARD_S_SUCCESS;
+	/* 0 bytes returned by default */
+	*lpBytesReturned = 0;
+
+	if (0 == hCard)
+		return SCARD_E_INVALID_HANDLE;
+
+	if (NULL == pbSendBuffer || 0 == cbSendLength)
+		return SCARD_E_INVALID_PARAMETER;
+
+	/*
+	 * Make sure no one has a lock on this reader 
+	 */
+	if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
+		return rv;
+
+	rv = RFReaderInfoById(hCard, &rContext);
+	if (rv != SCARD_S_SUCCESS)
+		return rv;
+
+	/*
+	 * Make sure the reader is working properly 
+	 */
+	rv = RFCheckReaderStatus(rContext);
+	if (rv != SCARD_S_SUCCESS)
+		return rv;
+
+	rv = RFFindReaderHandle(hCard);
+	if (rv != SCARD_S_SUCCESS)
+		return rv;
+
+	/*
+	 * Make sure some event has not occurred 
+	 */
+	if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+		return rv;
+
+	if (cbSendLength > MAX_BUFFER_SIZE)
+		return SCARD_E_INSUFFICIENT_BUFFER;
+
+	return IFDControl(rContext, dwControlCode, pbSendBuffer, cbSendLength,
+			pbRecvBuffer, cbRecvLength, lpBytesReturned);
 }
 
 LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
@@ -1305,7 +1350,7 @@
 
 	if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
 	{
-		rv = IFDControl(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
+		rv = IFDControl_v2(rContext, (PUCHAR) pbSendBuffer, cbSendLength,
 			pbRecvBuffer, &dwRxLength);
 	} else
 	{

Index: ifdwrapper.h
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/ifdwrapper.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- ifdwrapper.h	16 Jan 2004 11:30:54 -0000	1.5
+++ ifdwrapper.h	16 Apr 2004 15:27:21 -0000	1.6
@@ -22,7 +22,9 @@
 	LONG IFDCloseIFD(PREADER_CONTEXT);
 	LONG IFDPowerICC(PREADER_CONTEXT, DWORD, PUCHAR, PDWORD);
 	LONG IFDStatusICC(PREADER_CONTEXT, PDWORD, PDWORD, PUCHAR, PDWORD);
-	LONG IFDControl(PREADER_CONTEXT, PUCHAR, DWORD, PUCHAR, PDWORD);
+	LONG IFDControl_v2(PREADER_CONTEXT, PUCHAR, DWORD, PUCHAR, PDWORD);
+	LONG IFDControl(PREADER_CONTEXT, DWORD, LPCVOID, DWORD, LPCVOID,
+		DWORD, LPDWORD);
 	LONG IFDTransmit(PREADER_CONTEXT, SCARD_IO_HEADER,
 		PUCHAR, DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER);
 	LONG IFDSetPTS(PREADER_CONTEXT, DWORD, UCHAR, UCHAR, UCHAR, UCHAR);

Index: ifdwrapper.c
===================================================================
RCS file: /cvsroot/pcsclite/PCSC/src/ifdwrapper.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- ifdwrapper.c	15 Apr 2004 09:53:58 -0000	1.12
+++ ifdwrapper.c	16 Apr 2004 15:27:21 -0000	1.13
@@ -6,6 +6,7 @@
  * Copyright (C) 1999-2004
  *  David Corcoran <corcoran@linuxnet.com>
  *  Damien Sauveron <damien.sauveron@labri.fr>
+ *  Ludovic Rousseau <ludovic.rousseau@free.fr>
  *
  * $Id$
  */
@@ -21,6 +22,8 @@
 #include "sys_generic.h"
 #include "debuglog.h"
 
+#undef PCSCLITE_STATIC_DRIVER
+
 /*
  * Function: IFDSetPTS Purpose : To set the protocol type selection (PTS). 
  * This function sets the appropriate protocol to be used on the card. 
@@ -479,7 +482,7 @@
 		rv = IFD_Power_ICC(dwAction);
 	}
 	else
-		rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, dwAtrLen);
+		rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, pdwAtrLen);
 #endif
 	SYS_MutexUnLock(rContext->mMutex);
 
@@ -660,7 +663,11 @@
  * biometric. 
  */
 
-LONG IFDControl(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
+/*
+ * Valid only for IFDHandler version 2.0
+ */
+
+LONG IFDControl_v2(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
 	DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
 {
 	RESPONSECODE rv;
@@ -668,7 +675,7 @@
 	UCHAR ucValue[1];
 
 #ifndef PCSCLITE_STATIC_DRIVER
-	RESPONSECODE(*IFDH_control) (DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
+	RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
 #endif
 
 	/*
@@ -687,7 +694,7 @@
 	if (vFunction == 0)
 		return SCARD_E_UNSUPPORTED_FEATURE;
 
-	IFDH_control = (RESPONSECODE(*)(DWORD, PUCHAR, DWORD,
+	IFDH_control_v2 = (RESPONSECODE(*)(DWORD, PUCHAR, DWORD,
 			PUCHAR, PDWORD)) vFunction;
 #endif
 
@@ -698,17 +705,90 @@
 	SYS_MutexLock(rContext->mMutex);
 
 #ifndef PCSCLITE_STATIC_DRIVER
-	if (rContext->dwVersion == IFD_HVERSION_1_0)
+	if (rContext->dwVersion != IFD_HVERSION_1_0)
 		return SCARD_E_UNSUPPORTED_FEATURE;
 	else
-		rv = (*IFDH_control) (rContext->dwSlot, TxBuffer, TxLength,
+		rv = (*IFDH_control_v2) (rContext->dwSlot, TxBuffer, TxLength,
 			RxBuffer, RxLength);
 #else
-	if (rContext->dwVersion == IFD_HVERSION_1_0)
+	if (rContext->dwVersion != IFD_HVERSION_1_0)
 		rv = SCARD_E_UNSUPPORTED_FEATURE;
 	else
-		rv = IFDHControl(rContext->dwSlot, TxBuffer, TxLength,
+		rv = IFDHControl_v2(rContext->dwSlot, TxBuffer, TxLength,
 			RxBuffer, RxLength);
+#endif
+	SYS_MutexUnLock(rContext->mMutex);
+
+	/*
+	 * END OF LOCKED REGION 
+	 */
+
+	if (rv == IFD_SUCCESS)
+		return SCARD_S_SUCCESS;
+	else
+		return SCARD_E_NOT_TRANSACTED;
+}
+
+/*
+ * Function: IFDControl Purpose : This function provides a means for
+ * toggling a specific action on the reader such as swallow, eject,
+ * biometric. 
+ */
+
+/*
+ * Valid only for IFDHandler version 3.0 and up
+ */
+
+LONG IFDControl(PREADER_CONTEXT rContext, DWORD ControlCode,
+	LPCVOID TxBuffer, DWORD TxLength, LPCVOID RxBuffer, DWORD RxLength,
+	LPDWORD BytesReturned)
+{
+	RESPONSECODE rv;
+	LPVOID vFunction;
+	UCHAR ucValue[1];
+
+#ifndef PCSCLITE_STATIC_DRIVER
+	RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPCVOID, DWORD, LPDWORD);
+#endif
+
+	/*
+	 * Zero out everything 
+	 */
+	rv = 0;
+	vFunction = 0;
+	ucValue[0] = 0;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+	/*
+	 * Make sure the symbol exists in the driver 
+	 */
+	vFunction = rContext->psFunctions.pvfControl;
+
+	if (vFunction == NULL)
+		return SCARD_E_UNSUPPORTED_FEATURE;
+
+	IFDH_control = (RESPONSECODE(*)(DWORD, DWORD, LPCVOID, DWORD,
+			LPVOID, DWORD, LPDWORD)) vFunction;
+#endif
+
+	/*
+	 * LOCK THIS CODE REGION 
+	 */
+
+	SYS_MutexLock(rContext->mMutex);
+
+#ifndef PCSCLITE_STATIC_DRIVER
+	if (rContext->dwVersion < IFD_HVERSION_3_0)
+		return SCARD_E_UNSUPPORTED_FEATURE;
+	else
+		rv = (*IFDH_control) (rContext->dwSlot, ControlCode, TxBuffer,
+			TxLength, RxBuffer, RxLength, BytesReturned);
+#else
+	if (rContext->dwVersion < IFD_HVERSION_3_0)
+		rv = SCARD_E_UNSUPPORTED_FEATURE;
+	else
+		rv = IFDHControl(rContext->dwSlot, ControlCode, TxBuffer,
+			TxLength, RxBuffer, RxLength, BytesReturned);
 #endif
 	SYS_MutexUnLock(rContext->mMutex);