channels/smartcard: pcsc-lite fixes

This commit is contained in:
Marc-André Moreau 2014-04-09 14:27:44 -04:00
parent 39f04c870e
commit da56c8af62
3 changed files with 47 additions and 15 deletions

View File

@ -155,7 +155,7 @@ size_t smartcard_multi_string_length_a(const char* msz)
while ((p[0] != 0) && (p[1] != 0)) while ((p[0] != 0) && (p[1] != 0))
p++; p++;
return (p - msz); return (p - msz) + 1;
} }
size_t smartcard_multi_string_length_w(const WCHAR* msz) size_t smartcard_multi_string_length_w(const WCHAR* msz)
@ -168,7 +168,7 @@ size_t smartcard_multi_string_length_w(const WCHAR* msz)
while ((p[0] != 0) && (p[1] != 0)) while ((p[0] != 0) && (p[1] != 0))
p++; p++;
return (p - msz); return (p - msz) + 1;
} }
static UINT32 smartcard_EstablishContext(SMARTCARD_DEVICE* smartcard, IRP* irp) static UINT32 smartcard_EstablishContext(SMARTCARD_DEVICE* smartcard, IRP* irp)
@ -262,7 +262,7 @@ static UINT32 smartcard_ListReadersA(SMARTCARD_DEVICE* smartcard, IRP* irp)
return status; return status;
ret.msz = (BYTE*) mszReaders; ret.msz = (BYTE*) mszReaders;
ret.cBytes = smartcard_multi_string_length_a((char*) ret.msz) + 2; ret.cBytes = cchReaders;
status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret); status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret);
@ -302,7 +302,7 @@ static UINT32 smartcard_ListReadersW(SMARTCARD_DEVICE* smartcard, IRP* irp)
return status; return status;
ret.msz = (BYTE*) mszReaders; ret.msz = (BYTE*) mszReaders;
ret.cBytes = (smartcard_multi_string_length_w((WCHAR*) ret.msz) + 2) * 2; ret.cBytes = cchReaders;
status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret); status = smartcard_pack_list_readers_return(smartcard, irp->output, &ret);
@ -1032,7 +1032,7 @@ void smartcard_irp_device_control(SMARTCARD_DEVICE* smartcard, IRP* irp)
WLog_Print(smartcard->log, WLOG_DEBUG, "%s (0x%08X) FileId: %d CompletionId: %d", WLog_Print(smartcard->log, WLOG_DEBUG, "%s (0x%08X) FileId: %d CompletionId: %d",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId); smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
#if 0 #if 1
printf("%s (0x%08X) FileId: %d CompletionId: %d\n", printf("%s (0x%08X) FileId: %d CompletionId: %d\n",
smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId); smartcard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, irp->FileId, irp->CompletionId);
#endif #endif

View File

@ -523,7 +523,7 @@ UINT32 smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream*
Stream_Write(s, ret->msz, ret->cBytes); Stream_Write(s, ret->msz, ret->cBytes);
else else
Stream_Zero(s, ret->cBytes); Stream_Zero(s, ret->cBytes);
smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4); smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4);
return SCARD_S_SUCCESS; return SCARD_S_SUCCESS;
@ -776,8 +776,7 @@ UINT32 smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wS
Stream_Read(s, readerState->Common.rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ Stream_Read(s, readerState->Common.rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */
Stream_Seek_UINT32(s); /* rgbAtr [32..36] (4 bytes) */ Stream_Seek_UINT32(s); /* rgbAtr [32..36] (4 bytes) */
/* what is this used for? */ readerState->Common.dwCurrentState &= 0xFFFF;
readerState->Common.dwCurrentState &= 0x0000FFFF;
readerState->Common.dwEventState = 0; readerState->Common.dwEventState = 0;
} }

View File

