21#include <freerdp/config.h>
22#include <freerdp/freerdp.h>
25#include <winpr/wlog.h>
26#include <winpr/file.h>
27#include <winpr/path.h>
28#include <winpr/library.h>
29#include <winpr/smartcard.h>
30#include <winpr/collections.h>
31#include <winpr/crypto.h>
33#include <freerdp/emulate/scard/smartcard_emulate.h>
34#include "FreeRDP.ico.h"
36#include "smartcard_virtual_gids.h"
38#define MAX_CACHE_ITEM_SIZE 4096
39#define MAX_CACHE_ITEM_VALUES 4096
41static CHAR g_ReaderNameA[] = {
'F',
'r',
'e',
'e',
'R',
'D',
'P',
' ',
'E',
42 'm',
'u',
'l',
'a',
't',
'o',
'r',
'\0',
'\0' };
43static INIT_ONCE g_ReaderNameWGuard = INIT_ONCE_STATIC_INIT;
44static WCHAR g_ReaderNameW[32] = WINPR_C_ARRAY_INIT;
45static size_t g_ReaderNameWLen = 0;
47static char* card_id_and_name_a(
const UUID* CardIdentifier, LPCSTR LookupName)
49 WINPR_ASSERT(CardIdentifier);
50 WINPR_ASSERT(LookupName);
52 size_t len = strlen(LookupName) + 34;
53 char*
id = malloc(len);
57 (void)snprintf(
id, len,
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X\\%s",
58 CardIdentifier->Data1, CardIdentifier->Data2, CardIdentifier->Data3,
59 CardIdentifier->Data4[0], CardIdentifier->Data4[1], CardIdentifier->Data4[2],
60 CardIdentifier->Data4[3], CardIdentifier->Data4[4], CardIdentifier->Data4[5],
61 CardIdentifier->Data4[6], CardIdentifier->Data4[7], LookupName);
65static char* card_id_and_name_w(
const UUID* CardIdentifier, LPCWSTR LookupName)
68 char* tmp = ConvertWCharToUtf8Alloc(LookupName,
nullptr);
71 res = card_id_and_name_a(CardIdentifier, tmp);
76static BOOL CALLBACK g_ReaderNameWInit(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
78 WINPR_UNUSED(InitOnce);
79 WINPR_UNUSED(Parameter);
80 WINPR_UNUSED(Context);
81 InitializeConstWCharFromUtf8(g_ReaderNameA, g_ReaderNameW, ARRAYSIZE(g_ReaderNameW));
82 g_ReaderNameWLen = _wcsnlen(g_ReaderNameW, ARRAYSIZE(g_ReaderNameW) - 2) + 2;
86struct smartcard_emulation_context
88 const rdpSettings* settings;
89 DWORD log_default_level;
99#define MAX_EMULATED_READERS 1
123 DWORD dwActiveProtocol;
124 SCARDCONTEXT hContext;
127 size_t referencecount;
134 char data[MAX_CACHE_ITEM_SIZE];
137static SCardHandle* find_reader(SmartcardEmulationContext* smartcard,
const void* szReader,
140static const BYTE ATR[] = { 0x3b, 0xf7, 0x18, 0x00, 0x00, 0x80, 0x31, 0xfe, 0x45,
141 0x73, 0x66, 0x74, 0x65, 0x2d, 0x6e, 0x66, 0xc4 };
143static BOOL scard_status_transition(SCardContext* context)
145 WINPR_ASSERT(context);
147 switch (context->readerState)
153 reader->szReader = g_ReaderNameA;
154 reader->dwEventState = SCARD_STATE_PRESENT;
155 reader->cbAtr =
sizeof(ATR);
156 memcpy(reader->rgbAtr, ATR,
sizeof(ATR));
159 if (!InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit,
nullptr,
nullptr))
162 reader->szReader = g_ReaderNameW;
163 reader->dwEventState = SCARD_STATE_PRESENT;
164 reader->cbAtr =
sizeof(ATR);
165 memcpy(reader->rgbAtr, ATR,
sizeof(ATR));
167 context->readerState = 42;
174static UINT32 scard_copy_strings(SCardContext* ctx,
void* dst,
size_t dstSize,
const void* src,
180 WINPR_ASSERT(srcSize <= UINT32_MAX);
181 WINPR_ASSERT(dstSize <= UINT32_MAX);
183 if (dstSize == SCARD_AUTOALLOCATE)
185 void* tmp = malloc(srcSize);
186 memcpy(tmp, src, srcSize);
187 ArrayList_Append(ctx->strings, tmp);
188 *((
void**)dst) = tmp;
189 return (UINT32)srcSize;
193 const size_t min = MIN(dstSize, srcSize);
194 memcpy(dst, src, min);
199static void scard_context_free(
void* context)
201 SCardContext* ctx = context;
204 HashTable_Free(ctx->cards);
205 ArrayList_Free(ctx->strings);
206 HashTable_Free(ctx->cache);
211static SCardContext* scard_context_new(
void)
213 SCardContext* ctx = calloc(1,
sizeof(SCardContext));
217 ctx->strings = ArrayList_New(FALSE);
222 wObject* obj = ArrayList_Object(ctx->strings);
227 ctx->cache = HashTable_New(FALSE);
230 if (!HashTable_SetupForStringData(ctx->cache, FALSE))
234 wObject* val = HashTable_ValueObject(ctx->cache);
239 scard_status_transition(ctx);
242 scard_context_free(ctx);
246static void scard_handle_free(
void* handle)
248 SCardHandle* hdl = handle;
251 free(hdl->szReader.pv);
252 vgids_free(hdl->vgids);
257WINPR_ATTR_MALLOC(scard_handle_free, 1)
258static SCardHandle* scard_handle_new(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
259 const
void* name, BOOL unicode)
261 SCardHandle* hdl =
nullptr;
263 WINPR_ASSERT(smartcard);
265 hdl = calloc(1,
sizeof(SCardHandle));
274 size_t s = _wcslen(name);
276 hdl->szReader.pw = calloc(s + 2,
sizeof(WCHAR));
277 if (!hdl->szReader.pw)
279 memcpy(hdl->szReader.pv, name, s *
sizeof(WCHAR));
283 size_t s = strlen(name);
285 hdl->szReader.pc = calloc(s + 2,
sizeof(CHAR));
286 if (!hdl->szReader.pc)
288 memcpy(hdl->szReader.pv, name, s *
sizeof(CHAR));
291 if (!hdl->szReader.pv)
294 hdl->vgids = vgids_new();
306 if (!vgids_init(hdl->vgids, pem, key, pin))
310 hdl->unicode = unicode;
311 hdl->hContext = context;
315 scard_handle_free(hdl);
319static LONG scard_handle_valid(SmartcardEmulationContext* smartcard, SCARDHANDLE handle)
321 SCardHandle* ctx =
nullptr;
323 WINPR_ASSERT(smartcard);
325 ctx = HashTable_GetItemValue(smartcard->handles, (
const void*)handle);
327 return SCARD_E_INVALID_HANDLE;
329 return SCARD_S_SUCCESS;
332static LONG scard_reader_name_valid_a(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
335 SCardContext* ctx =
nullptr;
337 WINPR_ASSERT(smartcard);
338 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)context);
343 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
346 if (strcmp(reader->szReader, name) == 0)
347 return SCARD_S_SUCCESS;
350 return SCARD_E_UNKNOWN_READER;
353static LONG scard_reader_name_valid_w(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
356 SCardContext* ctx =
nullptr;
358 WINPR_ASSERT(smartcard);
359 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)context);
364 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
367 if (_wcscmp(reader->szReader, name) == 0)
368 return SCARD_S_SUCCESS;
371 return SCARD_E_UNKNOWN_READER;
378LONG WINAPI Emulate_SCardEstablishContext(SmartcardEmulationContext* smartcard, DWORD dwScope,
379 LPCVOID pvReserved1, LPCVOID pvReserved2,
380 LPSCARDCONTEXT phContext)
382 LONG status = SCARD_E_NO_MEMORY;
383 SCardContext* ctx =
nullptr;
385 WINPR_ASSERT(smartcard);
387 ctx = scard_context_new();
389 WINPR_UNUSED(pvReserved1);
390 WINPR_UNUSED(pvReserved2);
392 WLog_Print(smartcard->log, smartcard->log_default_level,
393 "SCardEstablishContext { dwScope: %s (0x%08" PRIX32
")",
394 SCardGetScopeString(dwScope), dwScope);
398 SCARDCONTEXT context = WINPR_C_ARRAY_INIT;
400 if (winpr_RAND(&context,
sizeof(SCARDCONTEXT)) >= 0)
402 if (HashTable_Insert(smartcard->contexts, (
const void*)context, ctx))
404 *phContext = context;
405 status = SCARD_S_SUCCESS;
410 WLog_Print(smartcard->log, smartcard->log_default_level,
411 "SCardEstablishContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
412 WINPR_CXX_COMPAT_CAST(UINT32, status));
414 if (status != SCARD_S_SUCCESS)
415 scard_context_free(ctx);
420LONG WINAPI Emulate_SCardReleaseContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
423 SCardContext* value =
nullptr;
425 WINPR_ASSERT(smartcard);
427 value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
429 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseContext { hContext: %p",
433 HashTable_Remove(smartcard->contexts, (
const void*)hContext);
435 status = SCARD_S_SUCCESS;
437 WLog_Print(smartcard->log, smartcard->log_default_level,
438 "SCardReleaseContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
439 WINPR_CXX_COMPAT_CAST(UINT32, status));
444LONG WINAPI Emulate_SCardIsValidContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
448 WINPR_ASSERT(smartcard);
450 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIsValidContext { hContext: %p",
453 status = HashTable_Contains(smartcard->contexts, (
const void*)hContext)
455 : SCARD_E_INVALID_HANDLE;
456 if (status == SCARD_S_SUCCESS)
458 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
461 return SCARD_F_INTERNAL_ERROR;
464 WLog_Print(smartcard->log, smartcard->log_default_level,
465 "SCardIsValidContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
466 WINPR_CXX_COMPAT_CAST(UINT32, status));
471LONG WINAPI Emulate_SCardListReaderGroupsA(
472 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
473 LPSTR mszGroups , LPDWORD pcchGroups)
475 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
477 WLog_Print(smartcard->log, smartcard->log_default_level,
478 "SCardListReaderGroupsA { hContext: %p", (
void*)hContext);
480 WINPR_UNUSED(mszGroups);
481 WINPR_UNUSED(pcchGroups);
484 if (status == SCARD_S_SUCCESS)
485 status = SCARD_E_UNSUPPORTED_FEATURE;
487 WLog_Print(smartcard->log, smartcard->log_default_level,
488 "SCardListReaderGroupsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
489 WINPR_CXX_COMPAT_CAST(UINT32, status));
494LONG WINAPI Emulate_SCardListReaderGroupsW(
495 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
496 LPWSTR mszGroups , LPDWORD pcchGroups)
498 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
500 WLog_Print(smartcard->log, smartcard->log_default_level,
501 "SCardListReaderGroupsW { hContext: %p", (
void*)hContext);
503 WINPR_UNUSED(mszGroups);
504 WINPR_UNUSED(pcchGroups);
507 if (status == SCARD_S_SUCCESS)
508 status = SCARD_E_UNSUPPORTED_FEATURE;
510 WLog_Print(smartcard->log, smartcard->log_default_level,
511 "SCardListReaderGroupsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
512 WINPR_CXX_COMPAT_CAST(UINT32, status));
517LONG WINAPI Emulate_SCardListReadersA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
518 LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
520 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
522 status = SCARD_E_INVALID_PARAMETER;
524 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListReadersA { hContext: %p",
527 WINPR_UNUSED(mszGroups);
529 if (SCARD_S_SUCCESS == status)
531 SCardContext* value =
532 (SCardContext*)HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
541 *pcchReaders = ARRAYSIZE(g_ReaderNameA);
544 *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameA,
545 sizeof(g_ReaderNameA));
549 WLog_Print(smartcard->log, smartcard->log_default_level,
550 "SCardListReadersA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
551 WINPR_CXX_COMPAT_CAST(UINT32, status));
556LONG WINAPI Emulate_SCardListReadersW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
557 LPCWSTR mszGroups, LPWSTR mszReaders, LPDWORD pcchReaders)
559 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
562 status = SCARD_E_INVALID_PARAMETER;
564 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListReadersW { hContext: %p",
567 WINPR_UNUSED(mszGroups);
569 if (!InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit,
nullptr,
nullptr))
571 if (SCARD_S_SUCCESS == status)
573 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
583 WINPR_ASSERT(g_ReaderNameWLen <= UINT32_MAX);
584 *pcchReaders = (UINT32)g_ReaderNameWLen;
588 *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameW,
589 g_ReaderNameWLen *
sizeof(WCHAR)) /
594 WLog_Print(smartcard->log, smartcard->log_default_level,
595 "SCardListReadersW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
596 WINPR_CXX_COMPAT_CAST(UINT32, status));
601LONG WINAPI Emulate_SCardListCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
602 LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
603 DWORD cguidInterfaceCount,
607 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
609 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListCardsA { hContext: %p",
613 WINPR_UNUSED(rgquidInterfaces);
614 WINPR_UNUSED(cguidInterfaceCount);
615 WINPR_UNUSED(mszCards);
616 WINPR_UNUSED(pcchCards);
619 if (status == SCARD_S_SUCCESS)
620 status = SCARD_E_UNSUPPORTED_FEATURE;
622 WLog_Print(smartcard->log, smartcard->log_default_level,
623 "SCardListCardsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
624 WINPR_CXX_COMPAT_CAST(UINT32, status));
629LONG WINAPI Emulate_SCardListCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
630 LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
631 DWORD cguidInterfaceCount,
635 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
637 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListCardsW { hContext: %p",
641 WINPR_UNUSED(rgquidInterfaces);
642 WINPR_UNUSED(cguidInterfaceCount);
643 WINPR_UNUSED(mszCards);
644 WINPR_UNUSED(pcchCards);
647 if (status == SCARD_S_SUCCESS)
648 status = SCARD_E_UNSUPPORTED_FEATURE;
650 WLog_Print(smartcard->log, smartcard->log_default_level,
651 "SCardListCardsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
652 WINPR_CXX_COMPAT_CAST(UINT32, status));
657LONG WINAPI Emulate_SCardListInterfacesA(
658 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szCard,
659 LPGUID pguidInterfaces, LPDWORD pcguidInterfaces )
661 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
663 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListInterfacesA { hContext: %p",
666 WINPR_UNUSED(szCard);
667 WINPR_UNUSED(pguidInterfaces);
668 WINPR_UNUSED(pcguidInterfaces);
671 if (status == SCARD_S_SUCCESS)
672 status = SCARD_E_UNSUPPORTED_FEATURE;
674 WLog_Print(smartcard->log, smartcard->log_default_level,
675 "SCardListInterfacesA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
676 WINPR_CXX_COMPAT_CAST(UINT32, status));
681LONG WINAPI Emulate_SCardListInterfacesW(
682 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szCard,
683 LPGUID pguidInterfaces, LPDWORD pcguidInterfaces )
685 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
687 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListInterfacesW { hContext: %p",
690 WINPR_UNUSED(szCard);
691 WINPR_UNUSED(pguidInterfaces);
692 WINPR_UNUSED(pcguidInterfaces);
695 if (status == SCARD_S_SUCCESS)
696 status = SCARD_E_UNSUPPORTED_FEATURE;
698 WLog_Print(smartcard->log, smartcard->log_default_level,
699 "SCardListInterfacesW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
700 WINPR_CXX_COMPAT_CAST(UINT32, status));
705LONG WINAPI Emulate_SCardGetProviderIdA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
706 LPCSTR szCard, LPGUID pguidProviderId)
708 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
710 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetProviderIdA { hContext: %p",
713 WINPR_UNUSED(szCard);
714 WINPR_UNUSED(pguidProviderId);
717 if (status == SCARD_S_SUCCESS)
718 status = SCARD_E_UNSUPPORTED_FEATURE;
720 WLog_Print(smartcard->log, smartcard->log_default_level,
721 "SCardGetProviderIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
722 WINPR_CXX_COMPAT_CAST(UINT32, status));
727LONG WINAPI Emulate_SCardGetProviderIdW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
728 LPCWSTR szCard, LPGUID pguidProviderId)
730 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
732 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetProviderIdW { hContext: %p",
735 WINPR_UNUSED(szCard);
736 WINPR_UNUSED(pguidProviderId);
739 if (status == SCARD_S_SUCCESS)
740 status = SCARD_E_UNSUPPORTED_FEATURE;
742 WLog_Print(smartcard->log, smartcard->log_default_level,
743 "SCardGetProviderIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
744 WINPR_CXX_COMPAT_CAST(UINT32, status));
749LONG WINAPI Emulate_SCardGetCardTypeProviderNameA(
750 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szCardName,
751 DWORD dwProviderId, CHAR* szProvider ,
752 LPDWORD pcchProvider )
754 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
756 WLog_Print(smartcard->log, smartcard->log_default_level,
757 "SCardGetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
759 WINPR_UNUSED(szCardName);
760 WINPR_UNUSED(dwProviderId);
761 WINPR_UNUSED(szProvider);
762 WINPR_UNUSED(pcchProvider);
765 if (status == SCARD_S_SUCCESS)
766 status = SCARD_E_UNSUPPORTED_FEATURE;
768 WLog_Print(smartcard->log, smartcard->log_default_level,
769 "SCardGetCardTypeProviderNameA } status: %s (0x%08" PRIX32
")",
770 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
775LONG WINAPI Emulate_SCardGetCardTypeProviderNameW(
776 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szCardName,
777 DWORD dwProviderId, WCHAR* szProvider ,
778 LPDWORD pcchProvider )
780 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
782 WLog_Print(smartcard->log, smartcard->log_default_level,
783 "SCardGetCardTypeProviderNameW { hContext: %p", (
void*)hContext);
785 WINPR_UNUSED(szCardName);
786 WINPR_UNUSED(dwProviderId);
787 WINPR_UNUSED(szProvider);
788 WINPR_UNUSED(pcchProvider);
791 if (status == SCARD_S_SUCCESS)
792 status = SCARD_E_UNSUPPORTED_FEATURE;
794 WLog_Print(smartcard->log, smartcard->log_default_level,
795 "SCardGetCardTypeProviderNameW } status: %s (0x%08" PRIX32
")",
796 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
801LONG WINAPI Emulate_SCardIntroduceReaderGroupA(SmartcardEmulationContext* smartcard,
802 SCARDCONTEXT hContext, LPCSTR szGroupName)
804 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
806 WLog_Print(smartcard->log, smartcard->log_default_level,
807 "SCardIntroduceReaderGroupA { hContext: %p", (
void*)hContext);
809 WINPR_UNUSED(szGroupName);
812 if (status == SCARD_S_SUCCESS)
813 status = SCARD_E_UNSUPPORTED_FEATURE;
815 WLog_Print(smartcard->log, smartcard->log_default_level,
816 "SCardIntroduceReaderGroupA } status: %s (0x%08" PRIX32
")",
817 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
822LONG WINAPI Emulate_SCardIntroduceReaderGroupW(SmartcardEmulationContext* smartcard,
823 SCARDCONTEXT hContext, LPCWSTR szGroupName)
825 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
827 WLog_Print(smartcard->log, smartcard->log_default_level,
828 "SCardIntroduceReaderGroupW { hContext: %p", (
void*)hContext);
830 WINPR_UNUSED(szGroupName);
833 if (status == SCARD_S_SUCCESS)
834 status = SCARD_E_UNSUPPORTED_FEATURE;
836 WLog_Print(smartcard->log, smartcard->log_default_level,
837 "SCardIntroduceReaderGroupW } status: %s (0x%08" PRIX32
")",
838 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
843LONG WINAPI Emulate_SCardForgetReaderGroupA(SmartcardEmulationContext* smartcard,
844 SCARDCONTEXT hContext, LPCSTR szGroupName)
846 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
848 WLog_Print(smartcard->log, smartcard->log_default_level,
849 "SCardForgetReaderGroupA { hContext: %p", (
void*)hContext);
851 WINPR_UNUSED(szGroupName);
854 if (status == SCARD_S_SUCCESS)
855 status = SCARD_E_UNSUPPORTED_FEATURE;
857 WLog_Print(smartcard->log, smartcard->log_default_level,
858 "SCardForgetReaderGroupA } status: %s (0x%08" PRIX32
")",
859 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
864LONG WINAPI Emulate_SCardForgetReaderGroupW(SmartcardEmulationContext* smartcard,
865 SCARDCONTEXT hContext, LPCWSTR szGroupName)
867 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
869 WLog_Print(smartcard->log, smartcard->log_default_level,
870 "SCardForgetReaderGroupW { hContext: %p", (
void*)hContext);
872 WINPR_UNUSED(szGroupName);
875 if (status == SCARD_S_SUCCESS)
876 status = SCARD_E_UNSUPPORTED_FEATURE;
878 WLog_Print(smartcard->log, smartcard->log_default_level,
879 "SCardForgetReaderGroupW } status: %s (0x%08" PRIX32
")",
880 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
885LONG WINAPI Emulate_SCardIntroduceReaderA(SmartcardEmulationContext* smartcard,
886 SCARDCONTEXT hContext, LPCSTR szReaderName,
889 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
891 if (status == SCARD_S_SUCCESS)
892 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
894 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIntroduceReaderA { hContext: %p",
897 WINPR_UNUSED(szDeviceName);
900 if (status == SCARD_S_SUCCESS)
901 status = SCARD_E_UNSUPPORTED_FEATURE;
903 WLog_Print(smartcard->log, smartcard->log_default_level,
904 "SCardIntroduceReaderA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
905 WINPR_CXX_COMPAT_CAST(UINT32, status));
910LONG WINAPI Emulate_SCardIntroduceReaderW(SmartcardEmulationContext* smartcard,
911 SCARDCONTEXT hContext, LPCWSTR szReaderName,
912 LPCWSTR szDeviceName)
914 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
916 if (status == SCARD_S_SUCCESS)
917 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
919 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIntroduceReaderW { hContext: %p",
922 WINPR_UNUSED(szDeviceName);
925 if (status == SCARD_S_SUCCESS)
926 status = SCARD_E_UNSUPPORTED_FEATURE;
928 WLog_Print(smartcard->log, smartcard->log_default_level,
929 "SCardIntroduceReaderW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
930 WINPR_CXX_COMPAT_CAST(UINT32, status));
935LONG WINAPI Emulate_SCardForgetReaderA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
938 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
940 if (status == SCARD_S_SUCCESS)
941 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
943 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetReaderA { hContext: %p",
947 if (status == SCARD_S_SUCCESS)
948 status = SCARD_E_UNSUPPORTED_FEATURE;
950 WLog_Print(smartcard->log, smartcard->log_default_level,
951 "SCardForgetReaderA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
952 WINPR_CXX_COMPAT_CAST(UINT32, status));
957LONG WINAPI Emulate_SCardForgetReaderW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
958 LPCWSTR szReaderName)
960 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
962 if (status == SCARD_S_SUCCESS)
963 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
965 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetReaderW { hContext: %p",
969 if (status == SCARD_S_SUCCESS)
970 status = SCARD_E_UNSUPPORTED_FEATURE;
972 WLog_Print(smartcard->log, smartcard->log_default_level,
973 "SCardForgetReaderW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
974 WINPR_CXX_COMPAT_CAST(UINT32, status));
979LONG WINAPI Emulate_SCardAddReaderToGroupA(SmartcardEmulationContext* smartcard,
980 SCARDCONTEXT hContext, LPCSTR szReaderName,
983 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
985 if (status == SCARD_S_SUCCESS)
986 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
988 WLog_Print(smartcard->log, smartcard->log_default_level,
989 "SCardAddReaderToGroupA { hContext: %p", (
void*)hContext);
991 WINPR_UNUSED(szGroupName);
994 if (status == SCARD_S_SUCCESS)
995 status = SCARD_E_UNSUPPORTED_FEATURE;
997 WLog_Print(smartcard->log, smartcard->log_default_level,
998 "SCardAddReaderToGroupA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
999 WINPR_CXX_COMPAT_CAST(UINT32, status));
1004LONG WINAPI Emulate_SCardAddReaderToGroupW(SmartcardEmulationContext* smartcard,
1005 SCARDCONTEXT hContext, LPCWSTR szReaderName,
1006 LPCWSTR szGroupName)
1008 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1010 if (status == SCARD_S_SUCCESS)
1011 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1013 WLog_Print(smartcard->log, smartcard->log_default_level,
1014 "SCardAddReaderToGroupW { hContext: %p", (
void*)hContext);
1016 WINPR_UNUSED(szGroupName);
1019 if (status == SCARD_S_SUCCESS)
1020 status = SCARD_E_UNSUPPORTED_FEATURE;
1022 WLog_Print(smartcard->log, smartcard->log_default_level,
1023 "SCardAddReaderToGroupW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1024 WINPR_CXX_COMPAT_CAST(UINT32, status));
1029LONG WINAPI Emulate_SCardRemoveReaderFromGroupA(SmartcardEmulationContext* smartcard,
1030 SCARDCONTEXT hContext, LPCSTR szReaderName,
1033 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1035 if (status == SCARD_S_SUCCESS)
1036 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
1038 WLog_Print(smartcard->log, smartcard->log_default_level,
1039 "SCardRemoveReaderFromGroupA { hContext: %p", (
void*)hContext);
1041 WINPR_UNUSED(szGroupName);
1044 if (status == SCARD_S_SUCCESS)
1045 status = SCARD_E_UNSUPPORTED_FEATURE;
1047 WLog_Print(smartcard->log, smartcard->log_default_level,
1048 "SCardRemoveReaderFromGroupA } status: %s (0x%08" PRIX32
")",
1049 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1054LONG WINAPI Emulate_SCardRemoveReaderFromGroupW(SmartcardEmulationContext* smartcard,
1055 SCARDCONTEXT hContext, LPCWSTR szReaderName,
1056 LPCWSTR szGroupName)
1058 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1060 if (status == SCARD_S_SUCCESS)
1061 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1063 WLog_Print(smartcard->log, smartcard->log_default_level,
1064 "SCardRemoveReaderFromGroupW { hContext: %p", (
void*)hContext);
1066 WINPR_UNUSED(szGroupName);
1069 if (status == SCARD_S_SUCCESS)
1070 status = SCARD_E_UNSUPPORTED_FEATURE;
1072 WLog_Print(smartcard->log, smartcard->log_default_level,
1073 "SCardRemoveReaderFromGroupW } status: %s (0x%08" PRIX32
")",
1074 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1079LONG WINAPI Emulate_SCardIntroduceCardTypeA(SmartcardEmulationContext* smartcard,
1080 SCARDCONTEXT hContext, LPCSTR szCardName,
1081 LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1082 DWORD dwInterfaceCount, LPCBYTE pbAtr,
1083 LPCBYTE pbAtrMask, DWORD cbAtrLen)
1085 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1087 WLog_Print(smartcard->log, smartcard->log_default_level,
1088 "SCardIntroduceCardTypeA { hContext: %p", (
void*)hContext);
1090 WINPR_UNUSED(szCardName);
1091 WINPR_UNUSED(pguidPrimaryProvider);
1092 WINPR_UNUSED(rgguidInterfaces);
1093 WINPR_UNUSED(dwInterfaceCount);
1094 WINPR_UNUSED(pbAtr);
1095 WINPR_UNUSED(pbAtrMask);
1096 WINPR_UNUSED(cbAtrLen);
1099 if (status == SCARD_S_SUCCESS)
1100 status = SCARD_E_UNSUPPORTED_FEATURE;
1102 WLog_Print(smartcard->log, smartcard->log_default_level,
1103 "SCardIntroduceCardTypeA } status: %s (0x%08" PRIX32
")",
1104 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1109LONG WINAPI Emulate_SCardIntroduceCardTypeW(SmartcardEmulationContext* smartcard,
1110 SCARDCONTEXT hContext, LPCWSTR szCardName,
1111 LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1112 DWORD dwInterfaceCount, LPCBYTE pbAtr,
1113 LPCBYTE pbAtrMask, DWORD cbAtrLen)
1115 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1117 WLog_Print(smartcard->log, smartcard->log_default_level,
1118 "SCardIntroduceCardTypeW { hContext: %p", (
void*)hContext);
1120 WINPR_UNUSED(szCardName);
1121 WINPR_UNUSED(pguidPrimaryProvider);
1122 WINPR_UNUSED(rgguidInterfaces);
1123 WINPR_UNUSED(dwInterfaceCount);
1124 WINPR_UNUSED(pbAtr);
1125 WINPR_UNUSED(pbAtrMask);
1126 WINPR_UNUSED(cbAtrLen);
1129 if (status == SCARD_S_SUCCESS)
1130 status = SCARD_E_UNSUPPORTED_FEATURE;
1132 WLog_Print(smartcard->log, smartcard->log_default_level,
1133 "SCardIntroduceCardTypeW } status: %s (0x%08" PRIX32
")",
1134 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1139LONG WINAPI Emulate_SCardSetCardTypeProviderNameA(SmartcardEmulationContext* smartcard,
1140 SCARDCONTEXT hContext, LPCSTR szCardName,
1141 DWORD dwProviderId, LPCSTR szProvider)
1143 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1145 WLog_Print(smartcard->log, smartcard->log_default_level,
1146 "SCardSetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
1148 WINPR_UNUSED(szCardName);
1149 WINPR_UNUSED(dwProviderId);
1150 WINPR_UNUSED(szProvider);
1153 if (status == SCARD_S_SUCCESS)
1154 status = SCARD_E_UNSUPPORTED_FEATURE;
1156 WLog_Print(smartcard->log, smartcard->log_default_level,
1157 "SCardSetCardTypeProviderNameA } status: %s (0x%08" PRIX32
")",
1158 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1163LONG WINAPI Emulate_SCardSetCardTypeProviderNameW(SmartcardEmulationContext* smartcard,
1164 SCARDCONTEXT hContext, LPCWSTR szCardName,
1165 DWORD dwProviderId, LPCWSTR szProvider)
1167 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1169 WLog_Print(smartcard->log, smartcard->log_default_level,
1170 "SCardSetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
1172 WINPR_UNUSED(szCardName);
1173 WINPR_UNUSED(dwProviderId);
1174 WINPR_UNUSED(szProvider);
1177 if (status == SCARD_S_SUCCESS)
1178 status = SCARD_E_UNSUPPORTED_FEATURE;
1180 WLog_Print(smartcard->log, smartcard->log_default_level,
1181 "SCardSetCardTypeProviderNameW } status: %s (0x%08" PRIX32
")",
1182 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1187LONG WINAPI Emulate_SCardForgetCardTypeA(SmartcardEmulationContext* smartcard,
1188 SCARDCONTEXT hContext, LPCSTR szCardName)
1190 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1192 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetCardTypeA { hContext: %p",
1195 WINPR_UNUSED(szCardName);
1198 if (status == SCARD_S_SUCCESS)
1199 status = SCARD_E_UNSUPPORTED_FEATURE;
1201 WLog_Print(smartcard->log, smartcard->log_default_level,
1202 "SCardForgetCardTypeA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1203 WINPR_CXX_COMPAT_CAST(UINT32, status));
1208LONG WINAPI Emulate_SCardForgetCardTypeW(SmartcardEmulationContext* smartcard,
1209 SCARDCONTEXT hContext, LPCWSTR szCardName)
1211 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1213 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetCardTypeW { hContext: %p",
1216 WINPR_UNUSED(szCardName);
1219 if (status == SCARD_S_SUCCESS)
1220 status = SCARD_E_UNSUPPORTED_FEATURE;
1222 WLog_Print(smartcard->log, smartcard->log_default_level,
1223 "SCardForgetCardTypeW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1224 WINPR_CXX_COMPAT_CAST(UINT32, status));
1229LONG WINAPI Emulate_SCardFreeMemory(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1232 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1234 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardFreeMemory { hContext: %p",
1237 if (status == SCARD_S_SUCCESS)
1239 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1240 WINPR_ASSERT(value);
1242 ArrayList_Remove(value->strings, pvMem);
1245 WLog_Print(smartcard->log, smartcard->log_default_level,
1246 "SCardFreeMemory } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1247 WINPR_CXX_COMPAT_CAST(UINT32, status));
1252HANDLE WINAPI Emulate_SCardAccessStartedEvent(SmartcardEmulationContext* smartcard)
1254 HANDLE hEvent =
nullptr;
1256 WINPR_ASSERT(smartcard);
1258 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAccessStartedEvent {");
1261 if (winpr_RAND((
void*)&hEvent,
sizeof(hEvent)) < 0)
1263 (void)fprintf(stderr,
"winpr_RAND failed.\n");
1266 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAccessStartedEvent } hEvent: %p",
1272void WINAPI Emulate_SCardReleaseStartedEvent(SmartcardEmulationContext* smartcard)
1274 WINPR_ASSERT(smartcard);
1276 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseStartedEvent {");
1280 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseStartedEvent }");
1283LONG WINAPI Emulate_SCardLocateCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1287 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1289 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardLocateCardsA { hContext: %p",
1292 WINPR_UNUSED(mszCards);
1293 WINPR_UNUSED(rgReaderStates);
1294 WINPR_UNUSED(cReaders);
1297 if (status == SCARD_S_SUCCESS)
1298 status = SCARD_E_UNSUPPORTED_FEATURE;
1300 WLog_Print(smartcard->log, smartcard->log_default_level,
1301 "SCardLocateCardsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1302 WINPR_CXX_COMPAT_CAST(UINT32, status));
1307LONG WINAPI Emulate_SCardLocateCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1311 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1313 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardLocateCardsW { hContext: %p",
1316 WINPR_UNUSED(mszCards);
1317 WINPR_UNUSED(rgReaderStates);
1318 WINPR_UNUSED(cReaders);
1321 if (status == SCARD_S_SUCCESS)
1322 status = SCARD_E_UNSUPPORTED_FEATURE;
1324 WLog_Print(smartcard->log, smartcard->log_default_level,
1325 "SCardLocateCardsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1326 WINPR_CXX_COMPAT_CAST(UINT32, status));
1331LONG WINAPI Emulate_SCardLocateCardsByATRA(SmartcardEmulationContext* smartcard,
1336 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1338 WLog_Print(smartcard->log, smartcard->log_default_level,
1339 "SCardLocateCardsByATRA { hContext: %p", (
void*)hContext);
1341 WINPR_UNUSED(rgAtrMasks);
1342 WINPR_UNUSED(cAtrs);
1343 WINPR_UNUSED(rgReaderStates);
1344 WINPR_UNUSED(cReaders);
1347 if (status == SCARD_S_SUCCESS)
1348 status = SCARD_E_UNSUPPORTED_FEATURE;
1350 WLog_Print(smartcard->log, smartcard->log_default_level,
1351 "SCardLocateCardsByATRA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1352 WINPR_CXX_COMPAT_CAST(UINT32, status));
1357LONG WINAPI Emulate_SCardLocateCardsByATRW(SmartcardEmulationContext* smartcard,
1362 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1364 WLog_Print(smartcard->log, smartcard->log_default_level,
1365 "SCardLocateCardsByATRW { hContext: %p", (
void*)hContext);
1367 WINPR_UNUSED(rgAtrMasks);
1368 WINPR_UNUSED(cAtrs);
1369 WINPR_UNUSED(rgReaderStates);
1370 WINPR_UNUSED(cReaders);
1373 if (status == SCARD_S_SUCCESS)
1374 status = SCARD_E_UNSUPPORTED_FEATURE;
1376 WLog_Print(smartcard->log, smartcard->log_default_level,
1377 "SCardLocateCardsByATRW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1378 WINPR_CXX_COMPAT_CAST(UINT32, status));
1383LONG WINAPI Emulate_SCardGetStatusChangeA(SmartcardEmulationContext* smartcard,
1384 SCARDCONTEXT hContext, DWORD dwTimeout,
1387 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1389 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetStatusChangeA { hContext: %p",
1392 if (status == SCARD_S_SUCCESS)
1394 const DWORD diff = 100;
1395 size_t eventCount = 0;
1396 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1397 WINPR_ASSERT(value);
1402 status = SCARD_E_TIMEOUT;
1405 for (
size_t x = 0; x < cReaders; x++)
1409 for (
size_t y = 0; y < MAX_EMULATED_READERS; y++)
1412 if (strcmp(out->szReader, in->szReader) == 0)
1414 const SCardHandle* hdl = find_reader(smartcard, in->szReader, FALSE);
1415 out->dwEventState = in->dwEventState;
1418 out->dwEventState |= SCARD_STATE_INUSE;
1419 if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1420 out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1423 if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1424 (out->dwCurrentState & SCARD_STATE_EMPTY))
1425 out->dwEventState |= SCARD_STATE_CHANGED;
1426 if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1427 (out->dwCurrentState & SCARD_STATE_PRESENT))
1428 out->dwEventState |= SCARD_STATE_CHANGED;
1430 out->cbAtr = in->cbAtr;
1431 memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1432 if (out->dwEventState & SCARD_STATE_CHANGED)
1437 if (value->canceled)
1439 status = SCARD_E_CANCELLED;
1442 if (eventCount != 0)
1444 status = SCARD_S_SUCCESS;
1448 if (dwTimeout != INFINITE)
1449 dwTimeout -= MIN(dwTimeout, diff);
1450 if (freerdp_shall_disconnect_context(inst->context))
1452 status = SCARD_E_CANCELLED;
1455 }
while (dwTimeout > 0);
1458 WLog_Print(smartcard->log, smartcard->log_default_level,
1459 "SCardGetStatusChangeA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1460 WINPR_CXX_COMPAT_CAST(UINT32, status));
1465LONG WINAPI Emulate_SCardGetStatusChangeW(SmartcardEmulationContext* smartcard,
1466 SCARDCONTEXT hContext, DWORD dwTimeout,
1469 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1471 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetStatusChangeW { hContext: %p",
1474 if (status == SCARD_S_SUCCESS)
1476 const DWORD diff = 100;
1477 size_t eventCount = 0;
1478 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1479 WINPR_ASSERT(value);
1484 status = SCARD_E_TIMEOUT;
1487 for (
size_t x = 0; x < cReaders; x++)
1491 for (
size_t y = 0; y < MAX_EMULATED_READERS; y++)
1494 if (_wcscmp(out->szReader, in->szReader) == 0)
1496 const SCardHandle* hdl = find_reader(smartcard, in->szReader, TRUE);
1497 out->dwEventState = in->dwEventState;
1500 out->dwEventState |= SCARD_STATE_INUSE;
1501 if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1502 out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1504 if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1505 (out->dwCurrentState & SCARD_STATE_EMPTY))
1506 out->dwEventState |= SCARD_STATE_CHANGED;
1507 if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1508 (out->dwCurrentState & SCARD_STATE_PRESENT))
1509 out->dwEventState |= SCARD_STATE_CHANGED;
1510 out->cbAtr = in->cbAtr;
1511 memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1513 if (out->dwEventState & SCARD_STATE_CHANGED)
1518 if (value->canceled)
1520 status = SCARD_E_CANCELLED;
1523 if (eventCount != 0)
1525 status = SCARD_S_SUCCESS;
1529 if (dwTimeout != INFINITE)
1530 dwTimeout -= MIN(dwTimeout, diff);
1531 if (freerdp_shall_disconnect_context(inst->context))
1533 status = SCARD_E_CANCELLED;
1536 }
while (dwTimeout > 0);
1539 WLog_Print(smartcard->log, smartcard->log_default_level,
1540 "SCardGetStatusChangeW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1541 WINPR_CXX_COMPAT_CAST(UINT32, status));
1546LONG WINAPI Emulate_SCardCancel(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
1548 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1550 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancel { hContext: %p",
1553 if (status == SCARD_S_SUCCESS)
1555 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1556 WINPR_ASSERT(value);
1557 value->canceled = TRUE;
1560 WLog_Print(smartcard->log, smartcard->log_default_level,
1561 "SCardCancel } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1562 WINPR_CXX_COMPAT_CAST(UINT32, status));
1567SCardHandle* find_reader(SmartcardEmulationContext* smartcard,
const void* szReader, BOOL unicode)
1569 SCardHandle* hdl =
nullptr;
1570 UINT_PTR* keys =
nullptr;
1573 WINPR_ASSERT(smartcard);
1574 count = HashTable_GetKeys(smartcard->handles, &keys);
1575 for (
size_t x = 0; x < count; x++)
1577 SCardHandle* cur = HashTable_GetItemValue(smartcard->handles, (
const void*)keys[x]);
1580 if (cur->unicode != unicode)
1582 if (!unicode && (strcmp(cur->szReader.pc, szReader) != 0))
1584 if (unicode && (_wcscmp(cur->szReader.pw, szReader) != 0))
1593WINPR_ATTR_MALLOC(scard_handle_free, 1)
1594static SCardHandle* reader2handle(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1595 const
void* szReader, BOOL unicode, DWORD dwShareMode,
1596 SCARDHANDLE* phCard, DWORD dwPreferredProtocols,
1597 LPDWORD pdwActiveProtocol)
1599 SCardHandle* hdl =
nullptr;
1601 WINPR_ASSERT(phCard);
1604 if (Emulate_SCardIsValidContext(smartcard, hContext) != SCARD_S_SUCCESS)
1607 hdl = scard_handle_new(smartcard, hContext, szReader, unicode);
1610 if (winpr_RAND(&hdl->card,
sizeof(hdl->card)) < 0)
1612 scard_handle_free(hdl);
1615 hdl->dwActiveProtocol = SCARD_PROTOCOL_T1;
1616 hdl->dwShareMode = dwShareMode;
1618 if (!HashTable_Insert(smartcard->handles, (
const void*)hdl->card, hdl))
1620 scard_handle_free(hdl);
1625 if (pdwActiveProtocol)
1627 if ((hdl->dwActiveProtocol & dwPreferredProtocols) == 0)
1629 scard_handle_free(hdl);
1633 *pdwActiveProtocol = hdl->dwActiveProtocol;
1637 hdl->referencecount++;
1638 *phCard = hdl->card;
1642 WLog_Print(smartcard->log, smartcard->log_default_level,
"{ %p }", (
void*)*phCard);
1646LONG WINAPI Emulate_SCardConnectA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1647 LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1648 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1650 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1652 if (!phCard || !pdwActiveProtocol)
1653 status = SCARD_E_INVALID_PARAMETER;
1655 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectA { hContext: %p",
1658 if (status == SCARD_S_SUCCESS)
1660 if (!reader2handle(smartcard, hContext, szReader, FALSE, dwShareMode, phCard,
1661 dwPreferredProtocols, pdwActiveProtocol))
1662 status = SCARD_E_NO_MEMORY;
1665 WLog_Print(smartcard->log, smartcard->log_default_level,
1666 "SCardConnectA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1667 WINPR_CXX_COMPAT_CAST(UINT32, status));
1672LONG WINAPI Emulate_SCardConnectW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1673 LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1674 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1676 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1678 if (!phCard || !pdwActiveProtocol)
1679 status = SCARD_E_INVALID_PARAMETER;
1681 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectW { hContext: %p",
1684 if (status == SCARD_S_SUCCESS)
1686 if (!reader2handle(smartcard, hContext, szReader, TRUE, dwShareMode, phCard,
1687 dwPreferredProtocols, pdwActiveProtocol))
1688 status = SCARD_E_NO_MEMORY;
1691 WLog_Print(smartcard->log, smartcard->log_default_level,
1692 "SCardConnectW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1693 WINPR_CXX_COMPAT_CAST(UINT32, status));
1698LONG WINAPI Emulate_SCardReconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1699 DWORD dwShareMode, WINPR_ATTR_UNUSED DWORD dwPreferredProtocols,
1700 WINPR_ATTR_UNUSED DWORD dwInitialization,
1701 LPDWORD pdwActiveProtocol)
1703 LONG status = scard_handle_valid(smartcard, hCard);
1705 if (!pdwActiveProtocol)
1706 status = SCARD_E_INVALID_PARAMETER;
1708 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReconnect { hCard: %p",
1711 if (status == SCARD_S_SUCCESS)
1713 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1717 hdl->dwShareMode = dwShareMode;
1718 hdl->transaction = FALSE;
1720 *pdwActiveProtocol = hdl->dwActiveProtocol;
1723 WLog_Print(smartcard->log, smartcard->log_default_level,
1724 "SCardReconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1725 WINPR_CXX_COMPAT_CAST(UINT32, status));
1730LONG WINAPI Emulate_SCardDisconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1731 DWORD dwDisposition)
1733 LONG status = scard_handle_valid(smartcard, hCard);
1735 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDisconnect { hCard: %p",
1738 WINPR_UNUSED(dwDisposition);
1740 if (status == SCARD_S_SUCCESS)
1742 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1745 hdl->referencecount--;
1746 if (hdl->referencecount == 0)
1747 HashTable_Remove(smartcard->handles, (
const void*)hCard);
1750 WLog_Print(smartcard->log, smartcard->log_default_level,
1751 "SCardDisconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1752 WINPR_CXX_COMPAT_CAST(UINT32, status));
1757LONG WINAPI Emulate_SCardBeginTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1759 LONG status = scard_handle_valid(smartcard, hCard);
1761 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardBeginTransaction { hCard: %p",
1764 if (status == SCARD_S_SUCCESS)
1766 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1768 if (hdl->transaction)
1769 status = SCARD_E_INVALID_VALUE;
1771 hdl->transaction = TRUE;
1774 WLog_Print(smartcard->log, smartcard->log_default_level,
1775 "SCardBeginTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1776 WINPR_CXX_COMPAT_CAST(UINT32, status));
1781LONG WINAPI Emulate_SCardEndTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1782 DWORD dwDisposition)
1784 LONG status = scard_handle_valid(smartcard, hCard);
1786 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardEndTransaction { hCard: %p",
1789 WINPR_UNUSED(dwDisposition);
1791 if (status == SCARD_S_SUCCESS)
1793 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1795 if (!hdl->transaction)
1796 status = SCARD_E_NOT_TRANSACTED;
1798 hdl->transaction = FALSE;
1801 WLog_Print(smartcard->log, smartcard->log_default_level,
1802 "SCardEndTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1803 WINPR_CXX_COMPAT_CAST(UINT32, status));
1808LONG WINAPI Emulate_SCardCancelTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1810 LONG status = scard_handle_valid(smartcard, hCard);
1812 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancelTransaction { hCard: %p",
1815 if (status == SCARD_S_SUCCESS)
1817 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1819 if (!hdl->transaction)
1820 status = SCARD_E_NOT_TRANSACTED;
1822 hdl->transaction = FALSE;
1825 WLog_Print(smartcard->log, smartcard->log_default_level,
1826 "SCardCancelTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1827 WINPR_CXX_COMPAT_CAST(UINT32, status));
1832LONG WINAPI Emulate_SCardState(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1833 LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
1836 LONG status = scard_handle_valid(smartcard, hCard);
1838 if (!pdwState || !pdwProtocol)
1839 status = SCARD_E_INVALID_PARAMETER;
1841 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardState { hCard: %p",
1844 if (status == SCARD_S_SUCCESS)
1846 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1850 *pdwState = SCARD_SPECIFIC;
1852 *pdwProtocol = SCARD_PROTOCOL_T1;
1857 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1860 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1866 if (_wcscmp(readerW->szReader, hdl->szReader.pw) == 0)
1868 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerW->rgbAtr,
1874 if (strcmp(readerA->szReader, hdl->szReader.pc) == 0)
1876 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerA->rgbAtr,
1884 WLog_Print(smartcard->log, smartcard->log_default_level,
1885 "SCardState } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1886 WINPR_CXX_COMPAT_CAST(UINT32, status));
1891LONG WINAPI Emulate_SCardStatusA(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1892 LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1893 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1895 LONG status = scard_handle_valid(smartcard, hCard);
1897 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusA { hCard: %p",
1900 if (status == SCARD_S_SUCCESS)
1902 SCardContext* ctx =
nullptr;
1903 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1906 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1911 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pc,
1912 (UINT32)strlen(hdl->szReader.pc) + 2);
1915 *pdwState = SCARD_SPECIFIC;
1917 *pdwProtocol = SCARD_PROTOCOL_T1;
1921 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1924 if (strcmp(reader->szReader, hdl->szReader.pc) == 0)
1927 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1933 WLog_Print(smartcard->log, smartcard->log_default_level,
1934 "SCardStatusA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1935 WINPR_CXX_COMPAT_CAST(UINT32, status));
1940LONG WINAPI Emulate_SCardStatusW(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1941 LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1942 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1944 LONG status = scard_handle_valid(smartcard, hCard);
1946 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusW { hCard: %p",
1949 if (status == SCARD_S_SUCCESS)
1951 SCardContext* ctx =
nullptr;
1952 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1955 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1960 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pw,
1961 (UINT32)(_wcslen(hdl->szReader.pw) + 2) *
sizeof(WCHAR)) /
1965 *pdwState = SCARD_SPECIFIC;
1967 *pdwProtocol = SCARD_PROTOCOL_T1;
1971 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1974 if (_wcscmp(reader->szReader, hdl->szReader.pw) == 0)
1976 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1981 WLog_Print(smartcard->log, smartcard->log_default_level,
1982 "SCardStatusW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1983 WINPR_CXX_COMPAT_CAST(UINT32, status));
1988LONG WINAPI Emulate_SCardTransmit(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1991 LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
1993 LONG status = scard_handle_valid(smartcard, hCard);
1995 if (!pioSendPci || !pbSendBuffer || !pbRecvBuffer || !pcbRecvLength)
1996 status = SCARD_E_INVALID_PARAMETER;
1998 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardTransmit { hCard: %p",
2001 if (status == SCARD_S_SUCCESS)
2003 BYTE* response =
nullptr;
2004 DWORD responseSize = 0;
2005 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2008 hdl->transmitcount++;
2010 if (!vgids_process_apdu(hdl->vgids, pbSendBuffer, cbSendLength, &response, &responseSize))
2011 status = SCARD_E_NO_SMARTCARD;
2015 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
2019 scard_copy_strings(ctx, pbRecvBuffer, *pcbRecvLength, response, responseSize);
2024 pioRecvPci->dwProtocol = hdl->dwActiveProtocol;
2028 WLog_Print(smartcard->log, smartcard->log_default_level,
2029 "SCardTransmit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2030 WINPR_CXX_COMPAT_CAST(UINT32, status));
2035LONG WINAPI Emulate_SCardGetTransmitCount(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2036 LPDWORD pcTransmitCount)
2038 LONG status = scard_handle_valid(smartcard, hCard);
2040 if (!pcTransmitCount)
2041 status = SCARD_E_INVALID_PARAMETER;
2043 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetTransmitCount { hCard: %p",
2046 if (status == SCARD_S_SUCCESS)
2048 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2051 *pcTransmitCount = hdl->transmitcount;
2054 WLog_Print(smartcard->log, smartcard->log_default_level,
2055 "SCardGetTransmitCount } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2056 WINPR_CXX_COMPAT_CAST(UINT32, status));
2061LONG WINAPI Emulate_SCardControl(
2062 SmartcardEmulationContext* smartcard, SCARDHANDLE hCard, DWORD dwControlCode,
2063 LPCVOID lpInBuffer, DWORD cbInBufferSize, LPVOID lpOutBuffer, DWORD cbOutBufferSize,
2064 LPDWORD lpBytesReturned )
2066 LONG status = scard_handle_valid(smartcard, hCard);
2068 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardControl { hCard: %p",
2071 if (status == SCARD_S_SUCCESS)
2073 WINPR_UNUSED(dwControlCode);
2074 WINPR_UNUSED(lpInBuffer);
2075 WINPR_UNUSED(cbInBufferSize);
2076 WINPR_UNUSED(lpOutBuffer);
2077 WINPR_UNUSED(cbOutBufferSize);
2078 WINPR_UNUSED(lpBytesReturned);
2081 status = SCARD_E_UNSUPPORTED_FEATURE;
2084 WLog_Print(smartcard->log, smartcard->log_default_level,
2085 "SCardControl } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2086 WINPR_CXX_COMPAT_CAST(UINT32, status));
2091LONG WINAPI Emulate_SCardGetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2094 LPDWORD pcbAttrLen )
2096 LONG status = scard_handle_valid(smartcard, hCard);
2098 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetAttrib { hCard: %p",
2101 WINPR_UNUSED(dwAttrId);
2102 WINPR_UNUSED(pbAttr);
2103 WINPR_UNUSED(pcbAttrLen);
2106 if (status == SCARD_S_SUCCESS)
2107 status = SCARD_F_INTERNAL_ERROR;
2109 WLog_Print(smartcard->log, smartcard->log_default_level,
2110 "SCardGetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2111 WINPR_CXX_COMPAT_CAST(UINT32, status));
2116LONG WINAPI Emulate_SCardSetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2117 DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
2119 LONG status = scard_handle_valid(smartcard, hCard);
2121 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardSetAttrib { hCard: %p",
2124 WINPR_UNUSED(dwAttrId);
2125 WINPR_UNUSED(pbAttr);
2126 WINPR_UNUSED(cbAttrLen);
2129 if (status == SCARD_S_SUCCESS)
2130 status = SCARD_F_INTERNAL_ERROR;
2132 WLog_Print(smartcard->log, smartcard->log_default_level,
2133 "SCardSetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2134 WINPR_CXX_COMPAT_CAST(UINT32, status));
2139LONG WINAPI Emulate_SCardUIDlgSelectCardA(SmartcardEmulationContext* smartcard,
2140 LPOPENCARDNAMEA_EX pDlgStruc)
2144 WINPR_ASSERT(smartcard);
2146 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardA {");
2148 WINPR_UNUSED(pDlgStruc);
2151 status = SCARD_E_UNSUPPORTED_FEATURE;
2153 WLog_Print(smartcard->log, smartcard->log_default_level,
2154 "SCardUIDlgSelectCardA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2155 WINPR_CXX_COMPAT_CAST(UINT32, status));
2160LONG WINAPI Emulate_SCardUIDlgSelectCardW(SmartcardEmulationContext* smartcard,
2161 LPOPENCARDNAMEW_EX pDlgStruc)
2165 WINPR_ASSERT(smartcard);
2167 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardW {");
2169 WINPR_UNUSED(pDlgStruc);
2172 status = SCARD_E_UNSUPPORTED_FEATURE;
2174 WLog_Print(smartcard->log, smartcard->log_default_level,
2175 "SCardUIDlgSelectCardW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2176 WINPR_CXX_COMPAT_CAST(UINT32, status));
2181LONG WINAPI Emulate_GetOpenCardNameA(SmartcardEmulationContext* smartcard,
2186 WINPR_ASSERT(smartcard);
2188 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameA {");
2190 WINPR_UNUSED(pDlgStruc);
2193 status = SCARD_E_UNSUPPORTED_FEATURE;
2195 WLog_Print(smartcard->log, smartcard->log_default_level,
2196 "GetOpenCardNameA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2197 WINPR_CXX_COMPAT_CAST(UINT32, status));
2202LONG WINAPI Emulate_GetOpenCardNameW(SmartcardEmulationContext* smartcard,
2207 WINPR_ASSERT(smartcard);
2209 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameW {");
2211 WINPR_UNUSED(pDlgStruc);
2214 status = SCARD_E_UNSUPPORTED_FEATURE;
2216 WLog_Print(smartcard->log, smartcard->log_default_level,
2217 "GetOpenCardNameW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2218 WINPR_CXX_COMPAT_CAST(UINT32, status));
2223LONG WINAPI Emulate_SCardDlgExtendedError(SmartcardEmulationContext* smartcard)
2227 WINPR_ASSERT(smartcard);
2229 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDlgExtendedError {");
2232 status = SCARD_E_UNSUPPORTED_FEATURE;
2234 WLog_Print(smartcard->log, smartcard->log_default_level,
2235 "SCardDlgExtendedError } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2236 WINPR_CXX_COMPAT_CAST(UINT32, status));
2241LONG WINAPI Emulate_SCardReadCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2242 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2243 PBYTE Data, DWORD* DataLen)
2246 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2248 if (!CardIdentifier || !DataLen)
2249 status = SCARD_E_INVALID_PARAMETER;
2251 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheA { hContext: %p",
2260 if (status == SCARD_S_SUCCESS)
2262 SCardCacheItem* data =
nullptr;
2263 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2264 WINPR_ASSERT(value);
2266 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2267 data = HashTable_GetItemValue(value->cache,
id);
2271 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2272 else if (data->freshness != FreshnessCounter)
2273 status = SCARD_W_CACHE_ITEM_STALE;
2275 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2278 WLog_Print(smartcard->log, smartcard->log_default_level,
2279 "SCardReadCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2280 WINPR_CXX_COMPAT_CAST(UINT32, status));
2285LONG WINAPI Emulate_SCardReadCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2286 UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName,
2287 PBYTE Data, DWORD* DataLen)
2290 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2292 if (!CardIdentifier || !DataLen)
2293 status = SCARD_E_INVALID_PARAMETER;
2295 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheW { hContext: %p",
2304 if (status == SCARD_S_SUCCESS)
2306 SCardCacheItem* data =
nullptr;
2307 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2308 WINPR_ASSERT(value);
2310 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2311 data = HashTable_GetItemValue(value->cache,
id);
2314 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2315 else if (data->freshness != FreshnessCounter)
2316 status = SCARD_W_CACHE_ITEM_STALE;
2318 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2321 WLog_Print(smartcard->log, smartcard->log_default_level,
2322 "SCardReadCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2323 WINPR_CXX_COMPAT_CAST(UINT32, status));
2328static LONG insert_data(wHashTable* table, DWORD FreshnessCounter,
const char* key,
2329 const PBYTE Data, DWORD DataLen)
2332 SCardCacheItem* item =
nullptr;
2334 WINPR_ASSERT(table);
2337 if (DataLen > MAX_CACHE_ITEM_SIZE)
2338 return SCARD_W_CACHE_ITEM_TOO_BIG;
2340 if (HashTable_Count(table) > MAX_CACHE_ITEM_VALUES)
2341 return SCARD_E_WRITE_TOO_MANY;
2343 item = HashTable_GetItemValue(table, key);
2346 item = calloc(1,
sizeof(SCardCacheItem));
2348 return SCARD_E_NO_MEMORY;
2350 rc = HashTable_Insert(table, key, item);
2354 return SCARD_E_NO_MEMORY;
2358 if (item->freshness > FreshnessCounter)
2359 return SCARD_W_CACHE_ITEM_STALE;
2360 item->freshness = FreshnessCounter;
2361 item->size = DataLen;
2362 memcpy(item->data, Data, DataLen);
2365 return SCARD_S_SUCCESS;
2368LONG WINAPI Emulate_SCardWriteCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2369 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2370 PBYTE Data, DWORD DataLen)
2372 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2374 if (!CardIdentifier)
2375 status = SCARD_E_INVALID_PARAMETER;
2377 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheA { hContext: %p",
2380 if (status == SCARD_S_SUCCESS)
2382 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2383 WINPR_ASSERT(value);
2385 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2387 status = SCARD_E_NO_MEMORY;
2390 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2395 WLog_Print(smartcard->log, smartcard->log_default_level,
2396 "SCardWriteCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2397 WINPR_CXX_COMPAT_CAST(UINT32, status));
2402LONG WINAPI Emulate_SCardWriteCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2403 UUID* CardIdentifier, DWORD FreshnessCounter,
2404 LPWSTR LookupName, PBYTE Data, DWORD DataLen)
2406 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2408 if (!CardIdentifier)
2409 status = SCARD_E_INVALID_PARAMETER;
2411 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheW { hContext: %p",
2414 if (status == SCARD_S_SUCCESS)
2416 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2417 WINPR_ASSERT(value);
2419 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2421 status = SCARD_E_NO_MEMORY;
2424 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2429 WLog_Print(smartcard->log, smartcard->log_default_level,
2430 "SCardWriteCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2431 WINPR_CXX_COMPAT_CAST(UINT32, status));
2436LONG WINAPI Emulate_SCardGetReaderIconA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2437 LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2439 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2441 if (!szReaderName || !pcbIcon)
2442 status = SCARD_E_INVALID_PARAMETER;
2444 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconA { hContext: %p",
2447 if (status == SCARD_S_SUCCESS)
2448 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2450 if (status == SCARD_S_SUCCESS)
2452 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2456 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2457 resources_FreeRDP_ico_len);
2459 *pcbIcon = resources_FreeRDP_ico_len;
2462 WLog_Print(smartcard->log, smartcard->log_default_level,
2463 "SCardGetReaderIconA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2464 WINPR_CXX_COMPAT_CAST(UINT32, status));
2469LONG WINAPI Emulate_SCardGetReaderIconW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2470 LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2472 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2474 if (!szReaderName || !pcbIcon)
2475 status = SCARD_E_INVALID_PARAMETER;
2477 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconW { hContext: %p",
2480 if (status == SCARD_S_SUCCESS)
2481 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2483 if (status == SCARD_S_SUCCESS)
2485 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2489 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2490 resources_FreeRDP_ico_len);
2492 *pcbIcon = resources_FreeRDP_ico_len;
2495 WLog_Print(smartcard->log, smartcard->log_default_level,
2496 "SCardGetReaderIconW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2497 WINPR_CXX_COMPAT_CAST(UINT32, status));
2502LONG WINAPI Emulate_SCardGetDeviceTypeIdA(SmartcardEmulationContext* smartcard,
2503 SCARDCONTEXT hContext, LPCSTR szReaderName,
2504 LPDWORD pdwDeviceTypeId)
2506 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2508 if (!pdwDeviceTypeId)
2509 status = SCARD_E_INVALID_PARAMETER;
2511 if (status == SCARD_S_SUCCESS)
2512 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2514 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdA { hContext: %p",
2517 if (status == SCARD_S_SUCCESS)
2519 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2522 WLog_Print(smartcard->log, smartcard->log_default_level,
2523 "SCardGetDeviceTypeIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2524 WINPR_CXX_COMPAT_CAST(UINT32, status));
2529LONG WINAPI Emulate_SCardGetDeviceTypeIdW(SmartcardEmulationContext* smartcard,
2530 SCARDCONTEXT hContext, LPCWSTR szReaderName,
2531 LPDWORD pdwDeviceTypeId)
2533 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2535 if (!pdwDeviceTypeId)
2536 status = SCARD_E_INVALID_PARAMETER;
2538 if (status == SCARD_S_SUCCESS)
2539 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2541 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdW { hContext: %p",
2544 if (status == SCARD_S_SUCCESS)
2546 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2549 WLog_Print(smartcard->log, smartcard->log_default_level,
2550 "SCardGetDeviceTypeIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2551 WINPR_CXX_COMPAT_CAST(UINT32, status));
2556LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdA(
2557 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szReaderName,
2558 LPSTR szDeviceInstanceId ,
2559 LPDWORD pcchDeviceInstanceId )
2561 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2563 if (status == SCARD_S_SUCCESS)
2564 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2566 WLog_Print(smartcard->log, smartcard->log_default_level,
2567 "SCardGetReaderDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2569 WINPR_UNUSED(szDeviceInstanceId);
2570 WINPR_UNUSED(pcchDeviceInstanceId);
2573 if (status == SCARD_S_SUCCESS)
2574 status = SCARD_E_UNSUPPORTED_FEATURE;
2576 WLog_Print(smartcard->log, smartcard->log_default_level,
2577 "SCardGetReaderDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2578 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2583LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdW(
2584 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szReaderName,
2585 LPWSTR szDeviceInstanceId ,
2586 LPDWORD pcchDeviceInstanceId )
2588 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2590 if (status == SCARD_S_SUCCESS)
2591 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2593 WLog_Print(smartcard->log, smartcard->log_default_level,
2594 "SCardGetReaderDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2596 WINPR_UNUSED(szDeviceInstanceId);
2597 WINPR_UNUSED(pcchDeviceInstanceId);
2600 if (status == SCARD_S_SUCCESS)
2601 status = SCARD_E_UNSUPPORTED_FEATURE;
2603 WLog_Print(smartcard->log, smartcard->log_default_level,
2604 "SCardGetReaderDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2605 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2610LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdA(
2611 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szDeviceInstanceId,
2613 LPDWORD pcchReaders )
2615 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2617 WLog_Print(smartcard->log, smartcard->log_default_level,
2618 "SCardListReadersWithDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2620 WINPR_UNUSED(szDeviceInstanceId);
2621 WINPR_UNUSED(mszReaders);
2622 WINPR_UNUSED(pcchReaders);
2625 if (status == SCARD_S_SUCCESS)
2626 status = SCARD_E_UNSUPPORTED_FEATURE;
2628 WLog_Print(smartcard->log, smartcard->log_default_level,
2629 "SCardListReadersWithDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2630 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2635LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdW(
2636 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szDeviceInstanceId,
2637 LPWSTR mszReaders , LPDWORD pcchReaders)
2639 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2641 WLog_Print(smartcard->log, smartcard->log_default_level,
2642 "SCardListReadersWithDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2644 WINPR_UNUSED(szDeviceInstanceId);
2645 WINPR_UNUSED(mszReaders);
2646 WINPR_UNUSED(pcchReaders);
2649 if (status == SCARD_S_SUCCESS)
2650 status = SCARD_E_UNSUPPORTED_FEATURE;
2652 WLog_Print(smartcard->log, smartcard->log_default_level,
2653 "SCardListReadersWithDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2654 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2659LONG WINAPI Emulate_SCardAudit(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2662 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2664 WINPR_UNUSED(dwEvent);
2666 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAudit { hContext: %p",
2670 if (status == SCARD_S_SUCCESS)
2671 status = SCARD_E_UNSUPPORTED_FEATURE;
2673 WLog_Print(smartcard->log, smartcard->log_default_level,
2674 "SCardAudit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2675 WINPR_CXX_COMPAT_CAST(UINT32, status));
2680static BOOL context_equals(
const void* pva,
const void* pvb)
2682 const SCARDCONTEXT a = (
const SCARDCONTEXT)pva;
2683 const SCARDCONTEXT b = (
const SCARDCONTEXT)pvb;
2692static BOOL handle_equals(
const void* pva,
const void* pvb)
2694 const SCARDHANDLE a = (
const SCARDHANDLE)pva;
2695 const SCARDHANDLE b = (
const SCARDHANDLE)pvb;
2704SmartcardEmulationContext* Emulate_New(
const rdpSettings* settings)
2706 SmartcardEmulationContext* smartcard =
nullptr;
2708 WINPR_ASSERT(settings);
2710 smartcard = calloc(1,
sizeof(SmartcardEmulationContext));
2714 smartcard->settings = settings;
2715 smartcard->log = WLog_Get(
"EmulateSCard");
2716 if (!smartcard->log)
2718 smartcard->log_default_level = WLOG_TRACE;
2720 smartcard->contexts = HashTable_New(FALSE);
2721 if (!smartcard->contexts)
2725 wObject* obj = HashTable_KeyObject(smartcard->contexts);
2729 if (!smartcard->contexts)
2733 wObject* obj = HashTable_ValueObject(smartcard->contexts);
2738 smartcard->handles = HashTable_New(FALSE);
2739 if (!smartcard->handles)
2743 wObject* obj = HashTable_KeyObject(smartcard->handles);
2747 if (!smartcard->handles)
2751 wObject* obj = HashTable_ValueObject(smartcard->handles);
2759 WINPR_PRAGMA_DIAG_PUSH
2760 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2761 Emulate_Free(smartcard);
2762 WINPR_PRAGMA_DIAG_POP
2766void Emulate_Free(SmartcardEmulationContext* context)
2771 HashTable_Free(context->handles);
2772 HashTable_Free(context->contexts);
2776BOOL Emulate_IsConfigured(SmartcardEmulationContext* context)
2779 vgidsContext* vgids =
nullptr;
2780 const char* pem =
nullptr;
2781 const char* key =
nullptr;
2782 const char* pin =
nullptr;
2784 WINPR_ASSERT(context);
2791 if ((context->pem == pem) && (context->key == key) && (context->pin == pin))
2792 return context->configured;
2798 vgids = vgids_new();
2800 rc = vgids_init(vgids, context->pem, context->key, context->pin);
2803 context->configured = rc;
WINPR_ATTR_NODISCARD FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
WINPR_ATTR_NODISCARD 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.
OBJECT_FREE_FN fnObjectFree
WINPR_ATTR_NODISCARD OBJECT_EQUALS_FN fnObjectEquals