2 * FreeRDP: A Remote Desktop Protocol Implementation
3 * Smart Card Structure Packing
5 * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 * Copyright 2015 Thincast Technologies GmbH
7 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8 * Copyright 2020 Armin Novak <armin.novak@thincast.com>
9 * Copyright 2020 Thincast Technologies GmbH
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
28 #include <winpr/crt.h>
29 #include <winpr/print.h>
31 #include "smartcard_pack.h"
33 static const DWORD g_LogLevel = WLOG_DEBUG;
35 #define smartcard_unpack_redir_scard_context(smartcard, s, context, index) \
36 smartcard_unpack_redir_scard_context_((smartcard), (s), (context), (index), __FILE__, \
37 __FUNCTION__, __LINE__)
38 #define smartcard_unpack_redir_scard_handle(smartcard, s, context, index) \
39 smartcard_unpack_redir_scard_handle_((smartcard), (s), (context), (index), __FILE__, \
40 __FUNCTION__, __LINE__)
42 static LONG smartcard_unpack_redir_scard_context_(SMARTCARD_DEVICE* smartcard, wStream* s,
43 REDIR_SCARDCONTEXT* context, UINT32* index,
44 const char* file, const char* function, int line);
45 static LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s,
46 const REDIR_SCARDCONTEXT* context, DWORD* index);
47 static LONG smartcard_unpack_redir_scard_handle_(SMARTCARD_DEVICE* smartcard, wStream* s,
48 REDIR_SCARDHANDLE* handle, UINT32* index,
49 const char* file, const char* function, int line);
50 static LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s,
51 const REDIR_SCARDHANDLE* handle, DWORD* index);
52 static LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s,
53 REDIR_SCARDCONTEXT* context);
54 static LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s,
55 const REDIR_SCARDCONTEXT* context);
57 static LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s,
58 REDIR_SCARDHANDLE* handle);
59 static LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s,
60 const REDIR_SCARDHANDLE* handle);
69 /* Reads a NDR pointer and checks if the value read has the expected relative
71 #define smartcard_ndr_pointer_read(s, index, ptr) \
72 smartcard_ndr_pointer_read_((s), (index), (ptr), __FILE__, __FUNCTION__, __LINE__)
73 static BOOL smartcard_ndr_pointer_read_(wStream* s, UINT32* index, UINT32* ptr, const char* file,
74 const char* fkt, int line)
76 const UINT32 expect = 0x20000 + (*index) * 4;
81 if (Stream_GetRemainingLength(s) < 4)
84 Stream_Read_UINT32(s, ndrPtr); /* mszGroupsNdrPtr (4 bytes) */
89 /* Allow NULL pointer if we read the result */
90 if (ptr && (ndrPtr == 0))
92 WLog_WARN(TAG, "[%s:%d] Read context pointer 0x%08" PRIx32 ", expected 0x%08" PRIx32, fkt,
93 line, ndrPtr, expect);
97 (*index) = (*index) + 1;
101 static LONG smartcard_ndr_read(wStream* s, BYTE** data, size_t min, size_t elementSize,
104 size_t len, offset, len2;
121 if (Stream_GetRemainingLength(s) < required)
123 WLog_ERR(TAG, "Short data while trying to read NDR pointer, expected 4, got %" PRIu32,
124 Stream_GetRemainingLength(s));
125 return STATUS_BUFFER_TOO_SMALL;
131 Stream_Read_UINT32(s, len);
132 Stream_Read_UINT32(s, offset);
133 Stream_Read_UINT32(s, len2);
134 if (len != offset + len2)
137 "Invalid data when reading full NDR pointer: total=%" PRIu32
138 ", offset=%" PRIu32 ", remaining=%" PRIu32,
140 return STATUS_BUFFER_TOO_SMALL;
144 Stream_Read_UINT32(s, len);
146 if ((len != min) && (min > 0))
149 "Invalid data when reading simple NDR pointer: total=%" PRIu32
150 ", expected=%" PRIu32,
152 return STATUS_BUFFER_TOO_SMALL;
162 WLog_ERR(TAG, "Invalid length read from NDR pointer, minimum %" PRIu32 ", got %" PRIu32,
164 return STATUS_DATA_ERROR;
167 if (len > SIZE_MAX / 2)
168 return STATUS_BUFFER_TOO_SMALL;
170 if (Stream_GetRemainingLength(s) / elementSize < len)
173 "Short data while trying to read data from NDR pointer, expected %" PRIu32
175 len, Stream_GetRemainingLength(s));
176 return STATUS_BUFFER_TOO_SMALL;
180 r = calloc(len + 1, sizeof(CHAR));
182 return SCARD_E_NO_MEMORY;
183 Stream_Read(s, r, len);
184 smartcard_unpack_read_size_align(NULL, s, len, 4);
186 return STATUS_SUCCESS;
189 static BOOL smartcard_ndr_pointer_write(wStream* s, UINT32* index, DWORD length)
191 const UINT32 ndrPtr = 0x20000 + (*index) * 4;
195 if (!Stream_EnsureRemainingCapacity(s, 4))
200 Stream_Write_UINT32(s, ndrPtr); /* mszGroupsNdrPtr (4 bytes) */
201 (*index) = (*index) + 1;
204 Stream_Write_UINT32(s, 0);
208 static LONG smartcard_ndr_write(wStream* s, const BYTE* data, UINT32 size, UINT32 elementSize,
211 const UINT32 offset = 0;
212 const UINT32 len = size;
213 const UINT32 dataLen = size * elementSize;
217 return SCARD_S_SUCCESS;
232 if (!Stream_EnsureRemainingCapacity(s, required + dataLen + 4))
233 return STATUS_BUFFER_TOO_SMALL;
238 Stream_Write_UINT32(s, len);
239 Stream_Write_UINT32(s, offset);
240 Stream_Write_UINT32(s, len);
243 Stream_Write_UINT32(s, len);
250 Stream_Write(s, data, dataLen);
252 Stream_Zero(s, dataLen);
253 return smartcard_pack_write_size_align(NULL, s, len, 4);
256 static LONG smartcard_ndr_write_state(wStream* s, const ReaderState_Return* data, UINT32 size,
261 const ReaderState_Return* reader;
266 return smartcard_ndr_write(s, cnv.data, size, sizeof(ReaderState_Return), type);
269 static LONG smartcard_ndr_read_atrmask(wStream* s, LocateCards_ATRMask** data, size_t min,
274 LocateCards_ATRMask** ppc;
278 return smartcard_ndr_read(s, u.ppv, min, sizeof(LocateCards_ATRMask), type);
281 static LONG smartcard_ndr_read_fixed_string_a(wStream* s, CHAR** data, size_t min, ndr_ptr_t type)
289 return smartcard_ndr_read(s, u.ppv, min, sizeof(CHAR), type);
292 static LONG smartcard_ndr_read_fixed_string_w(wStream* s, WCHAR** data, size_t min, ndr_ptr_t type)
300 return smartcard_ndr_read(s, u.ppv, min, sizeof(WCHAR), type);
303 static LONG smartcard_ndr_read_a(wStream* s, CHAR** data, ndr_ptr_t type)
311 return smartcard_ndr_read(s, u.ppv, 0, sizeof(CHAR), type);
314 static LONG smartcard_ndr_read_w(wStream* s, WCHAR** data, ndr_ptr_t type)
322 return smartcard_ndr_read(s, u.ppv, 0, sizeof(WCHAR), type);
325 static LONG smartcard_ndr_read_u(wStream* s, UUID** data)
333 return smartcard_ndr_read(s, u.ppv, 1, sizeof(UUID), NDR_PTR_FIXED);
336 static char* smartcard_convert_string_list(const void* in, size_t bytes, BOOL unicode)
338 size_t index, length;
354 length = (bytes / 2);
355 if (ConvertFromUnicode(CP_UTF8, 0, string.wz, (int)length, &mszA, 0, NULL, NULL) !=
365 mszA = (char*)malloc(length);
368 CopyMemory(mszA, string.sz, length);
371 for (index = 0; index < length - 1; index++)
373 if (mszA[index] == '\0')
380 static char* smartcard_msz_dump_a(const char* msz, size_t len, char* buffer, size_t bufferLen)
383 const char* cur = msz;
385 while ((len > 0) && cur && cur[0] != '\0' && (bufferLen > 0))
387 size_t clen = strnlen(cur, len);
388 int rc = _snprintf(buf, bufferLen, "%s", cur);
389 bufferLen -= (size_t)rc;
398 static char* smartcard_msz_dump_w(const WCHAR* msz, size_t len, char* buffer, size_t bufferLen)
401 ConvertFromUnicode(CP_UTF8, 0, msz, (int)len, &sz, 0, NULL, NULL);
402 return smartcard_msz_dump_a(sz, len, buffer, bufferLen);
405 static char* smartcard_array_dump(const void* pd, size_t len, char* buffer, size_t bufferLen)
407 const BYTE* data = pd;
410 char* start = buffer;
412 /* Ensure '\0' termination */
415 buffer[bufferLen - 1] = '\0';
419 rc = _snprintf(buffer, bufferLen, "{ ");
420 if ((rc < 0) || ((size_t)rc > bufferLen))
423 bufferLen -= (size_t)rc;
425 for (x = 0; x < len; x++)
427 rc = _snprintf(buffer, bufferLen, "%02X", data[x]);
428 if ((rc < 0) || ((size_t)rc > bufferLen))
431 bufferLen -= (size_t)rc;
434 rc = _snprintf(buffer, bufferLen, " }");
435 if ((rc < 0) || ((size_t)rc > bufferLen))
438 bufferLen -= (size_t)rc;
443 static void smartcard_log_redir_handle(const char* tag, const REDIR_SCARDHANDLE* pHandle)
447 WLog_LVL(tag, g_LogLevel, " hContext: %s",
448 smartcard_array_dump(pHandle->pbHandle, pHandle->cbHandle, buffer, sizeof(buffer)));
451 static void smartcard_log_context(const char* tag, const REDIR_SCARDCONTEXT* phContext)
456 smartcard_array_dump(phContext->pbContext, phContext->cbContext, buffer, sizeof(buffer)));
459 static void smartcard_trace_context_and_string_call_a(const char* name,
460 const REDIR_SCARDCONTEXT* phContext,
463 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
466 WLog_LVL(TAG, g_LogLevel, "%s {", name);
467 smartcard_log_context(TAG, phContext);
468 WLog_LVL(TAG, g_LogLevel, " sz=%s", sz);
470 WLog_LVL(TAG, g_LogLevel, "}");
473 static void smartcard_trace_context_and_string_call_w(const char* name,
474 const REDIR_SCARDCONTEXT* phContext,
478 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
481 WLog_LVL(TAG, g_LogLevel, "%s {", name);
482 smartcard_log_context(TAG, phContext);
483 ConvertFromUnicode(CP_UTF8, 0, sz, -1, &tmp, 0, NULL, NULL);
484 WLog_LVL(TAG, g_LogLevel, " sz=%s", tmp);
487 WLog_LVL(TAG, g_LogLevel, "}");
490 static void smartcard_trace_context_call(SMARTCARD_DEVICE* smartcard, const Context_Call* call,
493 WINPR_UNUSED(smartcard);
495 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
498 WLog_LVL(TAG, g_LogLevel, "%s_Call {", name);
499 smartcard_log_context(TAG, &call->handles.hContext);
501 WLog_LVL(TAG, g_LogLevel, "}");
504 static void smartcard_trace_list_reader_groups_call(SMARTCARD_DEVICE* smartcard,
505 const ListReaderGroups_Call* call, BOOL unicode)
507 WINPR_UNUSED(smartcard);
509 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
512 WLog_LVL(TAG, g_LogLevel, "ListReaderGroups%S_Call {", unicode ? "W" : "A");
513 smartcard_log_context(TAG, &call->handles.hContext);
515 WLog_LVL(TAG, g_LogLevel, "fmszGroupsIsNULL: %" PRId32 " cchGroups: 0x%08" PRIx32,
516 call->fmszGroupsIsNULL, call->cchGroups);
517 WLog_LVL(TAG, g_LogLevel, "}");
520 static void smartcard_trace_get_status_change_w_call(SMARTCARD_DEVICE* smartcard,
521 const GetStatusChangeW_Call* call)
525 char* szCurrentState;
526 LPSCARD_READERSTATEW readerState;
527 WINPR_UNUSED(smartcard);
529 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
532 WLog_LVL(TAG, g_LogLevel, "GetStatusChangeW_Call {");
533 smartcard_log_context(TAG, &call->handles.hContext);
535 WLog_LVL(TAG, g_LogLevel, "dwTimeOut: 0x%08" PRIX32 " cReaders: %" PRIu32 "", call->dwTimeOut,
538 for (index = 0; index < call->cReaders; index++)
540 char* szReaderA = NULL;
541 readerState = &call->rgReaderStates[index];
542 ConvertFromUnicode(CP_UTF8, 0, readerState->szReader, -1, &szReaderA, 0, NULL, NULL);
543 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index,
544 szReaderA, readerState->cbAtr);
545 szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState);
546 szEventState = SCardGetReaderStateString(readerState->dwEventState);
547 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index,
548 szCurrentState, readerState->dwCurrentState);
549 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index,
550 szEventState, readerState->dwEventState);
551 free(szCurrentState);
556 WLog_LVL(TAG, g_LogLevel, "}");
559 static void smartcard_trace_list_reader_groups_return(SMARTCARD_DEVICE* smartcard,
560 const ListReaderGroups_Return* ret,
564 WINPR_UNUSED(smartcard);
566 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
569 mszA = smartcard_convert_string_list(ret->msz, ret->cBytes, unicode);
571 WLog_LVL(TAG, g_LogLevel, "ListReaderGroups%s_Return {", unicode ? "W" : "A");
572 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIx32 ")",
573 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
574 WLog_LVL(TAG, g_LogLevel, " cBytes: %" PRIu32 " msz: %s", ret->cBytes, mszA);
575 WLog_LVL(TAG, g_LogLevel, "}");
579 static void smartcard_trace_list_readers_call(SMARTCARD_DEVICE* smartcard,
580 const ListReaders_Call* call, BOOL unicode)
582 char* mszGroupsA = NULL;
583 WINPR_UNUSED(smartcard);
585 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
588 mszGroupsA = smartcard_convert_string_list(call->mszGroups, call->cBytes, unicode);
590 WLog_LVL(TAG, g_LogLevel, "ListReaders%s_Call {", unicode ? "W" : "A");
591 smartcard_log_context(TAG, &call->handles.hContext);
593 WLog_LVL(TAG, g_LogLevel,
594 "cBytes: %" PRIu32 " mszGroups: %s fmszReadersIsNULL: %" PRId32
595 " cchReaders: 0x%08" PRIX32 "",
596 call->cBytes, mszGroupsA, call->fmszReadersIsNULL, call->cchReaders);
597 WLog_LVL(TAG, g_LogLevel, "}");
602 static void smartcard_trace_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard,
603 const LocateCardsByATRA_Call* call)
607 char* szCurrentState;
609 WINPR_UNUSED(smartcard);
611 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
614 WLog_LVL(TAG, g_LogLevel, "LocateCardsByATRA_Call {");
615 smartcard_log_context(TAG, &call->handles.hContext);
617 for (index = 0; index < call->cReaders; index++)
620 const LPSCARD_READERSTATEA readerState = &call->rgReaderStates[index];
622 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index,
623 readerState->szReader, readerState->cbAtr);
624 szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState);
625 szEventState = SCardGetReaderStateString(readerState->dwEventState);
626 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index,
627 szCurrentState, readerState->dwCurrentState);
628 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index,
629 szEventState, readerState->dwEventState);
632 TAG, "\t[%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index, readerState->cbAtr,
633 smartcard_array_dump(readerState->rgbAtr, readerState->cbAtr, buffer, sizeof(buffer)));
635 free(szCurrentState);
639 WLog_LVL(TAG, g_LogLevel, "}");
642 static void smartcard_trace_locate_cards_a_call(SMARTCARD_DEVICE* smartcard,
643 const LocateCardsA_Call* call)
646 WINPR_UNUSED(smartcard);
648 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
651 WLog_LVL(TAG, g_LogLevel, "LocateCardsA_Call {");
652 smartcard_log_context(TAG, &call->handles.hContext);
653 WLog_LVL(TAG, g_LogLevel, " cBytes=%" PRId32, call->cBytes);
654 WLog_LVL(TAG, g_LogLevel, " mszCards=%s",
655 smartcard_msz_dump_a(call->mszCards, call->cBytes, buffer, sizeof(buffer)));
656 WLog_LVL(TAG, g_LogLevel, " cReaders=%" PRId32, call->cReaders);
657 // WLog_LVL(TAG, g_LogLevel, " cReaders=%" PRId32, call->rgReaderStates);
659 WLog_LVL(TAG, g_LogLevel, "}");
662 static void smartcard_trace_locate_cards_return(SMARTCARD_DEVICE* smartcard,
663 const LocateCards_Return* ret)
665 WINPR_UNUSED(smartcard);
666 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
669 WLog_LVL(TAG, g_LogLevel, "LocateCards_Return {");
670 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
671 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
673 if (ret->ReturnCode == SCARD_S_SUCCESS)
675 WLog_LVL(TAG, g_LogLevel, " cReaders=%" PRId32, ret->cReaders);
677 WLog_LVL(TAG, g_LogLevel, "}");
680 static void smartcard_trace_get_reader_icon_return(SMARTCARD_DEVICE* smartcard,
681 const GetReaderIcon_Return* ret)
683 WINPR_UNUSED(smartcard);
684 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
687 WLog_LVL(TAG, g_LogLevel, "GetReaderIcon_Return {");
688 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
689 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
691 if (ret->ReturnCode == SCARD_S_SUCCESS)
693 WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRId32, ret->cbDataLen);
695 WLog_LVL(TAG, g_LogLevel, "}");
698 static void smartcard_trace_get_transmit_count_return(SMARTCARD_DEVICE* smartcard,
699 const GetTransmitCount_Return* ret)
701 WINPR_UNUSED(smartcard);
702 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
705 WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Return {");
706 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
707 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
709 WLog_LVL(TAG, g_LogLevel, " cTransmitCount=%" PRIu32, ret->cTransmitCount);
710 WLog_LVL(TAG, g_LogLevel, "}");
713 static void smartcard_trace_read_cache_return(SMARTCARD_DEVICE* smartcard,
714 const ReadCache_Return* ret)
716 WINPR_UNUSED(smartcard);
717 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
720 WLog_LVL(TAG, g_LogLevel, "ReadCache_Return {");
721 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
722 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
724 if (ret->ReturnCode == SCARD_S_SUCCESS)
727 WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRId32, ret->cbDataLen);
728 WLog_LVL(TAG, g_LogLevel, " cbData: %s",
729 smartcard_array_dump(ret->pbData, ret->cbDataLen, buffer, sizeof(buffer)));
731 WLog_LVL(TAG, g_LogLevel, "}");
734 static void smartcard_trace_locate_cards_w_call(SMARTCARD_DEVICE* smartcard,
735 const LocateCardsW_Call* call)
738 WINPR_UNUSED(smartcard);
739 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
742 WLog_LVL(TAG, g_LogLevel, "LocateCardsW_Call {");
743 smartcard_log_context(TAG, &call->handles.hContext);
744 WLog_LVL(TAG, g_LogLevel, " cBytes=%" PRId32, call->cBytes);
745 WLog_LVL(TAG, g_LogLevel, " sz2=%s",
746 smartcard_msz_dump_w(call->mszCards, call->cBytes, buffer, sizeof(buffer)));
747 WLog_LVL(TAG, g_LogLevel, " cReaders=%" PRId32, call->cReaders);
748 // WLog_LVL(TAG, g_LogLevel, " sz2=%s", call->rgReaderStates);
749 WLog_LVL(TAG, g_LogLevel, "}");
752 static void smartcard_trace_list_readers_return(SMARTCARD_DEVICE* smartcard,
753 const ListReaders_Return* ret, BOOL unicode)
756 WINPR_UNUSED(smartcard);
758 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
761 WLog_LVL(TAG, g_LogLevel, "ListReaders%s_Return {", unicode ? "W" : "A");
762 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
763 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
765 if (ret->ReturnCode != SCARD_S_SUCCESS)
767 WLog_LVL(TAG, g_LogLevel, "}");
771 mszA = smartcard_convert_string_list(ret->msz, ret->cBytes, unicode);
773 WLog_LVL(TAG, g_LogLevel, " cBytes: %" PRIu32 " msz: %s", ret->cBytes, mszA);
774 WLog_LVL(TAG, g_LogLevel, "}");
778 static void smartcard_trace_get_status_change_return(SMARTCARD_DEVICE* smartcard,
779 const GetStatusChange_Return* ret,
784 char* szCurrentState;
786 WINPR_UNUSED(smartcard);
788 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
791 WLog_LVL(TAG, g_LogLevel, "GetStatusChange%s_Return {", unicode ? "W" : "A");
792 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
793 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
794 WLog_LVL(TAG, g_LogLevel, " cReaders: %" PRIu32 "", ret->cReaders);
796 for (index = 0; index < ret->cReaders; index++)
799 const ReaderState_Return* rgReaderState = &(ret->rgReaderStates[index]);
800 szCurrentState = SCardGetReaderStateString(rgReaderState->dwCurrentState);
801 szEventState = SCardGetReaderStateString(rgReaderState->dwEventState);
802 WLog_LVL(TAG, g_LogLevel, " [%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index,
803 szCurrentState, rgReaderState->dwCurrentState);
804 WLog_LVL(TAG, g_LogLevel, " [%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index,
805 szEventState, rgReaderState->dwEventState);
806 WLog_LVL(TAG, g_LogLevel, " [%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index,
807 rgReaderState->cbAtr,
808 smartcard_array_dump(rgReaderState->rgbAtr, rgReaderState->cbAtr, buffer,
810 free(szCurrentState);
814 WLog_LVL(TAG, g_LogLevel, "}");
817 static void smartcard_trace_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard,
818 const ContextAndTwoStringA_Call* call)
820 WINPR_UNUSED(smartcard);
821 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
824 WLog_LVL(TAG, g_LogLevel, "ContextAndTwoStringW_Call {");
825 smartcard_log_context(TAG, &call->handles.hContext);
826 WLog_LVL(TAG, g_LogLevel, " sz1=%s", call->sz1);
827 WLog_LVL(TAG, g_LogLevel, " sz2=%s", call->sz2);
828 WLog_LVL(TAG, g_LogLevel, "}");
831 static void smartcard_trace_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard,
832 const ContextAndTwoStringW_Call* call)
837 WINPR_UNUSED(smartcard);
838 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
841 WLog_LVL(TAG, g_LogLevel, "ContextAndTwoStringW_Call {");
842 smartcard_log_context(TAG, &call->handles.hContext);
843 ConvertFromUnicode(CP_UTF8, 0, call->sz1, -1, &sz1, 0, NULL, NULL);
844 ConvertFromUnicode(CP_UTF8, 0, call->sz2, -1, &sz2, 0, NULL, NULL);
845 WLog_LVL(TAG, g_LogLevel, " sz1=%s", sz1);
846 WLog_LVL(TAG, g_LogLevel, " sz2=%s", sz2);
850 WLog_LVL(TAG, g_LogLevel, "}");
853 static void smartcard_trace_get_transmit_count_call(SMARTCARD_DEVICE* smartcard,
854 const GetTransmitCount_Call* call)
856 WINPR_UNUSED(smartcard);
857 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
860 WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {");
861 smartcard_log_context(TAG, &call->handles.hContext);
862 smartcard_log_redir_handle(TAG, &call->handles.hCard);
864 WLog_LVL(TAG, g_LogLevel, "}");
867 static void smartcard_trace_write_cache_a_call(SMARTCARD_DEVICE* smartcard,
868 const WriteCacheA_Call* call)
871 WINPR_UNUSED(smartcard);
872 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
875 WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {");
877 WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", call->szLookupName);
879 smartcard_log_context(TAG, &call->Common.handles.hContext);
881 TAG, "..CardIdentifier=%s",
882 smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer)));
883 WLog_LVL(TAG, g_LogLevel, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter);
884 WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRIu32, call->Common.cbDataLen);
887 smartcard_array_dump(call->Common.pbData, call->Common.cbDataLen, buffer, sizeof(buffer)));
888 WLog_LVL(TAG, g_LogLevel, "}");
891 static void smartcard_trace_write_cache_w_call(SMARTCARD_DEVICE* smartcard,
892 const WriteCacheW_Call* call)
896 WINPR_UNUSED(smartcard);
897 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
900 WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {");
902 ConvertFromUnicode(CP_UTF8, 0, call->szLookupName, -1, &tmp, 0, NULL, NULL);
903 WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", tmp);
905 smartcard_log_context(TAG, &call->Common.handles.hContext);
907 TAG, "..CardIdentifier=%s",
908 smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer)));
909 WLog_LVL(TAG, g_LogLevel, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter);
910 WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRIu32, call->Common.cbDataLen);
913 smartcard_array_dump(call->Common.pbData, call->Common.cbDataLen, buffer, sizeof(buffer)));
914 WLog_LVL(TAG, g_LogLevel, "}");
917 static void smartcard_trace_read_cache_a_call(SMARTCARD_DEVICE* smartcard,
918 const ReadCacheA_Call* call)
921 WINPR_UNUSED(smartcard);
922 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
925 WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {");
927 WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", call->szLookupName);
928 smartcard_log_context(TAG, &call->Common.handles.hContext);
930 TAG, "..CardIdentifier=%s",
931 smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer)));
932 WLog_LVL(TAG, g_LogLevel, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter);
933 WLog_LVL(TAG, g_LogLevel, " fPbDataIsNULL=%" PRId32, call->Common.fPbDataIsNULL);
934 WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRIu32, call->Common.cbDataLen);
936 WLog_LVL(TAG, g_LogLevel, "}");
939 static void smartcard_trace_read_cache_w_call(SMARTCARD_DEVICE* smartcard,
940 const ReadCacheW_Call* call)
944 WINPR_UNUSED(smartcard);
945 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
948 WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {");
950 ConvertFromUnicode(CP_UTF8, 0, call->szLookupName, -1, &tmp, 0, NULL, NULL);
951 WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", tmp);
953 smartcard_log_context(TAG, &call->Common.handles.hContext);
955 TAG, "..CardIdentifier=%s",
956 smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer)));
957 WLog_LVL(TAG, g_LogLevel, " FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter);
958 WLog_LVL(TAG, g_LogLevel, " fPbDataIsNULL=%" PRId32, call->Common.fPbDataIsNULL);
959 WLog_LVL(TAG, g_LogLevel, " cbDataLen=%" PRIu32, call->Common.cbDataLen);
961 WLog_LVL(TAG, g_LogLevel, "}");
964 static void smartcard_trace_transmit_call(SMARTCARD_DEVICE* smartcard, const Transmit_Call* call)
968 WINPR_UNUSED(smartcard);
970 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
973 WLog_LVL(TAG, g_LogLevel, "Transmit_Call {");
974 smartcard_log_context(TAG, &call->handles.hContext);
975 smartcard_log_redir_handle(TAG, &call->handles.hCard);
977 if (call->pioSendPci)
979 cbExtraBytes = (UINT32)(call->pioSendPci->cbPciLength - sizeof(SCARD_IO_REQUEST));
980 pbExtraBytes = &((BYTE*)call->pioSendPci)[sizeof(SCARD_IO_REQUEST)];
981 WLog_LVL(TAG, g_LogLevel, "pioSendPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "",
982 call->pioSendPci->dwProtocol, cbExtraBytes);
987 WLog_LVL(TAG, g_LogLevel, "pbExtraBytes: %s",
988 smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer)));
993 WLog_LVL(TAG, g_LogLevel, "pioSendPci: null");
996 WLog_LVL(TAG, g_LogLevel, "cbSendLength: %" PRIu32 "", call->cbSendLength);
998 if (call->pbSendBuffer)
1002 TAG, "pbSendBuffer: %s",
1003 smartcard_array_dump(call->pbSendBuffer, call->cbSendLength, buffer, sizeof(buffer)));
1007 WLog_LVL(TAG, g_LogLevel, "pbSendBuffer: null");
1010 if (call->pioRecvPci)
1012 cbExtraBytes = (UINT32)(call->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST));
1013 pbExtraBytes = &((BYTE*)call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
1014 WLog_LVL(TAG, g_LogLevel, "pioRecvPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "",
1015 call->pioRecvPci->dwProtocol, cbExtraBytes);
1020 WLog_LVL(TAG, g_LogLevel, "pbExtraBytes: %s",
1021 smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer)));
1026 WLog_LVL(TAG, g_LogLevel, "pioRecvPci: null");
1029 WLog_LVL(TAG, g_LogLevel, "fpbRecvBufferIsNULL: %" PRId32 " cbRecvLength: %" PRIu32 "",
1030 call->fpbRecvBufferIsNULL, call->cbRecvLength);
1031 WLog_LVL(TAG, g_LogLevel, "}");
1034 static void smartcard_trace_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard,
1035 const LocateCardsByATRW_Call* call)
1039 char* szCurrentState;
1041 WINPR_UNUSED(smartcard);
1043 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1046 WLog_LVL(TAG, g_LogLevel, "LocateCardsByATRW_Call {");
1047 smartcard_log_context(TAG, &call->handles.hContext);
1049 for (index = 0; index < call->cReaders; index++)
1053 const LPSCARD_READERSTATEW readerState =
1054 (const LPSCARD_READERSTATEW)&call->rgReaderStates[index];
1056 ConvertFromUnicode(CP_UTF8, 0, readerState->szReader, -1, &tmp, 0, NULL, NULL);
1057 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, tmp,
1058 readerState->cbAtr);
1059 szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState);
1060 szEventState = SCardGetReaderStateString(readerState->dwEventState);
1061 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index,
1062 szCurrentState, readerState->dwCurrentState);
1063 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index,
1064 szEventState, readerState->dwEventState);
1067 TAG, "\t[%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index, readerState->cbAtr,
1068 smartcard_array_dump(readerState->rgbAtr, readerState->cbAtr, buffer, sizeof(buffer)));
1070 free(szCurrentState);
1075 WLog_LVL(TAG, g_LogLevel, "}");
1078 static void smartcard_trace_transmit_return(SMARTCARD_DEVICE* smartcard, const Transmit_Return* ret)
1080 UINT32 cbExtraBytes;
1082 WINPR_UNUSED(smartcard);
1084 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1087 WLog_LVL(TAG, g_LogLevel, "Transmit_Return {");
1088 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1089 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1091 if (ret->pioRecvPci)
1093 cbExtraBytes = (UINT32)(ret->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST));
1094 pbExtraBytes = &((BYTE*)ret->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
1095 WLog_LVL(TAG, g_LogLevel, " pioRecvPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "",
1096 ret->pioRecvPci->dwProtocol, cbExtraBytes);
1101 WLog_LVL(TAG, g_LogLevel, " pbExtraBytes: %s",
1102 smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer)));
1107 WLog_LVL(TAG, g_LogLevel, " pioRecvPci: null");
1110 WLog_LVL(TAG, g_LogLevel, " cbRecvLength: %" PRIu32 "", ret->cbRecvLength);
1112 if (ret->pbRecvBuffer)
1116 TAG, " pbRecvBuffer: %s",
1117 smartcard_array_dump(ret->pbRecvBuffer, ret->cbRecvLength, buffer, sizeof(buffer)));
1121 WLog_LVL(TAG, g_LogLevel, " pbRecvBuffer: null");
1124 WLog_LVL(TAG, g_LogLevel, "}");
1127 static void smartcard_trace_control_return(SMARTCARD_DEVICE* smartcard, const Control_Return* ret)
1129 WINPR_UNUSED(smartcard);
1131 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1134 WLog_LVL(TAG, g_LogLevel, "Control_Return {");
1135 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1136 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1137 WLog_LVL(TAG, g_LogLevel, " cbOutBufferSize: %" PRIu32 "", ret->cbOutBufferSize);
1139 if (ret->pvOutBuffer)
1143 TAG, "pvOutBuffer: %s",
1144 smartcard_array_dump(ret->pvOutBuffer, ret->cbOutBufferSize, buffer, sizeof(buffer)));
1148 WLog_LVL(TAG, g_LogLevel, "pvOutBuffer: null");
1151 WLog_LVL(TAG, g_LogLevel, "}");
1154 static void smartcard_trace_control_call(SMARTCARD_DEVICE* smartcard, const Control_Call* call)
1156 WINPR_UNUSED(smartcard);
1158 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1161 WLog_LVL(TAG, g_LogLevel, "Control_Call {");
1162 smartcard_log_context(TAG, &call->handles.hContext);
1163 smartcard_log_redir_handle(TAG, &call->handles.hCard);
1165 WLog_LVL(TAG, g_LogLevel,
1166 "dwControlCode: 0x%08" PRIX32 " cbInBufferSize: %" PRIu32
1167 " fpvOutBufferIsNULL: %" PRId32 " cbOutBufferSize: %" PRIu32 "",
1168 call->dwControlCode, call->cbInBufferSize, call->fpvOutBufferIsNULL,
1169 call->cbOutBufferSize);
1171 if (call->pvInBuffer)
1175 TAG, "pbInBuffer: %s",
1176 smartcard_array_dump(call->pvInBuffer, call->cbInBufferSize, buffer, sizeof(buffer)));
1180 WLog_LVL(TAG, g_LogLevel, "pvInBuffer: null");
1183 WLog_LVL(TAG, g_LogLevel, "}");
1186 static void smartcard_trace_set_attrib_call(SMARTCARD_DEVICE* smartcard, const SetAttrib_Call* call)
1189 WINPR_UNUSED(smartcard);
1191 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1194 WLog_LVL(TAG, g_LogLevel, "GetAttrib_Call {");
1195 smartcard_log_context(TAG, &call->handles.hContext);
1196 smartcard_log_redir_handle(TAG, &call->handles.hCard);
1197 WLog_LVL(TAG, g_LogLevel, "dwAttrId: 0x%08" PRIX32, call->dwAttrId);
1198 WLog_LVL(TAG, g_LogLevel, "cbAttrLen: 0x%08" PRId32, call->cbAttrLen);
1199 WLog_LVL(TAG, g_LogLevel, "pbAttr: %s",
1200 smartcard_array_dump(call->pbAttr, call->cbAttrLen, buffer, sizeof(buffer)));
1201 WLog_LVL(TAG, g_LogLevel, "}");
1204 static void smartcard_trace_get_attrib_return(SMARTCARD_DEVICE* smartcard,
1205 const GetAttrib_Return* ret, DWORD dwAttrId)
1207 WINPR_UNUSED(smartcard);
1209 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1212 WLog_LVL(TAG, g_LogLevel, "GetAttrib_Return {");
1213 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1214 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1215 WLog_LVL(TAG, g_LogLevel, " dwAttrId: %s (0x%08" PRIX32 ") cbAttrLen: 0x%08" PRIX32 "",
1216 SCardGetAttributeString(dwAttrId), dwAttrId, ret->cbAttrLen);
1218 if (dwAttrId == SCARD_ATTR_VENDOR_NAME)
1220 WLog_LVL(TAG, g_LogLevel, " pbAttr: %.*s", ret->cbAttrLen, (char*)ret->pbAttr);
1222 else if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE)
1229 attr.pb = ret->pbAttr;
1230 WLog_LVL(TAG, g_LogLevel, " dwProtocolType: %s (0x%08" PRIX32 ")",
1231 SCardGetProtocolString(*attr.pd), *attr.pd);
1234 WLog_LVL(TAG, g_LogLevel, "}");
1237 static void smartcard_trace_get_attrib_call(SMARTCARD_DEVICE* smartcard, const GetAttrib_Call* call)
1239 WINPR_UNUSED(smartcard);
1241 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1244 WLog_LVL(TAG, g_LogLevel, "GetAttrib_Call {");
1245 smartcard_log_context(TAG, &call->handles.hContext);
1246 smartcard_log_redir_handle(TAG, &call->handles.hCard);
1248 WLog_LVL(TAG, g_LogLevel,
1249 "dwAttrId: %s (0x%08" PRIX32 ") fpbAttrIsNULL: %" PRId32 " cbAttrLen: 0x%08" PRIX32 "",
1250 SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->fpbAttrIsNULL,
1252 WLog_LVL(TAG, g_LogLevel, "}");
1255 static void smartcard_trace_status_call(SMARTCARD_DEVICE* smartcard, const Status_Call* call,
1258 WINPR_UNUSED(smartcard);
1260 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1263 WLog_LVL(TAG, g_LogLevel, "Status%s_Call {", unicode ? "W" : "A");
1264 smartcard_log_context(TAG, &call->handles.hContext);
1265 smartcard_log_redir_handle(TAG, &call->handles.hCard);
1267 WLog_LVL(TAG, g_LogLevel,
1268 "fmszReaderNamesIsNULL: %" PRId32 " cchReaderLen: %" PRIu32 " cbAtrLen: %" PRIu32 "",
1269 call->fmszReaderNamesIsNULL, call->cchReaderLen, call->cbAtrLen);
1270 WLog_LVL(TAG, g_LogLevel, "}");
1273 static void smartcard_trace_status_return(SMARTCARD_DEVICE* smartcard, const Status_Return* ret,
1276 char* mszReaderNamesA = NULL;
1279 WINPR_UNUSED(smartcard);
1281 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1284 mszReaderNamesA = smartcard_convert_string_list(ret->mszReaderNames, ret->cBytes, unicode);
1286 WLog_LVL(TAG, g_LogLevel, "Status%s_Return {", unicode ? "W" : "A");
1287 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1288 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1289 WLog_LVL(TAG, g_LogLevel, " dwState: %s (0x%08" PRIX32 ") dwProtocol: %s (0x%08" PRIX32 ")",
1290 SCardGetCardStateString(ret->dwState), ret->dwState,
1291 SCardGetProtocolString(ret->dwProtocol), ret->dwProtocol);
1293 WLog_LVL(TAG, g_LogLevel, " cBytes: %" PRIu32 " mszReaderNames: %s", ret->cBytes,
1296 WLog_LVL(TAG, g_LogLevel, " cbAtrLen: %" PRIu32 " pbAtr: %s", ret->cbAtrLen,
1297 smartcard_array_dump(ret->pbAtr, ret->cbAtrLen, buffer, sizeof(buffer)));
1298 WLog_LVL(TAG, g_LogLevel, "}");
1299 free(mszReaderNamesA);
1302 static void smartcard_trace_state_return(SMARTCARD_DEVICE* smartcard, const State_Return* ret)
1306 WINPR_UNUSED(smartcard);
1308 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1311 WLog_LVL(TAG, g_LogLevel, "Reconnect_Return {");
1312 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1313 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1314 WLog_LVL(TAG, g_LogLevel, " dwState: %s (0x%08" PRIX32 ")", ret->dwState);
1315 WLog_LVL(TAG, g_LogLevel, " dwProtocol: %s (0x%08" PRIX32 ")", ret->dwProtocol);
1316 WLog_LVL(TAG, g_LogLevel, " cbAtrLen: %s (0x%08" PRIX32 ")", ret->cbAtrLen);
1317 WLog_LVL(TAG, g_LogLevel, " rgAtr: %s",
1318 smartcard_array_dump(ret->rgAtr, sizeof(ret->rgAtr), buffer, sizeof(buffer)));
1319 WLog_LVL(TAG, g_LogLevel, "}");
1322 static void smartcard_trace_reconnect_return(SMARTCARD_DEVICE* smartcard,
1323 const Reconnect_Return* ret)
1325 WINPR_UNUSED(smartcard);
1327 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1330 WLog_LVL(TAG, g_LogLevel, "Reconnect_Return {");
1331 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1332 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1333 WLog_LVL(TAG, g_LogLevel, " dwActiveProtocol: %s (0x%08" PRIX32 ")",
1334 SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol);
1335 WLog_LVL(TAG, g_LogLevel, "}");
1338 static void smartcard_trace_connect_a_call(SMARTCARD_DEVICE* smartcard, const ConnectA_Call* call)
1340 WINPR_UNUSED(smartcard);
1342 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1345 WLog_LVL(TAG, g_LogLevel, "ConnectA_Call {");
1346 smartcard_log_context(TAG, &call->Common.handles.hContext);
1348 WLog_LVL(TAG, g_LogLevel,
1349 "szReader: %s dwShareMode: %s (0x%08" PRIX32 ") dwPreferredProtocols: %s (0x%08" PRIX32
1351 call->szReader, SCardGetShareModeString(call->Common.dwShareMode),
1352 call->Common.dwShareMode, SCardGetProtocolString(call->Common.dwPreferredProtocols),
1353 call->Common.dwPreferredProtocols);
1354 WLog_LVL(TAG, g_LogLevel, "}");
1357 static void smartcard_trace_connect_w_call(SMARTCARD_DEVICE* smartcard, const ConnectW_Call* call)
1359 char* szReaderA = NULL;
1360 WINPR_UNUSED(smartcard);
1362 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1365 ConvertFromUnicode(CP_UTF8, 0, call->szReader, -1, &szReaderA, 0, NULL, NULL);
1366 WLog_LVL(TAG, g_LogLevel, "ConnectW_Call {");
1367 smartcard_log_context(TAG, &call->Common.handles.hContext);
1369 WLog_LVL(TAG, g_LogLevel,
1370 "szReader: %s dwShareMode: %s (0x%08" PRIX32 ") dwPreferredProtocols: %s (0x%08" PRIX32
1372 szReaderA, SCardGetShareModeString(call->Common.dwShareMode), call->Common.dwShareMode,
1373 SCardGetProtocolString(call->Common.dwPreferredProtocols),
1374 call->Common.dwPreferredProtocols);
1375 WLog_LVL(TAG, g_LogLevel, "}");
1379 static void smartcard_trace_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard,
1380 const HCardAndDisposition_Call* call,
1383 WINPR_UNUSED(smartcard);
1385 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1388 WLog_LVL(TAG, g_LogLevel, "%s_Call {", name);
1389 smartcard_log_context(TAG, &call->handles.hContext);
1390 smartcard_log_redir_handle(TAG, &call->handles.hCard);
1392 WLog_LVL(TAG, g_LogLevel, "dwDisposition: %s (0x%08" PRIX32 ")",
1393 SCardGetDispositionString(call->dwDisposition), call->dwDisposition);
1394 WLog_LVL(TAG, g_LogLevel, "}");
1397 static void smartcard_trace_establish_context_call(SMARTCARD_DEVICE* smartcard,
1398 const EstablishContext_Call* call)
1400 WINPR_UNUSED(smartcard);
1402 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1405 WLog_LVL(TAG, g_LogLevel, "EstablishContext_Call {");
1406 WLog_LVL(TAG, g_LogLevel, "dwScope: %s (0x%08" PRIX32 ")", SCardGetScopeString(call->dwScope),
1408 WLog_LVL(TAG, g_LogLevel, "}");
1411 static void smartcard_trace_establish_context_return(SMARTCARD_DEVICE* smartcard,
1412 const EstablishContext_Return* ret)
1414 WINPR_UNUSED(smartcard);
1416 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1419 WLog_LVL(TAG, g_LogLevel, "EstablishContext_Return {");
1420 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1421 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1422 smartcard_log_context(TAG, &ret->hContext);
1424 WLog_LVL(TAG, g_LogLevel, "}");
1427 void smartcard_trace_long_return(SMARTCARD_DEVICE* smartcard, const Long_Return* ret,
1430 WINPR_UNUSED(smartcard);
1432 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1435 WLog_LVL(TAG, g_LogLevel, "%s_Return {", name);
1436 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1437 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1438 WLog_LVL(TAG, g_LogLevel, "}");
1441 static void smartcard_trace_connect_return(SMARTCARD_DEVICE* smartcard, const Connect_Return* ret)
1443 WINPR_UNUSED(smartcard);
1445 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1448 WLog_LVL(TAG, g_LogLevel, "Connect_Return {");
1449 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1450 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1451 smartcard_log_context(TAG, &ret->hContext);
1452 smartcard_log_redir_handle(TAG, &ret->hCard);
1454 WLog_LVL(TAG, g_LogLevel, " dwActiveProtocol: %s (0x%08" PRIX32 ")",
1455 SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol);
1456 WLog_LVL(TAG, g_LogLevel, "}");
1459 void smartcard_trace_reconnect_call(SMARTCARD_DEVICE* smartcard, const Reconnect_Call* call)
1461 WINPR_UNUSED(smartcard);
1463 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1466 WLog_LVL(TAG, g_LogLevel, "Reconnect_Call {");
1467 smartcard_log_context(TAG, &call->handles.hContext);
1468 smartcard_log_redir_handle(TAG, &call->handles.hCard);
1470 WLog_LVL(TAG, g_LogLevel,
1471 "dwShareMode: %s (0x%08" PRIX32 ") dwPreferredProtocols: %s (0x%08" PRIX32
1472 ") dwInitialization: %s (0x%08" PRIX32 ")",
1473 SCardGetShareModeString(call->dwShareMode), call->dwShareMode,
1474 SCardGetProtocolString(call->dwPreferredProtocols), call->dwPreferredProtocols,
1475 SCardGetDispositionString(call->dwInitialization), call->dwInitialization);
1476 WLog_LVL(TAG, g_LogLevel, "}");
1479 static void smartcard_trace_device_type_id_return(SMARTCARD_DEVICE* smartcard,
1480 const GetDeviceTypeId_Return* ret)
1482 WINPR_UNUSED(smartcard);
1484 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
1487 WLog_LVL(TAG, g_LogLevel, "GetDeviceTypeId_Return {");
1488 WLog_LVL(TAG, g_LogLevel, " ReturnCode: %s (0x%08" PRIX32 ")",
1489 SCardGetErrorString(ret->ReturnCode), ret->ReturnCode);
1490 WLog_LVL(TAG, g_LogLevel, " dwDeviceId=%08" PRIx32, ret->dwDeviceId);
1492 WLog_LVL(TAG, g_LogLevel, "}");
1495 static LONG smartcard_unpack_common_context_and_string_a(SMARTCARD_DEVICE* smartcard, wStream* s,
1496 REDIR_SCARDCONTEXT* phContext,
1497 CHAR** pszReaderName)
1501 status = smartcard_unpack_redir_scard_context(smartcard, s, phContext, &index);
1502 if (status != SCARD_S_SUCCESS)
1505 if (!smartcard_ndr_pointer_read(s, &index, NULL))
1506 return ERROR_INVALID_DATA;
1508 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, phContext);
1509 if (status != SCARD_S_SUCCESS)
1512 status = smartcard_ndr_read_a(s, pszReaderName, NDR_PTR_FULL);
1513 if (status != SCARD_S_SUCCESS)
1516 smartcard_trace_context_and_string_call_a(__FUNCTION__, phContext, *pszReaderName);
1517 return SCARD_S_SUCCESS;
1520 static LONG smartcard_unpack_common_context_and_string_w(SMARTCARD_DEVICE* smartcard, wStream* s,
1521 REDIR_SCARDCONTEXT* phContext,
1522 WCHAR** pszReaderName)
1527 status = smartcard_unpack_redir_scard_context(smartcard, s, phContext, &index);
1528 if (status != SCARD_S_SUCCESS)
1531 if (!smartcard_ndr_pointer_read(s, &index, NULL))
1532 return ERROR_INVALID_DATA;
1534 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, phContext);
1535 if (status != SCARD_S_SUCCESS)
1538 status = smartcard_ndr_read_w(s, pszReaderName, NDR_PTR_FULL);
1539 if (status != SCARD_S_SUCCESS)
1542 smartcard_trace_context_and_string_call_w(__FUNCTION__, phContext, *pszReaderName);
1543 return SCARD_S_SUCCESS;
1546 LONG smartcard_unpack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s)
1551 UINT16 commonHeaderLength;
1552 WINPR_UNUSED(smartcard);
1554 if (Stream_GetRemainingLength(s) < 8)
1556 WLog_WARN(TAG, "CommonTypeHeader is too short: %" PRIuz "", Stream_GetRemainingLength(s));
1557 return STATUS_BUFFER_TOO_SMALL;
1560 /* Process CommonTypeHeader */
1561 Stream_Read_UINT8(s, version); /* Version (1 byte) */
1562 Stream_Read_UINT8(s, endianness); /* Endianness (1 byte) */
1563 Stream_Read_UINT16(s, commonHeaderLength); /* CommonHeaderLength (2 bytes) */
1564 Stream_Read_UINT32(s, filler); /* Filler (4 bytes), should be 0xCCCCCCCC */
1568 WLog_WARN(TAG, "Unsupported CommonTypeHeader Version %" PRIu8 "", version);
1569 return STATUS_INVALID_PARAMETER;
1572 if (endianness != 0x10)
1574 WLog_WARN(TAG, "Unsupported CommonTypeHeader Endianness %" PRIu8 "", endianness);
1575 return STATUS_INVALID_PARAMETER;
1578 if (commonHeaderLength != 8)
1580 WLog_WARN(TAG, "Unsupported CommonTypeHeader CommonHeaderLength %" PRIu16 "",
1581 commonHeaderLength);
1582 return STATUS_INVALID_PARAMETER;
1585 if (filler != 0xCCCCCCCC)
1587 WLog_WARN(TAG, "Unexpected CommonTypeHeader Filler 0x%08" PRIX32 "", filler);
1588 return STATUS_INVALID_PARAMETER;
1591 return SCARD_S_SUCCESS;
1594 void smartcard_pack_common_type_header(SMARTCARD_DEVICE* smartcard, wStream* s)
1596 WINPR_UNUSED(smartcard);
1597 Stream_Write_UINT8(s, 1); /* Version (1 byte) */
1598 Stream_Write_UINT8(s, 0x10); /* Endianness (1 byte) */
1599 Stream_Write_UINT16(s, 8); /* CommonHeaderLength (2 bytes) */
1600 Stream_Write_UINT32(s, 0xCCCCCCCC); /* Filler (4 bytes), should be 0xCCCCCCCC */
1603 LONG smartcard_unpack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s)
1606 UINT32 objectBufferLength;
1607 WINPR_UNUSED(smartcard);
1609 if (Stream_GetRemainingLength(s) < 8)
1611 WLog_WARN(TAG, "PrivateTypeHeader is too short: %" PRIuz "", Stream_GetRemainingLength(s));
1612 return STATUS_BUFFER_TOO_SMALL;
1615 Stream_Read_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */
1616 Stream_Read_UINT32(s, filler); /* Filler (4 bytes), should be 0x00000000 */
1618 if (filler != 0x00000000)
1620 WLog_WARN(TAG, "Unexpected PrivateTypeHeader Filler 0x%08" PRIX32 "", filler);
1621 return STATUS_INVALID_PARAMETER;
1624 if (objectBufferLength != Stream_GetRemainingLength(s))
1627 "PrivateTypeHeader ObjectBufferLength mismatch: Actual: %" PRIu32
1628 ", Expected: %" PRIuz "",
1629 objectBufferLength, Stream_GetRemainingLength(s));
1630 return STATUS_INVALID_PARAMETER;
1633 return SCARD_S_SUCCESS;
1636 void smartcard_pack_private_type_header(SMARTCARD_DEVICE* smartcard, wStream* s,
1637 UINT32 objectBufferLength)
1639 WINPR_UNUSED(smartcard);
1640 Stream_Write_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */
1641 Stream_Write_UINT32(s, 0x00000000); /* Filler (4 bytes), should be 0x00000000 */
1644 LONG smartcard_unpack_read_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size,
1648 WINPR_UNUSED(smartcard);
1650 size = (size + alignment - 1) & ~(alignment - 1);
1654 Stream_Seek(s, pad);
1659 LONG smartcard_pack_write_size_align(SMARTCARD_DEVICE* smartcard, wStream* s, size_t size,
1663 WINPR_UNUSED(smartcard);
1665 size = (size + alignment - 1) & ~(alignment - 1);
1670 if (!Stream_EnsureRemainingCapacity(s, pad))
1672 WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
1673 return SCARD_F_INTERNAL_ERROR;
1676 Stream_Zero(s, pad);
1679 return SCARD_S_SUCCESS;
1682 SCARDCONTEXT smartcard_scard_context_native_from_redir(SMARTCARD_DEVICE* smartcard,
1683 REDIR_SCARDCONTEXT* context)
1685 SCARDCONTEXT hContext = { 0 };
1686 WINPR_UNUSED(smartcard);
1688 if ((context->cbContext != sizeof(ULONG_PTR)) && (context->cbContext != 0))
1691 "REDIR_SCARDCONTEXT does not match native size: Actual: %" PRIu32
1692 ", Expected: %" PRIuz "",
1693 context->cbContext, sizeof(ULONG_PTR));
1697 if (context->cbContext)
1698 CopyMemory(&hContext, &(context->pbContext), context->cbContext);
1703 void smartcard_scard_context_native_to_redir(SMARTCARD_DEVICE* smartcard,
1704 REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext)
1706 WINPR_UNUSED(smartcard);
1707 ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT));
1708 context->cbContext = sizeof(ULONG_PTR);
1709 CopyMemory(&(context->pbContext), &hContext, context->cbContext);
1712 SCARDHANDLE smartcard_scard_handle_native_from_redir(SMARTCARD_DEVICE* smartcard,
1713 REDIR_SCARDHANDLE* handle)
1715 SCARDHANDLE hCard = 0;
1716 WINPR_UNUSED(smartcard);
1718 if (handle->cbHandle == 0)
1721 if (handle->cbHandle != sizeof(ULONG_PTR))
1724 "REDIR_SCARDHANDLE does not match native size: Actual: %" PRIu32
1725 ", Expected: %" PRIuz "",
1726 handle->cbHandle, sizeof(ULONG_PTR));
1730 if (handle->cbHandle)
1731 CopyMemory(&hCard, &(handle->pbHandle), handle->cbHandle);
1736 void smartcard_scard_handle_native_to_redir(SMARTCARD_DEVICE* smartcard, REDIR_SCARDHANDLE* handle,
1739 WINPR_UNUSED(smartcard);
1740 ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE));
1741 handle->cbHandle = sizeof(ULONG_PTR);
1742 CopyMemory(&(handle->pbHandle), &hCard, handle->cbHandle);
1745 LONG smartcard_unpack_redir_scard_context_(SMARTCARD_DEVICE* smartcard, wStream* s,
1746 REDIR_SCARDCONTEXT* context, UINT32* index,
1747 const char* file, const char* function, int line)
1749 UINT32 pbContextNdrPtr;
1750 WINPR_UNUSED(smartcard);
1753 ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT));
1755 if (Stream_GetRemainingLength(s) < 4)
1757 WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: %" PRIuz "", Stream_GetRemainingLength(s));
1758 return STATUS_BUFFER_TOO_SMALL;
1761 Stream_Read_UINT32(s, context->cbContext); /* cbContext (4 bytes) */
1763 if (Stream_GetRemainingLength(s) < context->cbContext)
1765 WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "",
1766 Stream_GetRemainingLength(s), context->cbContext);
1767 return STATUS_BUFFER_TOO_SMALL;
1770 if ((context->cbContext != 0) && (context->cbContext != 4) && (context->cbContext != 8))
1772 WLog_WARN(TAG, "REDIR_SCARDCONTEXT length is not 0, 4 or 8: %" PRIu32 "",
1773 context->cbContext);
1774 return STATUS_INVALID_PARAMETER;
1777 if (!smartcard_ndr_pointer_read_(s, index, &pbContextNdrPtr, file, function, line))
1778 return ERROR_INVALID_DATA;
1780 if (((context->cbContext == 0) && pbContextNdrPtr) ||
1781 ((context->cbContext != 0) && !pbContextNdrPtr))
1784 "REDIR_SCARDCONTEXT cbContext (%" PRIu32 ") pbContextNdrPtr (%" PRIu32
1786 context->cbContext, pbContextNdrPtr);
1787 return STATUS_INVALID_PARAMETER;
1790 if (context->cbContext > Stream_GetRemainingLength(s))
1792 WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too long: Actual: %" PRIuz ", Expected: %" PRIu32 "",
1793 Stream_GetRemainingLength(s), context->cbContext);
1794 return STATUS_INVALID_PARAMETER;
1797 return SCARD_S_SUCCESS;
1800 LONG smartcard_pack_redir_scard_context(SMARTCARD_DEVICE* smartcard, wStream* s,
1801 const REDIR_SCARDCONTEXT* context, DWORD* index)
1803 const UINT32 pbContextNdrPtr = 0x00020000 + *index * 4;
1804 WINPR_UNUSED(smartcard);
1806 if (context->cbContext != 0)
1808 Stream_Write_UINT32(s, context->cbContext); /* cbContext (4 bytes) */
1809 Stream_Write_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */
1810 *index = *index + 1;
1815 return SCARD_S_SUCCESS;
1818 LONG smartcard_unpack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s,
1819 REDIR_SCARDCONTEXT* context)
1822 WINPR_UNUSED(smartcard);
1824 if (context->cbContext == 0)
1825 return SCARD_S_SUCCESS;
1827 if (Stream_GetRemainingLength(s) < 4)
1829 WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %" PRIuz ", Expected: 4",
1830 Stream_GetRemainingLength(s));
1831 return STATUS_BUFFER_TOO_SMALL;
1834 Stream_Read_UINT32(s, length); /* Length (4 bytes) */
1836 if (length != context->cbContext)
1838 WLog_WARN(TAG, "REDIR_SCARDCONTEXT length (%" PRIu32 ") cbContext (%" PRIu32 ") mismatch",
1839 length, context->cbContext);
1840 return STATUS_INVALID_PARAMETER;
1843 if ((context->cbContext != 0) && (context->cbContext != 4) && (context->cbContext != 8))
1845 WLog_WARN(TAG, "REDIR_SCARDCONTEXT length is not 4 or 8: %" PRIu32 "", context->cbContext);
1846 return STATUS_INVALID_PARAMETER;
1849 if (Stream_GetRemainingLength(s) < context->cbContext)
1851 WLog_WARN(TAG, "REDIR_SCARDCONTEXT is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "",
1852 Stream_GetRemainingLength(s), context->cbContext);
1853 return STATUS_BUFFER_TOO_SMALL;
1856 if (context->cbContext)
1857 Stream_Read(s, &(context->pbContext), context->cbContext);
1859 ZeroMemory(&(context->pbContext), sizeof(context->pbContext));
1861 return SCARD_S_SUCCESS;
1864 LONG smartcard_pack_redir_scard_context_ref(SMARTCARD_DEVICE* smartcard, wStream* s,
1865 const REDIR_SCARDCONTEXT* context)
1867 WINPR_UNUSED(smartcard);
1868 Stream_Write_UINT32(s, context->cbContext); /* Length (4 bytes) */
1870 if (context->cbContext)
1872 Stream_Write(s, &(context->pbContext), context->cbContext);
1875 return SCARD_S_SUCCESS;
1878 LONG smartcard_unpack_redir_scard_handle_(SMARTCARD_DEVICE* smartcard, wStream* s,
1879 REDIR_SCARDHANDLE* handle, UINT32* index,
1880 const char* file, const char* function, int line)
1882 WINPR_UNUSED(smartcard);
1883 ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE));
1885 if (Stream_GetRemainingLength(s) < 4)
1887 WLog_WARN(TAG, "SCARDHANDLE is too short: %" PRIuz "", Stream_GetRemainingLength(s));
1888 return STATUS_BUFFER_TOO_SMALL;
1891 Stream_Read_UINT32(s, handle->cbHandle); /* Length (4 bytes) */
1893 if ((Stream_GetRemainingLength(s) < handle->cbHandle) || (!handle->cbHandle))
1895 WLog_WARN(TAG, "SCARDHANDLE is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "",
1896 Stream_GetRemainingLength(s), handle->cbHandle);
1897 return STATUS_BUFFER_TOO_SMALL;
1900 if (!smartcard_ndr_pointer_read_(s, index, NULL, file, function, line))
1901 return ERROR_INVALID_DATA;
1903 return SCARD_S_SUCCESS;
1906 LONG smartcard_pack_redir_scard_handle(SMARTCARD_DEVICE* smartcard, wStream* s,
1907 const REDIR_SCARDHANDLE* handle, DWORD* index)
1909 const UINT32 pbContextNdrPtr = 0x00020000 + *index * 4;
1910 WINPR_UNUSED(smartcard);
1912 if (handle->cbHandle != 0)
1914 Stream_Write_UINT32(s, handle->cbHandle); /* cbContext (4 bytes) */
1915 Stream_Write_UINT32(s, pbContextNdrPtr); /* pbContextNdrPtr (4 bytes) */
1916 *index = *index + 1;
1920 return SCARD_S_SUCCESS;
1923 LONG smartcard_unpack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s,
1924 REDIR_SCARDHANDLE* handle)
1927 WINPR_UNUSED(smartcard);
1929 if (Stream_GetRemainingLength(s) < 4)
1931 WLog_WARN(TAG, "REDIR_SCARDHANDLE is too short: Actual: %" PRIuz ", Expected: 4",
1932 Stream_GetRemainingLength(s));
1933 return STATUS_BUFFER_TOO_SMALL;
1936 Stream_Read_UINT32(s, length); /* Length (4 bytes) */
1938 if (length != handle->cbHandle)
1940 WLog_WARN(TAG, "REDIR_SCARDHANDLE length (%" PRIu32 ") cbHandle (%" PRIu32 ") mismatch",
1941 length, handle->cbHandle);
1942 return STATUS_INVALID_PARAMETER;
1945 if ((handle->cbHandle != 4) && (handle->cbHandle != 8))
1947 WLog_WARN(TAG, "REDIR_SCARDHANDLE length is not 4 or 8: %" PRIu32 "", handle->cbHandle);
1948 return STATUS_INVALID_PARAMETER;
1951 if ((Stream_GetRemainingLength(s) < handle->cbHandle) || (!handle->cbHandle))
1953 WLog_WARN(TAG, "REDIR_SCARDHANDLE is too short: Actual: %" PRIuz ", Expected: %" PRIu32 "",
1954 Stream_GetRemainingLength(s), handle->cbHandle);
1955 return STATUS_BUFFER_TOO_SMALL;
1958 if (handle->cbHandle)
1959 Stream_Read(s, &(handle->pbHandle), handle->cbHandle);
1961 return SCARD_S_SUCCESS;
1964 LONG smartcard_pack_redir_scard_handle_ref(SMARTCARD_DEVICE* smartcard, wStream* s,
1965 const REDIR_SCARDHANDLE* handle)
1967 WINPR_UNUSED(smartcard);
1968 Stream_Write_UINT32(s, handle->cbHandle); /* Length (4 bytes) */
1970 if (handle->cbHandle)
1971 Stream_Write(s, &(handle->pbHandle), handle->cbHandle);
1973 return SCARD_S_SUCCESS;
1976 LONG smartcard_unpack_establish_context_call(SMARTCARD_DEVICE* smartcard, wStream* s,
1977 EstablishContext_Call* call)
1979 WINPR_UNUSED(smartcard);
1981 if (Stream_GetRemainingLength(s) < 4)
1983 WLog_WARN(TAG, "EstablishContext_Call is too short: Actual: %" PRIuz ", Expected: 4",
1984 Stream_GetRemainingLength(s));
1985 return STATUS_BUFFER_TOO_SMALL;
1988 Stream_Read_UINT32(s, call->dwScope); /* dwScope (4 bytes) */
1989 smartcard_trace_establish_context_call(smartcard, call);
1990 return SCARD_S_SUCCESS;
1993 LONG smartcard_pack_establish_context_return(SMARTCARD_DEVICE* smartcard, wStream* s,
1994 const EstablishContext_Return* ret)
1999 smartcard_trace_establish_context_return(smartcard, ret);
2000 if (ret->ReturnCode != SCARD_S_SUCCESS)
2001 return ret->ReturnCode;
2003 if ((status = smartcard_pack_redir_scard_context(smartcard, s, &(ret->hContext), &index)))
2006 return smartcard_pack_redir_scard_context_ref(smartcard, s, &(ret->hContext));
2009 LONG smartcard_unpack_context_call(SMARTCARD_DEVICE* smartcard, wStream* s, Context_Call* call,
2015 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2016 if (status != SCARD_S_SUCCESS)
2020 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2021 WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
2024 smartcard_trace_context_call(smartcard, call, name);
2028 LONG smartcard_unpack_list_reader_groups_call(SMARTCARD_DEVICE* smartcard, wStream* s,
2029 ListReaderGroups_Call* call, BOOL unicode)
2033 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2035 if (status != SCARD_S_SUCCESS)
2038 if (Stream_GetRemainingLength(s) < 8)
2040 WLog_WARN(TAG, "ListReaderGroups_Call is too short: %" PRIdz, Stream_GetRemainingLength(s));
2041 return STATUS_BUFFER_TOO_SMALL;
2044 Stream_Read_INT32(s, call->fmszGroupsIsNULL); /* fmszGroupsIsNULL (4 bytes) */
2045 Stream_Read_UINT32(s, call->cchGroups); /* cchGroups (4 bytes) */
2046 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext));
2048 if (status != SCARD_S_SUCCESS)
2051 smartcard_trace_list_reader_groups_call(smartcard, call, unicode);
2052 return SCARD_S_SUCCESS;
2055 LONG smartcard_pack_list_reader_groups_return(SMARTCARD_DEVICE* smartcard, wStream* s,
2056 const ListReaderGroups_Return* ret, BOOL unicode)
2059 DWORD cBytes = ret->cBytes;
2062 smartcard_trace_list_reader_groups_return(smartcard, ret, unicode);
2063 if (ret->ReturnCode != SCARD_S_SUCCESS)
2065 if (cBytes == SCARD_AUTOALLOCATE)
2068 if (!Stream_EnsureRemainingCapacity(s, 4))
2069 return SCARD_E_NO_MEMORY;
2071 Stream_Write_UINT32(s, cBytes); /* cBytes (4 bytes) */
2072 if (!smartcard_ndr_pointer_write(s, &index, cBytes))
2073 return SCARD_E_NO_MEMORY;
2075 status = smartcard_ndr_write(s, ret->msz, cBytes, 1, NDR_PTR_SIMPLE);
2076 if (status != SCARD_S_SUCCESS)
2078 return ret->ReturnCode;
2081 LONG smartcard_unpack_list_readers_call(SMARTCARD_DEVICE* smartcard, wStream* s,
2082 ListReaders_Call* call, BOOL unicode)
2086 UINT32 mszGroupsNdrPtr;
2087 call->mszGroups = NULL;
2089 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2090 if (status != SCARD_S_SUCCESS)
2093 if (Stream_GetRemainingLength(s) < 16)
2095 WLog_WARN(TAG, "ListReaders_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s));
2096 return STATUS_BUFFER_TOO_SMALL;
2099 Stream_Read_UINT32(s, call->cBytes); /* cBytes (4 bytes) */
2100 if (!smartcard_ndr_pointer_read(s, &index, &mszGroupsNdrPtr))
2101 return ERROR_INVALID_DATA;
2102 Stream_Read_INT32(s, call->fmszReadersIsNULL); /* fmszReadersIsNULL (4 bytes) */
2103 Stream_Read_UINT32(s, call->cchReaders); /* cchReaders (4 bytes) */
2106 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2109 if (mszGroupsNdrPtr)
2111 status = smartcard_ndr_read(s, &call->mszGroups, call->cBytes, 1, NDR_PTR_SIMPLE);
2112 if (status != SCARD_S_SUCCESS)
2116 smartcard_trace_list_readers_call(smartcard, call, unicode);
2117 return SCARD_S_SUCCESS;
2120 LONG smartcard_pack_list_readers_return(SMARTCARD_DEVICE* smartcard, wStream* s,
2121 const ListReaders_Return* ret, BOOL unicode)
2125 UINT32 size = unicode ? sizeof(WCHAR) : sizeof(CHAR);
2127 size *= ret->cBytes;
2129 smartcard_trace_list_readers_return(smartcard, ret, unicode);
2130 if (ret->ReturnCode != SCARD_S_SUCCESS)
2133 if (!Stream_EnsureRemainingCapacity(s, 4))
2135 WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
2136 return SCARD_F_INTERNAL_ERROR;
2139 Stream_Write_UINT32(s, size); /* cBytes (4 bytes) */
2140 if (!smartcard_ndr_pointer_write(s, &index, size))
2141 return SCARD_E_NO_MEMORY;
2143 status = smartcard_ndr_write(s, ret->msz, size, 1, NDR_PTR_SIMPLE);
2144 if (status != SCARD_S_SUCCESS)
2146 return ret->ReturnCode;
2149 static LONG smartcard_unpack_connect_common(SMARTCARD_DEVICE* smartcard, wStream* s,
2150 Connect_Common_Call* common, UINT32* index)
2154 status = smartcard_unpack_redir_scard_context(smartcard, s, &(common->handles.hContext), index);
2155 if (status != SCARD_S_SUCCESS)
2158 if (Stream_GetRemainingLength(s) < 8)
2160 WLog_WARN(TAG, "Connect_Common is too short: %" PRIuz "", Stream_GetRemainingLength(s));
2161 return STATUS_BUFFER_TOO_SMALL;
2164 Stream_Read_UINT32(s, common->dwShareMode); /* dwShareMode (4 bytes) */
2165 Stream_Read_UINT32(s, common->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */
2166 return SCARD_S_SUCCESS;
2169 LONG smartcard_unpack_connect_a_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectA_Call* call)
2173 call->szReader = NULL;
2175 if (!smartcard_ndr_pointer_read(s, &index, NULL))
2176 return ERROR_INVALID_DATA;
2178 if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common), &index)))
2180 WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %" PRId32 "", status);
2184 status = smartcard_ndr_read_a(s, &call->szReader, NDR_PTR_FULL);
2185 if (status != SCARD_S_SUCCESS)
2188 if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s,
2189 &(call->Common.handles.hContext))))
2190 WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
2193 smartcard_trace_connect_a_call(smartcard, call);
2197 LONG smartcard_unpack_connect_w_call(SMARTCARD_DEVICE* smartcard, wStream* s, ConnectW_Call* call)
2202 call->szReader = NULL;
2204 if (!smartcard_ndr_pointer_read(s, &index, NULL))
2205 return ERROR_INVALID_DATA;
2207 if ((status = smartcard_unpack_connect_common(smartcard, s, &(call->Common), &index)))
2209 WLog_ERR(TAG, "smartcard_unpack_connect_common failed with error %" PRId32 "", status);
2213 status = smartcard_ndr_read_w(s, &call->szReader, NDR_PTR_FULL);
2214 if (status != SCARD_S_SUCCESS)
2217 if ((status = smartcard_unpack_redir_scard_context_ref(smartcard, s,
2218 &(call->Common.handles.hContext))))
2219 WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
2222 smartcard_trace_connect_w_call(smartcard, call);
2226 LONG smartcard_pack_connect_return(SMARTCARD_DEVICE* smartcard, wStream* s,
2227 const Connect_Return* ret)
2232 smartcard_trace_connect_return(smartcard, ret);
2234 status = smartcard_pack_redir_scard_context(smartcard, s, &ret->hContext, &index);
2235 if (status != SCARD_S_SUCCESS)
2238 status = smartcard_pack_redir_scard_handle(smartcard, s, &ret->hCard, &index);
2239 if (status != SCARD_S_SUCCESS)
2242 if (!Stream_EnsureRemainingCapacity(s, 4))
2243 return SCARD_E_NO_MEMORY;
2245 Stream_Write_UINT32(s, ret->dwActiveProtocol); /* dwActiveProtocol (4 bytes) */
2246 status = smartcard_pack_redir_scard_context_ref(smartcard, s, &ret->hContext);
2247 if (status != SCARD_S_SUCCESS)
2249 return smartcard_pack_redir_scard_handle_ref(smartcard, s, &(ret->hCard));
2252 LONG smartcard_unpack_reconnect_call(SMARTCARD_DEVICE* smartcard, wStream* s, Reconnect_Call* call)
2257 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2258 if (status != SCARD_S_SUCCESS)
2261 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
2262 if (status != SCARD_S_SUCCESS)
2265 if (Stream_GetRemainingLength(s) < 12)
2267 WLog_WARN(TAG, "Reconnect_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s));
2268 return STATUS_BUFFER_TOO_SMALL;
2271 Stream_Read_UINT32(s, call->dwShareMode); /* dwShareMode (4 bytes) */
2272 Stream_Read_UINT32(s, call->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */
2273 Stream_Read_UINT32(s, call->dwInitialization); /* dwInitialization (4 bytes) */
2276 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2278 WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
2283 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
2284 WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "",
2287 smartcard_trace_reconnect_call(smartcard, call);
2291 LONG smartcard_pack_reconnect_return(SMARTCARD_DEVICE* smartcard, wStream* s,
2292 const Reconnect_Return* ret)
2294 smartcard_trace_reconnect_return(smartcard, ret);
2296 if (!Stream_EnsureRemainingCapacity(s, 4))
2297 return SCARD_E_NO_MEMORY;
2298 Stream_Write_UINT32(s, ret->dwActiveProtocol); /* dwActiveProtocol (4 bytes) */
2299 return ret->ReturnCode;
2302 LONG smartcard_unpack_hcard_and_disposition_call(SMARTCARD_DEVICE* smartcard, wStream* s,
2303 HCardAndDisposition_Call* call, const char* name)
2308 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2309 if (status != SCARD_S_SUCCESS)
2312 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
2313 if (status != SCARD_S_SUCCESS)
2316 if (Stream_GetRemainingLength(s) < 4)
2318 WLog_WARN(TAG, "HCardAndDisposition_Call is too short: %" PRIuz "",
2319 Stream_GetRemainingLength(s));
2320 return STATUS_BUFFER_TOO_SMALL;
2323 Stream_Read_UINT32(s, call->dwDisposition); /* dwDisposition (4 bytes) */
2326 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2329 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
2332 smartcard_trace_hcard_and_disposition_call(smartcard, call, name);
2336 static void smartcard_trace_get_status_change_a_call(SMARTCARD_DEVICE* smartcard,
2337 const GetStatusChangeA_Call* call)
2341 char* szCurrentState;
2342 LPSCARD_READERSTATEA readerState;
2343 WINPR_UNUSED(smartcard);
2345 if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel))
2348 WLog_LVL(TAG, g_LogLevel, "GetStatusChangeA_Call {");
2349 smartcard_log_context(TAG, &call->handles.hContext);
2351 WLog_LVL(TAG, g_LogLevel, "dwTimeOut: 0x%08" PRIX32 " cReaders: %" PRIu32 "", call->dwTimeOut,
2354 for (index = 0; index < call->cReaders; index++)
2356 readerState = &call->rgReaderStates[index];
2357 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index,
2358 readerState->szReader, readerState->cbAtr);
2359 szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState);
2360 szEventState = SCardGetReaderStateString(readerState->dwEventState);
2361 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index,
2362 szCurrentState, readerState->dwCurrentState);
2363 WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index,
2364 szEventState, readerState->dwEventState);
2365 free(szCurrentState);
2369 WLog_LVL(TAG, g_LogLevel, "}");
2372 static LONG smartcard_unpack_reader_state_a(wStream* s, LPSCARD_READERSTATEA* ppcReaders,
2373 UINT32 cReaders, UINT32* ptrIndex)
2376 LONG status = SCARD_E_NO_MEMORY;
2377 LPSCARD_READERSTATEA rgReaderStates;
2380 if (Stream_GetRemainingLength(s) < 4)
2383 Stream_Read_UINT32(s, len);
2384 if (len != cReaders)
2386 WLog_ERR(TAG, "Count mismatch when reading LPSCARD_READERSTATEA");
2389 rgReaderStates = (LPSCARD_READERSTATEA)calloc(cReaders, sizeof(SCARD_READERSTATEA));
2390 states = calloc(cReaders, sizeof(BOOL));
2391 if (!rgReaderStates || !states)
2393 status = ERROR_INVALID_DATA;
2395 for (index = 0; index < cReaders; index++)
2397 UINT32 ptr = UINT32_MAX;
2398 LPSCARD_READERSTATEA readerState = &rgReaderStates[index];
2400 if (Stream_GetRemainingLength(s) < 52)
2402 WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "",
2403 Stream_GetRemainingLength(s));
2407 if (!smartcard_ndr_pointer_read(s, ptrIndex, &ptr))
2412 /* Ignore NULL length strings */
2413 states[index] = ptr != 0;
2414 Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */
2415 Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */
2416 Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */
2417 Stream_Read(s, readerState->rgbAtr, 36); /* rgbAtr [0..36] (36 bytes) */
2420 for (index = 0; index < cReaders; index++)
2422 LPSCARD_READERSTATEA readerState = &rgReaderStates[index];
2424 /* Ignore empty strings */
2427 status = smartcard_ndr_read_a(s, &readerState->szReader, NDR_PTR_FULL);
2428 if (status != SCARD_S_SUCCESS)
2432 *ppcReaders = rgReaderStates;
2434 return SCARD_S_SUCCESS;
2438 for (index = 0; index < cReaders; index++)
2440 LPSCARD_READERSTATEA readerState = &rgReaderStates[index];
2441 free(readerState->szReader);
2444 free(rgReaderStates);
2449 static LONG smartcard_unpack_reader_state_w(wStream* s, LPSCARD_READERSTATEW* ppcReaders,
2450 UINT32 cReaders, UINT32* ptrIndex)
2453 LONG status = SCARD_E_NO_MEMORY;
2454 LPSCARD_READERSTATEW rgReaderStates;
2457 if (Stream_GetRemainingLength(s) < 4)
2460 Stream_Read_UINT32(s, len);
2461 if (len != cReaders)
2463 WLog_ERR(TAG, "Count mismatch when reading LPSCARD_READERSTATEW");
2467 rgReaderStates = (LPSCARD_READERSTATEW)calloc(cReaders, sizeof(SCARD_READERSTATEW));
2468 states = calloc(cReaders, sizeof(BOOL));
2470 if (!rgReaderStates || !states)
2473 status = ERROR_INVALID_DATA;
2474 for (index = 0; index < cReaders; index++)
2476 UINT32 ptr = UINT32_MAX;
2477 LPSCARD_READERSTATEW readerState = &rgReaderStates[index];
2479 if (Stream_GetRemainingLength(s) < 52)
2481 WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "",
2482 Stream_GetRemainingLength(s));
2486 if (!smartcard_ndr_pointer_read(s, ptrIndex, &ptr))
2491 /* Ignore NULL length strings */
2492 states[index] = ptr != 0;
2493 Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */
2494 Stream_Read_UINT32(s, readerState->dwEventState); /* dwEventState (4 bytes) */
2495 Stream_Read_UINT32(s, readerState->cbAtr); /* cbAtr (4 bytes) */
2496 Stream_Read(s, readerState->rgbAtr, 36); /* rgbAtr [0..36] (36 bytes) */
2499 for (index = 0; index < cReaders; index++)
2501 LPSCARD_READERSTATEW readerState = &rgReaderStates[index];
2503 /* Skip NULL pointers */
2507 status = smartcard_ndr_read_w(s, &readerState->szReader, NDR_PTR_FULL);
2508 if (status != SCARD_S_SUCCESS)
2512 *ppcReaders = rgReaderStates;
2514 return SCARD_S_SUCCESS;
2518 for (index = 0; index < cReaders; index++)
2520 LPSCARD_READERSTATEW readerState = &rgReaderStates[index];
2521 free(readerState->szReader);
2524 free(rgReaderStates);
2529 /******************************************************************************/
2530 /************************************* End Trace Functions ********************/
2531 /******************************************************************************/
2533 LONG smartcard_unpack_get_status_change_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
2534 GetStatusChangeA_Call* call)
2539 call->rgReaderStates = NULL;
2541 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2542 if (status != SCARD_S_SUCCESS)
2545 if (Stream_GetRemainingLength(s) < 12)
2547 WLog_WARN(TAG, "GetStatusChangeA_Call is too short: %" PRIuz "",
2548 Stream_GetRemainingLength(s));
2549 return STATUS_BUFFER_TOO_SMALL;
2552 Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */
2553 Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */
2554 if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr))
2555 return ERROR_INVALID_DATA;
2558 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2563 status = smartcard_unpack_reader_state_a(s, &call->rgReaderStates, call->cReaders, &index);
2564 if (status != SCARD_S_SUCCESS)
2568 smartcard_trace_get_status_change_a_call(smartcard, call);
2569 return SCARD_S_SUCCESS;
2572 LONG smartcard_unpack_get_status_change_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
2573 GetStatusChangeW_Call* call)
2579 call->rgReaderStates = NULL;
2581 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2582 if (status != SCARD_S_SUCCESS)
2585 if (Stream_GetRemainingLength(s) < 12)
2587 WLog_WARN(TAG, "GetStatusChangeW_Call is too short: %" PRIuz "",
2588 Stream_GetRemainingLength(s));
2589 return STATUS_BUFFER_TOO_SMALL;
2592 Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */
2593 Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */
2594 if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr))
2595 return ERROR_INVALID_DATA;
2598 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2603 status = smartcard_unpack_reader_state_w(s, &call->rgReaderStates, call->cReaders, &index);
2604 if (status != SCARD_S_SUCCESS)
2608 smartcard_trace_get_status_change_w_call(smartcard, call);
2609 return SCARD_S_SUCCESS;
2612 LONG smartcard_pack_get_status_change_return(SMARTCARD_DEVICE* smartcard, wStream* s,
2613 const GetStatusChange_Return* ret, BOOL unicode)
2616 DWORD cReaders = ret->cReaders;
2619 smartcard_trace_get_status_change_return(smartcard, ret, unicode);
2620 if (ret->ReturnCode != SCARD_S_SUCCESS)
2622 if (cReaders == SCARD_AUTOALLOCATE)
2625 if (!Stream_EnsureRemainingCapacity(s, 4))
2626 return SCARD_E_NO_MEMORY;
2628 Stream_Write_UINT32(s, cReaders); /* cReaders (4 bytes) */
2629 if (!smartcard_ndr_pointer_write(s, &index, cReaders))
2630 return SCARD_E_NO_MEMORY;
2631 status = smartcard_ndr_write_state(s, ret->rgReaderStates, cReaders, NDR_PTR_SIMPLE);
2632 if (status != SCARD_S_SUCCESS)
2634 return ret->ReturnCode;
2637 LONG smartcard_unpack_state_call(SMARTCARD_DEVICE* smartcard, wStream* s, State_Call* call)
2642 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2643 if (status != SCARD_S_SUCCESS)
2646 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
2647 if (status != SCARD_S_SUCCESS)
2650 if (Stream_GetRemainingLength(s) < 8)
2652 WLog_WARN(TAG, "State_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s));
2653 return STATUS_BUFFER_TOO_SMALL;
2656 Stream_Read_INT32(s, call->fpbAtrIsNULL); /* fpbAtrIsNULL (4 bytes) */
2657 Stream_Read_UINT32(s, call->cbAtrLen); /* cbAtrLen (4 bytes) */
2660 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2663 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
2669 LONG smartcard_pack_state_return(SMARTCARD_DEVICE* smartcard, wStream* s, const State_Return* ret)
2672 DWORD cbAtrLen = ret->cbAtrLen;
2675 smartcard_trace_state_return(smartcard, ret);
2676 if (ret->ReturnCode != SCARD_S_SUCCESS)
2678 if (cbAtrLen == SCARD_AUTOALLOCATE)
2681 Stream_Write_UINT32(s, ret->dwState); /* dwState (4 bytes) */
2682 Stream_Write_UINT32(s, ret->dwProtocol); /* dwProtocol (4 bytes) */
2683 Stream_Write_UINT32(s, cbAtrLen); /* cbAtrLen (4 bytes) */
2684 if (!smartcard_ndr_pointer_write(s, &index, cbAtrLen))
2685 return SCARD_E_NO_MEMORY;
2686 status = smartcard_ndr_write(s, ret->rgAtr, cbAtrLen, 1, NDR_PTR_SIMPLE);
2687 if (status != SCARD_S_SUCCESS)
2689 return ret->ReturnCode;
2692 LONG smartcard_unpack_status_call(SMARTCARD_DEVICE* smartcard, wStream* s, Status_Call* call,
2697 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2698 if (status != SCARD_S_SUCCESS)
2701 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
2702 if (status != SCARD_S_SUCCESS)
2705 if (Stream_GetRemainingLength(s) < 12)
2707 WLog_WARN(TAG, "Status_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s));
2708 return STATUS_BUFFER_TOO_SMALL;
2711 Stream_Read_INT32(s, call->fmszReaderNamesIsNULL); /* fmszReaderNamesIsNULL (4 bytes) */
2712 Stream_Read_UINT32(s, call->cchReaderLen); /* cchReaderLen (4 bytes) */
2713 Stream_Read_UINT32(s, call->cbAtrLen); /* cbAtrLen (4 bytes) */
2716 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2719 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
2722 smartcard_trace_status_call(smartcard, call, unicode);
2726 LONG smartcard_pack_status_return(SMARTCARD_DEVICE* smartcard, wStream* s, const Status_Return* ret,
2731 DWORD cBytes = ret->cBytes;
2733 smartcard_trace_status_return(smartcard, ret, unicode);
2734 if (ret->ReturnCode != SCARD_S_SUCCESS)
2736 if (cBytes == SCARD_AUTOALLOCATE)
2739 if (!Stream_EnsureRemainingCapacity(s, 4))
2740 return SCARD_F_INTERNAL_ERROR;
2742 Stream_Write_UINT32(s, cBytes); /* cBytes (4 bytes) */
2743 if (!smartcard_ndr_pointer_write(s, &index, cBytes))
2744 return SCARD_E_NO_MEMORY;
2746 if (!Stream_EnsureRemainingCapacity(s, 44))
2747 return SCARD_F_INTERNAL_ERROR;
2749 Stream_Write_UINT32(s, ret->dwState); /* dwState (4 bytes) */
2750 Stream_Write_UINT32(s, ret->dwProtocol); /* dwProtocol (4 bytes) */
2751 Stream_Write(s, ret->pbAtr, sizeof(ret->pbAtr)); /* pbAtr (32 bytes) */
2752 Stream_Write_UINT32(s, ret->cbAtrLen); /* cbAtrLen (4 bytes) */
2753 status = smartcard_ndr_write(s, ret->mszReaderNames, cBytes, 1, NDR_PTR_SIMPLE);
2754 if (status != SCARD_S_SUCCESS)
2756 return ret->ReturnCode;
2759 LONG smartcard_unpack_get_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, GetAttrib_Call* call)
2764 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2765 if (status != SCARD_S_SUCCESS)
2768 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
2769 if (status != SCARD_S_SUCCESS)
2772 if (Stream_GetRemainingLength(s) < 12)
2774 WLog_WARN(TAG, "GetAttrib_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s));
2775 return STATUS_BUFFER_TOO_SMALL;
2778 Stream_Read_UINT32(s, call->dwAttrId); /* dwAttrId (4 bytes) */
2779 Stream_Read_INT32(s, call->fpbAttrIsNULL); /* fpbAttrIsNULL (4 bytes) */
2780 Stream_Read_UINT32(s, call->cbAttrLen); /* cbAttrLen (4 bytes) */
2783 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2786 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
2789 smartcard_trace_get_attrib_call(smartcard, call);
2793 LONG smartcard_pack_get_attrib_return(SMARTCARD_DEVICE* smartcard, wStream* s,
2794 const GetAttrib_Return* ret, DWORD dwAttrId)
2799 smartcard_trace_get_attrib_return(smartcard, ret, dwAttrId);
2801 if (!Stream_EnsureRemainingCapacity(s, 4))
2802 return SCARD_F_INTERNAL_ERROR;
2804 cbAttrLen = ret->cbAttrLen;
2805 if (cbAttrLen == SCARD_AUTOALLOCATE)
2807 Stream_Write_UINT32(s, cbAttrLen); /* cbAttrLen (4 bytes) */
2808 if (!smartcard_ndr_pointer_write(s, &index, cbAttrLen))
2809 return SCARD_E_NO_MEMORY;
2811 status = smartcard_ndr_write(s, ret->pbAttr, cbAttrLen, 1, NDR_PTR_SIMPLE);
2812 if (status != SCARD_S_SUCCESS)
2814 return ret->ReturnCode;
2817 LONG smartcard_unpack_control_call(SMARTCARD_DEVICE* smartcard, wStream* s, Control_Call* call)
2821 UINT32 pvInBufferNdrPtr;
2823 call->pvInBuffer = NULL;
2825 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2826 if (status != SCARD_S_SUCCESS)
2829 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
2830 if (status != SCARD_S_SUCCESS)
2833 if (Stream_GetRemainingLength(s) < 20)
2835 WLog_WARN(TAG, "Control_Call is too short: %" PRIuz "", Stream_GetRemainingLength(s));
2836 return STATUS_BUFFER_TOO_SMALL;
2839 Stream_Read_UINT32(s, call->dwControlCode); /* dwControlCode (4 bytes) */
2840 Stream_Read_UINT32(s, call->cbInBufferSize); /* cbInBufferSize (4 bytes) */
2841 if (!smartcard_ndr_pointer_read(s, &index, &pvInBufferNdrPtr)) /* pvInBufferNdrPtr (4 bytes) */
2842 return ERROR_INVALID_DATA;
2843 Stream_Read_INT32(s, call->fpvOutBufferIsNULL); /* fpvOutBufferIsNULL (4 bytes) */
2844 Stream_Read_UINT32(s, call->cbOutBufferSize); /* cbOutBufferSize (4 bytes) */
2847 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2850 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
2853 if (pvInBufferNdrPtr)
2855 status = smartcard_ndr_read(s, &call->pvInBuffer, call->cbInBufferSize, 1, NDR_PTR_SIMPLE);
2856 if (status != SCARD_S_SUCCESS)
2860 smartcard_trace_control_call(smartcard, call);
2861 return SCARD_S_SUCCESS;
2864 LONG smartcard_pack_control_return(SMARTCARD_DEVICE* smartcard, wStream* s,
2865 const Control_Return* ret)
2868 DWORD cbDataLen = ret->cbOutBufferSize;
2871 smartcard_trace_control_return(smartcard, ret);
2872 if (ret->ReturnCode != SCARD_S_SUCCESS)
2874 if (cbDataLen == SCARD_AUTOALLOCATE)
2877 if (!Stream_EnsureRemainingCapacity(s, 4))
2878 return SCARD_F_INTERNAL_ERROR;
2880 Stream_Write_UINT32(s, cbDataLen); /* cbOutBufferSize (4 bytes) */
2881 if (!smartcard_ndr_pointer_write(s, &index, cbDataLen))
2882 return SCARD_E_NO_MEMORY;
2884 status = smartcard_ndr_write(s, ret->pvOutBuffer, cbDataLen, 1, NDR_PTR_SIMPLE);
2885 if (status != SCARD_S_SUCCESS)
2887 return ret->ReturnCode;
2890 LONG smartcard_unpack_transmit_call(SMARTCARD_DEVICE* smartcard, wStream* s, Transmit_Call* call)
2895 UINT32 pbExtraBytesNdrPtr;
2896 UINT32 pbSendBufferNdrPtr;
2897 UINT32 pioRecvPciNdrPtr;
2898 SCardIO_Request ioSendPci;
2899 SCardIO_Request ioRecvPci;
2901 call->pioSendPci = NULL;
2902 call->pioRecvPci = NULL;
2903 call->pbSendBuffer = NULL;
2905 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
2906 if (status != SCARD_S_SUCCESS)
2909 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
2910 if (status != SCARD_S_SUCCESS)
2913 if (Stream_GetRemainingLength(s) < 32)
2915 WLog_WARN(TAG, "Transmit_Call is too short: Actual: %" PRIuz ", Expected: 32",
2916 Stream_GetRemainingLength(s));
2917 return STATUS_BUFFER_TOO_SMALL;
2920 Stream_Read_UINT32(s, ioSendPci.dwProtocol); /* dwProtocol (4 bytes) */
2921 Stream_Read_UINT32(s, ioSendPci.cbExtraBytes); /* cbExtraBytes (4 bytes) */
2922 if (!smartcard_ndr_pointer_read(s, &index,
2923 &pbExtraBytesNdrPtr)) /* pbExtraBytesNdrPtr (4 bytes) */
2924 return ERROR_INVALID_DATA;
2926 Stream_Read_UINT32(s, call->cbSendLength); /* cbSendLength (4 bytes) */
2927 if (!smartcard_ndr_pointer_read(s, &index,
2928 &pbSendBufferNdrPtr)) /* pbSendBufferNdrPtr (4 bytes) */
2929 return ERROR_INVALID_DATA;
2931 if (!smartcard_ndr_pointer_read(s, &index, &pioRecvPciNdrPtr)) /* pioRecvPciNdrPtr (4 bytes) */
2932 return ERROR_INVALID_DATA;
2934 Stream_Read_INT32(s, call->fpbRecvBufferIsNULL); /* fpbRecvBufferIsNULL (4 bytes) */
2935 Stream_Read_UINT32(s, call->cbRecvLength); /* cbRecvLength (4 bytes) */
2937 if (ioSendPci.cbExtraBytes > 1024)
2940 "Transmit_Call ioSendPci.cbExtraBytes is out of bounds: %" PRIu32 " (max: 1024)",
2941 ioSendPci.cbExtraBytes);
2942 return STATUS_INVALID_PARAMETER;
2945 if (call->cbSendLength > 66560)
2947 WLog_WARN(TAG, "Transmit_Call cbSendLength is out of bounds: %" PRIu32 " (max: 66560)",
2948 ioSendPci.cbExtraBytes);
2949 return STATUS_INVALID_PARAMETER;
2953 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
2956 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
2959 if (ioSendPci.cbExtraBytes && !pbExtraBytesNdrPtr)
2962 TAG, "Transmit_Call ioSendPci.cbExtraBytes is non-zero but pbExtraBytesNdrPtr is null");
2963 return STATUS_INVALID_PARAMETER;
2966 if (pbExtraBytesNdrPtr)
2968 // TODO: Use unified pointer reading
2969 if (Stream_GetRemainingLength(s) < 4)
2971 WLog_WARN(TAG, "Transmit_Call is too short: %" PRIuz " (ioSendPci.pbExtraBytes)",
2972 Stream_GetRemainingLength(s));
2973 return STATUS_BUFFER_TOO_SMALL;
2976 Stream_Read_UINT32(s, length); /* Length (4 bytes) */
2978 if (Stream_GetRemainingLength(s) < ioSendPci.cbExtraBytes)
2981 "Transmit_Call is too short: Actual: %" PRIuz ", Expected: %" PRIu32
2982 " (ioSendPci.cbExtraBytes)",
2983 Stream_GetRemainingLength(s), ioSendPci.cbExtraBytes);
2984 return STATUS_BUFFER_TOO_SMALL;
2987 ioSendPci.pbExtraBytes = Stream_Pointer(s);
2989 (LPSCARD_IO_REQUEST)malloc(sizeof(SCARD_IO_REQUEST) + ioSendPci.cbExtraBytes);
2991 if (!call->pioSendPci)
2993 WLog_WARN(TAG, "Transmit_Call out of memory error (pioSendPci)");
2994 return STATUS_NO_MEMORY;
2997 call->pioSendPci->dwProtocol = ioSendPci.dwProtocol;
2998 call->pioSendPci->cbPciLength = (DWORD)(ioSendPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST));
2999 pbExtraBytes = &((BYTE*)call->pioSendPci)[sizeof(SCARD_IO_REQUEST)];
3000 Stream_Read(s, pbExtraBytes, ioSendPci.cbExtraBytes);
3001 smartcard_unpack_read_size_align(smartcard, s, ioSendPci.cbExtraBytes, 4);
3005 call->pioSendPci = (LPSCARD_IO_REQUEST)calloc(1, sizeof(SCARD_IO_REQUEST));
3007 if (!call->pioSendPci)
3009 WLog_WARN(TAG, "Transmit_Call out of memory error (pioSendPci)");
3010 return STATUS_NO_MEMORY;
3013 call->pioSendPci->dwProtocol = ioSendPci.dwProtocol;
3014 call->pioSendPci->cbPciLength = sizeof(SCARD_IO_REQUEST);
3017 if (pbSendBufferNdrPtr)
3019 status = smartcard_ndr_read(s, &call->pbSendBuffer, call->cbSendLength, 1, NDR_PTR_SIMPLE);
3020 if (status != SCARD_S_SUCCESS)
3024 if (pioRecvPciNdrPtr)
3026 if (Stream_GetRemainingLength(s) < 12)
3028 WLog_WARN(TAG, "Transmit_Call is too short: Actual: %" PRIuz ", Expected: 12",
3029 Stream_GetRemainingLength(s));
3030 return STATUS_BUFFER_TOO_SMALL;
3033 Stream_Read_UINT32(s, ioRecvPci.dwProtocol); /* dwProtocol (4 bytes) */
3034 Stream_Read_UINT32(s, ioRecvPci.cbExtraBytes); /* cbExtraBytes (4 bytes) */
3035 if (!smartcard_ndr_pointer_read(s, &index,
3036 &pbExtraBytesNdrPtr)) /* pbExtraBytesNdrPtr (4 bytes) */
3037 return ERROR_INVALID_DATA;
3039 if (ioRecvPci.cbExtraBytes && !pbExtraBytesNdrPtr)
3043 "Transmit_Call ioRecvPci.cbExtraBytes is non-zero but pbExtraBytesNdrPtr is null");
3044 return STATUS_INVALID_PARAMETER;
3047 if (pbExtraBytesNdrPtr)
3049 // TODO: Unify ndr pointer reading
3050 if (Stream_GetRemainingLength(s) < 4)
3052 WLog_WARN(TAG, "Transmit_Call is too short: %" PRIuz " (ioRecvPci.pbExtraBytes)",
3053 Stream_GetRemainingLength(s));
3054 return STATUS_BUFFER_TOO_SMALL;
3057 Stream_Read_UINT32(s, length); /* Length (4 bytes) */
3059 if (ioRecvPci.cbExtraBytes > 1024)
3062 "Transmit_Call ioRecvPci.cbExtraBytes is out of bounds: %" PRIu32
3064 ioRecvPci.cbExtraBytes);
3065 return STATUS_INVALID_PARAMETER;
3068 if (length != ioRecvPci.cbExtraBytes)
3071 "Transmit_Call unexpected length: Actual: %" PRIu32 ", Expected: %" PRIu32
3072 " (ioRecvPci.cbExtraBytes)",
3073 length, ioRecvPci.cbExtraBytes);
3074 return STATUS_INVALID_PARAMETER;
3077 if (Stream_GetRemainingLength(s) < ioRecvPci.cbExtraBytes)
3080 "Transmit_Call is too short: Actual: %" PRIuz ", Expected: %" PRIu32
3081 " (ioRecvPci.cbExtraBytes)",
3082 Stream_GetRemainingLength(s), ioRecvPci.cbExtraBytes);
3083 return STATUS_BUFFER_TOO_SMALL;
3086 ioRecvPci.pbExtraBytes = Stream_Pointer(s);
3088 (LPSCARD_IO_REQUEST)malloc(sizeof(SCARD_IO_REQUEST) + ioRecvPci.cbExtraBytes);
3090 if (!call->pioRecvPci)
3092 WLog_WARN(TAG, "Transmit_Call out of memory error (pioRecvPci)");
3093 return STATUS_NO_MEMORY;
3096 call->pioRecvPci->dwProtocol = ioRecvPci.dwProtocol;
3097 call->pioRecvPci->cbPciLength =
3098 (DWORD)(ioRecvPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST));
3099 pbExtraBytes = &((BYTE*)call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
3100 Stream_Read(s, pbExtraBytes, ioRecvPci.cbExtraBytes);
3101 smartcard_unpack_read_size_align(smartcard, s, ioRecvPci.cbExtraBytes, 4);
3105 call->pioRecvPci = (LPSCARD_IO_REQUEST)calloc(1, sizeof(SCARD_IO_REQUEST));
3107 if (!call->pioRecvPci)
3109 WLog_WARN(TAG, "Transmit_Call out of memory error (pioRecvPci)");
3110 return STATUS_NO_MEMORY;
3113 call->pioRecvPci->dwProtocol = ioRecvPci.dwProtocol;
3114 call->pioRecvPci->cbPciLength = sizeof(SCARD_IO_REQUEST);
3118 smartcard_trace_transmit_call(smartcard, call);
3119 return SCARD_S_SUCCESS;
3122 LONG smartcard_pack_transmit_return(SMARTCARD_DEVICE* smartcard, wStream* s,
3123 const Transmit_Return* ret)
3128 UINT32 cbRecvLength = ret->cbRecvLength;
3129 UINT32 cbRecvPci = ret->pioRecvPci ? ret->pioRecvPci->cbPciLength : 0;
3131 smartcard_trace_transmit_return(smartcard, ret);
3133 if (!ret->pbRecvBuffer)
3136 if (!smartcard_ndr_pointer_write(s, &index, cbRecvPci))
3137 return SCARD_E_NO_MEMORY;
3138 if (!Stream_EnsureRemainingCapacity(s, 4))
3139 return SCARD_E_NO_MEMORY;
3140 Stream_Write_UINT32(s, cbRecvLength); /* cbRecvLength (4 bytes) */
3141 if (!smartcard_ndr_pointer_write(s, &index, cbRecvLength))
3142 return SCARD_E_NO_MEMORY;
3144 if (ret->pioRecvPci)
3146 UINT32 cbExtraBytes = (UINT32)(ret->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST));
3147 BYTE* pbExtraBytes = &((BYTE*)ret->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
3149 if (!Stream_EnsureRemainingCapacity(s, cbExtraBytes + 16))
3151 WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
3152 return SCARD_F_INTERNAL_ERROR;
3155 Stream_Write_UINT32(s, ret->pioRecvPci->dwProtocol); /* dwProtocol (4 bytes) */
3156 Stream_Write_UINT32(s, cbExtraBytes); /* cbExtraBytes (4 bytes) */
3157 if (!smartcard_ndr_pointer_write(s, &index, cbExtraBytes))
3158 return SCARD_E_NO_MEMORY;
3159 error = smartcard_ndr_write(s, pbExtraBytes, cbExtraBytes, 1, NDR_PTR_SIMPLE);
3164 status = smartcard_ndr_write(s, ret->pbRecvBuffer, ret->cbRecvLength, 1, NDR_PTR_SIMPLE);
3165 if (status != SCARD_S_SUCCESS)
3167 return ret->ReturnCode;
3170 LONG smartcard_unpack_locate_cards_by_atr_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3171 LocateCardsByATRA_Call* call)
3174 UINT32 rgReaderStatesNdrPtr;
3175 UINT32 rgAtrMasksNdrPtr;
3177 call->rgReaderStates = NULL;
3179 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
3180 if (status != SCARD_S_SUCCESS)
3183 if (Stream_GetRemainingLength(s) < 16)
3185 WLog_WARN(TAG, "LocateCardsByATRA_Call is too short: %" PRIuz "",
3186 Stream_GetRemainingLength(s));
3187 return STATUS_BUFFER_TOO_SMALL;
3190 Stream_Read_UINT32(s, call->cAtrs);
3191 if (!smartcard_ndr_pointer_read(s, &index, &rgAtrMasksNdrPtr))
3192 return ERROR_INVALID_DATA;
3193 Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */
3194 if (!smartcard_ndr_pointer_read(s, &index, &rgReaderStatesNdrPtr))
3195 return ERROR_INVALID_DATA;
3198 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
3201 if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs))
3204 "LocateCardsByATRA_Call rgAtrMasksNdrPtr (0x%08" PRIX32
3205 ") and cAtrs (0x%08" PRIX32 ") inconsistency",
3206 rgAtrMasksNdrPtr, call->cAtrs);
3207 return STATUS_INVALID_PARAMETER;
3210 if (rgAtrMasksNdrPtr)
3212 status = smartcard_ndr_read_atrmask(s, &call->rgAtrMasks, call->cAtrs, NDR_PTR_SIMPLE);
3213 if (status != SCARD_S_SUCCESS)
3217 if (rgReaderStatesNdrPtr)
3219 status = smartcard_unpack_reader_state_a(s, &call->rgReaderStates, call->cReaders, &index);
3220 if (status != SCARD_S_SUCCESS)
3224 smartcard_trace_locate_cards_by_atr_a_call(smartcard, call);
3225 return SCARD_S_SUCCESS;
3228 LONG smartcard_unpack_context_and_two_strings_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3229 ContextAndTwoStringA_Call* call)
3232 UINT32 sz1NdrPtr, sz2NdrPtr;
3235 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
3236 if (status != SCARD_S_SUCCESS)
3239 if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr))
3240 return ERROR_INVALID_DATA;
3241 if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr))
3242 return ERROR_INVALID_DATA;
3244 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->handles.hContext);
3245 if (status != SCARD_S_SUCCESS)
3250 status = smartcard_ndr_read_a(s, &call->sz1, NDR_PTR_FULL);
3251 if (status != SCARD_S_SUCCESS)
3256 status = smartcard_ndr_read_a(s, &call->sz2, NDR_PTR_FULL);
3257 if (status != SCARD_S_SUCCESS)
3260 smartcard_trace_context_and_two_strings_a_call(smartcard, call);
3261 return SCARD_S_SUCCESS;
3264 LONG smartcard_unpack_context_and_two_strings_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3265 ContextAndTwoStringW_Call* call)
3268 UINT32 sz1NdrPtr, sz2NdrPtr;
3270 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
3271 if (status != SCARD_S_SUCCESS)
3274 if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr))
3275 return ERROR_INVALID_DATA;
3276 if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr))
3277 return ERROR_INVALID_DATA;
3279 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->handles.hContext);
3280 if (status != SCARD_S_SUCCESS)
3285 status = smartcard_ndr_read_w(s, &call->sz1, NDR_PTR_FULL);
3286 if (status != SCARD_S_SUCCESS)
3291 status = smartcard_ndr_read_w(s, &call->sz2, NDR_PTR_FULL);
3292 if (status != SCARD_S_SUCCESS)
3295 smartcard_trace_context_and_two_strings_w_call(smartcard, call);
3296 return SCARD_S_SUCCESS;
3299 LONG smartcard_unpack_locate_cards_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3300 LocateCardsA_Call* call)
3303 UINT32 sz1NdrPtr, sz2NdrPtr;
3305 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
3306 if (status != SCARD_S_SUCCESS)
3309 if (Stream_GetRemainingLength(s) < 16)
3311 WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, Stream_GetRemainingLength(s));
3312 return STATUS_BUFFER_TOO_SMALL;
3314 Stream_Read_UINT32(s, call->cBytes);
3315 if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr))
3316 return ERROR_INVALID_DATA;
3318 Stream_Read_UINT32(s, call->cReaders);
3319 if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr))
3320 return ERROR_INVALID_DATA;
3325 smartcard_ndr_read_fixed_string_a(s, &call->mszCards, call->cBytes, NDR_PTR_SIMPLE);
3326 if (status != SCARD_S_SUCCESS)
3331 status = smartcard_unpack_reader_state_a(s, &call->rgReaderStates, call->cReaders, &index);
3332 if (status != SCARD_S_SUCCESS)
3335 smartcard_trace_locate_cards_a_call(smartcard, call);
3336 return SCARD_S_SUCCESS;
3339 LONG smartcard_unpack_locate_cards_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3340 LocateCardsW_Call* call)
3343 UINT32 sz1NdrPtr, sz2NdrPtr;
3346 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
3347 if (status != SCARD_S_SUCCESS)
3350 if (Stream_GetRemainingLength(s) < 16)
3352 WLog_WARN(TAG, "%s is too short: %" PRIuz "", __FUNCTION__, Stream_GetRemainingLength(s));
3353 return STATUS_BUFFER_TOO_SMALL;
3355 Stream_Read_UINT32(s, call->cBytes);
3356 if (!smartcard_ndr_pointer_read(s, &index, &sz1NdrPtr))
3357 return ERROR_INVALID_DATA;
3359 Stream_Read_UINT32(s, call->cReaders);
3360 if (!smartcard_ndr_pointer_read(s, &index, &sz2NdrPtr))
3361 return ERROR_INVALID_DATA;
3366 smartcard_ndr_read_fixed_string_w(s, &call->mszCards, call->cBytes, NDR_PTR_SIMPLE);
3367 if (status != SCARD_S_SUCCESS)
3372 status = smartcard_unpack_reader_state_w(s, &call->rgReaderStates, call->cReaders, &index);
3373 if (status != SCARD_S_SUCCESS)
3376 smartcard_trace_locate_cards_w_call(smartcard, call);
3377 return SCARD_S_SUCCESS;
3380 LONG smartcard_unpack_set_attrib_call(SMARTCARD_DEVICE* smartcard, wStream* s, SetAttrib_Call* call)
3386 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
3387 if (status != SCARD_S_SUCCESS)
3389 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
3390 if (status != SCARD_S_SUCCESS)
3393 if (Stream_GetRemainingLength(s) < 12)
3394 return STATUS_BUFFER_TOO_SMALL;
3395 Stream_Read_UINT32(s, call->dwAttrId);
3396 Stream_Read_UINT32(s, call->cbAttrLen);
3398 if (!smartcard_ndr_pointer_read(s, &index, &ndrPtr))
3399 return ERROR_INVALID_DATA;
3402 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
3405 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
3410 // TODO: call->cbAttrLen was larger than the pointer value.
3411 // TODO: Maybe need to refine the checks?
3412 status = smartcard_ndr_read(s, &call->pbAttr, 0, 1, NDR_PTR_SIMPLE);
3413 if (status != SCARD_S_SUCCESS)
3416 smartcard_trace_set_attrib_call(smartcard, call);
3417 return SCARD_S_SUCCESS;
3420 LONG smartcard_unpack_locate_cards_by_atr_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3421 LocateCardsByATRW_Call* call)
3424 UINT32 rgReaderStatesNdrPtr;
3425 UINT32 rgAtrMasksNdrPtr;
3427 call->rgReaderStates = NULL;
3429 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
3430 if (status != SCARD_S_SUCCESS)
3433 if (Stream_GetRemainingLength(s) < 16)
3435 WLog_WARN(TAG, "LocateCardsByATRW_Call is too short: %" PRIuz "",
3436 Stream_GetRemainingLength(s));
3437 return STATUS_BUFFER_TOO_SMALL;
3440 Stream_Read_UINT32(s, call->cAtrs);
3441 if (!smartcard_ndr_pointer_read(s, &index, &rgAtrMasksNdrPtr))
3442 return ERROR_INVALID_DATA;
3444 Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */
3445 if (!smartcard_ndr_pointer_read(s, &index, &rgReaderStatesNdrPtr))
3446 return ERROR_INVALID_DATA;
3449 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
3452 if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs))
3455 "LocateCardsByATRW_Call rgAtrMasksNdrPtr (0x%08" PRIX32
3456 ") and cAtrs (0x%08" PRIX32 ") inconsistency",
3457 rgAtrMasksNdrPtr, call->cAtrs);
3458 return STATUS_INVALID_PARAMETER;
3461 if (rgAtrMasksNdrPtr)
3463 status = smartcard_ndr_read_atrmask(s, &call->rgAtrMasks, call->cAtrs, NDR_PTR_SIMPLE);
3464 if (status != SCARD_S_SUCCESS)
3468 if (rgReaderStatesNdrPtr)
3470 status = smartcard_unpack_reader_state_w(s, &call->rgReaderStates, call->cReaders, &index);
3471 if (status != SCARD_S_SUCCESS)
3475 smartcard_trace_locate_cards_by_atr_w_call(smartcard, call);
3476 return SCARD_S_SUCCESS;
3479 LONG smartcard_unpack_read_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3480 ReadCacheA_Call* call)
3484 UINT32 contextNdrPtr;
3487 if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr))
3488 return ERROR_INVALID_DATA;
3490 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.handles.hContext),
3492 if (status != SCARD_S_SUCCESS)
3495 if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr))
3496 return ERROR_INVALID_DATA;
3498 if (Stream_GetRemainingLength(s) < 12)
3499 return STATUS_BUFFER_TOO_SMALL;
3500 Stream_Read_UINT32(s, call->Common.FreshnessCounter);
3501 Stream_Read_INT32(s, call->Common.fPbDataIsNULL);
3502 Stream_Read_UINT32(s, call->Common.cbDataLen);
3504 call->szLookupName = NULL;
3507 status = smartcard_ndr_read_a(s, &call->szLookupName, NDR_PTR_FULL);
3508 if (status != SCARD_S_SUCCESS)
3512 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.handles.hContext);
3513 if (status != SCARD_S_SUCCESS)
3518 status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier);
3519 if (status != SCARD_S_SUCCESS)
3522 smartcard_trace_read_cache_a_call(smartcard, call);
3523 return SCARD_S_SUCCESS;
3526 LONG smartcard_unpack_read_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3527 ReadCacheW_Call* call)
3531 UINT32 contextNdrPtr;
3534 if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr))
3535 return ERROR_INVALID_DATA;
3537 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.handles.hContext),
3539 if (status != SCARD_S_SUCCESS)
3542 if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr))
3543 return ERROR_INVALID_DATA;
3545 if (Stream_GetRemainingLength(s) < 12)
3546 return STATUS_BUFFER_TOO_SMALL;
3547 Stream_Read_UINT32(s, call->Common.FreshnessCounter);
3548 Stream_Read_INT32(s, call->Common.fPbDataIsNULL);
3549 Stream_Read_UINT32(s, call->Common.cbDataLen);
3551 call->szLookupName = NULL;
3554 status = smartcard_ndr_read_w(s, &call->szLookupName, NDR_PTR_FULL);
3555 if (status != SCARD_S_SUCCESS)
3559 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.handles.hContext);
3560 if (status != SCARD_S_SUCCESS)
3565 status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier);
3566 if (status != SCARD_S_SUCCESS)
3569 smartcard_trace_read_cache_w_call(smartcard, call);
3570 return SCARD_S_SUCCESS;
3573 LONG smartcard_unpack_write_cache_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3574 WriteCacheA_Call* call)
3578 UINT32 contextNdrPtr;
3579 UINT32 pbDataNdrPtr;
3582 if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr))
3583 return ERROR_INVALID_DATA;
3585 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.handles.hContext),
3587 if (status != SCARD_S_SUCCESS)
3590 if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr))
3591 return ERROR_INVALID_DATA;
3593 if (Stream_GetRemainingLength(s) < 8)
3594 return STATUS_BUFFER_TOO_SMALL;
3596 Stream_Read_UINT32(s, call->Common.FreshnessCounter);
3597 Stream_Read_UINT32(s, call->Common.cbDataLen);
3599 if (!smartcard_ndr_pointer_read(s, &index, &pbDataNdrPtr))
3600 return ERROR_INVALID_DATA;
3602 call->szLookupName = NULL;
3605 status = smartcard_ndr_read_a(s, &call->szLookupName, NDR_PTR_FULL);
3606 if (status != SCARD_S_SUCCESS)
3610 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.handles.hContext);
3611 if (status != SCARD_S_SUCCESS)
3614 call->Common.CardIdentifier = NULL;
3617 status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier);
3618 if (status != SCARD_S_SUCCESS)
3622 call->Common.pbData = NULL;
3626 smartcard_ndr_read(s, &call->Common.pbData, call->Common.cbDataLen, 1, NDR_PTR_SIMPLE);
3627 if (status != SCARD_S_SUCCESS)
3630 smartcard_trace_write_cache_a_call(smartcard, call);
3631 return SCARD_S_SUCCESS;
3634 LONG smartcard_unpack_write_cache_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3635 WriteCacheW_Call* call)
3639 UINT32 contextNdrPtr;
3640 UINT32 pbDataNdrPtr;
3643 if (!smartcard_ndr_pointer_read(s, &index, &mszNdrPtr))
3644 return ERROR_INVALID_DATA;
3646 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->Common.handles.hContext),
3648 if (status != SCARD_S_SUCCESS)
3651 if (!smartcard_ndr_pointer_read(s, &index, &contextNdrPtr))
3652 return ERROR_INVALID_DATA;
3654 if (Stream_GetRemainingLength(s) < 8)
3655 return STATUS_BUFFER_TOO_SMALL;
3656 Stream_Read_UINT32(s, call->Common.FreshnessCounter);
3657 Stream_Read_UINT32(s, call->Common.cbDataLen);
3659 if (!smartcard_ndr_pointer_read(s, &index, &pbDataNdrPtr))
3660 return ERROR_INVALID_DATA;
3662 call->szLookupName = NULL;
3665 status = smartcard_ndr_read_w(s, &call->szLookupName, NDR_PTR_FULL);
3666 if (status != SCARD_S_SUCCESS)
3670 status = smartcard_unpack_redir_scard_context_ref(smartcard, s, &call->Common.handles.hContext);
3671 if (status != SCARD_S_SUCCESS)
3674 call->Common.CardIdentifier = NULL;
3677 status = smartcard_ndr_read_u(s, &call->Common.CardIdentifier);
3678 if (status != SCARD_S_SUCCESS)
3682 call->Common.pbData = NULL;
3686 smartcard_ndr_read(s, &call->Common.pbData, call->Common.cbDataLen, 1, NDR_PTR_SIMPLE);
3687 if (status != SCARD_S_SUCCESS)
3690 smartcard_trace_write_cache_w_call(smartcard, call);
3694 LONG smartcard_unpack_get_transmit_count_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3695 GetTransmitCount_Call* call)
3700 status = smartcard_unpack_redir_scard_context(smartcard, s, &(call->handles.hContext), &index);
3701 if (status != SCARD_S_SUCCESS)
3704 status = smartcard_unpack_redir_scard_handle(smartcard, s, &(call->handles.hCard), &index);
3705 if (status != SCARD_S_SUCCESS)
3709 smartcard_unpack_redir_scard_context_ref(smartcard, s, &(call->handles.hContext))))
3711 WLog_ERR(TAG, "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
3716 if ((status = smartcard_unpack_redir_scard_handle_ref(smartcard, s, &(call->handles.hCard))))
3717 WLog_ERR(TAG, "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "",
3720 smartcard_trace_get_transmit_count_call(smartcard, call);
3724 LONG smartcard_unpack_get_reader_icon_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3725 GetReaderIcon_Call* call)
3727 return smartcard_unpack_common_context_and_string_w(smartcard, s, &call->handles.hContext,
3728 &call->szReaderName);
3731 LONG smartcard_unpack_context_and_string_a_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3732 ContextAndStringA_Call* call)
3734 return smartcard_unpack_common_context_and_string_a(smartcard, s, &call->handles.hContext,
3738 LONG smartcard_unpack_context_and_string_w_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3739 ContextAndStringW_Call* call)
3741 return smartcard_unpack_common_context_and_string_w(smartcard, s, &call->handles.hContext,
3745 LONG smartcard_unpack_get_device_type_id_call(SMARTCARD_DEVICE* smartcard, wStream* s,
3746 GetDeviceTypeId_Call* call)
3748 return smartcard_unpack_common_context_and_string_w(smartcard, s, &call->handles.hContext,
3749 &call->szReaderName);
3752 LONG smartcard_pack_device_type_id_return(SMARTCARD_DEVICE* smartcard, wStream* s,
3753 const GetDeviceTypeId_Return* ret)
3755 smartcard_trace_device_type_id_return(smartcard, ret);
3757 if (!Stream_EnsureRemainingCapacity(s, 4))
3759 WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
3760 return SCARD_F_INTERNAL_ERROR;
3763 Stream_Write_UINT32(s, ret->dwDeviceId); /* cBytes (4 bytes) */
3765 return ret->ReturnCode;
3768 LONG smartcard_pack_locate_cards_return(SMARTCARD_DEVICE* smartcard, wStream* s,
3769 const LocateCards_Return* ret)
3772 DWORD cbDataLen = ret->cReaders;
3775 smartcard_trace_locate_cards_return(smartcard, ret);
3776 if (ret->ReturnCode != SCARD_S_SUCCESS)
3778 if (cbDataLen == SCARD_AUTOALLOCATE)
3781 if (!Stream_EnsureRemainingCapacity(s, 4))
3783 WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
3784 return SCARD_F_INTERNAL_ERROR;
3787 Stream_Write_UINT32(s, cbDataLen); /* cBytes (4 cbDataLen) */
3788 if (!smartcard_ndr_pointer_write(s, &index, cbDataLen))
3789 return SCARD_E_NO_MEMORY;
3791 status = smartcard_ndr_write_state(s, ret->rgReaderStates, cbDataLen, NDR_PTR_SIMPLE);
3792 if (status != SCARD_S_SUCCESS)
3794 return ret->ReturnCode;
3797 LONG smartcard_pack_get_reader_icon_return(SMARTCARD_DEVICE* smartcard, wStream* s,
3798 const GetReaderIcon_Return* ret)
3802 DWORD cbDataLen = ret->cbDataLen;
3803 smartcard_trace_get_reader_icon_return(smartcard, ret);
3804 if (ret->ReturnCode != SCARD_S_SUCCESS)
3806 if (cbDataLen == SCARD_AUTOALLOCATE)
3809 if (!Stream_EnsureRemainingCapacity(s, 4))
3811 WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
3812 return SCARD_F_INTERNAL_ERROR;
3815 Stream_Write_UINT32(s, cbDataLen); /* cBytes (4 cbDataLen) */
3816 if (!smartcard_ndr_pointer_write(s, &index, cbDataLen))
3817 return SCARD_E_NO_MEMORY;
3819 status = smartcard_ndr_write(s, ret->pbData, cbDataLen, 1, NDR_PTR_SIMPLE);
3820 if (status != SCARD_S_SUCCESS)
3822 return ret->ReturnCode;
3825 LONG smartcard_pack_get_transmit_count_return(SMARTCARD_DEVICE* smartcard, wStream* s,
3826 const GetTransmitCount_Return* ret)
3828 smartcard_trace_get_transmit_count_return(smartcard, ret);
3830 if (!Stream_EnsureRemainingCapacity(s, 4))
3832 WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
3833 return SCARD_F_INTERNAL_ERROR;
3836 Stream_Write_UINT32(s, ret->cTransmitCount); /* cBytes (4 cbDataLen) */
3838 return ret->ReturnCode;
3841 LONG smartcard_pack_read_cache_return(SMARTCARD_DEVICE* smartcard, wStream* s,
3842 const ReadCache_Return* ret)
3846 DWORD cbDataLen = ret->cbDataLen;
3847 smartcard_trace_read_cache_return(smartcard, ret);
3848 if (ret->ReturnCode != SCARD_S_SUCCESS)
3851 if (cbDataLen == SCARD_AUTOALLOCATE)
3854 if (!Stream_EnsureRemainingCapacity(s, 4))
3856 WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
3857 return SCARD_F_INTERNAL_ERROR;
3860 Stream_Write_UINT32(s, cbDataLen); /* cBytes (4 cbDataLen) */
3861 if (!smartcard_ndr_pointer_write(s, &index, cbDataLen))
3862 return SCARD_E_NO_MEMORY;
3864 status = smartcard_ndr_write(s, ret->pbData, cbDataLen, 1, NDR_PTR_SIMPLE);
3865 if (status != SCARD_S_SUCCESS)
3867 return ret->ReturnCode;