[Pcsclite-cvs-commit] r2250 - trunk/PCSC/src

Ludovic Rousseau rousseau at alioth.debian.org
Thu Nov 30 23:26:35 CET 2006


Author: rousseau
Date: 2006-11-30 23:26:35 +0100 (Thu, 30 Nov 2006)
New Revision: 2250

Modified:
   trunk/PCSC/src/winscard_clnt.c
   trunk/PCSC/src/winscard_msg.c
   trunk/PCSC/src/winscard_msg.h
   trunk/PCSC/src/winscard_svc.c
Log:
add support of "extended" SCardControl()


Modified: trunk/PCSC/src/winscard_clnt.c
===================================================================
--- trunk/PCSC/src/winscard_clnt.c	2006-11-30 20:54:22 UTC (rev 2249)
+++ trunk/PCSC/src/winscard_clnt.c	2006-11-30 22:26:35 UTC (rev 2250)
@@ -2193,59 +2193,134 @@
 		return SCARD_E_READER_UNAVAILABLE;
 	}
 
-	if (cbSendLength > MAX_BUFFER_SIZE)
+	if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
+		|| (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
 	{
 		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);
+	if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
+	{
+		/* extended control */
+		unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
+		control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
+		sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
 
-	rv = WrapSHMWrite(SCARD_CONTROL, psContextMap[dwContextIndex].dwClientID,
-		sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
+		scControlStructExtended->hCard = hCard;
+		scControlStructExtended->dwControlCode = dwControlCode;
+		scControlStructExtended->cbSendLength = cbSendLength;
+		scControlStructExtended->cbRecvLength = cbRecvLength;
+		scControlStructExtended->size = sizeof(*scControlStructExtended) + cbSendLength;
+		memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
 
-	if (rv == -1)
-	{
-		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
-		return SCARD_E_NO_SERVICE;
-	}
+		rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
+			psContextMap[dwContextIndex].dwClientID,
+			scControlStructExtended->size,
+			PCSCLITE_CLIENT_ATTEMPTS, buffer);
 
-	/*
-	 * 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_E_NO_SERVICE;
+		}
 
-	if (rv == -1)
+		/*
+		 * Read a message from the server
+		 */
+		/* read the first block */
+		rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
+		if (rv == -1)
+		{
+			SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+			return SCARD_F_COMM_ERROR;
+		}
+
+		/* we receive a sharedSegmentMsg and not a control_struct_extended */
+		scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
+
+		/* a second block is present */
+		if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
+		{
+			rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
+				scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
+				psContextMap[dwContextIndex].dwClientID,
+				PCSCLITE_CLIENT_ATTEMPTS);
+			if (rv == -1)
+			{
+				SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+				return SCARD_F_COMM_ERROR;
+			}
+		}
+
+		if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
+		{
+			/*
+			 * Copy and zero it so any secret information is not leaked
+			 */
+			memcpy(pbRecvBuffer, scControlStructExtended -> data,
+				scControlStructExtended -> pdwBytesReturned);
+			memset(scControlStructExtended -> data, 0x00,
+				scControlStructExtended -> pdwBytesReturned);
+		}
+
+		if (NULL != lpBytesReturned)
+			*lpBytesReturned = scControlStructExtended -> pdwBytesReturned;
+
+		rv = scControlStructExtended -> rv;
+	}
+	else
 	{
-		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
-		return SCARD_F_COMM_ERROR;
-	}
+		scControlStruct.hCard = hCard;
+		scControlStruct.dwControlCode = dwControlCode;
+		scControlStruct.cbSendLength = cbSendLength;
+		scControlStruct.cbRecvLength = cbRecvLength;
+		memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
 
-	memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
+		rv = WrapSHMWrite(SCARD_CONTROL, psContextMap[dwContextIndex].dwClientID,
+			sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
 
-	if (NULL != lpBytesReturned)
-		*lpBytesReturned = scControlStruct.dwBytesReturned;
+		if (rv == -1)
+		{
+			SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+			return SCARD_E_NO_SERVICE;
+		}
 
-	if (scControlStruct.rv == SCARD_S_SUCCESS)
-	{
 		/*
-		 * Copy and zero it so any secret information is not leaked
+		 * Read a message from the server
 		 */
-		memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
-			scControlStruct.cbRecvLength);
-		memset(scControlStruct.pbRecvBuffer, 0x00,
-			sizeof(scControlStruct.pbRecvBuffer));
+		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));
+		}
+
+		rv = scControlStruct.rv;
 	}
 
 	SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
 
 	PROFILE_END
 
-	return scControlStruct.rv;
+	return rv;
 }
 
 /**

Modified: trunk/PCSC/src/winscard_msg.c
===================================================================
--- trunk/PCSC/src/winscard_msg.c	2006-11-30 20:54:22 UTC (rev 2249)
+++ trunk/PCSC/src/winscard_msg.c	2006-11-30 22:26:35 UTC (rev 2250)
@@ -407,7 +407,8 @@
 	msgStruct.group_id = SYS_GetGID();
 	msgStruct.command = command;
 	msgStruct.date = time(NULL);
-	if (SCARD_TRANSMIT_EXTENDED == command)
+	if ((SCARD_TRANSMIT_EXTENDED == command)
+		|| (SCARD_CONTROL_EXTENDED == command))
 	{
 		/* first block */
 		memcpy(msgStruct.data, data, PCSCLITE_MAX_MESSAGE_SIZE);

