diff --git a/channels/smartcard/client/smartcard_pack.c b/channels/smartcard/client/smartcard_pack.c index 4de589846..b1b66f4b9 100644 --- a/channels/smartcard/client/smartcard_pack.c +++ b/channels/smartcard/client/smartcard_pack.c @@ -515,16 +515,24 @@ UINT32 smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* UINT32 smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s, ListReaders_Return* ret) { - Stream_Write_UINT32(s, ret->cBytes); /* cBytes (4 bytes) */ - Stream_Write_UINT32(s, 0x00020008); /* mszNdrPtr (4 bytes) */ - Stream_Write_UINT32(s, ret->cBytes); /* mszNdrLen (4 bytes) */ - - if (ret->msz) - Stream_Write(s, ret->msz, ret->cBytes); - else - Stream_Zero(s, ret->cBytes); + UINT32 mszNdrPtr; - smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4); + mszNdrPtr = (ret->cBytes) ? 0x00020008 : 0; + + Stream_Write_UINT32(s, ret->cBytes); /* cBytes (4 bytes) */ + Stream_Write_UINT32(s, mszNdrPtr); /* mszNdrPtr (4 bytes) */ + + if (mszNdrPtr) + { + Stream_Write_UINT32(s, ret->cBytes); /* mszNdrLen (4 bytes) */ + + if (ret->msz) + Stream_Write(s, ret->msz, ret->cBytes); + else + Stream_Zero(s, ret->cBytes); + + smartcard_pack_write_size_align(smartcard, s, ret->cBytes, 4); + } return SCARD_S_SUCCESS; } @@ -775,9 +783,6 @@ UINT32 smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wS Stream_Read_UINT32(s, readerState->Common.cbAtr); /* cbAtr (4 bytes) */ Stream_Read(s, readerState->Common.rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ Stream_Seek_UINT32(s); /* rgbAtr [32..36] (4 bytes) */ - - readerState->Common.dwCurrentState &= 0xFFFF; - readerState->Common.dwEventState = 0; } for (index = 0; index < call->cReaders; index++) @@ -884,10 +889,6 @@ UINT32 smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wS Stream_Read_UINT32(s, readerState->Common.cbAtr); /* cbAtr (4 bytes) */ Stream_Read(s, readerState->Common.rgbAtr, 32); /* rgbAtr [0..32] (32 bytes) */ Stream_Seek_UINT32(s); /* rgbAtr [32..36] (4 bytes) */ - - /* what is this used for? */ - readerState->Common.dwCurrentState &= 0x0000FFFF; - readerState->Common.dwEventState = 0; } for (index = 0; index < call->cReaders; index++) @@ -1255,8 +1256,7 @@ UINT32 smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, T call->pioSendPci->cbPciLength = ioSendPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST); pbExtraBytes = &((BYTE*) call->pioSendPci)[sizeof(SCARD_IO_REQUEST)]; - CopyMemory(pbExtraBytes, ioSendPci.pbExtraBytes, ioSendPci.cbExtraBytes); - Stream_Seek(s, ioSendPci.cbExtraBytes); + Stream_Read(s, pbExtraBytes, ioSendPci.cbExtraBytes); } else { @@ -1363,8 +1363,7 @@ UINT32 smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, T call->pioRecvPci->cbPciLength = ioRecvPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST); pbExtraBytes = &((BYTE*) call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)]; - CopyMemory(pbExtraBytes, ioRecvPci.pbExtraBytes, ioRecvPci.cbExtraBytes); - Stream_Seek(s, ioRecvPci.cbExtraBytes); + Stream_Read(s, pbExtraBytes, ioRecvPci.cbExtraBytes); } return SCARD_S_SUCCESS; @@ -1410,3 +1409,4 @@ UINT32 smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s, T return SCARD_S_SUCCESS; } + diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index ec7b0b900..30bbbfc2d 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -67,6 +67,40 @@ LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode) return errorCode; } +DWORD PCSC_ConvertStatusToWinSCard(DWORD dwState) +{ + /** + * pcsc-lite's SCardStatus returns a bit-field, not an enumerated value. + * + * State WinSCard pcsc-lite + * + * SCARD_UNKNOWN 0 0x0001 + * SCARD_ABSENT 1 0x0002 + * SCARD_PRESENT 2 0x0004 + * SCARD_SWALLOWED 3 0x0008 + * SCARD_POWERED 4 0x0010 + * SCARD_NEGOTIABLE 5 0x0020 + * SCARD_SPECIFIC 6 0x0040 + */ + + if (dwState & 0x0001) + return SCARD_UNKNOWN; + if (dwState & 0x0002) + return SCARD_ABSENT; + if (dwState & 0x0004) + return SCARD_PRESENT; + if (dwState & 0x0008) + return SCARD_SWALLOWED; + if (dwState & 0x0010) + return SCARD_POWERED; + if (dwState & 0x0020) + return SCARD_NEGOTIABLE; + if (dwState & 0x0040) + return SCARD_SPECIFIC; + + return SCARD_UNKNOWN; +} + size_t PCSC_MultiStringLengthA(const char* msz) { char* p = (char*) msz; @@ -419,7 +453,7 @@ WINSCARDAPI LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext, if (status && *pMszReadersA) { - *pcchReaders = ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, *pcchReaders, (WCHAR**) mszReaders, 0); + *pcchReaders = ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, *pcchReaders, (WCHAR**) mszReaders, 0) * 2; PCSC_AddMemoryBlock(hContext, mszReaders); } @@ -992,6 +1026,9 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard, pdwState, pdwProtocol, pbAtr, pcbAtrLen); } + *pdwState &= 0xFFFF; + *pdwState = PCSC_ConvertStatusToWinSCard(*pdwState); + status = PCSC_MapErrorCodeToWinSCard(status); } @@ -1006,7 +1043,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, if (g_PCSC.pfnSCardStatus) { - UINT32 length; SCARDCONTEXT hContext = 0; BOOL pcbAtrLenWrapAlloc = FALSE; BOOL pcchReaderLenWrapAlloc = FALSE; @@ -1014,6 +1050,8 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, LPBYTE* pPbAtr = (LPBYTE*) pbAtr; LPSTR* pMszReaderNamesA = &mszReaderNamesA; + hContext = PCSC_GetCardContextFromHandle(hCard); + if ((*pcbAtrLen == SCARD_AUTOALLOCATE) && !g_SCardAutoAllocate) pcbAtrLenWrapAlloc = TRUE; @@ -1064,8 +1102,6 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, } else { - hContext = PCSC_GetCardContextFromHandle(hCard); - if (pcbAtrLenWrapAlloc) PCSC_AddMemoryBlock(hContext, *pPbAtr); @@ -1084,15 +1120,14 @@ WINSCARDAPI LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, if (mszReaderNamesA) { - length = (UINT32) PCSC_MultiStringLengthA(mszReaderNamesA); - ConvertToUnicode(CP_UTF8, 0, mszReaderNamesA, length + 2, (WCHAR**) mszReaderNames, 0); - - hContext = PCSC_GetCardContextFromHandle(hCard); - + *pcchReaderLen = ConvertToUnicode(CP_UTF8, 0, mszReaderNamesA, *pcchReaderLen, (WCHAR**) mszReaderNames, 0) * 2; PCSC_AddMemoryBlock(hContext, mszReaderNames); PCSC_SCardFreeMemory(hContext, mszReaderNamesA); } + + *pdwState &= 0xFFFF; + *pdwState = PCSC_ConvertStatusToWinSCard(*pdwState); } return status;