channels/smartcard: fix SCardGetAttrib SCARD_AUTOALLOCATE support

This commit is contained in:
Marc-André Moreau
2014-12-22 13:28:16 -05:00
parent d5edfa4721
commit 0625be2720
2 changed files with 46 additions and 15 deletions

View File

@@ -781,8 +781,9 @@ static DWORD smartcard_StatusA_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
ret.cbAtrLen = call->cbAtrLen;
ZeroMemory(ret.pbAtr, 32);
cchReaderLen = SCARD_AUTOALLOCATE;
status = ret.ReturnCode = SCardStatusA(operation->hCard, (LPSTR) &mszReaderNames, &cchReaderLen,
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
if (status == SCARD_S_SUCCESS)
{
@@ -831,8 +832,10 @@ static DWORD smartcard_StatusW_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERA
ret.cbAtrLen = call->cbAtrLen;
ZeroMemory(ret.pbAtr, 32);
cchReaderLen = SCARD_AUTOALLOCATE;
status = ret.ReturnCode = SCardStatusW(operation->hCard, (LPWSTR) &mszReaderNames, &cchReaderLen,
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
&ret.dwState, &ret.dwProtocol, (BYTE*) &ret.pbAtr, &ret.cbAtrLen);
ret.mszReaderNames = (BYTE*) mszReaderNames;
ret.cBytes = cchReaderLen * 2;
smartcard_trace_status_return(smartcard, &ret, TRUE);
@@ -930,8 +933,9 @@ static UINT32 smartcard_Control_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPER
return SCARD_E_NO_MEMORY;
status = ret.ReturnCode = SCardControl(operation->hCard,
call->dwControlCode, call->pvInBuffer, call->cbInBufferSize,
ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize);
call->dwControlCode, call->pvInBuffer, call->cbInBufferSize,
ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize);
smartcard_trace_control_return(smartcard, &ret);
status = smartcard_pack_control_return(smartcard, irp->output, &ret);
@@ -966,19 +970,32 @@ static UINT32 smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OP
{
LONG status;
DWORD cbAttrLen;
BOOL autoAllocate;
GetAttrib_Return ret;
IRP* irp = operation->irp;
ret.pbAttr = NULL;
if (call->fpbAttrIsNULL)
call->cbAttrLen = 0;
if (call->cbAttrLen)
autoAllocate = (call->cbAttrLen == SCARD_AUTOALLOCATE) ? TRUE : FALSE;
if (call->cbAttrLen && !autoAllocate)
{
ret.pbAttr = (BYTE*) malloc(call->cbAttrLen);
if (!ret.pbAttr)
return SCARD_E_NO_MEMORY;
}
cbAttrLen = call->cbAttrLen;
status = ret.ReturnCode = SCardGetAttrib(operation->hCard, call->dwAttrId, ret.pbAttr, &cbAttrLen);
status = ret.ReturnCode = SCardGetAttrib(operation->hCard, call->dwAttrId,
autoAllocate ? (LPBYTE) &(ret.pbAttr) : ret.pbAttr, &cbAttrLen);
ret.cbAttrLen = cbAttrLen;
smartcard_trace_get_attrib_return(smartcard, &ret, call->dwAttrId);
if (ret.ReturnCode)

View File

@@ -2333,18 +2333,24 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, L
BOOL pcbAttrLenAlloc = FALSE;
LONG status = SCARD_S_SUCCESS;
LPBYTE* pPbAttr = (LPBYTE*) pbAttr;
cbAttrLen = *pcbAttrLen;
if (*pcbAttrLen == SCARD_AUTOALLOCATE)
{
pcbAttrLenAlloc = TRUE;
*pPbAttr = NULL;
}
else
{
/**
* pcsc-lite returns SCARD_E_INSUFFICIENT_BUFFER if the given
* buffer size is larger than PCSC_MAX_BUFFER_SIZE (264)
*/
/**
* pcsc-lite returns SCARD_E_INSUFFICIENT_BUFFER if the given
* buffer size is larger than PCSC_MAX_BUFFER_SIZE (264)
*/
if (*pcbAttrLen > PCSC_MAX_BUFFER_SIZE)
*pcbAttrLen = PCSC_MAX_BUFFER_SIZE;
if (*pcbAttrLen > PCSC_MAX_BUFFER_SIZE)
*pcbAttrLen = PCSC_MAX_BUFFER_SIZE;
}
hContext = PCSC_GetCardContextFromHandle(hCard);
@@ -2363,14 +2369,22 @@ WINSCARDAPI LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, L
{
if (dwAttrId == SCARD_ATTR_VENDOR_NAME)
{
const char* vendorName;
/**
* pcsc-lite adds a null terminator to the vendor name,
* while WinSCard doesn't. Strip the null terminator.
*/
if (pcbAttrLenAlloc)
*pcbAttrLen = strlen((char*) *pPbAttr);
vendorName = (char*) *pPbAttr;
else
*pcbAttrLen = strlen((char*) pbAttr);
vendorName = (char*) pbAttr;
if (vendorName)
*pcbAttrLen = strlen(vendorName);
else
*pcbAttrLen = 0;
}
}
else