fix smartcard: SCardStatus unicode handling

* fix StatusW_Call to rely and use SCardStatusW
* fix trace call in  StatusW_Call - needs to be called after the sizes
  are set
* unify SCardStatus functions for pcsc - let the internal function handle unicode directly

This fixes an issue with size calculations of SCardStatusW.
This commit is contained in:
Bernhard Miklautz 2017-12-14 15:46:14 +01:00
parent 94b35cb4f7
commit 5a1c0081c5
2 changed files with 41 additions and 35 deletions

View File

@ -1135,23 +1135,24 @@ static LONG smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERAT
else else
cchReaderLen = SCARD_AUTOALLOCATE; cchReaderLen = SCARD_AUTOALLOCATE;
ret.cbAtrLen = call->cbAtrLen; cbAtrLen = call->cbAtrLen;
ZeroMemory(ret.pbAtr, 32); ZeroMemory(ret.pbAtr, 32);
status = ret.ReturnCode = SCardStatusW(operation->hCard, status = ret.ReturnCode = SCardStatusW(operation->hCard,
call->fmszReaderNamesIsNULL ? NULL : (LPWSTR) &mszReaderNames, call->fmszReaderNamesIsNULL ? NULL : (LPWSTR) &mszReaderNames,
&cchReaderLen, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &cbAtrLen); &cchReaderLen, &ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &cbAtrLen);
smartcard_trace_status_return(smartcard, &ret, TRUE);
if (status == SCARD_S_SUCCESS) if (status == SCARD_S_SUCCESS)
{ {
if (!call->fmszReaderNamesIsNULL) if (!call->fmszReaderNamesIsNULL)
ret.mszReaderNames = (BYTE*) mszReaderNames; ret.mszReaderNames = (BYTE*) mszReaderNames;
ret.cBytes = cchReaderLen * 2; ret.cBytes = cchReaderLen;
if (call->cbAtrLen) if (call->cbAtrLen)
ret.cbAtrLen = cbAtrLen; ret.cbAtrLen = cbAtrLen;
} }
smartcard_trace_status_return(smartcard, &ret, TRUE);
if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret))) if ((status = smartcard_pack_status_return(smartcard, irp->output, &ret)))
{ {

View File

@ -1562,7 +1562,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard,
*/ */
WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard,
LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen, BOOL unicode)
{ {
PCSC_SCARDHANDLE* pCard = NULL; PCSC_SCARDHANDLE* pCard = NULL;
SCARDCONTEXT hContext; SCARDCONTEXT hContext;
@ -1600,6 +1600,9 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard,
pcsc_cchReaderLen++; pcsc_cchReaderLen++;
if (unicode)
pcsc_cchReaderLen *= 2;
if (pcchReaderLen) if (pcchReaderLen)
{ {
if (*pcchReaderLen == SCARD_AUTOALLOCATE) if (*pcchReaderLen == SCARD_AUTOALLOCATE)
@ -1670,8 +1673,29 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard,
if (tReader) if (tReader)
{ {
PCSC_AddMemoryBlock(hContext, tReader); if (unicode)
*(LPSTR*)mszReaderNames = tReader; {
LPSTR mszReaderNamesW = NULL;
int pcsc_cchReaderLenW = 0;
pcsc_cchReaderLenW = ConvertToUnicode(CP_UTF8, 0, tReader, *pcchReaderLen,
(WCHAR**) &mszReaderNamesW, 0);
if (pcsc_cchReaderLenW <= 0 || mszReaderNamesW == NULL)
{
status = ERROR_NOT_ENOUGH_MEMORY;
goto out_fail;
}
readerNames = mszReaderNamesW;
free(tReader);
PCSC_AddMemoryBlock(hContext, mszReaderNamesW);
*(LPSTR*) mszReaderNames = mszReaderNamesW;
}
else
{
PCSC_AddMemoryBlock(hContext, tReader);
*(LPSTR*) mszReaderNames = tReader;
}
} }
pcsc_dwState &= 0xFFFF; pcsc_dwState &= 0xFFFF;
@ -1686,7 +1710,12 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard,
*pcbAtrLen = (DWORD) pcsc_cbAtrLen; *pcbAtrLen = (DWORD) pcsc_cbAtrLen;
if (pcchReaderLen) if (pcchReaderLen)
*pcchReaderLen = pcsc_cchReaderLen + 1; {
if (unicode)
*pcchReaderLen = (pcsc_cchReaderLen + 1) * 2;
else
*pcchReaderLen = pcsc_cchReaderLen + 1;
}
/* Make sure the last byte is set */ /* Make sure the last byte is set */
if (readerNames) if (readerNames)
@ -1703,40 +1732,16 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard,
LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
{ {
LONG status = SCARD_S_SUCCESS; return PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol,
status = PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen, FALSE);
pbAtr, pcbAtrLen);
return status;
} }
WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard,
LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
{ {
SCARDCONTEXT hContext = 0; return PCSC_SCardStatus_Internal(hCard, (LPSTR) mszReaderNames, pcchReaderLen, pdwState,
LPSTR mszReaderNamesA = NULL; pdwProtocol, pbAtr, pcbAtrLen, TRUE);
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardStatus)
return SCARD_E_NO_SERVICE;
hContext = PCSC_GetCardContextFromHandle(hCard);
if (!hContext)
return SCARD_E_INVALID_VALUE;
status = PCSC_SCardStatus_Internal(hCard, (LPSTR) &mszReaderNamesA, pcchReaderLen, pdwState,
pdwProtocol, pbAtr, pcbAtrLen);
if (mszReaderNamesA)
{
*pcchReaderLen = ConvertToUnicode(CP_UTF8, 0, mszReaderNamesA, *pcchReaderLen,
(WCHAR**) mszReaderNames, 0);
PCSC_AddMemoryBlock(hContext, mszReaderNames);
PCSC_SCardFreeMemory_Internal(hContext, mszReaderNamesA);
}
return status;
} }
WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard, WINSCARDAPI LONG WINAPI PCSC_SCardTransmit(SCARDHANDLE hCard,