From e2536433865c6d85affd457b14933fab32cc6f5c Mon Sep 17 00:00:00 2001 From: akallabeth Date: Fri, 30 Jan 2026 22:03:10 +0100 Subject: [PATCH] [winpr,smartcard] simplify PCSC_ReadDeviceSystemName * If we read SCARD_ATTR_DEVICE_SYSTEM_NAME_A just pass the actual destination buffer, no further processing required. * In case of SCARD_ATTR_DEVICE_SYSTEM_NAME_W allocate a WCHAR version of the result, copy back to destination buffer. --- winpr/libwinpr/smartcard/smartcard_pcsc.c | 117 +++++++--------------- 1 file changed, 36 insertions(+), 81 deletions(-) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index afac57934..e2ba5beb2 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -48,6 +48,10 @@ #include "../log.h" #define TAG WINPR_TAG("smartcard") +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + #define WINSCARD_LOAD_PROC_EX(module, pcsc, _fname, _name) \ do \ { \ @@ -2506,102 +2510,53 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA return status; } -static LONG PCSC_ReadDeviceSystemName(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, - LPDWORD pcbAttrLen) +static LONG PCSC_ReadDeviceSystemName(SCARDCONTEXT hContext, SCARDHANDLE hCard, DWORD dwAttrId, + LPBYTE pbAttr, LPDWORD pcbAttrLen) { /* Get reader name from SCardStatus */ CHAR* szReader = NULL; - PCSC_DWORD cchReader = 0; PCSC_DWORD dwState = 0; PCSC_DWORD dwProtocol = 0; LONG status = 0; - const DWORD cbAttrLen = *pcbAttrLen; + DWORD cbAttrLen = *pcbAttrLen; if (cbAttrLen == SCARD_AUTOALLOCATE) return SCARD_E_UNEXPECTED; - else - { - PCSC_DWORD cbAtr = 0; - const PCSC_LONG rc = - g_PCSC.pfnSCardStatus(hCard, NULL, &cchReader, &dwState, &dwProtocol, NULL, &cbAtr); - status = WINPR_ASSERTING_INT_CAST(LONG, rc); - if (status != SCARD_S_SUCCESS) - return status; - switch (dwAttrId) - { - case SCARD_ATTR_DEVICE_SYSTEM_NAME_A: - if (cchReader > cbAttrLen) - return SCARD_E_INSUFFICIENT_BUFFER; - break; - case SCARD_ATTR_DEVICE_SYSTEM_NAME_W: - if (cchReader > cbAttrLen / sizeof(WCHAR)) - return SCARD_E_INSUFFICIENT_BUFFER; - break; - default: - return SCARD_E_INVALID_PARAMETER; - } - if (cchReader == 0) - { - *pcbAttrLen = 0; - return SCARD_S_SUCCESS; - } + if (dwAttrId == SCARD_ATTR_DEVICE_SYSTEM_NAME_W) + cbAttrLen /= sizeof(WCHAR); - if (!pbAttr) - return SCARD_E_INVALID_VALUE; + PCSC_DWORD cbAtr = 0; + PCSC_DWORD cchReader = cbAttrLen; + const PCSC_LONG rc = g_PCSC.pfnSCardStatus(hCard, (LPSTR)pbAttr, &cchReader, &dwState, + &dwProtocol, NULL, &cbAtr); - szReader = calloc(cchReader, sizeof(CHAR)); - if (!szReader) - return SCARD_E_NO_MEMORY; - } - - { - PCSC_DWORD rlen = cchReader; - PCSC_DWORD cbAtr = 0; - const PCSC_LONG rc = - g_PCSC.pfnSCardStatus(hCard, szReader, &rlen, &dwState, &dwProtocol, NULL, &cbAtr); - status = WINPR_ASSERTING_INT_CAST(LONG, rc); - if (status != SCARD_S_SUCCESS) - goto out; - - if (cchReader != rlen) - { - status = SCARD_E_INVALID_VALUE; - goto out; - } - } *pcbAttrLen = cchReader; + status = WINPR_ASSERTING_INT_CAST(LONG, rc); + if (status != SCARD_S_SUCCESS) + return status; - switch (dwAttrId) + if (cchReader > cbAttrLen) + return SCARD_E_INSUFFICIENT_BUFFER; + + if (dwAttrId == SCARD_ATTR_DEVICE_SYSTEM_NAME_W) { - case SCARD_ATTR_DEVICE_SYSTEM_NAME_A: - if (!strncpy((char*)pbAttr, szReader, *pcbAttrLen)) - { - status = SCARD_E_NO_MEMORY; - goto out; - } - break; - case SCARD_ATTR_DEVICE_SYSTEM_NAME_W: - if (cchReader > cbAttrLen / sizeof(WCHAR)) - { - status = SCARD_E_INSUFFICIENT_BUFFER; - goto out; - } - if (ConvertUtf8NToWChar(szReader, *pcbAttrLen, (WCHAR*)pbAttr, *pcbAttrLen) != - *pcbAttrLen) - { - status = SCARD_E_NO_MEMORY; - goto out; - } - *pcbAttrLen *= sizeof(WCHAR); - break; - default: - status = SCARD_E_INVALID_PARAMETER; - break; + size_t wlen = 0; + WCHAR* tmp = ConvertMszUtf8NToWCharAlloc((LPSTR)pbAttr, cchReader, &wlen); + if (!tmp) + return SCARD_E_NO_MEMORY; + + /* utf-8 to utf-16 is no simple y=x*2, check again if the size fits. */ + if (wlen > cbAttrLen) + { + free(tmp); + return SCARD_E_INSUFFICIENT_BUFFER; + } + *pcbAttrLen = MIN(wlen, cchReader) * sizeof(WCHAR); + memcpy(pbAttr, tmp, *pcbAttrLen); + free(tmp); } -out: - free(szReader); return status; } @@ -2742,12 +2697,12 @@ static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE else if (dwAttrId == SCARD_ATTR_DEVICE_SYSTEM_NAME_A) { if (!pcbAttrLenAlloc) - status = PCSC_ReadDeviceSystemName(hCard, dwAttrId, pbAttr, pcbAttrLen); + status = PCSC_ReadDeviceSystemName(hContext, hCard, dwAttrId, pbAttr, pcbAttrLen); } else if (dwAttrId == SCARD_ATTR_DEVICE_SYSTEM_NAME_W) { if (!pcbAttrLenAlloc) - status = PCSC_ReadDeviceSystemName(hCard, dwAttrId, pbAttr, pcbAttrLen); + status = PCSC_ReadDeviceSystemName(hContext, hCard, dwAttrId, pbAttr, pcbAttrLen); } else if (dwAttrId == SCARD_ATTR_DEVICE_UNIT) {