26 #include <freerdp/config.h>
28 #include <winpr/assert.h>
30 #include <winpr/crt.h>
31 #include <winpr/print.h>
32 #include <winpr/stream.h>
33 #include <winpr/library.h>
34 #include <winpr/smartcard.h>
36 #include <freerdp/freerdp.h>
37 #include <freerdp/channels/rdpdr.h>
38 #include <freerdp/channels/scard.h>
40 #include <freerdp/utils/rdpdr_utils.h>
41 #include <freerdp/utils/smartcard_pack.h>
42 #include <freerdp/utils/smartcard_call.h>
44 #include <freerdp/log.h>
45 #define TAG FREERDP_TAG("utils.smartcard.call")
47 #if defined(WITH_SMARTCARD_EMULATE)
48 #include <freerdp/emulate/scard/smartcard_emulate.h>
50 #define wrap(ctx, fkt, ...) \
51 ctx->useEmulatedCard ? Emulate_##fkt(ctx->emulation, ##__VA_ARGS__) \
52 : ctx->pWinSCardApi->pfn##fkt(__VA_ARGS__)
53 #define wrap_ptr(ctx, fkt, ...) wrap(ctx, fkt, ##__VA_ARGS__)
55 #define wrap(ctx, fkt, ...) \
56 ctx->useEmulatedCard ? SCARD_F_INTERNAL_ERROR : ctx->pWinSCardApi->pfn##fkt(__VA_ARGS__)
57 #define wrap_ptr(ctx, fkt, ...) \
58 ctx->useEmulatedCard ? NULL : ctx->pWinSCardApi->pfn##fkt(__VA_ARGS__)
61 struct s_scard_call_context
66 wHashTable* rgSCardContextList;
67 #if defined(WITH_SMARTCARD_EMULATE)
68 SmartcardEmulationContext* emulation;
70 HANDLE hWinSCardLibrary;
76 void* (*fn_new)(
void*, SCARDCONTEXT);
77 void (*fn_free)(
void*);
80 struct s_scard_context_element
83 void (*fn_free)(
void*);
86 static void context_free(
void* arg);
88 static LONG smartcard_EstablishContext_Call(scard_call_context* smartcard,
wStream* out,
92 SCARDCONTEXT hContext = { 0 };
95 status = ret.ReturnCode =
96 wrap(smartcard, SCardEstablishContext, call->dwScope, NULL, NULL, &hContext);
98 if (ret.ReturnCode == SCARD_S_SUCCESS)
100 const void* key = (
void*)(
size_t)hContext;
101 struct s_scard_context_element* pContext =
102 calloc(1,
sizeof(
struct s_scard_context_element));
104 return STATUS_NO_MEMORY;
106 pContext->fn_free = smartcard->fn_free;
108 if (smartcard->fn_new)
110 pContext->context = smartcard->fn_new(smartcard->userdata, hContext);
111 if (!pContext->context)
114 return STATUS_NO_MEMORY;
118 if (!HashTable_Insert(smartcard->rgSCardContextList, key, (
void*)pContext))
120 WLog_ERR(TAG,
"ListDictionary_Add failed!");
121 context_free(pContext);
122 return STATUS_INTERNAL_ERROR;
127 return scard_log_status_error(TAG,
"SCardEstablishContext", status);
131 smartcard_scard_context_native_to_redir(&(ret.hContext), hContext);
133 status = smartcard_pack_establish_context_return(out, &ret);
134 if (status != SCARD_S_SUCCESS)
136 return scard_log_status_error(TAG,
"smartcard_pack_establish_context_return", status);
139 return ret.ReturnCode;
142 static LONG smartcard_ReleaseContext_Call(scard_call_context* smartcard,
wStream* out,
147 WINPR_ASSERT(smartcard);
149 WINPR_ASSERT(operation);
151 ret.ReturnCode = wrap(smartcard, SCardReleaseContext, operation->hContext);
153 if (ret.ReturnCode == SCARD_S_SUCCESS)
154 HashTable_Remove(smartcard->rgSCardContextList, (
void*)operation->hContext);
157 return scard_log_status_error(TAG,
"SCardReleaseContext", ret.ReturnCode);
160 smartcard_trace_long_return(&ret,
"ReleaseContext");
161 return ret.ReturnCode;
164 static LONG smartcard_IsValidContext_Call(scard_call_context* smartcard,
wStream* out,
169 WINPR_ASSERT(smartcard);
171 WINPR_ASSERT(operation);
173 ret.ReturnCode = wrap(smartcard, SCardIsValidContext, operation->hContext);
174 smartcard_trace_long_return(&ret,
"IsValidContext");
175 return ret.ReturnCode;
178 static LONG smartcard_ListReaderGroupsA_Call(scard_call_context* smartcard,
wStream* out,
183 LPSTR mszGroups = NULL;
186 WINPR_ASSERT(smartcard);
188 WINPR_ASSERT(operation);
190 cchGroups = SCARD_AUTOALLOCATE;
192 wrap(smartcard, SCardListReaderGroupsA, operation->hContext, (LPSTR)&mszGroups, &cchGroups);
193 if (cchGroups == SCARD_AUTOALLOCATE)
194 return SCARD_F_UNKNOWN_ERROR;
196 ret.msz = (BYTE*)mszGroups;
197 ret.cBytes = cchGroups;
199 status = smartcard_pack_list_reader_groups_return(out, &ret, FALSE);
201 if (status != SCARD_S_SUCCESS)
205 wrap(smartcard, SCardFreeMemory, operation->hContext, mszGroups);
207 return ret.ReturnCode;
210 static LONG smartcard_ListReaderGroupsW_Call(scard_call_context* smartcard,
wStream* out,
215 LPWSTR mszGroups = NULL;
218 WINPR_ASSERT(smartcard);
220 WINPR_ASSERT(operation);
222 cchGroups = SCARD_AUTOALLOCATE;
223 status = ret.ReturnCode = wrap(smartcard, SCardListReaderGroupsW, operation->hContext,
224 (LPWSTR)&mszGroups, &cchGroups);
225 if (cchGroups == SCARD_AUTOALLOCATE)
226 return SCARD_F_UNKNOWN_ERROR;
228 ret.msz = (BYTE*)mszGroups;
230 WINPR_ASSERT(cchGroups < SCARD_AUTOALLOCATE /
sizeof(WCHAR));
231 const size_t blen =
sizeof(WCHAR) * cchGroups;
232 WINPR_ASSERT(blen <= UINT32_MAX);
233 ret.cBytes = (UINT32)blen;
235 if (status != SCARD_S_SUCCESS)
238 status = smartcard_pack_list_reader_groups_return(out, &ret, TRUE);
240 if (status != SCARD_S_SUCCESS)
244 wrap(smartcard, SCardFreeMemory, operation->hContext, mszGroups);
246 return ret.ReturnCode;
249 static BOOL filter_match(wLinkedList* list, LPCSTR reader,
size_t readerLen)
254 LinkedList_Enumerator_Reset(list);
256 while (LinkedList_Enumerator_MoveNext(list))
258 const char* filter = LinkedList_Enumerator_Current(list);
262 if (strstr(reader, filter) != NULL)
270 static DWORD filter_device_by_name_a(wLinkedList* list, LPSTR* mszReaders, DWORD cchReaders)
275 if (*mszReaders == NULL || LinkedList_Count(list) < 1)
280 LPCSTR rreader = &(*mszReaders)[rpos];
281 LPSTR wreader = &(*mszReaders)[wpos];
282 size_t readerLen = strnlen(rreader, cchReaders - rpos);
284 rpos += readerLen + 1;
286 if (filter_match(list, rreader, readerLen))
288 if (rreader != wreader)
289 memmove(wreader, rreader, readerLen + 1);
291 wpos += readerLen + 1;
293 }
while (rpos < cchReaders);
298 if (wpos >= cchReaders)
301 (*mszReaders)[wpos++] =
'\0';
307 static DWORD filter_device_by_name_w(wLinkedList* list, LPWSTR* mszReaders, DWORD cchReaders)
310 LPSTR readers = NULL;
312 if (LinkedList_Count(list) < 1)
315 readers = ConvertMszWCharNToUtf8Alloc(*mszReaders, cchReaders, NULL);
325 rc = filter_device_by_name_a(list, &readers, cchReaders);
327 *mszReaders = ConvertMszUtf8NToWCharAlloc(readers, rc, NULL);
335 static LONG smartcard_ListReadersA_Call(scard_call_context* smartcard,
wStream* out,
339 LPSTR mszReaders = NULL;
341 WINPR_ASSERT(smartcard);
343 WINPR_ASSERT(operation);
346 DWORD cchReaders = SCARD_AUTOALLOCATE;
347 LONG status = ret.ReturnCode = wrap(smartcard, SCardListReadersA, operation->hContext,
348 (LPCSTR)call->mszGroups, (LPSTR)&mszReaders, &cchReaders);
349 if (cchReaders == SCARD_AUTOALLOCATE)
350 return SCARD_F_UNKNOWN_ERROR;
352 if (status != SCARD_S_SUCCESS)
353 return scard_log_status_error(TAG,
"SCardListReadersA", status);
355 cchReaders = filter_device_by_name_a(smartcard->names, &mszReaders, cchReaders);
356 ret.msz = (BYTE*)mszReaders;
357 ret.cBytes = cchReaders;
359 status = smartcard_pack_list_readers_return(out, &ret, FALSE);
361 wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaders);
363 if (status != SCARD_S_SUCCESS)
364 return scard_log_status_error(TAG,
"smartcard_pack_list_readers_return", status);
366 return ret.ReturnCode;
369 static LONG smartcard_ListReadersW_Call(scard_call_context* smartcard,
wStream* out,
374 DWORD cchReaders = 0;
390 WINPR_ASSERT(smartcard);
391 WINPR_ASSERT(operation);
393 call = &operation->call.listReaders;
395 string.bp = call->mszGroups;
396 cchReaders = SCARD_AUTOALLOCATE;
397 status = ret.ReturnCode = wrap(smartcard, SCardListReadersW, operation->hContext,
string.wz,
398 (LPWSTR)&mszReaders.pw, &cchReaders);
399 if (cchReaders == SCARD_AUTOALLOCATE)
400 return SCARD_F_UNKNOWN_ERROR;
402 if (status != SCARD_S_SUCCESS)
403 return scard_log_status_error(TAG,
"SCardListReadersW", status);
405 cchReaders = filter_device_by_name_w(smartcard->names, &mszReaders.pw, cchReaders);
406 ret.msz = mszReaders.pb;
407 ret.cBytes = cchReaders *
sizeof(WCHAR);
408 status = smartcard_pack_list_readers_return(out, &ret, TRUE);
411 wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaders.pb);
413 if (status != SCARD_S_SUCCESS)
416 return ret.ReturnCode;
419 static LONG smartcard_IntroduceReaderGroupA_Call(scard_call_context* smartcard,
wStream* out,
425 WINPR_ASSERT(smartcard);
427 WINPR_ASSERT(operation);
429 call = &operation->call.contextAndStringA;
430 ret.ReturnCode = wrap(smartcard, SCardIntroduceReaderGroupA, operation->hContext, call->sz);
431 scard_log_status_error(TAG,
"SCardIntroduceReaderGroupA", ret.ReturnCode);
432 smartcard_trace_long_return(&ret,
"IntroduceReaderGroupA");
433 return ret.ReturnCode;
436 static LONG smartcard_IntroduceReaderGroupW_Call(scard_call_context* smartcard,
wStream* out,
442 WINPR_ASSERT(smartcard);
444 WINPR_ASSERT(operation);
446 call = &operation->call.contextAndStringW;
447 ret.ReturnCode = wrap(smartcard, SCardIntroduceReaderGroupW, operation->hContext, call->sz);
448 scard_log_status_error(TAG,
"SCardIntroduceReaderGroupW", ret.ReturnCode);
449 smartcard_trace_long_return(&ret,
"IntroduceReaderGroupW");
450 return ret.ReturnCode;
453 static LONG smartcard_IntroduceReaderA_Call(scard_call_context* smartcard,
wStream* out,
459 WINPR_ASSERT(smartcard);
461 WINPR_ASSERT(operation);
463 call = &operation->call.contextAndTwoStringA;
465 wrap(smartcard, SCardIntroduceReaderA, operation->hContext, call->sz1, call->sz2);
466 scard_log_status_error(TAG,
"SCardIntroduceReaderA", ret.ReturnCode);
467 smartcard_trace_long_return(&ret,
"IntroduceReaderA");
468 return ret.ReturnCode;
471 static LONG smartcard_IntroduceReaderW_Call(scard_call_context* smartcard,
wStream* out,
477 WINPR_ASSERT(smartcard);
479 WINPR_ASSERT(operation);
481 call = &operation->call.contextAndTwoStringW;
483 wrap(smartcard, SCardIntroduceReaderW, operation->hContext, call->sz1, call->sz2);
484 scard_log_status_error(TAG,
"SCardIntroduceReaderW", ret.ReturnCode);
485 smartcard_trace_long_return(&ret,
"IntroduceReaderW");
486 return ret.ReturnCode;
489 static LONG smartcard_ForgetReaderA_Call(scard_call_context* smartcard,
wStream* out,
495 WINPR_ASSERT(smartcard);
497 WINPR_ASSERT(operation);
499 call = &operation->call.contextAndStringA;
500 ret.ReturnCode = wrap(smartcard, SCardForgetReaderA, operation->hContext, call->sz);
501 scard_log_status_error(TAG,
"SCardForgetReaderA", ret.ReturnCode);
502 smartcard_trace_long_return(&ret,
"SCardForgetReaderA");
503 return ret.ReturnCode;
506 static LONG smartcard_ForgetReaderW_Call(scard_call_context* smartcard,
wStream* out,
512 WINPR_ASSERT(smartcard);
514 WINPR_ASSERT(operation);
516 call = &operation->call.contextAndStringW;
517 ret.ReturnCode = wrap(smartcard, SCardForgetReaderW, operation->hContext, call->sz);
518 scard_log_status_error(TAG,
"SCardForgetReaderW", ret.ReturnCode);
519 smartcard_trace_long_return(&ret,
"SCardForgetReaderW");
520 return ret.ReturnCode;
523 static LONG smartcard_AddReaderToGroupA_Call(scard_call_context* smartcard,
wStream* out,
529 WINPR_ASSERT(smartcard);
531 WINPR_ASSERT(operation);
533 call = &operation->call.contextAndTwoStringA;
535 wrap(smartcard, SCardAddReaderToGroupA, operation->hContext, call->sz1, call->sz2);
536 scard_log_status_error(TAG,
"SCardAddReaderToGroupA", ret.ReturnCode);
537 smartcard_trace_long_return(&ret,
"SCardAddReaderToGroupA");
538 return ret.ReturnCode;
541 static LONG smartcard_AddReaderToGroupW_Call(scard_call_context* smartcard,
wStream* out,
547 WINPR_ASSERT(smartcard);
549 WINPR_ASSERT(operation);
551 call = &operation->call.contextAndTwoStringW;
553 wrap(smartcard, SCardAddReaderToGroupW, operation->hContext, call->sz1, call->sz2);
554 scard_log_status_error(TAG,
"SCardAddReaderToGroupW", ret.ReturnCode);
555 smartcard_trace_long_return(&ret,
"SCardAddReaderToGroupA");
556 return ret.ReturnCode;
559 static LONG smartcard_RemoveReaderFromGroupA_Call(scard_call_context* smartcard,
wStream* out,
565 WINPR_ASSERT(smartcard);
567 WINPR_ASSERT(operation);
569 call = &operation->call.contextAndTwoStringA;
571 wrap(smartcard, SCardRemoveReaderFromGroupA, operation->hContext, call->sz1, call->sz2);
572 scard_log_status_error(TAG,
"SCardRemoveReaderFromGroupA", ret.ReturnCode);
573 smartcard_trace_long_return(&ret,
"SCardRemoveReaderFromGroupA");
574 return ret.ReturnCode;
577 static LONG smartcard_RemoveReaderFromGroupW_Call(scard_call_context* smartcard,
wStream* out,
583 WINPR_ASSERT(smartcard);
585 WINPR_ASSERT(operation);
587 call = &operation->call.contextAndTwoStringW;
589 wrap(smartcard, SCardRemoveReaderFromGroupW, operation->hContext, call->sz1, call->sz2);
590 scard_log_status_error(TAG,
"SCardRemoveReaderFromGroupW", ret.ReturnCode);
591 smartcard_trace_long_return(&ret,
"SCardRemoveReaderFromGroupW");
592 return ret.ReturnCode;
595 static LONG smartcard_LocateCardsA_Call(scard_call_context* smartcard,
wStream* out,
602 WINPR_ASSERT(smartcard);
603 WINPR_ASSERT(operation);
605 call = &operation->call.locateCardsA;
607 ret.ReturnCode = wrap(smartcard, SCardLocateCardsA, operation->hContext, call->mszCards,
608 call->rgReaderStates, call->cReaders);
609 scard_log_status_error(TAG,
"SCardLocateCardsA", ret.ReturnCode);
610 ret.cReaders = call->cReaders;
611 ret.rgReaderStates = NULL;
613 if (ret.cReaders > 0)
617 if (!ret.rgReaderStates)
618 return STATUS_NO_MEMORY;
621 for (UINT32 x = 0; x < ret.cReaders; x++)
623 ret.rgReaderStates[x].dwCurrentState = call->rgReaderStates[x].dwCurrentState;
624 ret.rgReaderStates[x].dwEventState = call->rgReaderStates[x].dwEventState;
625 ret.rgReaderStates[x].cbAtr = call->rgReaderStates[x].cbAtr;
626 CopyMemory(&(ret.rgReaderStates[x].rgbAtr), &(call->rgReaderStates[x].rgbAtr),
627 sizeof(ret.rgReaderStates[x].rgbAtr));
630 status = smartcard_pack_locate_cards_return(out, &ret);
632 if (status != SCARD_S_SUCCESS)
635 return ret.ReturnCode;
638 static LONG smartcard_LocateCardsW_Call(scard_call_context* smartcard,
wStream* out,
645 WINPR_ASSERT(smartcard);
646 WINPR_ASSERT(operation);
648 call = &operation->call.locateCardsW;
650 ret.ReturnCode = wrap(smartcard, SCardLocateCardsW, operation->hContext, call->mszCards,
651 call->rgReaderStates, call->cReaders);
652 scard_log_status_error(TAG,
"SCardLocateCardsW", ret.ReturnCode);
653 ret.cReaders = call->cReaders;
654 ret.rgReaderStates = NULL;
656 if (ret.cReaders > 0)
660 if (!ret.rgReaderStates)
661 return STATUS_NO_MEMORY;
664 for (UINT32 x = 0; x < ret.cReaders; x++)
666 ret.rgReaderStates[x].dwCurrentState = call->rgReaderStates[x].dwCurrentState;
667 ret.rgReaderStates[x].dwEventState = call->rgReaderStates[x].dwEventState;
668 ret.rgReaderStates[x].cbAtr = call->rgReaderStates[x].cbAtr;
669 CopyMemory(&(ret.rgReaderStates[x].rgbAtr), &(call->rgReaderStates[x].rgbAtr),
670 sizeof(ret.rgReaderStates[x].rgbAtr));
673 status = smartcard_pack_locate_cards_return(out, &ret);
675 if (status != SCARD_S_SUCCESS)
678 return ret.ReturnCode;
681 static LONG smartcard_ReadCacheA_Call(scard_call_context* smartcard,
wStream* out,
689 WINPR_ASSERT(smartcard);
691 WINPR_ASSERT(operation);
693 call = &operation->call.readCacheA;
694 autoalloc = (call->Common.cbDataLen == SCARD_AUTOALLOCATE);
696 if (!call->Common.fPbDataIsNULL)
698 ret.cbDataLen = call->Common.cbDataLen;
701 ret.pbData = malloc(ret.cbDataLen);
703 return SCARD_F_INTERNAL_ERROR;
708 ret.ReturnCode = wrap(smartcard, SCardReadCacheA, operation->hContext,
709 call->Common.CardIdentifier, call->Common.FreshnessCounter,
710 call->szLookupName, (BYTE*)&ret.pbData, &ret.cbDataLen);
713 wrap(smartcard, SCardReadCacheA, operation->hContext, call->Common.CardIdentifier,
714 call->Common.FreshnessCounter, call->szLookupName, ret.pbData, &ret.cbDataLen);
715 if ((ret.ReturnCode != SCARD_W_CACHE_ITEM_NOT_FOUND) &&
716 (ret.ReturnCode != SCARD_W_CACHE_ITEM_STALE))
718 scard_log_status_error(TAG,
"SCardReadCacheA", ret.ReturnCode);
721 status = smartcard_pack_read_cache_return(out, &ret);
723 wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData);
726 if (status != SCARD_S_SUCCESS)
729 return ret.ReturnCode;
732 static LONG smartcard_ReadCacheW_Call(scard_call_context* smartcard,
wStream* out,
739 WINPR_ASSERT(smartcard);
741 WINPR_ASSERT(operation);
743 call = &operation->call.readCacheW;
745 if (!call->Common.fPbDataIsNULL)
746 ret.cbDataLen = SCARD_AUTOALLOCATE;
749 wrap(smartcard, SCardReadCacheW, operation->hContext, call->Common.CardIdentifier,
750 call->Common.FreshnessCounter, call->szLookupName, (BYTE*)&ret.pbData, &ret.cbDataLen);
752 if ((ret.ReturnCode != SCARD_W_CACHE_ITEM_NOT_FOUND) &&
753 (ret.ReturnCode != SCARD_W_CACHE_ITEM_STALE))
755 scard_log_status_error(TAG,
"SCardReadCacheW", ret.ReturnCode);
758 status = smartcard_pack_read_cache_return(out, &ret);
760 wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData);
762 if (status != SCARD_S_SUCCESS)
765 return ret.ReturnCode;
768 static LONG smartcard_WriteCacheA_Call(scard_call_context* smartcard,
wStream* out,
774 WINPR_ASSERT(smartcard);
776 WINPR_ASSERT(operation);
778 call = &operation->call.writeCacheA;
780 ret.ReturnCode = wrap(smartcard, SCardWriteCacheA, operation->hContext,
781 call->Common.CardIdentifier, call->Common.FreshnessCounter,
782 call->szLookupName, call->Common.pbData, call->Common.cbDataLen);
783 scard_log_status_error(TAG,
"SCardWriteCacheA", ret.ReturnCode);
784 smartcard_trace_long_return(&ret,
"SCardWriteCacheA");
785 return ret.ReturnCode;
788 static LONG smartcard_WriteCacheW_Call(scard_call_context* smartcard,
wStream* out,
794 WINPR_ASSERT(smartcard);
796 WINPR_ASSERT(operation);
798 call = &operation->call.writeCacheW;
800 ret.ReturnCode = wrap(smartcard, SCardWriteCacheW, operation->hContext,
801 call->Common.CardIdentifier, call->Common.FreshnessCounter,
802 call->szLookupName, call->Common.pbData, call->Common.cbDataLen);
803 scard_log_status_error(TAG,
"SCardWriteCacheW", ret.ReturnCode);
804 smartcard_trace_long_return(&ret,
"SCardWriteCacheW");
805 return ret.ReturnCode;
808 static LONG smartcard_GetTransmitCount_Call(scard_call_context* smartcard,
wStream* out,
814 WINPR_ASSERT(smartcard);
816 WINPR_ASSERT(operation);
818 ret.ReturnCode = wrap(smartcard, SCardGetTransmitCount, operation->hCard, &ret.cTransmitCount);
819 scard_log_status_error(TAG,
"SCardGetTransmitCount", ret.ReturnCode);
820 status = smartcard_pack_get_transmit_count_return(out, &ret);
821 if (status != SCARD_S_SUCCESS)
824 return ret.ReturnCode;
827 static LONG smartcard_ReleaseStartedEvent_Call(scard_call_context* smartcard,
wStream* out,
830 WINPR_UNUSED(smartcard);
832 WINPR_UNUSED(operation);
834 WLog_WARN(TAG,
"According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules "
835 "this is not supported?!?");
836 return SCARD_E_UNSUPPORTED_FEATURE;
839 static LONG smartcard_GetReaderIcon_Call(scard_call_context* smartcard,
wStream* out,
846 WINPR_ASSERT(smartcard);
848 WINPR_ASSERT(operation);
850 call = &operation->call.getReaderIcon;
852 ret.cbDataLen = SCARD_AUTOALLOCATE;
853 ret.ReturnCode = wrap(smartcard, SCardGetReaderIconW, operation->hContext, call->szReaderName,
854 (LPBYTE)&ret.pbData, &ret.cbDataLen);
855 scard_log_status_error(TAG,
"SCardGetReaderIconW", ret.ReturnCode);
856 if (ret.cbDataLen == SCARD_AUTOALLOCATE)
857 return SCARD_F_UNKNOWN_ERROR;
859 status = smartcard_pack_get_reader_icon_return(out, &ret);
860 wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbData);
861 if (status != SCARD_S_SUCCESS)
864 return ret.ReturnCode;
867 static LONG smartcard_GetDeviceTypeId_Call(scard_call_context* smartcard,
wStream* out,
874 WINPR_ASSERT(smartcard);
876 WINPR_ASSERT(operation);
878 call = &operation->call.getDeviceTypeId;
880 ret.ReturnCode = wrap(smartcard, SCardGetDeviceTypeIdW, operation->hContext, call->szReaderName,
882 scard_log_status_error(TAG,
"SCardGetDeviceTypeIdW", ret.ReturnCode);
884 status = smartcard_pack_device_type_id_return(out, &ret);
885 if (status != SCARD_S_SUCCESS)
888 return ret.ReturnCode;
891 static LONG smartcard_GetStatusChangeA_Call(scard_call_context* smartcard,
wStream* out,
894 LONG status = STATUS_NO_MEMORY;
896 const DWORD dwTimeStep = 100;
901 WINPR_ASSERT(smartcard);
903 WINPR_ASSERT(operation);
905 call = &operation->call.getStatusChangeA;
906 dwTimeOut = call->dwTimeOut;
908 if (call->cReaders > 0)
910 ret.cReaders = call->cReaders;
913 if (!rgReaderStates || !ret.rgReaderStates)
917 for (UINT32 x = 0; x < MAX(1, dwTimeOut);)
919 if (call->cReaders > 0)
920 memcpy(rgReaderStates, call->rgReaderStates,
922 ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeA, operation->hContext,
923 MIN(dwTimeOut, dwTimeStep), rgReaderStates, call->cReaders);
924 if (ret.ReturnCode != SCARD_E_TIMEOUT)
926 if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
928 if (dwTimeOut != INFINITE)
931 scard_log_status_error(TAG,
"SCardGetStatusChangeA", ret.ReturnCode);
933 for (UINT32 index = 0; index < ret.cReaders; index++)
938 rout->dwCurrentState = cur->dwCurrentState;
939 rout->dwEventState = cur->dwEventState;
940 rout->cbAtr = cur->cbAtr;
941 CopyMemory(&(rout->rgbAtr), cur->rgbAtr,
sizeof(rout->rgbAtr));
944 status = smartcard_pack_get_status_change_return(out, &ret, TRUE);
946 free(ret.rgReaderStates);
947 free(rgReaderStates);
948 if (status != SCARD_S_SUCCESS)
950 return ret.ReturnCode;
953 static LONG smartcard_GetStatusChangeW_Call(scard_call_context* smartcard,
wStream* out,
956 LONG status = STATUS_NO_MEMORY;
958 const DWORD dwTimeStep = 100;
963 WINPR_ASSERT(smartcard);
965 WINPR_ASSERT(operation);
967 call = &operation->call.getStatusChangeW;
968 dwTimeOut = call->dwTimeOut;
970 if (call->cReaders > 0)
972 ret.cReaders = call->cReaders;
975 if (!rgReaderStates || !ret.rgReaderStates)
979 for (UINT32 x = 0; x < MAX(1, dwTimeOut);)
981 if (call->cReaders > 0)
982 memcpy(rgReaderStates, call->rgReaderStates,
985 ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeW, operation->hContext,
986 MIN(dwTimeOut, dwTimeStep), rgReaderStates, call->cReaders);
988 if (ret.ReturnCode != SCARD_E_TIMEOUT)
990 if (WaitForSingleObject(smartcard->stopEvent, 0) == WAIT_OBJECT_0)
992 if (dwTimeOut != INFINITE)
995 scard_log_status_error(TAG,
"SCardGetStatusChangeW", ret.ReturnCode);
997 for (UINT32 index = 0; index < ret.cReaders; index++)
1002 rout->dwCurrentState = cur->dwCurrentState;
1003 rout->dwEventState = cur->dwEventState;
1004 rout->cbAtr = cur->cbAtr;
1005 CopyMemory(&(rout->rgbAtr), cur->rgbAtr,
sizeof(rout->rgbAtr));
1008 status = smartcard_pack_get_status_change_return(out, &ret, TRUE);
1010 free(ret.rgReaderStates);
1011 free(rgReaderStates);
1012 if (status != SCARD_S_SUCCESS)
1014 return ret.ReturnCode;
1017 static LONG smartcard_Cancel_Call(scard_call_context* smartcard,
wStream* out,
1022 WINPR_ASSERT(smartcard);
1024 WINPR_ASSERT(operation);
1026 ret.ReturnCode = wrap(smartcard, SCardCancel, operation->hContext);
1027 scard_log_status_error(TAG,
"SCardCancel", ret.ReturnCode);
1028 smartcard_trace_long_return(&ret,
"Cancel");
1029 return ret.ReturnCode;
1032 static LONG smartcard_ConnectA_Call(scard_call_context* smartcard,
wStream* out,
1036 SCARDHANDLE hCard = 0;
1040 WINPR_ASSERT(smartcard);
1042 WINPR_ASSERT(operation);
1044 call = &operation->call.connectA;
1046 if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) &&
1047 (call->Common.dwShareMode != SCARD_SHARE_DIRECT))
1049 call->Common.dwPreferredProtocols = SCARD_PROTOCOL_Tx;
1052 ret.ReturnCode = wrap(smartcard, SCardConnectA, operation->hContext, (
char*)call->szReader,
1053 call->Common.dwShareMode, call->Common.dwPreferredProtocols, &hCard,
1054 &ret.dwActiveProtocol);
1055 smartcard_scard_context_native_to_redir(&(ret.hContext), operation->hContext);
1056 smartcard_scard_handle_native_to_redir(&(ret.hCard), hCard);
1058 status = smartcard_pack_connect_return(out, &ret);
1059 if (status != SCARD_S_SUCCESS)
1062 status = ret.ReturnCode;
1068 static LONG smartcard_ConnectW_Call(scard_call_context* smartcard,
wStream* out,
1072 SCARDHANDLE hCard = 0;
1076 WINPR_ASSERT(smartcard);
1078 WINPR_ASSERT(operation);
1080 call = &operation->call.connectW;
1082 if ((call->Common.dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED) &&
1083 (call->Common.dwShareMode != SCARD_SHARE_DIRECT))
1085 call->Common.dwPreferredProtocols = SCARD_PROTOCOL_Tx;
1088 ret.ReturnCode = wrap(smartcard, SCardConnectW, operation->hContext, (WCHAR*)call->szReader,
1089 call->Common.dwShareMode, call->Common.dwPreferredProtocols, &hCard,
1090 &ret.dwActiveProtocol);
1091 smartcard_scard_context_native_to_redir(&(ret.hContext), operation->hContext);
1092 smartcard_scard_handle_native_to_redir(&(ret.hCard), hCard);
1094 status = smartcard_pack_connect_return(out, &ret);
1095 if (status != SCARD_S_SUCCESS)
1098 status = ret.ReturnCode;
1104 static LONG smartcard_Reconnect_Call(scard_call_context* smartcard,
wStream* out,
1111 WINPR_ASSERT(smartcard);
1113 WINPR_ASSERT(operation);
1115 call = &operation->call.reconnect;
1117 wrap(smartcard, SCardReconnect, operation->hCard, call->dwShareMode,
1118 call->dwPreferredProtocols, call->dwInitialization, &ret.dwActiveProtocol);
1119 scard_log_status_error(TAG,
"SCardReconnect", ret.ReturnCode);
1120 status = smartcard_pack_reconnect_return(out, &ret);
1121 if (status != SCARD_S_SUCCESS)
1124 return ret.ReturnCode;
1127 static LONG smartcard_Disconnect_Call(scard_call_context* smartcard,
wStream* out,
1133 WINPR_ASSERT(smartcard);
1135 WINPR_ASSERT(operation);
1137 call = &operation->call.hCardAndDisposition;
1139 ret.ReturnCode = wrap(smartcard, SCardDisconnect, operation->hCard, call->dwDisposition);
1140 scard_log_status_error(TAG,
"SCardDisconnect", ret.ReturnCode);
1141 smartcard_trace_long_return(&ret,
"Disconnect");
1143 return ret.ReturnCode;
1146 static LONG smartcard_BeginTransaction_Call(scard_call_context* smartcard,
wStream* out,
1151 WINPR_ASSERT(smartcard);
1153 WINPR_ASSERT(operation);
1155 ret.ReturnCode = wrap(smartcard, SCardBeginTransaction, operation->hCard);
1156 scard_log_status_error(TAG,
"SCardBeginTransaction", ret.ReturnCode);
1157 smartcard_trace_long_return(&ret,
"BeginTransaction");
1158 return ret.ReturnCode;
1161 static LONG smartcard_EndTransaction_Call(scard_call_context* smartcard,
wStream* out,
1167 WINPR_ASSERT(smartcard);
1169 WINPR_ASSERT(operation);
1171 call = &operation->call.hCardAndDisposition;
1173 ret.ReturnCode = wrap(smartcard, SCardEndTransaction, operation->hCard, call->dwDisposition);
1174 scard_log_status_error(TAG,
"SCardEndTransaction", ret.ReturnCode);
1175 smartcard_trace_long_return(&ret,
"EndTransaction");
1176 return ret.ReturnCode;
1179 static LONG smartcard_State_Call(scard_call_context* smartcard,
wStream* out,
1185 WINPR_ASSERT(smartcard);
1187 WINPR_ASSERT(operation);
1189 ret.cbAtrLen = SCARD_ATR_LENGTH;
1190 ret.ReturnCode = wrap(smartcard, SCardState, operation->hCard, &ret.dwState, &ret.dwProtocol,
1191 (BYTE*)&ret.rgAtr, &ret.cbAtrLen);
1193 scard_log_status_error(TAG,
"SCardState", ret.ReturnCode);
1194 status = smartcard_pack_state_return(out, &ret);
1195 if (status != SCARD_S_SUCCESS)
1198 return ret.ReturnCode;
1201 static LONG smartcard_StatusA_Call(scard_call_context* smartcard,
wStream* out,
1206 DWORD cchReaderLen = 0;
1208 LPSTR mszReaderNames = NULL;
1211 WINPR_ASSERT(smartcard);
1213 WINPR_ASSERT(operation);
1215 call = &operation->call.status;
1217 call->cbAtrLen = 32;
1218 cbAtrLen = call->cbAtrLen;
1220 if (call->fmszReaderNamesIsNULL)
1223 cchReaderLen = SCARD_AUTOALLOCATE;
1225 status = ret.ReturnCode =
1226 wrap(smartcard, SCardStatusA, operation->hCard,
1227 call->fmszReaderNamesIsNULL ? NULL : (LPSTR)&mszReaderNames, &cchReaderLen,
1228 &ret.dwState, &ret.dwProtocol, cbAtrLen ? (BYTE*)&ret.pbAtr : NULL, &cbAtrLen);
1230 scard_log_status_error(TAG,
"SCardStatusA", status);
1231 if (cchReaderLen == SCARD_AUTOALLOCATE)
1232 return SCARD_F_UNKNOWN_ERROR;
1234 if (status == SCARD_S_SUCCESS)
1236 if (!call->fmszReaderNamesIsNULL)
1237 ret.mszReaderNames = (BYTE*)mszReaderNames;
1239 ret.cBytes = cchReaderLen;
1242 ret.cbAtrLen = cbAtrLen;
1245 status = smartcard_pack_status_return(out, &ret, FALSE);
1248 wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaderNames);
1250 if (status != SCARD_S_SUCCESS)
1252 return ret.ReturnCode;
1255 static LONG smartcard_StatusW_Call(scard_call_context* smartcard,
wStream* out,
1260 LPWSTR mszReaderNames = NULL;
1264 WINPR_ASSERT(smartcard);
1266 WINPR_ASSERT(operation);
1268 call = &operation->call.status;
1274 cbAtrLen = call->cbAtrLen = 32;
1276 if (call->fmszReaderNamesIsNULL)
1279 ret.cBytes = SCARD_AUTOALLOCATE;
1281 status = ret.ReturnCode =
1282 wrap(smartcard, SCardStatusW, operation->hCard,
1283 call->fmszReaderNamesIsNULL ? NULL : (LPWSTR)&mszReaderNames, &ret.cBytes,
1284 &ret.dwState, &ret.dwProtocol, (BYTE*)&ret.pbAtr, &cbAtrLen);
1285 scard_log_status_error(TAG,
"SCardStatusW", status);
1286 if (ret.cBytes == SCARD_AUTOALLOCATE)
1287 return SCARD_F_UNKNOWN_ERROR;
1289 if (status == SCARD_S_SUCCESS)
1291 if (!call->fmszReaderNamesIsNULL)
1292 ret.mszReaderNames = (BYTE*)mszReaderNames;
1294 ret.cbAtrLen = cbAtrLen;
1298 WINPR_ASSERT(ret.cBytes < SCARD_AUTOALLOCATE /
sizeof(WCHAR));
1299 const size_t blen =
sizeof(WCHAR) * ret.cBytes;
1300 WINPR_ASSERT(blen <= UINT32_MAX);
1301 ret.cBytes = (UINT32)blen;
1303 status = smartcard_pack_status_return(out, &ret, TRUE);
1304 if (status != SCARD_S_SUCCESS)
1308 wrap(smartcard, SCardFreeMemory, operation->hContext, mszReaderNames);
1310 return ret.ReturnCode;
1313 static LONG smartcard_Transmit_Call(scard_call_context* smartcard,
wStream* out,
1320 WINPR_ASSERT(smartcard);
1322 WINPR_ASSERT(operation);
1324 call = &operation->call.transmit;
1325 ret.cbRecvLength = 0;
1326 ret.pbRecvBuffer = NULL;
1328 if (call->cbRecvLength && !call->fpbRecvBufferIsNULL)
1330 if (call->cbRecvLength >= 66560)
1331 call->cbRecvLength = 66560;
1333 ret.cbRecvLength = call->cbRecvLength;
1334 ret.pbRecvBuffer = (BYTE*)malloc(ret.cbRecvLength);
1336 if (!ret.pbRecvBuffer)
1337 return STATUS_NO_MEMORY;
1340 ret.pioRecvPci = call->pioRecvPci;
1342 wrap(smartcard, SCardTransmit, operation->hCard, call->pioSendPci, call->pbSendBuffer,
1343 call->cbSendLength, ret.pioRecvPci, ret.pbRecvBuffer, &(ret.cbRecvLength));
1345 scard_log_status_error(TAG,
"SCardTransmit", ret.ReturnCode);
1347 status = smartcard_pack_transmit_return(out, &ret);
1348 free(ret.pbRecvBuffer);
1350 if (status != SCARD_S_SUCCESS)
1352 return ret.ReturnCode;
1355 static LONG smartcard_Control_Call(scard_call_context* smartcard,
wStream* out,
1362 WINPR_ASSERT(smartcard);
1364 WINPR_ASSERT(operation);
1366 call = &operation->call.control;
1367 ret.cbOutBufferSize = call->cbOutBufferSize;
1368 ret.pvOutBuffer = (BYTE*)malloc(call->cbOutBufferSize);
1370 if (!ret.pvOutBuffer)
1371 return SCARD_E_NO_MEMORY;
1374 wrap(smartcard, SCardControl, operation->hCard, call->dwControlCode, call->pvInBuffer,
1375 call->cbInBufferSize, ret.pvOutBuffer, call->cbOutBufferSize, &ret.cbOutBufferSize);
1376 scard_log_status_error(TAG,
"SCardControl", ret.ReturnCode);
1377 status = smartcard_pack_control_return(out, &ret);
1379 free(ret.pvOutBuffer);
1380 if (status != SCARD_S_SUCCESS)
1382 return ret.ReturnCode;
1385 static LONG smartcard_GetAttrib_Call(scard_call_context* smartcard,
wStream* out,
1388 BOOL autoAllocate = FALSE;
1390 DWORD cbAttrLen = 0;
1391 LPBYTE pbAttr = NULL;
1395 WINPR_ASSERT(smartcard);
1396 WINPR_ASSERT(operation);
1398 call = &operation->call.getAttrib;
1400 if (!call->fpbAttrIsNULL)
1402 autoAllocate = (call->cbAttrLen == SCARD_AUTOALLOCATE) ? TRUE : FALSE;
1403 cbAttrLen = call->cbAttrLen;
1404 if (cbAttrLen && !autoAllocate)
1406 ret.pbAttr = (BYTE*)malloc(cbAttrLen);
1409 return SCARD_E_NO_MEMORY;
1412 pbAttr = autoAllocate ? (LPBYTE) & (ret.pbAttr) : ret.pbAttr;
1416 wrap(smartcard, SCardGetAttrib, operation->hCard, call->dwAttrId, pbAttr, &cbAttrLen);
1417 scard_log_status_error(TAG,
"SCardGetAttrib", ret.ReturnCode);
1418 if (cbAttrLen == SCARD_AUTOALLOCATE)
1419 return SCARD_F_UNKNOWN_ERROR;
1421 ret.cbAttrLen = cbAttrLen;
1423 status = smartcard_pack_get_attrib_return(out, &ret, call->dwAttrId, call->cbAttrLen);
1426 wrap(smartcard, SCardFreeMemory, operation->hContext, ret.pbAttr);
1432 static LONG smartcard_SetAttrib_Call(scard_call_context* smartcard,
wStream* out,
1438 WINPR_ASSERT(smartcard);
1440 WINPR_ASSERT(operation);
1442 call = &operation->call.setAttrib;
1444 ret.ReturnCode = wrap(smartcard, SCardSetAttrib, operation->hCard, call->dwAttrId, call->pbAttr,
1446 scard_log_status_error(TAG,
"SCardSetAttrib", ret.ReturnCode);
1447 smartcard_trace_long_return(&ret,
"SetAttrib");
1449 return ret.ReturnCode;
1452 static LONG smartcard_AccessStartedEvent_Call(scard_call_context* smartcard,
wStream* out,
1455 LONG status = SCARD_S_SUCCESS;
1457 WINPR_ASSERT(smartcard);
1459 WINPR_UNUSED(operation);
1461 if (!smartcard->StartedEvent)
1462 smartcard->StartedEvent = wrap_ptr(smartcard, SCardAccessStartedEvent);
1464 if (!smartcard->StartedEvent)
1465 status = SCARD_E_NO_SERVICE;
1470 static LONG smartcard_LocateCardsByATRA_Call(scard_call_context* smartcard,
wStream* out,
1479 WINPR_ASSERT(smartcard);
1480 WINPR_ASSERT(operation);
1482 call = &operation->call.locateCardsByATRA;
1486 return STATUS_NO_MEMORY;
1488 for (UINT32 i = 0; i < call->cReaders; i++)
1490 states[i].szReader = call->rgReaderStates[i].szReader;
1491 states[i].dwCurrentState = call->rgReaderStates[i].dwCurrentState;
1492 states[i].dwEventState = call->rgReaderStates[i].dwEventState;
1493 states[i].cbAtr = call->rgReaderStates[i].cbAtr;
1494 CopyMemory(&(states[i].rgbAtr), &(call->rgReaderStates[i].rgbAtr), 36);
1497 status = ret.ReturnCode = wrap(smartcard, SCardGetStatusChangeA, operation->hContext,
1498 0x000001F4, states, call->cReaders);
1500 scard_log_status_error(TAG,
"SCardGetStatusChangeA", status);
1501 for (UINT32 i = 0; i < call->cAtrs; i++)
1503 for (UINT32 j = 0; j < call->cReaders; j++)
1505 for (UINT32 k = 0; k < call->rgAtrMasks[i].cbAtr; k++)
1507 if ((call->rgAtrMasks[i].rgbAtr[k] & call->rgAtrMasks[i].rgbMask[k]) !=
1508 (states[j].rgbAtr[k] & call->rgAtrMasks[i].rgbMask[k]))
1513 states[j].dwEventState |= SCARD_STATE_ATRMATCH;
1518 ret.cReaders = call->cReaders;
1519 ret.rgReaderStates = NULL;
1521 if (ret.cReaders > 0)
1524 if (!ret.rgReaderStates)
1527 return STATUS_NO_MEMORY;
1530 for (UINT32 i = 0; i < ret.cReaders; i++)
1533 ret.rgReaderStates[i].dwCurrentState = state->dwCurrentState;
1534 ret.rgReaderStates[i].dwEventState = state->dwEventState;
1535 ret.rgReaderStates[i].cbAtr = state->cbAtr;
1536 CopyMemory(&(ret.rgReaderStates[i].rgbAtr), &(state->rgbAtr),
1537 sizeof(ret.rgReaderStates[i].rgbAtr));
1542 status = smartcard_pack_get_status_change_return(out, &ret, FALSE);
1544 free(ret.rgReaderStates);
1545 if (status != SCARD_S_SUCCESS)
1547 return ret.ReturnCode;
1550 LONG smartcard_irp_device_control_call(scard_call_context* smartcard,
wStream* out,
1555 UINT32 ioControlCode = 0;
1556 size_t outputBufferLength = 0;
1557 size_t objectBufferLength = 0;
1559 WINPR_ASSERT(smartcard);
1561 WINPR_ASSERT(pIoStatus);
1562 WINPR_ASSERT(operation);
1564 ioControlCode = operation->ioControlCode;
1572 if (!Stream_EnsureRemainingCapacity(out, 2048))
1573 return SCARD_E_NO_MEMORY;
1576 Stream_Write_UINT32(out, 0);
1577 Stream_Zero(out, SMARTCARD_COMMON_TYPE_HEADER_LENGTH);
1578 Stream_Zero(out, SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH);
1579 Stream_Write_UINT32(out, 0);
1582 switch (ioControlCode)
1584 case SCARD_IOCTL_ESTABLISHCONTEXT:
1585 result = smartcard_EstablishContext_Call(smartcard, out, operation);
1588 case SCARD_IOCTL_RELEASECONTEXT:
1589 result = smartcard_ReleaseContext_Call(smartcard, out, operation);
1592 case SCARD_IOCTL_ISVALIDCONTEXT:
1593 result = smartcard_IsValidContext_Call(smartcard, out, operation);
1596 case SCARD_IOCTL_LISTREADERGROUPSA:
1597 result = smartcard_ListReaderGroupsA_Call(smartcard, out, operation);
1600 case SCARD_IOCTL_LISTREADERGROUPSW:
1601 result = smartcard_ListReaderGroupsW_Call(smartcard, out, operation);
1604 case SCARD_IOCTL_LISTREADERSA:
1605 result = smartcard_ListReadersA_Call(smartcard, out, operation);
1608 case SCARD_IOCTL_LISTREADERSW:
1609 result = smartcard_ListReadersW_Call(smartcard, out, operation);
1612 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
1613 result = smartcard_IntroduceReaderGroupA_Call(smartcard, out, operation);
1616 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
1617 result = smartcard_IntroduceReaderGroupW_Call(smartcard, out, operation);
1620 case SCARD_IOCTL_FORGETREADERGROUPA:
1621 result = smartcard_ForgetReaderA_Call(smartcard, out, operation);
1624 case SCARD_IOCTL_FORGETREADERGROUPW:
1625 result = smartcard_ForgetReaderW_Call(smartcard, out, operation);
1628 case SCARD_IOCTL_INTRODUCEREADERA:
1629 result = smartcard_IntroduceReaderA_Call(smartcard, out, operation);
1632 case SCARD_IOCTL_INTRODUCEREADERW:
1633 result = smartcard_IntroduceReaderW_Call(smartcard, out, operation);
1636 case SCARD_IOCTL_FORGETREADERA:
1637 result = smartcard_ForgetReaderA_Call(smartcard, out, operation);
1640 case SCARD_IOCTL_FORGETREADERW:
1641 result = smartcard_ForgetReaderW_Call(smartcard, out, operation);
1644 case SCARD_IOCTL_ADDREADERTOGROUPA:
1645 result = smartcard_AddReaderToGroupA_Call(smartcard, out, operation);
1648 case SCARD_IOCTL_ADDREADERTOGROUPW:
1649 result = smartcard_AddReaderToGroupW_Call(smartcard, out, operation);
1652 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
1653 result = smartcard_RemoveReaderFromGroupA_Call(smartcard, out, operation);
1656 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
1657 result = smartcard_RemoveReaderFromGroupW_Call(smartcard, out, operation);
1660 case SCARD_IOCTL_LOCATECARDSA:
1661 result = smartcard_LocateCardsA_Call(smartcard, out, operation);
1664 case SCARD_IOCTL_LOCATECARDSW:
1665 result = smartcard_LocateCardsW_Call(smartcard, out, operation);
1668 case SCARD_IOCTL_GETSTATUSCHANGEA:
1669 result = smartcard_GetStatusChangeA_Call(smartcard, out, operation);
1672 case SCARD_IOCTL_GETSTATUSCHANGEW:
1673 result = smartcard_GetStatusChangeW_Call(smartcard, out, operation);
1676 case SCARD_IOCTL_CANCEL:
1677 result = smartcard_Cancel_Call(smartcard, out, operation);
1680 case SCARD_IOCTL_CONNECTA:
1681 result = smartcard_ConnectA_Call(smartcard, out, operation);
1684 case SCARD_IOCTL_CONNECTW:
1685 result = smartcard_ConnectW_Call(smartcard, out, operation);
1688 case SCARD_IOCTL_RECONNECT:
1689 result = smartcard_Reconnect_Call(smartcard, out, operation);
1692 case SCARD_IOCTL_DISCONNECT:
1693 result = smartcard_Disconnect_Call(smartcard, out, operation);
1696 case SCARD_IOCTL_BEGINTRANSACTION:
1697 result = smartcard_BeginTransaction_Call(smartcard, out, operation);
1700 case SCARD_IOCTL_ENDTRANSACTION:
1701 result = smartcard_EndTransaction_Call(smartcard, out, operation);
1704 case SCARD_IOCTL_STATE:
1705 result = smartcard_State_Call(smartcard, out, operation);
1708 case SCARD_IOCTL_STATUSA:
1709 result = smartcard_StatusA_Call(smartcard, out, operation);
1712 case SCARD_IOCTL_STATUSW:
1713 result = smartcard_StatusW_Call(smartcard, out, operation);
1716 case SCARD_IOCTL_TRANSMIT:
1717 result = smartcard_Transmit_Call(smartcard, out, operation);
1720 case SCARD_IOCTL_CONTROL:
1721 result = smartcard_Control_Call(smartcard, out, operation);
1724 case SCARD_IOCTL_GETATTRIB:
1725 result = smartcard_GetAttrib_Call(smartcard, out, operation);
1728 case SCARD_IOCTL_SETATTRIB:
1729 result = smartcard_SetAttrib_Call(smartcard, out, operation);
1732 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
1733 result = smartcard_AccessStartedEvent_Call(smartcard, out, operation);
1736 case SCARD_IOCTL_LOCATECARDSBYATRA:
1737 result = smartcard_LocateCardsByATRA_Call(smartcard, out, operation);
1740 case SCARD_IOCTL_LOCATECARDSBYATRW:
1741 result = smartcard_LocateCardsW_Call(smartcard, out, operation);
1744 case SCARD_IOCTL_READCACHEA:
1745 result = smartcard_ReadCacheA_Call(smartcard, out, operation);
1748 case SCARD_IOCTL_READCACHEW:
1749 result = smartcard_ReadCacheW_Call(smartcard, out, operation);
1752 case SCARD_IOCTL_WRITECACHEA:
1753 result = smartcard_WriteCacheA_Call(smartcard, out, operation);
1756 case SCARD_IOCTL_WRITECACHEW:
1757 result = smartcard_WriteCacheW_Call(smartcard, out, operation);
1760 case SCARD_IOCTL_GETTRANSMITCOUNT:
1761 result = smartcard_GetTransmitCount_Call(smartcard, out, operation);
1764 case SCARD_IOCTL_RELEASETARTEDEVENT:
1765 result = smartcard_ReleaseStartedEvent_Call(smartcard, out, operation);
1768 case SCARD_IOCTL_GETREADERICON:
1769 result = smartcard_GetReaderIcon_Call(smartcard, out, operation);
1772 case SCARD_IOCTL_GETDEVICETYPEID:
1773 result = smartcard_GetDeviceTypeId_Call(smartcard, out, operation);
1777 result = STATUS_UNSUCCESSFUL;
1787 if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
1788 (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
1790 offset = (RDPDR_DEVICE_IO_RESPONSE_LENGTH + RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH);
1791 smartcard_pack_write_size_align(out, Stream_GetPosition(out) - offset, 8);
1794 if ((result != SCARD_S_SUCCESS) && (result != SCARD_E_TIMEOUT) &&
1795 (result != SCARD_E_NO_READERS_AVAILABLE) && (result != SCARD_E_NO_SERVICE) &&
1796 (result != SCARD_W_CACHE_ITEM_NOT_FOUND) && (result != SCARD_W_CACHE_ITEM_STALE))
1798 WLog_WARN(TAG,
"IRP failure: %s (0x%08" PRIX32
"), status: %s (0x%08" PRIX32
")",
1799 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode,
1800 SCardGetErrorString(result), result);
1803 *pIoStatus = STATUS_SUCCESS;
1805 if ((result & 0xC0000000L) == 0xC0000000L)
1808 *pIoStatus = (UINT32)result;
1809 WLog_WARN(TAG,
"IRP failure: %s (0x%08" PRIX32
"), ntstatus: 0x%08" PRIX32
"",
1810 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, result);
1813 Stream_SealLength(out);
1814 outputBufferLength = Stream_Length(out);
1815 WINPR_ASSERT(outputBufferLength >= RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4U);
1816 outputBufferLength -= (RDPDR_DEVICE_IO_RESPONSE_LENGTH + 4U);
1817 WINPR_ASSERT(outputBufferLength >= RDPDR_DEVICE_IO_RESPONSE_LENGTH);
1818 objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH;
1819 WINPR_ASSERT(outputBufferLength <= UINT32_MAX);
1820 WINPR_ASSERT(objectBufferLength <= UINT32_MAX);
1821 Stream_SetPosition(out, RDPDR_DEVICE_IO_RESPONSE_LENGTH);
1823 Stream_Write_UINT32(out, (UINT32)outputBufferLength);
1824 smartcard_pack_common_type_header(out);
1825 smartcard_pack_private_type_header(
1826 out, (UINT32)objectBufferLength);
1827 Stream_Write_INT32(out, result);
1828 Stream_SetPosition(out, Stream_Length(out));
1829 return SCARD_S_SUCCESS;
1832 void context_free(
void* arg)
1834 struct s_scard_context_element* element = arg;
1838 if (element->fn_free)
1839 element->fn_free(element->context);
1843 scard_call_context* smartcard_call_context_new(
const rdpSettings* settings)
1846 scard_call_context* ctx = NULL;
1848 WINPR_ASSERT(settings);
1849 ctx = calloc(1,
sizeof(scard_call_context));
1853 ctx->stopEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
1854 if (!ctx->stopEvent)
1857 ctx->names = LinkedList_New();
1861 #if defined(WITH_SMARTCARD_EMULATE)
1865 if (ctx->useEmulatedCard)
1867 #if defined(WITH_SMARTCARD_EMULATE)
1868 ctx->emulation = Emulate_New(settings);
1869 if (!ctx->emulation)
1872 WLog_ERR(TAG,
"Smartcard emulation requested, but not supported!");
1881 ctx->hWinSCardLibrary = LoadLibraryX(WinSCardModule);
1883 if (!ctx->hWinSCardLibrary)
1885 WLog_ERR(TAG,
"Failed to load WinSCard library: '%s'", WinSCardModule);
1889 if (!WinSCard_LoadApiTableFunctions(&ctx->WinSCardApi, ctx->hWinSCardLibrary))
1891 ctx->pWinSCardApi = &ctx->WinSCardApi;
1895 ctx->pWinSCardApi = WinPR_GetSCardApiFunctionTable();
1898 if (!ctx->pWinSCardApi)
1900 WLog_ERR(TAG,
"Failed to load WinSCard API!");
1905 ctx->rgSCardContextList = HashTable_New(FALSE);
1906 if (!ctx->rgSCardContextList)
1909 obj = HashTable_ValueObject(ctx->rgSCardContextList);
1911 obj->fnObjectFree = context_free;
1915 WINPR_PRAGMA_DIAG_PUSH
1916 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1917 smartcard_call_context_free(ctx);
1918 WINPR_PRAGMA_DIAG_POP
1922 void smartcard_call_context_free(scard_call_context* ctx)
1927 smartcard_call_context_signal_stop(ctx, FALSE);
1929 LinkedList_Free(ctx->names);
1930 if (ctx->StartedEvent)
1932 WINPR_ASSERT(ctx->useEmulatedCard || ctx->pWinSCardApi);
1933 wrap(ctx, SCardReleaseStartedEvent);
1936 if (ctx->useEmulatedCard)
1938 #ifdef WITH_SMARTCARD_EMULATE
1941 Emulate_Free(ctx->emulation);
1942 ctx->emulation = NULL;
1947 if (ctx->hWinSCardLibrary)
1950 FreeLibrary(ctx->hWinSCardLibrary);
1951 ctx->hWinSCardLibrary = NULL;
1954 ctx->pWinSCardApi = NULL;
1956 HashTable_Free(ctx->rgSCardContextList);
1957 (void)CloseHandle(ctx->stopEvent);
1961 BOOL smartcard_call_context_add(scard_call_context* ctx,
const char* name)
1965 return LinkedList_AddLast(ctx->names, name);
1968 BOOL smartcard_call_cancel_context(scard_call_context* ctx, SCARDCONTEXT hContext)
1971 if (wrap(ctx, SCardIsValidContext, hContext) == SCARD_S_SUCCESS)
1973 wrap(ctx, SCardCancel, hContext);
1978 BOOL smartcard_call_release_context(scard_call_context* ctx, SCARDCONTEXT hContext)
1981 wrap(ctx, SCardReleaseContext, hContext);
1985 BOOL smartcard_call_cancel_all_context(scard_call_context* ctx)
1989 HashTable_Clear(ctx->rgSCardContextList);
1993 BOOL smarcard_call_set_callbacks(scard_call_context* ctx,
void* userdata,
1994 void* (*fn_new)(
void*, SCARDCONTEXT),
void (*fn_free)(
void*))
1997 ctx->userdata = userdata;
1998 ctx->fn_new = fn_new;
1999 ctx->fn_free = fn_free;
2003 void* smartcard_call_get_context(scard_call_context* ctx, SCARDCONTEXT hContext)
2005 struct s_scard_context_element* element = NULL;
2008 element = HashTable_GetItemValue(ctx->rgSCardContextList, (
void*)hContext);
2011 return element->context;
2014 BOOL smartcard_call_is_configured(scard_call_context* ctx)
2018 #if defined(WITH_SMARTCARD_EMULATE)
2019 if (ctx->useEmulatedCard)
2020 return Emulate_IsConfigured(ctx->emulation);
2026 BOOL smartcard_call_context_signal_stop(scard_call_context* ctx, BOOL reset)
2029 if (!ctx->stopEvent)
2033 return ResetEvent(ctx->stopEvent);
2035 return SetEvent(ctx->stopEvent);
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
This struct contains function pointer to initialize/free objects.