Merge pull request #12273 from akallabeth/winpr-scard-fix

[winpr,smartcard] simplify PCSC_ReadDeviceSystemName
This commit is contained in:
akallabeth
2026-02-09 12:20:32 +01:00
committed by GitHub

View File

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