@ -67,7 +67,7 @@ size_t PCSC_MultiStringLengthA(const char* msz)
while ((p[0] != 0) && (p[1] != 0)) while ((p[0] != 0) && (p[1] != 0))
p++; p++;
return (p - msz); return (p - msz) + 1;
} }
size_t PCSC_MultiStringLengthW(const WCHAR* msz) size_t PCSC_MultiStringLengthW(const WCHAR* msz)
@ -80,7 +80,7 @@ size_t PCSC_MultiStringLengthW(const WCHAR* msz)
while ((p[0] != 0) && (p[1] != 0)) while ((p[0] != 0) && (p[1] != 0))
p++; p++;
return (p - msz); return (p - msz) + 1;
} }
void PCSC_AddSmartCardHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard) void PCSC_AddSmartCardHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard)
@ -152,6 +152,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope,
if (g_PCSC.pfnSCardEstablishContext) if (g_PCSC.pfnSCardEstablishContext)
{ {
dwScope = SCARD_SCOPE_SYSTEM; /* this is the only scope supported by pcsc-lite */
status = g_PCSC.pfnSCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext); status = g_PCSC.pfnSCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext);
status = PCSC_MapErrorCodeToWinSCard(status); status = PCSC_MapErrorCodeToWinSCard(status);
} }
@ -228,6 +230,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersA(SCARDCONTEXT hContext,
BOOL pcchReadersWrapAlloc = FALSE; BOOL pcchReadersWrapAlloc = FALSE;
LPSTR* pMszReaders = (LPSTR*) mszReaders; LPSTR* pMszReaders = (LPSTR*) mszReaders;
mszGroups = NULL; /* mszGroups is not supported by pcsc-lite */
if ((*pcchReaders == SCARD_AUTOALLOCATE) && !g_SCardAutoAllocate) if ((*pcchReaders == SCARD_AUTOALLOCATE) && !g_SCardAutoAllocate)
pcchReadersWrapAlloc = TRUE; pcchReadersWrapAlloc = TRUE;
@ -270,12 +274,13 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext,
if (g_PCSC.pfnSCardListReaders) if (g_PCSC.pfnSCardListReaders)
{ {
UINT32 length;
LPSTR mszGroupsA = NULL; LPSTR mszGroupsA = NULL;
LPSTR mszReadersA = NULL; LPSTR mszReadersA = NULL;
BOOL pcchReadersWrapAlloc = FALSE; BOOL pcchReadersWrapAlloc = FALSE;
LPSTR* pMszReadersA = &mszReadersA; LPSTR* pMszReadersA = &mszReadersA;
mszGroups = NULL; /* mszGroups is not supported by pcsc-lite */
if ((*pcchReaders == SCARD_AUTOALLOCATE) && !g_SCardAutoAllocate) if ((*pcchReaders == SCARD_AUTOALLOCATE) && !g_SCardAutoAllocate)
pcchReadersWrapAlloc = TRUE; pcchReadersWrapAlloc = TRUE;
@ -299,8 +304,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext,
if (status && *pMszReadersA) if (status && *pMszReadersA)
{ {
length = (UINT32) PCSC_MultiStringLengthA(*pMszReadersA); *pcchReaders = ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, *pcchReaders, (WCHAR**) mszReaders, 0);
ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, length + 2, (WCHAR**) mszReaders, 0);
PCSC_AddMemoryBlock(hContext, mszReaders); PCSC_AddMemoryBlock(hContext, mszReaders);
} }
@ -313,8 +317,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext,
if (mszReadersA) if (mszReadersA)
{ {
length = (UINT32) PCSC_MultiStringLengthA(mszReadersA); *pcchReaders = ConvertToUnicode(CP_UTF8, 0, mszReadersA, *pcchReaders, (WCHAR**) mszReaders, 0) * 2;
ConvertToUnicode(CP_UTF8, 0, mszReadersA, length + 2, (WCHAR**) mszReaders, 0);
PCSC_AddMemoryBlock(hContext, mszReaders); PCSC_AddMemoryBlock(hContext, mszReaders);
PCSC_SCardFreeMemory(hContext, mszReadersA); PCSC_SCardFreeMemory(hContext, mszReadersA);
@ -541,8 +544,30 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChangeA(SCARDCONTEXT hContext,
if (g_PCSC.pfnSCardGetStatusChange) if (g_PCSC.pfnSCardGetStatusChange)
{ {
DWORD index;
/**
* pcsc-lite interprets value 0 as INFINITE, while it really shouldn't.
* Work around this issue by using the smallest non-zero timeout value.
*/
if (!dwTimeout)
dwTimeout++;
for (index = 0; index < cReaders; index++)
{
rgReaderStates[index].dwCurrentState &= 0xFFFF;
rgReaderStates[index].dwEventState = 0;
}
status = g_PCSC.pfnSCardGetStatusChange(hContext, dwTimeout, rgReaderStates, cReaders); status = g_PCSC.pfnSCardGetStatusChange(hContext, dwTimeout, rgReaderStates, cReaders);
status = PCSC_MapErrorCodeToWinSCard(status); status = PCSC_MapErrorCodeToWinSCard(status);
for (index = 0; index < cReaders; index++)
{
/* pcsc-lite puts an event count in the higher bits of dwEventState */
rgReaderStates[index].dwEventState &= 0xFFFF;
}
} }
return status; return status;
@ -558,6 +583,9 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChangeW(SCARDCONTEXT hContext,
DWORD index; DWORD index;
LPSCARD_READERSTATEA rgReaderStatesA; LPSCARD_READERSTATEA rgReaderStatesA;
if (!dwTimeout)
dwTimeout++;
rgReaderStatesA = (LPSCARD_READERSTATEA) calloc(cReaders, sizeof(SCARD_READERSTATEA)); rgReaderStatesA = (LPSCARD_READERSTATEA) calloc(cReaders, sizeof(SCARD_READERSTATEA));
for (index = 0; index < cReaders; index++) for (index = 0; index < cReaders; index++)
@ -567,6 +595,9 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChangeW(SCARDCONTEXT hContext,
ConvertFromUnicode(CP_UTF8, 0, rgReaderStates[index].szReader, -1, ConvertFromUnicode(CP_UTF8, 0, rgReaderStates[index].szReader, -1,
(char**) &rgReaderStatesA[index].szReader, 0, NULL, NULL); (char**) &rgReaderStatesA[index].szReader, 0, NULL, NULL);
rgReaderStates[index].dwCurrentState &= 0xFFFF;
rgReaderStates[index].dwEventState = 0;
rgReaderStatesA[index].pvUserData = rgReaderStates[index].pvUserData; rgReaderStatesA[index].pvUserData = rgReaderStates[index].pvUserData;
rgReaderStatesA[index].dwCurrentState = rgReaderStates[index].dwCurrentState; rgReaderStatesA[index].dwCurrentState = rgReaderStates[index].dwCurrentState;
rgReaderStatesA[index].dwEventState = rgReaderStates[index].dwEventState; rgReaderStatesA[index].dwEventState = rgReaderStates[index].dwEventState;
@ -586,6 +617,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetStatusChangeW(SCARDCONTEXT hContext,
rgReaderStates[index].dwEventState = rgReaderStatesA[index].dwEventState; rgReaderStates[index].dwEventState = rgReaderStatesA[index].dwEventState;
rgReaderStates[index].cbAtr = rgReaderStatesA[index].cbAtr; rgReaderStates[index].cbAtr = rgReaderStatesA[index].cbAtr;
CopyMemory(&(rgReaderStates[index].rgbAtr), &(rgReaderStatesA[index].rgbAtr), 36); CopyMemory(&(rgReaderStates[index].rgbAtr), &(rgReaderStatesA[index].rgbAtr), 36);
rgReaderStates[index].dwEventState &= 0xFFFF;
} }
free(rgReaderStatesA); free(rgReaderStatesA);