[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