From 86b018ee211d35b160747d28c610a0023c6dfef0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 3 May 2014 14:20:17 -0400 Subject: [PATCH] libwinpr-smartcard: fix pcsc-lite SCARD_IO_REQUEST incompatibility --- winpr/libwinpr/smartcard/smartcard_pcsc.c | 70 +++++++++++++++++++++++++++---- winpr/libwinpr/smartcard/smartcard_pcsc.h | 13 +++--- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 54cb474..472570b 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -69,6 +69,10 @@ char SMARTCARD_PNP_NOTIFICATION_A[] = "\\\\?PnP?\\Notification"; WCHAR SMARTCARD_PNP_NOTIFICATION_W[] = { '\\','\\','?','P','n','P','?', '\\','N','o','t','i','f','i','c','a','t','i','o','n','\0' }; +const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT0Pci = { SCARD_PROTOCOL_T0, sizeof(PCSC_SCARD_IO_REQUEST) }; +const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(PCSC_SCARD_IO_REQUEST) }; +const PCSC_SCARD_IO_REQUEST g_PCSC_rgSCardRawPci = { PCSC_SCARD_PROTOCOL_RAW, sizeof(PCSC_SCARD_IO_REQUEST) }; + WINSCARDAPI LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPCVOID pvMem); LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) @@ -1660,12 +1664,25 @@ WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) { LONG status = SCARD_S_SUCCESS; + PCSC_DWORD cbExtraBytes = 0; + BYTE* pbExtraBytes = NULL; + BYTE* pcsc_pbExtraBytes = NULL; + PCSC_SCARD_IO_REQUEST* pcsc_pioSendPci = NULL; + PCSC_SCARD_IO_REQUEST* pcsc_pioRecvPci = NULL; PCSC_DWORD pcsc_cbSendLength = (PCSC_DWORD) cbSendLength; - PCSC_DWORD pcsc_cbRecvLength = (PCSC_DWORD) *pcbRecvLength; + PCSC_DWORD pcsc_cbRecvLength = 0; if (!g_PCSC.pfnSCardTransmit) return SCARD_E_NO_SERVICE; + if (!pcbRecvLength) + return SCARD_E_INVALID_PARAMETER; + + if (*pcbRecvLength == SCARD_AUTOALLOCATE) + return SCARD_E_INVALID_PARAMETER; + + pcsc_cbRecvLength = (PCSC_DWORD) *pcbRecvLength; + if (!pioSendPci) { PCSC_DWORD dwState = 0; @@ -1683,20 +1700,59 @@ WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, if (status == SCARD_S_SUCCESS) { if (dwProtocol == SCARD_PROTOCOL_T0) - pioSendPci = SCARD_PCI_T0; + pcsc_pioSendPci = (PCSC_SCARD_IO_REQUEST*) PCSC_SCARD_PCI_T0; else if (dwProtocol == SCARD_PROTOCOL_T1) - pioSendPci = SCARD_PCI_T1; - else if (dwProtocol == SCARD_PROTOCOL_RAW) - pioSendPci = SCARD_PCI_RAW; + pcsc_pioSendPci = (PCSC_SCARD_IO_REQUEST*) PCSC_SCARD_PCI_T1; + else if (dwProtocol == PCSC_SCARD_PROTOCOL_RAW) + pcsc_pioSendPci = (PCSC_SCARD_IO_REQUEST*) PCSC_SCARD_PCI_RAW; } } + else + { + cbExtraBytes = pioSendPci->cbPciLength - sizeof(SCARD_IO_REQUEST); + pcsc_pioSendPci = (PCSC_SCARD_IO_REQUEST*) malloc(sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes); + + if (!pcsc_pioSendPci) + return SCARD_E_NO_MEMORY; + + pcsc_pioSendPci->dwProtocol = (PCSC_DWORD) pioSendPci->dwProtocol; + pcsc_pioSendPci->cbPciLength = sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes; + + pbExtraBytes = &((BYTE*) pioSendPci)[sizeof(SCARD_IO_REQUEST)]; + pcsc_pbExtraBytes = &((BYTE*) pcsc_pioSendPci)[sizeof(PCSC_SCARD_IO_REQUEST)]; + + CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes); + } + + if (pioRecvPci) + { + cbExtraBytes = pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST); + pcsc_pioRecvPci = (PCSC_SCARD_IO_REQUEST*) malloc(sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes); + + if (!pcsc_pioRecvPci) + return SCARD_E_NO_MEMORY; + + pcsc_pioRecvPci->dwProtocol = (PCSC_DWORD) pioRecvPci->dwProtocol; + pcsc_pioRecvPci->cbPciLength = sizeof(PCSC_SCARD_IO_REQUEST) + cbExtraBytes; - status = (LONG) g_PCSC.pfnSCardTransmit(hCard, pioSendPci, pbSendBuffer, - pcsc_cbSendLength, pioRecvPci, pbRecvBuffer, &pcsc_cbRecvLength); + pbExtraBytes = &((BYTE*) pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; + pcsc_pbExtraBytes = &((BYTE*) pcsc_pioRecvPci)[sizeof(PCSC_SCARD_IO_REQUEST)]; + + CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes); + } + + status = (LONG) g_PCSC.pfnSCardTransmit(hCard, pcsc_pioSendPci, pbSendBuffer, + pcsc_cbSendLength, pcsc_pioRecvPci, pbRecvBuffer, &pcsc_cbRecvLength); status = PCSC_MapErrorCodeToWinSCard(status); *pcbRecvLength = (DWORD) pcsc_cbRecvLength; + if (pioSendPci) + free(pcsc_pioSendPci); /* pcsc_pioSendPci is dynamically allocated only when pioSendPci is non null */ + + if (pioRecvPci) + free(pcsc_pioRecvPci); /* pcsc_pioRecvPci is dynamically allocated only when pioRecvPci is non null */ + return status; } diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.h b/winpr/libwinpr/smartcard/smartcard_pcsc.h index d9f9229..acb3f37 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.h +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.h @@ -71,6 +71,10 @@ typedef long PCSC_LONG; #define PCSC_SCARD_AUTOALLOCATE (PCSC_DWORD)(-1) +#define PCSC_SCARD_PCI_T0 (&g_PCSC_rgSCardT0Pci) +#define PCSC_SCARD_PCI_T1 (&g_PCSC_rgSCardT1Pci) +#define PCSC_SCARD_PCI_RAW (&g_PCSC_rgSCardRawPci) + typedef struct { LPCSTR szReader; @@ -82,12 +86,11 @@ typedef struct } PCSC_SCARD_READERSTATE; -typedef struct _PCSC_SCARD_IO_REQUEST +typedef struct { PCSC_DWORD dwProtocol; PCSC_DWORD cbPciLength; -} PCSC_SCARD_IO_REQUEST, *PCSC_PSCARD_IO_REQUEST, *PCSC_LPSCARD_IO_REQUEST; -typedef const PCSC_SCARD_IO_REQUEST *PCSC_LPCSCARD_IO_REQUEST; +} PCSC_SCARD_IO_REQUEST; struct _PCSCFunctionTable { @@ -113,8 +116,8 @@ struct _PCSCFunctionTable PCSC_DWORD dwControlCode, LPCVOID pbSendBuffer, PCSC_DWORD cbSendLength, LPVOID pbRecvBuffer, PCSC_DWORD cbRecvLength, PCSC_LPDWORD lpBytesReturned); PCSC_LONG (* pfnSCardTransmit)(SCARDHANDLE hCard, - const SCARD_IO_REQUEST* pioSendPci, LPCBYTE pbSendBuffer, PCSC_DWORD cbSendLength, - SCARD_IO_REQUEST* pioRecvPci, LPBYTE pbRecvBuffer, PCSC_LPDWORD pcbRecvLength); + const PCSC_SCARD_IO_REQUEST* pioSendPci, LPCBYTE pbSendBuffer, PCSC_DWORD cbSendLength, + PCSC_SCARD_IO_REQUEST* pioRecvPci, LPBYTE pbRecvBuffer, PCSC_LPDWORD pcbRecvLength); PCSC_LONG (* pfnSCardListReaderGroups)(SCARDCONTEXT hContext, LPSTR mszGroups, PCSC_LPDWORD pcchGroups); PCSC_LONG (* pfnSCardListReaders)(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, PCSC_LPDWORD pcchReaders); -- 2.7.4