libwinpr-smartcard: fix pcsc-lite SCARD_IO_REQUEST incompatibility

This commit is contained in:
Marc-André Moreau 2014-05-03 14:20:17 -04:00
parent cd7e3151cd
commit 86b018ee21
2 changed files with 71 additions and 12 deletions

View File

@ -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);
status = (LONG) g_PCSC.pfnSCardTransmit(hCard, pioSendPci, pbSendBuffer,
pcsc_cbSendLength, pioRecvPci, pbRecvBuffer, &pcsc_cbRecvLength);
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;
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;
}

View File

@ -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);