diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 24f046605..6133d5c48 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -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) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 72f21f663..bc5527962 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -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