Modified: trunk/PCSC/src/winscard_msg.h
===================================================================
--- trunk/PCSC/src/winscard_msg.h	2006-11-30 20:54:22 UTC (rev 2249)
+++ trunk/PCSC/src/winscard_msg.h	2006-11-30 22:26:35 UTC (rev 2250)
@@ -21,7 +21,7 @@
 /** Major version of the current message protocol */
 #define PROTOCOL_VERSION_MAJOR 2
 /** Minor version of the current message protocol */
-#define PROTOCOL_VERSION_MINOR 1
+#define PROTOCOL_VERSION_MINOR 2
 
 #ifdef __cplusplus
 extern "C"
@@ -88,7 +88,8 @@
 		SCARD_CANCEL_TRANSACTION = 0x0E,
 		SCARD_GET_ATTRIB = 0x0F,
 		SCARD_SET_ATTRIB = 0x10,
-		SCARD_TRANSMIT_EXTENDED = 0x11
+		SCARD_TRANSMIT_EXTENDED = 0x11,
+		SCARD_CONTROL_EXTENDED = 0x12
 	};
 
 	/**
@@ -289,6 +290,24 @@
 	typedef struct control_struct control_struct;
 
 	/**
+	 * @brief contained in \c SCARD_CONTROL_EXTENDED Messages.
+	 *
+	 * These data are passed throw the field \c sharedSegmentMsg.data.
+	 */
+	struct control_struct_extended
+	{
+		SCARDHANDLE hCard;
+		DWORD dwControlCode;
+		DWORD cbSendLength;
+		DWORD cbRecvLength;
+		DWORD pdwBytesReturned;
+		LONG rv;
+		size_t size;
+		BYTE data[1];
+	};
+	typedef struct control_struct_extended control_struct_extended;
+
+	/**
 	 * @brief contained in \c SCARD_GET_ATTRIB and \c  Messages.
 	 *
 	 * These data are passed throw the field \c sharedSegmentMsg.data.

Modified: trunk/PCSC/src/winscard_svc.c
===================================================================
--- trunk/PCSC/src/winscard_svc.c	2006-11-30 20:54:22 UTC (rev 2249)
+++ trunk/PCSC/src/winscard_svc.c	2006-11-30 22:26:35 UTC (rev 2250)
@@ -159,7 +159,8 @@
 
 				/* the SCARD_TRANSMIT_EXTENDED anwser is already sent by
 				 * MSGFunctionDemarshall */
-				if (msgStruct.command != SCARD_TRANSMIT_EXTENDED)
+				if ((msgStruct.command != SCARD_TRANSMIT_EXTENDED)
+					&& (msgStruct.command != SCARD_CONTROL_EXTENDED))
 					rv = SHMMessageSend(&msgStruct, sizeof(msgStruct),
 						psContext[dwContextIndex].dwClientID,
 						PCSCLITE_SERVER_ATTEMPTS);
@@ -456,6 +457,75 @@
 		}
 		break;
 
+	case SCARD_CONTROL_EXTENDED:
+		{
+			control_struct_extended *cteStr;
+			unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
+			unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
+
+			cteStr = ((control_struct_extended *) msgStruct->data);
+			rv = MSGCheckHandleAssociation(cteStr->hCard, dwContextIndex);
+			if (rv != 0) return rv;
+
+			/* on more block to read? */
+			if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
+			{
+				/* copy the first data part */
+				memcpy(pbSendBuffer, cteStr->data,
+					PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr));
+
+				/* receive the second block */
+				rv = SHMMessageReceive(
+					pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr),
+					cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
+					psContext[dwContextIndex].dwClientID,
+					PCSCLITE_SERVER_ATTEMPTS);
+				if (rv)
+					Log1(PCSC_LOG_CRITICAL, "reception failed");
+			}
+			else
+				memcpy(pbSendBuffer, cteStr->data, cteStr->cbSendLength);
+
+			cteStr->rv = SCardControl(cteStr->hCard, cteStr->dwControlCode,
+				pbSendBuffer, cteStr->cbSendLength,
+				pbRecvBuffer, cteStr->cbRecvLength,
+				&cteStr->pdwBytesReturned);
+
+			cteStr->size = sizeof(*cteStr) + cteStr->pdwBytesReturned;
+			if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
+			{
+				/* two blocks */
+				memcpy(cteStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
+					- sizeof(*cteStr));
+
+				rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
+					psContext[dwContextIndex].dwClientID,
+					PCSCLITE_SERVER_ATTEMPTS);
+				if (rv)
+					Log1(PCSC_LOG_CRITICAL, "transmission failed");
+
+				rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
+					- sizeof(*cteStr),
+					cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
+					psContext[dwContextIndex].dwClientID,
+					PCSCLITE_SERVER_ATTEMPTS);
+				if (rv)
+					Log1(PCSC_LOG_CRITICAL, "transmission failed");
+			}
+			else
+			{
+				/* one block only */
+				memcpy(cteStr->data, pbRecvBuffer, cteStr->pdwBytesReturned);
+
+				rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
+					psContext[dwContextIndex].dwClientID,
+					PCSCLITE_SERVER_ATTEMPTS);
+				if (rv)
+					Log1(PCSC_LOG_CRITICAL, "transmission failed");
+			}
+		}
+		break;
+
 	default:
 		Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", msgStruct->command);
 		return -1;




More information about the Pcsclite-cvs-commit mailing list