channels/smartcard: fix SCardGetAttrib SCARD_AUTOALLOCATE support
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 22 Dec 2014 18:28:16 +0000 (13:28 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 22 Dec 2014 18:28:16 +0000 (13:28 -0500)
channels/smartcard/client/smartcard_operations.c
winpr/libwinpr/smartcard/smartcard_pcsc.c

index 24f0466..6133d5c 100644 (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)
index 72f21f6..bc55279 100644 (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
+                               vendorName = (char*) pbAttr;
+
+                       if (vendorName)
+                               *pcbAttrLen = strlen(vendorName);
                        else
-                               *pcbAttrLen = strlen((char*) pbAttr);
+                               *pcbAttrLen = 0;
                }
        }
        else