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>
32#include <winpr/interlocked.h>
34#include <freerdp/emulate/scard/smartcard_emulate.h>
35#include "FreeRDP.ico.h"
37#include "smartcard_virtual_gids.h"
39#define MAX_CACHE_ITEM_SIZE 4096
40#define MAX_CACHE_ITEM_VALUES 4096
42#define VGIDS_DEFAULT_RETRY_COUNTER 3
50static CHAR g_ReaderNameA[] = {
'F',
'r',
'e',
'e',
'R',
'D',
'P',
' ',
'E',
51 'm',
'u',
'l',
'a',
't',
'o',
'r',
'\0',
'\0' };
52static INIT_ONCE g_ReaderNameWGuard = INIT_ONCE_STATIC_INIT;
53static WCHAR g_ReaderNameW[32] = WINPR_C_ARRAY_INIT;
54static size_t g_ReaderNameWLen = 0;
56WINPR_ATTR_MALLOC(free, 1)
57static
char* card_id_and_name_a(const
UUID* CardIdentifier, LPCSTR LookupName)
59 if (!CardIdentifier || !LookupName)
62 size_t len = strlen(LookupName) + 34;
63 char*
id = malloc(len);
67 (void)snprintf(
id, len,
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X\\%s",
68 CardIdentifier->Data1, CardIdentifier->Data2, CardIdentifier->Data3,
69 CardIdentifier->Data4[0], CardIdentifier->Data4[1], CardIdentifier->Data4[2],
70 CardIdentifier->Data4[3], CardIdentifier->Data4[4], CardIdentifier->Data4[5],
71 CardIdentifier->Data4[6], CardIdentifier->Data4[7], LookupName);
75WINPR_ATTR_MALLOC(free, 1)
76static
char* card_id_and_name_w(const
UUID* CardIdentifier, LPCWSTR LookupName)
79 char* tmp = ConvertWCharToUtf8Alloc(LookupName,
nullptr);
82 res = card_id_and_name_a(CardIdentifier, tmp);
88static BOOL CALLBACK g_ReaderNameWInit(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
90 WINPR_UNUSED(InitOnce);
91 WINPR_UNUSED(Parameter);
92 WINPR_UNUSED(Context);
93 InitializeConstWCharFromUtf8(g_ReaderNameA, g_ReaderNameW, ARRAYSIZE(g_ReaderNameW));
94 g_ReaderNameWLen = _wcsnlen(g_ReaderNameW, ARRAYSIZE(g_ReaderNameW) - 2) + 2;
98struct smartcard_emulation_context
100 const rdpSettings* settings;
101 DWORD log_default_level;
103 wHashTable* contexts;
109 wHashTable* pinCounters;
115 UINT16 curRetryCounter;
117} SmartcardPinCounterEntry;
119#define MAX_EMULATED_READERS 1
129 volatile LONG semaphore;
144 DWORD dwActiveProtocol;
145 SCARDCONTEXT hContext;
148 size_t referencecount;
155 char data[MAX_CACHE_ITEM_SIZE];
159static SCardHandle* find_reader(SmartcardEmulationContext* smartcard,
const void* szReader,
162static const BYTE ATR[] = { 0x3b, 0xf7, 0x18, 0x00, 0x00, 0x80, 0x31, 0xfe, 0x45,
163 0x73, 0x66, 0x74, 0x65, 0x2d, 0x6e, 0x66, 0xc4 };
166static BOOL scard_status_transition(SCardContext* context)
168 WINPR_ASSERT(context);
170 switch (context->readerState)
176 reader->szReader = g_ReaderNameA;
177 reader->dwEventState = SCARD_STATE_PRESENT;
178 reader->cbAtr =
sizeof(ATR);
179 memcpy(reader->rgbAtr, ATR,
sizeof(ATR));
182 if (!InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit,
nullptr,
nullptr))
185 reader->szReader = g_ReaderNameW;
186 reader->dwEventState = SCARD_STATE_PRESENT;
187 reader->cbAtr =
sizeof(ATR);
188 memcpy(reader->rgbAtr, ATR,
sizeof(ATR));
190 context->readerState = 42;
198static UINT32 scard_copy_strings(SCardContext* ctx,
void* dst,
size_t dstSize,
const void* src,
204 WINPR_ASSERT(srcSize <= UINT32_MAX);
205 WINPR_ASSERT(dstSize <= UINT32_MAX);
207 if (dstSize == SCARD_AUTOALLOCATE)
212 void* tmp = malloc(srcSize);
215 memcpy(tmp, src, srcSize);
216 ArrayList_Append(ctx->strings, tmp);
217 *((
void**)dst) = tmp;
218 return (UINT32)srcSize;
222 const size_t min = MIN(dstSize, srcSize);
223 memcpy(dst, src, min);
228static void waitForCancel(SCardContext* ctx)
231 while (InterlockedCompareExchange(&ctx->semaphore, 0, 0) > 0)
235static void scard_context_free(
void* context)
237 SCardContext* ctx = context;
246 ctx->canceled = TRUE;
249 HashTable_Free(ctx->cards);
250 ArrayList_Free(ctx->strings);
251 HashTable_Free(ctx->cache);
256WINPR_ATTR_MALLOC(scard_context_free, 1)
257static SCardContext* scard_context_new(
void)
259 SCardContext* ctx = calloc(1,
sizeof(SCardContext));
263 ctx->strings = ArrayList_New(FALSE);
268 wObject* obj = ArrayList_Object(ctx->strings);
273 ctx->cache = HashTable_New(FALSE);
276 if (!HashTable_SetupForStringData(ctx->cache, FALSE))
280 wObject* val = HashTable_ValueObject(ctx->cache);
285 if (!scard_status_transition(ctx))
289 scard_context_free(ctx);
293static void scard_handle_free(
void* handle)
295 SCardHandle* hdl = handle;
298 free(hdl->szReader.pv);
299 vgids_free(hdl->vgids);
304WINPR_ATTR_MALLOC(scard_handle_free, 1)
305static SCardHandle* scard_handle_new(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
306 const
void* name, BOOL unicode)
308 SCardHandle* hdl =
nullptr;
310 WINPR_ASSERT(smartcard);
312 hdl = calloc(1,
sizeof(SCardHandle));
321 size_t s = _wcslen(name);
323 hdl->szReader.pw = calloc(s + 2,
sizeof(WCHAR));
324 if (!hdl->szReader.pw)
326 memcpy(hdl->szReader.pv, name, s *
sizeof(WCHAR));
330 size_t s = strlen(name);
332 hdl->szReader.pc = calloc(s + 2,
sizeof(CHAR));
333 if (!hdl->szReader.pc)
335 memcpy(hdl->szReader.pv, name, s *
sizeof(CHAR));
338 if (!hdl->szReader.pv)
341 hdl->vgids = vgids_new(smartcard);
353 if (!vgids_init(hdl->vgids, pem, key, pin))
357 hdl->unicode = unicode;
358 hdl->hContext = context;
362 scard_handle_free(hdl);
367static LONG scard_handle_valid(SmartcardEmulationContext* smartcard, SCARDHANDLE handle)
369 WINPR_ASSERT(smartcard);
371 SCardHandle* ctx = HashTable_GetItemValue(smartcard->handles, (
const void*)handle);
373 return SCARD_E_INVALID_HANDLE;
375 return SCARD_S_SUCCESS;
379static LONG scard_reader_name_valid_a(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
382 SCardContext* ctx =
nullptr;
384 WINPR_ASSERT(smartcard);
385 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)context);
390 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
393 if (strcmp(reader->szReader, name) == 0)
394 return SCARD_S_SUCCESS;
397 return SCARD_E_UNKNOWN_READER;
401static LONG scard_reader_name_valid_w(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
404 SCardContext* ctx =
nullptr;
406 WINPR_ASSERT(smartcard);
407 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)context);
412 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
415 if (_wcscmp(reader->szReader, name) == 0)
416 return SCARD_S_SUCCESS;
419 return SCARD_E_UNKNOWN_READER;
426LONG WINAPI Emulate_SCardEstablishContext(SmartcardEmulationContext* smartcard, DWORD dwScope,
427 LPCVOID pvReserved1, LPCVOID pvReserved2,
428 LPSCARDCONTEXT phContext)
430 LONG status = SCARD_E_NO_MEMORY;
431 SCardContext* ctx =
nullptr;
433 WINPR_ASSERT(smartcard);
435 ctx = scard_context_new();
437 WINPR_UNUSED(pvReserved1);
438 WINPR_UNUSED(pvReserved2);
440 WLog_Print(smartcard->log, smartcard->log_default_level,
441 "SCardEstablishContext { dwScope: %s (0x%08" PRIX32
")",
442 SCardGetScopeString(dwScope), dwScope);
446 SCARDCONTEXT context = WINPR_C_ARRAY_INIT;
448 if (winpr_RAND(&context,
sizeof(SCARDCONTEXT)) >= 0)
450 if (HashTable_Insert(smartcard->contexts, (
const void*)context, ctx))
452 *phContext = context;
453 status = SCARD_S_SUCCESS;
458 WLog_Print(smartcard->log, smartcard->log_default_level,
459 "SCardEstablishContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
460 WINPR_CXX_COMPAT_CAST(UINT32, status));
462 if (status != SCARD_S_SUCCESS)
463 scard_context_free(ctx);
469static BOOL remove_handles(
const void* key,
void* value,
void* arg)
474 const HandleCleanLoopArg* harg = arg;
475 SCardHandle* handle = value;
476 if (handle->hContext == harg->context)
478 if (!HashTable_Remove(harg->table, key))
484LONG WINAPI Emulate_SCardReleaseContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
486 LONG status = SCARD_S_SUCCESS;
488 WINPR_ASSERT(smartcard);
490 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
492 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseContext { hContext: %p",
495 HandleCleanLoopArg arg = { .context = hContext, .table = smartcard->handles };
496 if (!HashTable_Foreach(smartcard->handles, remove_handles, &arg))
497 status = SCARD_E_INVALID_HANDLE;
500 HashTable_Remove(smartcard->contexts, (
const void*)hContext);
502 WLog_Print(smartcard->log, smartcard->log_default_level,
503 "SCardReleaseContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
504 WINPR_CXX_COMPAT_CAST(UINT32, status));
509LONG WINAPI Emulate_SCardIsValidContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
513 WINPR_ASSERT(smartcard);
515 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIsValidContext { hContext: %p",
518 status = HashTable_Contains(smartcard->contexts, (
const void*)hContext)
520 : SCARD_E_INVALID_HANDLE;
521 if (status == SCARD_S_SUCCESS)
523 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
526 return SCARD_F_INTERNAL_ERROR;
529 WLog_Print(smartcard->log, smartcard->log_default_level,
530 "SCardIsValidContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
531 WINPR_CXX_COMPAT_CAST(UINT32, status));
536LONG WINAPI Emulate_SCardListReaderGroupsA(
537 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
538 LPSTR mszGroups , LPDWORD pcchGroups)
540 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
542 WLog_Print(smartcard->log, smartcard->log_default_level,
543 "SCardListReaderGroupsA { hContext: %p", (
void*)hContext);
545 WINPR_UNUSED(mszGroups);
546 WINPR_UNUSED(pcchGroups);
549 if (status == SCARD_S_SUCCESS)
550 status = SCARD_E_UNSUPPORTED_FEATURE;
552 WLog_Print(smartcard->log, smartcard->log_default_level,
553 "SCardListReaderGroupsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
554 WINPR_CXX_COMPAT_CAST(UINT32, status));
559LONG WINAPI Emulate_SCardListReaderGroupsW(
560 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
561 LPWSTR mszGroups , LPDWORD pcchGroups)
563 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
565 WLog_Print(smartcard->log, smartcard->log_default_level,
566 "SCardListReaderGroupsW { hContext: %p", (
void*)hContext);
568 WINPR_UNUSED(mszGroups);
569 WINPR_UNUSED(pcchGroups);
572 if (status == SCARD_S_SUCCESS)
573 status = SCARD_E_UNSUPPORTED_FEATURE;
575 WLog_Print(smartcard->log, smartcard->log_default_level,
576 "SCardListReaderGroupsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
577 WINPR_CXX_COMPAT_CAST(UINT32, status));
582LONG WINAPI Emulate_SCardListReadersA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
583 LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
585 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
587 status = SCARD_E_INVALID_PARAMETER;
589 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListReadersA { hContext: %p",
592 WINPR_UNUSED(mszGroups);
594 if (SCARD_S_SUCCESS == status)
596 SCardContext* value =
597 (SCardContext*)HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
606 *pcchReaders = ARRAYSIZE(g_ReaderNameA);
609 *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameA,
610 sizeof(g_ReaderNameA));
614 WLog_Print(smartcard->log, smartcard->log_default_level,
615 "SCardListReadersA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
616 WINPR_CXX_COMPAT_CAST(UINT32, status));
621LONG WINAPI Emulate_SCardListReadersW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
622 LPCWSTR mszGroups, LPWSTR mszReaders, LPDWORD pcchReaders)
624 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
627 status = SCARD_E_INVALID_PARAMETER;
629 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListReadersW { hContext: %p",
632 WINPR_UNUSED(mszGroups);
634 if (!InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit,
nullptr,
nullptr))
636 if (SCARD_S_SUCCESS == status)
638 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
648 WINPR_ASSERT(g_ReaderNameWLen <= UINT32_MAX);
649 *pcchReaders = (UINT32)g_ReaderNameWLen;
653 *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameW,
654 g_ReaderNameWLen *
sizeof(WCHAR)) /
659 WLog_Print(smartcard->log, smartcard->log_default_level,
660 "SCardListReadersW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
661 WINPR_CXX_COMPAT_CAST(UINT32, status));
666LONG WINAPI Emulate_SCardListCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
667 LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
668 DWORD cguidInterfaceCount,
672 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
674 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListCardsA { hContext: %p",
678 WINPR_UNUSED(rgquidInterfaces);
679 WINPR_UNUSED(cguidInterfaceCount);
680 WINPR_UNUSED(mszCards);
681 WINPR_UNUSED(pcchCards);
684 if (status == SCARD_S_SUCCESS)
685 status = SCARD_E_UNSUPPORTED_FEATURE;
687 WLog_Print(smartcard->log, smartcard->log_default_level,
688 "SCardListCardsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
689 WINPR_CXX_COMPAT_CAST(UINT32, status));
694LONG WINAPI Emulate_SCardListCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
695 LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
696 DWORD cguidInterfaceCount,
700 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
702 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListCardsW { hContext: %p",
706 WINPR_UNUSED(rgquidInterfaces);
707 WINPR_UNUSED(cguidInterfaceCount);
708 WINPR_UNUSED(mszCards);
709 WINPR_UNUSED(pcchCards);
712 if (status == SCARD_S_SUCCESS)
713 status = SCARD_E_UNSUPPORTED_FEATURE;
715 WLog_Print(smartcard->log, smartcard->log_default_level,
716 "SCardListCardsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
717 WINPR_CXX_COMPAT_CAST(UINT32, status));
722LONG WINAPI Emulate_SCardListInterfacesA(
723 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szCard,
724 LPGUID pguidInterfaces, LPDWORD pcguidInterfaces )
726 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
728 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListInterfacesA { hContext: %p",
731 WINPR_UNUSED(szCard);
732 WINPR_UNUSED(pguidInterfaces);
733 WINPR_UNUSED(pcguidInterfaces);
736 if (status == SCARD_S_SUCCESS)
737 status = SCARD_E_UNSUPPORTED_FEATURE;
739 WLog_Print(smartcard->log, smartcard->log_default_level,
740 "SCardListInterfacesA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
741 WINPR_CXX_COMPAT_CAST(UINT32, status));
746LONG WINAPI Emulate_SCardListInterfacesW(
747 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szCard,
748 LPGUID pguidInterfaces, LPDWORD pcguidInterfaces )
750 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
752 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListInterfacesW { hContext: %p",
755 WINPR_UNUSED(szCard);
756 WINPR_UNUSED(pguidInterfaces);
757 WINPR_UNUSED(pcguidInterfaces);
760 if (status == SCARD_S_SUCCESS)
761 status = SCARD_E_UNSUPPORTED_FEATURE;
763 WLog_Print(smartcard->log, smartcard->log_default_level,
764 "SCardListInterfacesW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
765 WINPR_CXX_COMPAT_CAST(UINT32, status));
770LONG WINAPI Emulate_SCardGetProviderIdA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
771 LPCSTR szCard, LPGUID pguidProviderId)
773 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
775 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetProviderIdA { hContext: %p",
778 WINPR_UNUSED(szCard);
779 WINPR_UNUSED(pguidProviderId);
782 if (status == SCARD_S_SUCCESS)
783 status = SCARD_E_UNSUPPORTED_FEATURE;
785 WLog_Print(smartcard->log, smartcard->log_default_level,
786 "SCardGetProviderIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
787 WINPR_CXX_COMPAT_CAST(UINT32, status));
792LONG WINAPI Emulate_SCardGetProviderIdW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
793 LPCWSTR szCard, LPGUID pguidProviderId)
795 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
797 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetProviderIdW { hContext: %p",
800 WINPR_UNUSED(szCard);
801 WINPR_UNUSED(pguidProviderId);
804 if (status == SCARD_S_SUCCESS)
805 status = SCARD_E_UNSUPPORTED_FEATURE;
807 WLog_Print(smartcard->log, smartcard->log_default_level,
808 "SCardGetProviderIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
809 WINPR_CXX_COMPAT_CAST(UINT32, status));
814LONG WINAPI Emulate_SCardGetCardTypeProviderNameA(
815 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szCardName,
816 DWORD dwProviderId, CHAR* szProvider ,
817 LPDWORD pcchProvider )
819 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
821 WLog_Print(smartcard->log, smartcard->log_default_level,
822 "SCardGetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
824 WINPR_UNUSED(szCardName);
825 WINPR_UNUSED(dwProviderId);
826 WINPR_UNUSED(szProvider);
827 WINPR_UNUSED(pcchProvider);
830 if (status == SCARD_S_SUCCESS)
831 status = SCARD_E_UNSUPPORTED_FEATURE;
833 WLog_Print(smartcard->log, smartcard->log_default_level,
834 "SCardGetCardTypeProviderNameA } status: %s (0x%08" PRIX32
")",
835 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
840LONG WINAPI Emulate_SCardGetCardTypeProviderNameW(
841 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szCardName,
842 DWORD dwProviderId, WCHAR* szProvider ,
843 LPDWORD pcchProvider )
845 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
847 WLog_Print(smartcard->log, smartcard->log_default_level,
848 "SCardGetCardTypeProviderNameW { hContext: %p", (
void*)hContext);
850 WINPR_UNUSED(szCardName);
851 WINPR_UNUSED(dwProviderId);
852 WINPR_UNUSED(szProvider);
853 WINPR_UNUSED(pcchProvider);
856 if (status == SCARD_S_SUCCESS)
857 status = SCARD_E_UNSUPPORTED_FEATURE;
859 WLog_Print(smartcard->log, smartcard->log_default_level,
860 "SCardGetCardTypeProviderNameW } status: %s (0x%08" PRIX32
")",
861 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
866LONG WINAPI Emulate_SCardIntroduceReaderGroupA(SmartcardEmulationContext* smartcard,
867 SCARDCONTEXT hContext, LPCSTR szGroupName)
869 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
871 WLog_Print(smartcard->log, smartcard->log_default_level,
872 "SCardIntroduceReaderGroupA { hContext: %p", (
void*)hContext);
874 WINPR_UNUSED(szGroupName);
877 if (status == SCARD_S_SUCCESS)
878 status = SCARD_E_UNSUPPORTED_FEATURE;
880 WLog_Print(smartcard->log, smartcard->log_default_level,
881 "SCardIntroduceReaderGroupA } status: %s (0x%08" PRIX32
")",
882 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
887LONG WINAPI Emulate_SCardIntroduceReaderGroupW(SmartcardEmulationContext* smartcard,
888 SCARDCONTEXT hContext, LPCWSTR szGroupName)
890 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
892 WLog_Print(smartcard->log, smartcard->log_default_level,
893 "SCardIntroduceReaderGroupW { hContext: %p", (
void*)hContext);
895 WINPR_UNUSED(szGroupName);
898 if (status == SCARD_S_SUCCESS)
899 status = SCARD_E_UNSUPPORTED_FEATURE;
901 WLog_Print(smartcard->log, smartcard->log_default_level,
902 "SCardIntroduceReaderGroupW } status: %s (0x%08" PRIX32
")",
903 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
908LONG WINAPI Emulate_SCardForgetReaderGroupA(SmartcardEmulationContext* smartcard,
909 SCARDCONTEXT hContext, LPCSTR szGroupName)
911 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
913 WLog_Print(smartcard->log, smartcard->log_default_level,
914 "SCardForgetReaderGroupA { hContext: %p", (
void*)hContext);
916 WINPR_UNUSED(szGroupName);
919 if (status == SCARD_S_SUCCESS)
920 status = SCARD_E_UNSUPPORTED_FEATURE;
922 WLog_Print(smartcard->log, smartcard->log_default_level,
923 "SCardForgetReaderGroupA } status: %s (0x%08" PRIX32
")",
924 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
929LONG WINAPI Emulate_SCardForgetReaderGroupW(SmartcardEmulationContext* smartcard,
930 SCARDCONTEXT hContext, LPCWSTR szGroupName)
932 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
934 WLog_Print(smartcard->log, smartcard->log_default_level,
935 "SCardForgetReaderGroupW { hContext: %p", (
void*)hContext);
937 WINPR_UNUSED(szGroupName);
940 if (status == SCARD_S_SUCCESS)
941 status = SCARD_E_UNSUPPORTED_FEATURE;
943 WLog_Print(smartcard->log, smartcard->log_default_level,
944 "SCardForgetReaderGroupW } status: %s (0x%08" PRIX32
")",
945 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
950LONG WINAPI Emulate_SCardIntroduceReaderA(SmartcardEmulationContext* smartcard,
951 SCARDCONTEXT hContext, LPCSTR szReaderName,
954 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
956 if (status == SCARD_S_SUCCESS)
957 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
959 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIntroduceReaderA { hContext: %p",
962 WINPR_UNUSED(szDeviceName);
965 if (status == SCARD_S_SUCCESS)
966 status = SCARD_E_UNSUPPORTED_FEATURE;
968 WLog_Print(smartcard->log, smartcard->log_default_level,
969 "SCardIntroduceReaderA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
970 WINPR_CXX_COMPAT_CAST(UINT32, status));
975LONG WINAPI Emulate_SCardIntroduceReaderW(SmartcardEmulationContext* smartcard,
976 SCARDCONTEXT hContext, LPCWSTR szReaderName,
977 LPCWSTR szDeviceName)
979 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
981 if (status == SCARD_S_SUCCESS)
982 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
984 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIntroduceReaderW { hContext: %p",
987 WINPR_UNUSED(szDeviceName);
990 if (status == SCARD_S_SUCCESS)
991 status = SCARD_E_UNSUPPORTED_FEATURE;
993 WLog_Print(smartcard->log, smartcard->log_default_level,
994 "SCardIntroduceReaderW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
995 WINPR_CXX_COMPAT_CAST(UINT32, status));
1000LONG WINAPI Emulate_SCardForgetReaderA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1001 LPCSTR szReaderName)
1003 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1005 if (status == SCARD_S_SUCCESS)
1006 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
1008 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetReaderA { hContext: %p",
1012 if (status == SCARD_S_SUCCESS)
1013 status = SCARD_E_UNSUPPORTED_FEATURE;
1015 WLog_Print(smartcard->log, smartcard->log_default_level,
1016 "SCardForgetReaderA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1017 WINPR_CXX_COMPAT_CAST(UINT32, status));
1022LONG WINAPI Emulate_SCardForgetReaderW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1023 LPCWSTR szReaderName)
1025 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1027 if (status == SCARD_S_SUCCESS)
1028 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1030 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetReaderW { hContext: %p",
1034 if (status == SCARD_S_SUCCESS)
1035 status = SCARD_E_UNSUPPORTED_FEATURE;
1037 WLog_Print(smartcard->log, smartcard->log_default_level,
1038 "SCardForgetReaderW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1039 WINPR_CXX_COMPAT_CAST(UINT32, status));
1044LONG WINAPI Emulate_SCardAddReaderToGroupA(SmartcardEmulationContext* smartcard,
1045 SCARDCONTEXT hContext, LPCSTR szReaderName,
1048 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1050 if (status == SCARD_S_SUCCESS)
1051 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
1053 WLog_Print(smartcard->log, smartcard->log_default_level,
1054 "SCardAddReaderToGroupA { hContext: %p", (
void*)hContext);
1056 WINPR_UNUSED(szGroupName);
1059 if (status == SCARD_S_SUCCESS)
1060 status = SCARD_E_UNSUPPORTED_FEATURE;
1062 WLog_Print(smartcard->log, smartcard->log_default_level,
1063 "SCardAddReaderToGroupA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1064 WINPR_CXX_COMPAT_CAST(UINT32, status));
1069LONG WINAPI Emulate_SCardAddReaderToGroupW(SmartcardEmulationContext* smartcard,
1070 SCARDCONTEXT hContext, LPCWSTR szReaderName,
1071 LPCWSTR szGroupName)
1073 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1075 if (status == SCARD_S_SUCCESS)
1076 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1078 WLog_Print(smartcard->log, smartcard->log_default_level,
1079 "SCardAddReaderToGroupW { hContext: %p", (
void*)hContext);
1081 WINPR_UNUSED(szGroupName);
1084 if (status == SCARD_S_SUCCESS)
1085 status = SCARD_E_UNSUPPORTED_FEATURE;
1087 WLog_Print(smartcard->log, smartcard->log_default_level,
1088 "SCardAddReaderToGroupW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1089 WINPR_CXX_COMPAT_CAST(UINT32, status));
1094LONG WINAPI Emulate_SCardRemoveReaderFromGroupA(SmartcardEmulationContext* smartcard,
1095 SCARDCONTEXT hContext, LPCSTR szReaderName,
1098 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1100 if (status == SCARD_S_SUCCESS)
1101 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
1103 WLog_Print(smartcard->log, smartcard->log_default_level,
1104 "SCardRemoveReaderFromGroupA { hContext: %p", (
void*)hContext);
1106 WINPR_UNUSED(szGroupName);
1109 if (status == SCARD_S_SUCCESS)
1110 status = SCARD_E_UNSUPPORTED_FEATURE;
1112 WLog_Print(smartcard->log, smartcard->log_default_level,
1113 "SCardRemoveReaderFromGroupA } status: %s (0x%08" PRIX32
")",
1114 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1119LONG WINAPI Emulate_SCardRemoveReaderFromGroupW(SmartcardEmulationContext* smartcard,
1120 SCARDCONTEXT hContext, LPCWSTR szReaderName,
1121 LPCWSTR szGroupName)
1123 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1125 if (status == SCARD_S_SUCCESS)
1126 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1128 WLog_Print(smartcard->log, smartcard->log_default_level,
1129 "SCardRemoveReaderFromGroupW { hContext: %p", (
void*)hContext);
1131 WINPR_UNUSED(szGroupName);
1134 if (status == SCARD_S_SUCCESS)
1135 status = SCARD_E_UNSUPPORTED_FEATURE;
1137 WLog_Print(smartcard->log, smartcard->log_default_level,
1138 "SCardRemoveReaderFromGroupW } status: %s (0x%08" PRIX32
")",
1139 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1144LONG WINAPI Emulate_SCardIntroduceCardTypeA(SmartcardEmulationContext* smartcard,
1145 SCARDCONTEXT hContext, LPCSTR szCardName,
1146 LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1147 DWORD dwInterfaceCount, LPCBYTE pbAtr,
1148 LPCBYTE pbAtrMask, DWORD cbAtrLen)
1150 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1152 WLog_Print(smartcard->log, smartcard->log_default_level,
1153 "SCardIntroduceCardTypeA { hContext: %p", (
void*)hContext);
1155 WINPR_UNUSED(szCardName);
1156 WINPR_UNUSED(pguidPrimaryProvider);
1157 WINPR_UNUSED(rgguidInterfaces);
1158 WINPR_UNUSED(dwInterfaceCount);
1159 WINPR_UNUSED(pbAtr);
1160 WINPR_UNUSED(pbAtrMask);
1161 WINPR_UNUSED(cbAtrLen);
1164 if (status == SCARD_S_SUCCESS)
1165 status = SCARD_E_UNSUPPORTED_FEATURE;
1167 WLog_Print(smartcard->log, smartcard->log_default_level,
1168 "SCardIntroduceCardTypeA } status: %s (0x%08" PRIX32
")",
1169 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1174LONG WINAPI Emulate_SCardIntroduceCardTypeW(SmartcardEmulationContext* smartcard,
1175 SCARDCONTEXT hContext, LPCWSTR szCardName,
1176 LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1177 DWORD dwInterfaceCount, LPCBYTE pbAtr,
1178 LPCBYTE pbAtrMask, DWORD cbAtrLen)
1180 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1182 WLog_Print(smartcard->log, smartcard->log_default_level,
1183 "SCardIntroduceCardTypeW { hContext: %p", (
void*)hContext);
1185 WINPR_UNUSED(szCardName);
1186 WINPR_UNUSED(pguidPrimaryProvider);
1187 WINPR_UNUSED(rgguidInterfaces);
1188 WINPR_UNUSED(dwInterfaceCount);
1189 WINPR_UNUSED(pbAtr);
1190 WINPR_UNUSED(pbAtrMask);
1191 WINPR_UNUSED(cbAtrLen);
1194 if (status == SCARD_S_SUCCESS)
1195 status = SCARD_E_UNSUPPORTED_FEATURE;
1197 WLog_Print(smartcard->log, smartcard->log_default_level,
1198 "SCardIntroduceCardTypeW } status: %s (0x%08" PRIX32
")",
1199 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1204LONG WINAPI Emulate_SCardSetCardTypeProviderNameA(SmartcardEmulationContext* smartcard,
1205 SCARDCONTEXT hContext, LPCSTR szCardName,
1206 DWORD dwProviderId, LPCSTR szProvider)
1208 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1210 WLog_Print(smartcard->log, smartcard->log_default_level,
1211 "SCardSetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
1213 WINPR_UNUSED(szCardName);
1214 WINPR_UNUSED(dwProviderId);
1215 WINPR_UNUSED(szProvider);
1218 if (status == SCARD_S_SUCCESS)
1219 status = SCARD_E_UNSUPPORTED_FEATURE;
1221 WLog_Print(smartcard->log, smartcard->log_default_level,
1222 "SCardSetCardTypeProviderNameA } status: %s (0x%08" PRIX32
")",
1223 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1228LONG WINAPI Emulate_SCardSetCardTypeProviderNameW(SmartcardEmulationContext* smartcard,
1229 SCARDCONTEXT hContext, LPCWSTR szCardName,
1230 DWORD dwProviderId, LPCWSTR szProvider)
1232 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1234 WLog_Print(smartcard->log, smartcard->log_default_level,
1235 "SCardSetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
1237 WINPR_UNUSED(szCardName);
1238 WINPR_UNUSED(dwProviderId);
1239 WINPR_UNUSED(szProvider);
1242 if (status == SCARD_S_SUCCESS)
1243 status = SCARD_E_UNSUPPORTED_FEATURE;
1245 WLog_Print(smartcard->log, smartcard->log_default_level,
1246 "SCardSetCardTypeProviderNameW } status: %s (0x%08" PRIX32
")",
1247 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1252LONG WINAPI Emulate_SCardForgetCardTypeA(SmartcardEmulationContext* smartcard,
1253 SCARDCONTEXT hContext, LPCSTR szCardName)
1255 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1257 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetCardTypeA { hContext: %p",
1260 WINPR_UNUSED(szCardName);
1263 if (status == SCARD_S_SUCCESS)
1264 status = SCARD_E_UNSUPPORTED_FEATURE;
1266 WLog_Print(smartcard->log, smartcard->log_default_level,
1267 "SCardForgetCardTypeA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1268 WINPR_CXX_COMPAT_CAST(UINT32, status));
1273LONG WINAPI Emulate_SCardForgetCardTypeW(SmartcardEmulationContext* smartcard,
1274 SCARDCONTEXT hContext, LPCWSTR szCardName)
1276 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1278 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetCardTypeW { hContext: %p",
1281 WINPR_UNUSED(szCardName);
1284 if (status == SCARD_S_SUCCESS)
1285 status = SCARD_E_UNSUPPORTED_FEATURE;
1287 WLog_Print(smartcard->log, smartcard->log_default_level,
1288 "SCardForgetCardTypeW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1289 WINPR_CXX_COMPAT_CAST(UINT32, status));
1294LONG WINAPI Emulate_SCardFreeMemory(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1297 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1299 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardFreeMemory { hContext: %p",
1302 if (status == SCARD_S_SUCCESS)
1304 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1305 WINPR_ASSERT(value);
1307 ArrayList_Remove(value->strings, pvMem);
1310 WLog_Print(smartcard->log, smartcard->log_default_level,
1311 "SCardFreeMemory } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1312 WINPR_CXX_COMPAT_CAST(UINT32, status));
1317HANDLE WINAPI Emulate_SCardAccessStartedEvent(SmartcardEmulationContext* smartcard)
1319 HANDLE hEvent =
nullptr;
1321 WINPR_ASSERT(smartcard);
1323 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAccessStartedEvent {");
1326 if (winpr_RAND((
void*)&hEvent,
sizeof(hEvent)) < 0)
1328 (void)fprintf(stderr,
"winpr_RAND failed.\n");
1331 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAccessStartedEvent } hEvent: %p",
1337void WINAPI Emulate_SCardReleaseStartedEvent(SmartcardEmulationContext* smartcard)
1339 WINPR_ASSERT(smartcard);
1341 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseStartedEvent {");
1345 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseStartedEvent }");
1348LONG WINAPI Emulate_SCardLocateCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1352 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1354 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardLocateCardsA { hContext: %p",
1357 WINPR_UNUSED(mszCards);
1358 WINPR_UNUSED(rgReaderStates);
1359 WINPR_UNUSED(cReaders);
1362 if (status == SCARD_S_SUCCESS)
1363 status = SCARD_E_UNSUPPORTED_FEATURE;
1365 WLog_Print(smartcard->log, smartcard->log_default_level,
1366 "SCardLocateCardsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1367 WINPR_CXX_COMPAT_CAST(UINT32, status));
1372LONG WINAPI Emulate_SCardLocateCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1376 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1378 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardLocateCardsW { hContext: %p",
1381 WINPR_UNUSED(mszCards);
1382 WINPR_UNUSED(rgReaderStates);
1383 WINPR_UNUSED(cReaders);
1386 if (status == SCARD_S_SUCCESS)
1387 status = SCARD_E_UNSUPPORTED_FEATURE;
1389 WLog_Print(smartcard->log, smartcard->log_default_level,
1390 "SCardLocateCardsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1391 WINPR_CXX_COMPAT_CAST(UINT32, status));
1396LONG WINAPI Emulate_SCardLocateCardsByATRA(SmartcardEmulationContext* smartcard,
1401 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1403 WLog_Print(smartcard->log, smartcard->log_default_level,
1404 "SCardLocateCardsByATRA { hContext: %p", (
void*)hContext);
1406 WINPR_UNUSED(rgAtrMasks);
1407 WINPR_UNUSED(cAtrs);
1408 WINPR_UNUSED(rgReaderStates);
1409 WINPR_UNUSED(cReaders);
1412 if (status == SCARD_S_SUCCESS)
1413 status = SCARD_E_UNSUPPORTED_FEATURE;
1415 WLog_Print(smartcard->log, smartcard->log_default_level,
1416 "SCardLocateCardsByATRA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1417 WINPR_CXX_COMPAT_CAST(UINT32, status));
1422LONG WINAPI Emulate_SCardLocateCardsByATRW(SmartcardEmulationContext* smartcard,
1427 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1429 WLog_Print(smartcard->log, smartcard->log_default_level,
1430 "SCardLocateCardsByATRW { hContext: %p", (
void*)hContext);
1432 WINPR_UNUSED(rgAtrMasks);
1433 WINPR_UNUSED(cAtrs);
1434 WINPR_UNUSED(rgReaderStates);
1435 WINPR_UNUSED(cReaders);
1438 if (status == SCARD_S_SUCCESS)
1439 status = SCARD_E_UNSUPPORTED_FEATURE;
1441 WLog_Print(smartcard->log, smartcard->log_default_level,
1442 "SCardLocateCardsByATRW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1443 WINPR_CXX_COMPAT_CAST(UINT32, status));
1448LONG WINAPI Emulate_SCardGetStatusChangeA(SmartcardEmulationContext* smartcard,
1449 SCARDCONTEXT hContext, DWORD dwTimeout,
1452 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1454 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetStatusChangeA { hContext: %p",
1457 if (status == SCARD_S_SUCCESS)
1459 const DWORD diff = 100;
1460 size_t eventCount = 0;
1461 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1462 WINPR_ASSERT(value);
1464 InterlockedIncrement(&value->semaphore);
1469 status = SCARD_E_TIMEOUT;
1472 for (
size_t x = 0; x < cReaders; x++)
1476 for (
size_t y = 0; y < MAX_EMULATED_READERS; y++)
1479 if (out->szReader && in->szReader && (strcmp(out->szReader, in->szReader) == 0))
1481 HashTable_Lock(smartcard->handles);
1482 const SCardHandle* hdl = find_reader(smartcard, in->szReader, FALSE);
1483 out->dwEventState = in->dwEventState;
1486 out->dwEventState |= SCARD_STATE_INUSE;
1487 if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1488 out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1490 HashTable_Unlock(smartcard->handles);
1491 if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1492 (out->dwCurrentState & SCARD_STATE_EMPTY))
1493 out->dwEventState |= SCARD_STATE_CHANGED;
1494 if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1495 (out->dwCurrentState & SCARD_STATE_PRESENT))
1496 out->dwEventState |= SCARD_STATE_CHANGED;
1498 out->cbAtr = in->cbAtr;
1499 memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1500 if (out->dwEventState & SCARD_STATE_CHANGED)
1505 if (value->canceled)
1507 status = SCARD_E_CANCELLED;
1510 if (eventCount != 0)
1512 status = SCARD_S_SUCCESS;
1516 if (dwTimeout != INFINITE)
1517 dwTimeout -= MIN(dwTimeout, diff);
1518 if (freerdp_shall_disconnect_context(inst->context))
1520 status = SCARD_E_CANCELLED;
1523 }
while (dwTimeout > 0);
1524 InterlockedDecrement(&value->semaphore);
1527 WLog_Print(smartcard->log, smartcard->log_default_level,
1528 "SCardGetStatusChangeA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1529 WINPR_CXX_COMPAT_CAST(UINT32, status));
1534LONG WINAPI Emulate_SCardGetStatusChangeW(SmartcardEmulationContext* smartcard,
1535 SCARDCONTEXT hContext, DWORD dwTimeout,
1538 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1540 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetStatusChangeW { hContext: %p",
1543 if (status == SCARD_S_SUCCESS)
1545 const DWORD diff = 100;
1546 size_t eventCount = 0;
1547 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1548 WINPR_ASSERT(value);
1550 InterlockedIncrement(&value->semaphore);
1554 status = SCARD_E_TIMEOUT;
1557 for (
size_t x = 0; x < cReaders; x++)
1561 for (
size_t y = 0; y < MAX_EMULATED_READERS; y++)
1564 if (out->szReader && in->szReader &&
1565 (_wcscmp(out->szReader, in->szReader) == 0))
1567 HashTable_Lock(smartcard->handles);
1568 const SCardHandle* hdl = find_reader(smartcard, in->szReader, TRUE);
1569 out->dwEventState = in->dwEventState;
1572 out->dwEventState |= SCARD_STATE_INUSE;
1573 if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1574 out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1576 HashTable_Unlock(smartcard->handles);
1577 if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1578 (out->dwCurrentState & SCARD_STATE_EMPTY))
1579 out->dwEventState |= SCARD_STATE_CHANGED;
1580 if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1581 (out->dwCurrentState & SCARD_STATE_PRESENT))
1582 out->dwEventState |= SCARD_STATE_CHANGED;
1583 out->cbAtr = in->cbAtr;
1584 memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1586 if (out->dwEventState & SCARD_STATE_CHANGED)
1591 if (value->canceled)
1593 status = SCARD_E_CANCELLED;
1596 if (eventCount != 0)
1598 status = SCARD_S_SUCCESS;
1602 if (dwTimeout != INFINITE)
1603 dwTimeout -= MIN(dwTimeout, diff);
1604 if (freerdp_shall_disconnect_context(inst->context))
1606 status = SCARD_E_CANCELLED;
1609 }
while (dwTimeout > 0);
1610 InterlockedDecrement(&value->semaphore);
1613 WLog_Print(smartcard->log, smartcard->log_default_level,
1614 "SCardGetStatusChangeW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1615 WINPR_CXX_COMPAT_CAST(UINT32, status));
1620LONG WINAPI Emulate_SCardCancel(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
1622 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1624 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancel { hContext: %p",
1627 if (status == SCARD_S_SUCCESS)
1629 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1630 WINPR_ASSERT(value);
1631 value->canceled = TRUE;
1633 waitForCancel(value);
1636 WLog_Print(smartcard->log, smartcard->log_default_level,
1637 "SCardCancel } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1638 WINPR_CXX_COMPAT_CAST(UINT32, status));
1643SCardHandle* find_reader(SmartcardEmulationContext* smartcard,
const void* szReader, BOOL unicode)
1645 SCardHandle* hdl =
nullptr;
1646 ULONG_PTR* keys =
nullptr;
1648 WINPR_ASSERT(smartcard);
1649 const size_t count = HashTable_GetKeys(smartcard->handles, &keys);
1650 for (
size_t x = 0; x < count; x++)
1652 SCardHandle* cur = HashTable_GetItemValue(smartcard->handles, (
const void*)keys[x]);
1662 if (cur->unicode != unicode)
1664 if (!unicode && (strcmp(cur->szReader.pc, szReader) != 0))
1666 if (unicode && (_wcscmp(cur->szReader.pw, szReader) != 0))
1675WINPR_ATTR_MALLOC(scard_handle_free, 1)
1676static SCardHandle* reader2handle(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1677 const
void* szReader, BOOL unicode, DWORD dwShareMode,
1678 SCARDHANDLE* phCard, DWORD dwPreferredProtocols,
1679 LPDWORD pdwActiveProtocol)
1681 WINPR_ASSERT(phCard);
1682 SCardHandle* hdl =
nullptr;
1685 if (Emulate_SCardIsValidContext(smartcard, hContext) != SCARD_S_SUCCESS)
1688 hdl = scard_handle_new(smartcard, hContext, szReader, unicode);
1692 if (winpr_RAND(&hdl->card,
sizeof(hdl->card)) < 0)
1694 scard_handle_free(hdl);
1698 hdl->dwActiveProtocol = SCARD_PROTOCOL_T1;
1699 hdl->dwShareMode = dwShareMode;
1701 DWORD activeProtocol = 0;
1702 if (pdwActiveProtocol)
1704 if ((hdl->dwActiveProtocol & dwPreferredProtocols) == 0)
1706 scard_handle_free(hdl);
1711 activeProtocol = hdl->dwActiveProtocol;
1714 if (!HashTable_Insert(smartcard->handles, (
const void*)hdl->card, hdl))
1716 scard_handle_free(hdl);
1721 hdl->referencecount++;
1722 *pdwActiveProtocol = activeProtocol;
1723 *phCard = hdl->card;
1726 WLog_Print(smartcard->log, smartcard->log_default_level,
"{ %p }", (
void*)*phCard);
1730LONG WINAPI Emulate_SCardConnectA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1731 LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1732 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1734 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1736 if (!phCard || !pdwActiveProtocol)
1737 status = SCARD_E_INVALID_PARAMETER;
1739 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectA { hContext: %p",
1742 if (status == SCARD_S_SUCCESS)
1744 if (!reader2handle(smartcard, hContext, szReader, FALSE, dwShareMode, phCard,
1745 dwPreferredProtocols, pdwActiveProtocol))
1746 status = SCARD_E_NO_MEMORY;
1749 WLog_Print(smartcard->log, smartcard->log_default_level,
1750 "SCardConnectA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1751 WINPR_CXX_COMPAT_CAST(UINT32, status));
1756LONG WINAPI Emulate_SCardConnectW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1757 LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1758 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1760 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1762 if (!phCard || !pdwActiveProtocol)
1763 status = SCARD_E_INVALID_PARAMETER;
1765 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectW { hContext: %p",
1768 if (status == SCARD_S_SUCCESS)
1770 if (!reader2handle(smartcard, hContext, szReader, TRUE, dwShareMode, phCard,
1771 dwPreferredProtocols, pdwActiveProtocol))
1772 status = SCARD_E_NO_MEMORY;
1775 WLog_Print(smartcard->log, smartcard->log_default_level,
1776 "SCardConnectW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1777 WINPR_CXX_COMPAT_CAST(UINT32, status));
1782LONG WINAPI Emulate_SCardReconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1783 DWORD dwShareMode, WINPR_ATTR_UNUSED DWORD dwPreferredProtocols,
1784 WINPR_ATTR_UNUSED DWORD dwInitialization,
1785 LPDWORD pdwActiveProtocol)
1787 LONG status = scard_handle_valid(smartcard, hCard);
1789 if (!pdwActiveProtocol)
1790 status = SCARD_E_INVALID_PARAMETER;
1792 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReconnect { hCard: %p",
1795 if (status == SCARD_S_SUCCESS)
1797 HashTable_Lock(smartcard->handles);
1798 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1802 hdl->dwShareMode = dwShareMode;
1803 hdl->transaction = FALSE;
1805 *pdwActiveProtocol = hdl->dwActiveProtocol;
1806 HashTable_Unlock(smartcard->handles);
1809 WLog_Print(smartcard->log, smartcard->log_default_level,
1810 "SCardReconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1811 WINPR_CXX_COMPAT_CAST(UINT32, status));
1816LONG WINAPI Emulate_SCardDisconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1817 DWORD dwDisposition)
1819 LONG status = scard_handle_valid(smartcard, hCard);
1821 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDisconnect { hCard: %p",
1824 WINPR_UNUSED(dwDisposition);
1826 if (status == SCARD_S_SUCCESS)
1828 HashTable_Lock(smartcard->handles);
1829 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1832 hdl->referencecount--;
1833 if (hdl->referencecount == 0)
1834 HashTable_Remove(smartcard->handles, (
const void*)hCard);
1835 HashTable_Unlock(smartcard->handles);
1838 WLog_Print(smartcard->log, smartcard->log_default_level,
1839 "SCardDisconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1840 WINPR_CXX_COMPAT_CAST(UINT32, status));
1845LONG WINAPI Emulate_SCardBeginTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1847 LONG status = scard_handle_valid(smartcard, hCard);
1849 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardBeginTransaction { hCard: %p",
1852 if (status == SCARD_S_SUCCESS)
1854 HashTable_Lock(smartcard->handles);
1855 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1857 if (hdl->transaction)
1858 status = SCARD_E_INVALID_VALUE;
1860 hdl->transaction = TRUE;
1861 HashTable_Unlock(smartcard->handles);
1864 WLog_Print(smartcard->log, smartcard->log_default_level,
1865 "SCardBeginTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1866 WINPR_CXX_COMPAT_CAST(UINT32, status));
1871LONG WINAPI Emulate_SCardEndTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1872 DWORD dwDisposition)
1874 LONG status = scard_handle_valid(smartcard, hCard);
1876 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardEndTransaction { hCard: %p",
1879 WINPR_UNUSED(dwDisposition);
1881 if (status == SCARD_S_SUCCESS)
1883 HashTable_Lock(smartcard->handles);
1884 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1886 if (!hdl->transaction)
1887 status = SCARD_E_NOT_TRANSACTED;
1889 hdl->transaction = FALSE;
1890 HashTable_Unlock(smartcard->handles);
1893 WLog_Print(smartcard->log, smartcard->log_default_level,
1894 "SCardEndTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1895 WINPR_CXX_COMPAT_CAST(UINT32, status));
1900LONG WINAPI Emulate_SCardCancelTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1902 LONG status = scard_handle_valid(smartcard, hCard);
1904 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancelTransaction { hCard: %p",
1907 if (status == SCARD_S_SUCCESS)
1909 HashTable_Lock(smartcard->handles);
1910 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1912 if (!hdl->transaction)
1913 status = SCARD_E_NOT_TRANSACTED;
1915 hdl->transaction = FALSE;
1916 HashTable_Unlock(smartcard->handles);
1919 WLog_Print(smartcard->log, smartcard->log_default_level,
1920 "SCardCancelTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1921 WINPR_CXX_COMPAT_CAST(UINT32, status));
1926LONG WINAPI Emulate_SCardState(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1927 LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
1930 LONG status = scard_handle_valid(smartcard, hCard);
1932 if (!pdwState || !pdwProtocol)
1933 status = SCARD_E_INVALID_PARAMETER;
1935 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardState { hCard: %p",
1938 if (status == SCARD_S_SUCCESS)
1940 HashTable_Lock(smartcard->handles);
1941 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1945 *pdwState = SCARD_SPECIFIC;
1947 *pdwProtocol = SCARD_PROTOCOL_T1;
1952 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1955 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1961 if (_wcscmp(readerW->szReader, hdl->szReader.pw) == 0)
1963 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerW->rgbAtr,
1969 if (strcmp(readerA->szReader, hdl->szReader.pc) == 0)
1971 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerA->rgbAtr,
1977 HashTable_Unlock(smartcard->handles);
1980 WLog_Print(smartcard->log, smartcard->log_default_level,
1981 "SCardState } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1982 WINPR_CXX_COMPAT_CAST(UINT32, status));
1987LONG WINAPI Emulate_SCardStatusA(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1988 LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1989 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1991 LONG status = scard_handle_valid(smartcard, hCard);
1993 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusA { hCard: %p",
1996 if (status == SCARD_S_SUCCESS)
1998 SCardContext* ctx =
nullptr;
1999 HashTable_Lock(smartcard->handles);
2000 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2003 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
2008 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pc,
2009 (UINT32)strlen(hdl->szReader.pc) + 2);
2012 *pdwState = SCARD_SPECIFIC;
2014 *pdwProtocol = SCARD_PROTOCOL_T1;
2018 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
2021 if (strcmp(reader->szReader, hdl->szReader.pc) == 0)
2024 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
2028 HashTable_Unlock(smartcard->handles);
2031 WLog_Print(smartcard->log, smartcard->log_default_level,
2032 "SCardStatusA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2033 WINPR_CXX_COMPAT_CAST(UINT32, status));
2038LONG WINAPI Emulate_SCardStatusW(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2039 LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
2040 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
2042 LONG status = scard_handle_valid(smartcard, hCard);
2044 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusW { hCard: %p",
2047 if (status == SCARD_S_SUCCESS)
2049 SCardContext* ctx =
nullptr;
2050 HashTable_Lock(smartcard->handles);
2051 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2054 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
2059 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pw,
2060 (UINT32)(_wcslen(hdl->szReader.pw) + 2) *
sizeof(WCHAR)) /
2064 *pdwState = SCARD_SPECIFIC;
2066 *pdwProtocol = SCARD_PROTOCOL_T1;
2070 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
2073 if (_wcscmp(reader->szReader, hdl->szReader.pw) == 0)
2075 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
2078 HashTable_Unlock(smartcard->handles);
2081 WLog_Print(smartcard->log, smartcard->log_default_level,
2082 "SCardStatusW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2083 WINPR_CXX_COMPAT_CAST(UINT32, status));
2088LONG WINAPI Emulate_SCardTransmit(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2091 LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
2093 LONG status = scard_handle_valid(smartcard, hCard);
2095 if (!pioSendPci || !pbSendBuffer || !pbRecvBuffer || !pcbRecvLength)
2096 status = SCARD_E_INVALID_PARAMETER;
2098 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardTransmit { hCard: %p",
2101 if (status == SCARD_S_SUCCESS)
2103 BYTE* response =
nullptr;
2104 DWORD responseSize = 0;
2105 HashTable_Lock(smartcard->handles);
2106 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2109 hdl->transmitcount++;
2111 if (!vgids_process_apdu(hdl->vgids, pbSendBuffer, cbSendLength, &response, &responseSize))
2112 status = SCARD_E_NO_SMARTCARD;
2116 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
2120 scard_copy_strings(ctx, pbRecvBuffer, *pcbRecvLength, response, responseSize);
2125 pioRecvPci->dwProtocol = hdl->dwActiveProtocol;
2127 HashTable_Unlock(smartcard->handles);
2130 WLog_Print(smartcard->log, smartcard->log_default_level,
2131 "SCardTransmit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2132 WINPR_CXX_COMPAT_CAST(UINT32, status));
2137LONG WINAPI Emulate_SCardGetTransmitCount(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2138 LPDWORD pcTransmitCount)
2140 LONG status = scard_handle_valid(smartcard, hCard);
2142 if (!pcTransmitCount)
2143 status = SCARD_E_INVALID_PARAMETER;
2145 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetTransmitCount { hCard: %p",
2148 if (status == SCARD_S_SUCCESS)
2150 HashTable_Lock(smartcard->handles);
2151 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2154 *pcTransmitCount = hdl->transmitcount;
2155 HashTable_Unlock(smartcard->handles);
2158 WLog_Print(smartcard->log, smartcard->log_default_level,
2159 "SCardGetTransmitCount } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2160 WINPR_CXX_COMPAT_CAST(UINT32, status));
2165LONG WINAPI Emulate_SCardControl(
2166 SmartcardEmulationContext* smartcard, SCARDHANDLE hCard, DWORD dwControlCode,
2167 LPCVOID lpInBuffer, DWORD cbInBufferSize, LPVOID lpOutBuffer, DWORD cbOutBufferSize,
2168 LPDWORD lpBytesReturned )
2170 LONG status = scard_handle_valid(smartcard, hCard);
2172 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardControl { hCard: %p",
2175 if (status == SCARD_S_SUCCESS)
2177 WINPR_UNUSED(dwControlCode);
2178 WINPR_UNUSED(lpInBuffer);
2179 WINPR_UNUSED(cbInBufferSize);
2180 WINPR_UNUSED(lpOutBuffer);
2181 WINPR_UNUSED(cbOutBufferSize);
2182 WINPR_UNUSED(lpBytesReturned);
2185 status = SCARD_E_UNSUPPORTED_FEATURE;
2188 WLog_Print(smartcard->log, smartcard->log_default_level,
2189 "SCardControl } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2190 WINPR_CXX_COMPAT_CAST(UINT32, status));
2195LONG WINAPI Emulate_SCardGetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2198 LPDWORD pcbAttrLen )
2200 LONG status = scard_handle_valid(smartcard, hCard);
2202 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetAttrib { hCard: %p",
2205 WINPR_UNUSED(dwAttrId);
2206 WINPR_UNUSED(pbAttr);
2207 WINPR_UNUSED(pcbAttrLen);
2210 if (status == SCARD_S_SUCCESS)
2211 status = SCARD_F_INTERNAL_ERROR;
2213 WLog_Print(smartcard->log, smartcard->log_default_level,
2214 "SCardGetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2215 WINPR_CXX_COMPAT_CAST(UINT32, status));
2220LONG WINAPI Emulate_SCardSetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2221 DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
2223 LONG status = scard_handle_valid(smartcard, hCard);
2225 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardSetAttrib { hCard: %p",
2228 WINPR_UNUSED(dwAttrId);
2229 WINPR_UNUSED(pbAttr);
2230 WINPR_UNUSED(cbAttrLen);
2233 if (status == SCARD_S_SUCCESS)
2234 status = SCARD_F_INTERNAL_ERROR;
2236 WLog_Print(smartcard->log, smartcard->log_default_level,
2237 "SCardSetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2238 WINPR_CXX_COMPAT_CAST(UINT32, status));
2243LONG WINAPI Emulate_SCardUIDlgSelectCardA(SmartcardEmulationContext* smartcard,
2244 LPOPENCARDNAMEA_EX pDlgStruc)
2248 WINPR_ASSERT(smartcard);
2250 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardA {");
2252 WINPR_UNUSED(pDlgStruc);
2255 status = SCARD_E_UNSUPPORTED_FEATURE;
2257 WLog_Print(smartcard->log, smartcard->log_default_level,
2258 "SCardUIDlgSelectCardA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2259 WINPR_CXX_COMPAT_CAST(UINT32, status));
2264LONG WINAPI Emulate_SCardUIDlgSelectCardW(SmartcardEmulationContext* smartcard,
2265 LPOPENCARDNAMEW_EX pDlgStruc)
2269 WINPR_ASSERT(smartcard);
2271 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardW {");
2273 WINPR_UNUSED(pDlgStruc);
2276 status = SCARD_E_UNSUPPORTED_FEATURE;
2278 WLog_Print(smartcard->log, smartcard->log_default_level,
2279 "SCardUIDlgSelectCardW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2280 WINPR_CXX_COMPAT_CAST(UINT32, status));
2285LONG WINAPI Emulate_GetOpenCardNameA(SmartcardEmulationContext* smartcard,
2290 WINPR_ASSERT(smartcard);
2292 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameA {");
2294 WINPR_UNUSED(pDlgStruc);
2297 status = SCARD_E_UNSUPPORTED_FEATURE;
2299 WLog_Print(smartcard->log, smartcard->log_default_level,
2300 "GetOpenCardNameA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2301 WINPR_CXX_COMPAT_CAST(UINT32, status));
2306LONG WINAPI Emulate_GetOpenCardNameW(SmartcardEmulationContext* smartcard,
2311 WINPR_ASSERT(smartcard);
2313 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameW {");
2315 WINPR_UNUSED(pDlgStruc);
2318 status = SCARD_E_UNSUPPORTED_FEATURE;
2320 WLog_Print(smartcard->log, smartcard->log_default_level,
2321 "GetOpenCardNameW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2322 WINPR_CXX_COMPAT_CAST(UINT32, status));
2327LONG WINAPI Emulate_SCardDlgExtendedError(SmartcardEmulationContext* smartcard)
2331 WINPR_ASSERT(smartcard);
2333 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDlgExtendedError {");
2336 status = SCARD_E_UNSUPPORTED_FEATURE;
2338 WLog_Print(smartcard->log, smartcard->log_default_level,
2339 "SCardDlgExtendedError } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2340 WINPR_CXX_COMPAT_CAST(UINT32, status));
2345LONG WINAPI Emulate_SCardReadCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2346 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2347 PBYTE Data, DWORD* DataLen)
2350 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2352 if (!CardIdentifier || !DataLen)
2353 status = SCARD_E_INVALID_PARAMETER;
2355 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheA { hContext: %p",
2364 if (status == SCARD_S_SUCCESS)
2366 SCardCacheItem* data =
nullptr;
2367 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2368 WINPR_ASSERT(value);
2370 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2372 data = HashTable_GetItemValue(value->cache,
id);
2376 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2377 else if (data->freshness != FreshnessCounter)
2378 status = SCARD_W_CACHE_ITEM_STALE;
2380 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2383 WLog_Print(smartcard->log, smartcard->log_default_level,
2384 "SCardReadCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2385 WINPR_CXX_COMPAT_CAST(UINT32, status));
2390LONG WINAPI Emulate_SCardReadCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2391 UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName,
2392 PBYTE Data, DWORD* DataLen)
2395 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2397 if (!CardIdentifier || !DataLen)
2398 status = SCARD_E_INVALID_PARAMETER;
2400 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheW { hContext: %p",
2409 if (status == SCARD_S_SUCCESS)
2411 SCardCacheItem* data =
nullptr;
2412 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2413 WINPR_ASSERT(value);
2415 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2416 data = HashTable_GetItemValue(value->cache,
id);
2419 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2420 else if (data->freshness != FreshnessCounter)
2421 status = SCARD_W_CACHE_ITEM_STALE;
2423 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2426 WLog_Print(smartcard->log, smartcard->log_default_level,
2427 "SCardReadCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2428 WINPR_CXX_COMPAT_CAST(UINT32, status));
2434static LONG insert_data(wHashTable* table, DWORD FreshnessCounter,
const char* key,
2435 const PBYTE Data, DWORD DataLen)
2438 SCardCacheItem* item =
nullptr;
2440 WINPR_ASSERT(table);
2443 if (DataLen > MAX_CACHE_ITEM_SIZE)
2444 return SCARD_W_CACHE_ITEM_TOO_BIG;
2446 if (HashTable_Count(table) > MAX_CACHE_ITEM_VALUES)
2447 return SCARD_E_WRITE_TOO_MANY;
2449 item = HashTable_GetItemValue(table, key);
2452 item = calloc(1,
sizeof(SCardCacheItem));
2454 return SCARD_E_NO_MEMORY;
2456 rc = HashTable_Insert(table, key, item);
2460 return SCARD_E_NO_MEMORY;
2464 if (item->freshness > FreshnessCounter)
2465 return SCARD_W_CACHE_ITEM_STALE;
2466 item->freshness = FreshnessCounter;
2467 item->size = DataLen;
2468 memcpy(item->data, Data, DataLen);
2471 return SCARD_S_SUCCESS;
2474LONG WINAPI Emulate_SCardWriteCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2475 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2476 PBYTE Data, DWORD DataLen)
2478 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2480 if (!CardIdentifier)
2481 status = SCARD_E_INVALID_PARAMETER;
2483 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheA { hContext: %p",
2486 if (status == SCARD_S_SUCCESS)
2488 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2489 WINPR_ASSERT(value);
2491 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2493 status = SCARD_E_NO_MEMORY;
2496 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2501 WLog_Print(smartcard->log, smartcard->log_default_level,
2502 "SCardWriteCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2503 WINPR_CXX_COMPAT_CAST(UINT32, status));
2508LONG WINAPI Emulate_SCardWriteCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2509 UUID* CardIdentifier, DWORD FreshnessCounter,
2510 LPWSTR LookupName, PBYTE Data, DWORD DataLen)
2512 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2514 if (!CardIdentifier)
2515 status = SCARD_E_INVALID_PARAMETER;
2517 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheW { hContext: %p",
2520 if (status == SCARD_S_SUCCESS)
2522 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2523 WINPR_ASSERT(value);
2525 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2527 status = SCARD_E_NO_MEMORY;
2530 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2535 WLog_Print(smartcard->log, smartcard->log_default_level,
2536 "SCardWriteCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2537 WINPR_CXX_COMPAT_CAST(UINT32, status));
2542LONG WINAPI Emulate_SCardGetReaderIconA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2543 LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2545 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2547 if (!szReaderName || !pcbIcon)
2548 status = SCARD_E_INVALID_PARAMETER;
2550 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconA { hContext: %p",
2553 if (status == SCARD_S_SUCCESS)
2554 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2556 if (status == SCARD_S_SUCCESS)
2558 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2562 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2563 resources_FreeRDP_ico_len);
2565 *pcbIcon = resources_FreeRDP_ico_len;
2568 WLog_Print(smartcard->log, smartcard->log_default_level,
2569 "SCardGetReaderIconA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2570 WINPR_CXX_COMPAT_CAST(UINT32, status));
2575LONG WINAPI Emulate_SCardGetReaderIconW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2576 LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2578 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2580 if (!szReaderName || !pcbIcon)
2581 status = SCARD_E_INVALID_PARAMETER;
2583 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconW { hContext: %p",
2586 if (status == SCARD_S_SUCCESS)
2587 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2589 if (status == SCARD_S_SUCCESS)
2591 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2595 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2596 resources_FreeRDP_ico_len);
2598 *pcbIcon = resources_FreeRDP_ico_len;
2601 WLog_Print(smartcard->log, smartcard->log_default_level,
2602 "SCardGetReaderIconW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2603 WINPR_CXX_COMPAT_CAST(UINT32, status));
2608LONG WINAPI Emulate_SCardGetDeviceTypeIdA(SmartcardEmulationContext* smartcard,
2609 SCARDCONTEXT hContext, LPCSTR szReaderName,
2610 LPDWORD pdwDeviceTypeId)
2612 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2614 if (!pdwDeviceTypeId)
2615 status = SCARD_E_INVALID_PARAMETER;
2617 if (status == SCARD_S_SUCCESS)
2618 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2620 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdA { hContext: %p",
2623 if (status == SCARD_S_SUCCESS)
2625 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2628 WLog_Print(smartcard->log, smartcard->log_default_level,
2629 "SCardGetDeviceTypeIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2630 WINPR_CXX_COMPAT_CAST(UINT32, status));
2635LONG WINAPI Emulate_SCardGetDeviceTypeIdW(SmartcardEmulationContext* smartcard,
2636 SCARDCONTEXT hContext, LPCWSTR szReaderName,
2637 LPDWORD pdwDeviceTypeId)
2639 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2641 if (!pdwDeviceTypeId)
2642 status = SCARD_E_INVALID_PARAMETER;
2644 if (status == SCARD_S_SUCCESS)
2645 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2647 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdW { hContext: %p",
2650 if (status == SCARD_S_SUCCESS)
2652 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2655 WLog_Print(smartcard->log, smartcard->log_default_level,
2656 "SCardGetDeviceTypeIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2657 WINPR_CXX_COMPAT_CAST(UINT32, status));
2662LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdA(
2663 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szReaderName,
2664 LPSTR szDeviceInstanceId ,
2665 LPDWORD pcchDeviceInstanceId )
2667 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2669 if (status == SCARD_S_SUCCESS)
2670 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2672 WLog_Print(smartcard->log, smartcard->log_default_level,
2673 "SCardGetReaderDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2675 WINPR_UNUSED(szDeviceInstanceId);
2676 WINPR_UNUSED(pcchDeviceInstanceId);
2679 if (status == SCARD_S_SUCCESS)
2680 status = SCARD_E_UNSUPPORTED_FEATURE;
2682 WLog_Print(smartcard->log, smartcard->log_default_level,
2683 "SCardGetReaderDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2684 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2689LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdW(
2690 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szReaderName,
2691 LPWSTR szDeviceInstanceId ,
2692 LPDWORD pcchDeviceInstanceId )
2694 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2696 if (status == SCARD_S_SUCCESS)
2697 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2699 WLog_Print(smartcard->log, smartcard->log_default_level,
2700 "SCardGetReaderDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2702 WINPR_UNUSED(szDeviceInstanceId);
2703 WINPR_UNUSED(pcchDeviceInstanceId);
2706 if (status == SCARD_S_SUCCESS)
2707 status = SCARD_E_UNSUPPORTED_FEATURE;
2709 WLog_Print(smartcard->log, smartcard->log_default_level,
2710 "SCardGetReaderDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2711 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2716LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdA(
2717 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szDeviceInstanceId,
2719 LPDWORD pcchReaders )
2721 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2723 WLog_Print(smartcard->log, smartcard->log_default_level,
2724 "SCardListReadersWithDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2726 WINPR_UNUSED(szDeviceInstanceId);
2727 WINPR_UNUSED(mszReaders);
2728 WINPR_UNUSED(pcchReaders);
2731 if (status == SCARD_S_SUCCESS)
2732 status = SCARD_E_UNSUPPORTED_FEATURE;
2734 WLog_Print(smartcard->log, smartcard->log_default_level,
2735 "SCardListReadersWithDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2736 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2741LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdW(
2742 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szDeviceInstanceId,
2743 LPWSTR mszReaders , LPDWORD pcchReaders)
2745 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2747 WLog_Print(smartcard->log, smartcard->log_default_level,
2748 "SCardListReadersWithDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2750 WINPR_UNUSED(szDeviceInstanceId);
2751 WINPR_UNUSED(mszReaders);
2752 WINPR_UNUSED(pcchReaders);
2755 if (status == SCARD_S_SUCCESS)
2756 status = SCARD_E_UNSUPPORTED_FEATURE;
2758 WLog_Print(smartcard->log, smartcard->log_default_level,
2759 "SCardListReadersWithDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2760 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2765LONG WINAPI Emulate_SCardAudit(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2768 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2770 WINPR_UNUSED(dwEvent);
2772 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAudit { hContext: %p",
2776 if (status == SCARD_S_SUCCESS)
2777 status = SCARD_E_UNSUPPORTED_FEATURE;
2779 WLog_Print(smartcard->log, smartcard->log_default_level,
2780 "SCardAudit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2781 WINPR_CXX_COMPAT_CAST(UINT32, status));
2787static BOOL context_equals(
const void* pva,
const void* pvb)
2789 const SCARDCONTEXT a = (
const SCARDCONTEXT)pva;
2790 const SCARDCONTEXT b = (
const SCARDCONTEXT)pvb;
2800static BOOL handle_equals(
const void* pva,
const void* pvb)
2802 const SCARDHANDLE a = (
const SCARDHANDLE)pva;
2803 const SCARDHANDLE b = (
const SCARDHANDLE)pvb;
2812static void entry_free(
void* ptr)
2814 SmartcardPinCounterEntry* entry = ptr;
2818 winpr_zfree(entry->pin);
2822WINPR_ATTR_MALLOC(entry_free, 1)
2823static
void* entry_clone(const
void* other)
2825 const SmartcardPinCounterEntry* entry = other;
2829 SmartcardPinCounterEntry* clone = calloc(1,
sizeof(SmartcardPinCounterEntry));
2835 clone->pin = _strdup(entry->pin);
2845SmartcardEmulationContext* Emulate_New(
const rdpSettings* settings)
2847 SmartcardEmulationContext* smartcard =
nullptr;
2849 WINPR_ASSERT(settings);
2851 smartcard = calloc(1,
sizeof(SmartcardEmulationContext));
2855 smartcard->settings = settings;
2856 smartcard->log = WLog_Get(
"EmulateSCard");
2857 if (!smartcard->log)
2859 smartcard->log_default_level = WLOG_TRACE;
2861 smartcard->contexts = HashTable_New(FALSE);
2862 if (!smartcard->contexts)
2866 wObject* obj = HashTable_KeyObject(smartcard->contexts);
2870 if (!smartcard->contexts)
2874 wObject* obj = HashTable_ValueObject(smartcard->contexts);
2879 smartcard->handles = HashTable_New(TRUE);
2880 if (!smartcard->handles)
2884 wObject* obj = HashTable_KeyObject(smartcard->handles);
2888 if (!smartcard->handles)
2892 wObject* obj = HashTable_ValueObject(smartcard->handles);
2897 smartcard->pinCounters = HashTable_New(TRUE);
2898 if (!smartcard->pinCounters)
2900 else if (!HashTable_SetupForStringData(smartcard->pinCounters, FALSE))
2904 wObject* obj = HashTable_ValueObject(smartcard->pinCounters);
2913 WINPR_PRAGMA_DIAG_PUSH
2914 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2915 Emulate_Free(smartcard);
2916 WINPR_PRAGMA_DIAG_POP
2920void Emulate_Free(SmartcardEmulationContext* context)
2925 HashTable_Free(context->handles);
2926 HashTable_Free(context->contexts);
2927 HashTable_Free(context->pinCounters);
2931BOOL Emulate_IsConfigured(SmartcardEmulationContext* context)
2934 vgidsContext* vgids =
nullptr;
2935 const char* pem =
nullptr;
2936 const char* key =
nullptr;
2937 const char* pin =
nullptr;
2939 WINPR_ASSERT(context);
2946 if ((context->pem == pem) && (context->key == key) && (context->pin == pin))
2947 return context->configured;
2953 vgids = vgids_new(context);
2955 rc = vgids_init(vgids, context->pem, context->key, context->pin);
2958 context->configured = rc;
2962BOOL Emulate_SetupPin(SmartcardEmulationContext* context,
const char* name,
const char* pin)
2964 WINPR_ASSERT(context);
2966 const SmartcardPinCounterEntry entry = { .curRetryCounter = VGIDS_DEFAULT_RETRY_COUNTER,
2967 .retryCounter = VGIDS_DEFAULT_RETRY_COUNTER,
2968 .pin = WINPR_CAST_CONST_PTR_AWAY(pin,
char*) };
2971 HashTable_Lock(context->pinCounters);
2972 const SmartcardPinCounterEntry* val = HashTable_GetItemValue(context->pinCounters, name);
2974 rc = HashTable_Insert(context->pinCounters, name, &entry);
2977 if (val->pin && pin)
2978 rc = strcmp(val->pin, pin) == 0;
2980 HashTable_Unlock(context->pinCounters);
2984BOOL Emulate_IsPinValid(SmartcardEmulationContext* context,
const char* name,
const char* pin,
2985 size_t bytelen, UINT16* remaining)
2987 WINPR_ASSERT(context);
2988 WINPR_ASSERT(remaining);
2993 HashTable_Lock(context->pinCounters);
2994 SmartcardPinCounterEntry* val = HashTable_GetItemValue(context->pinCounters, name);
2997 if (val->pin && pin)
2999 const size_t min = strlen(val->pin);
3001 rc = strncmp(val->pin, pin, min + 1) == 0;
3005 if (val->curRetryCounter > 0)
3006 val->curRetryCounter--;
3008 val->curRetryCounter = val->retryCounter;
3010 *remaining = val->curRetryCounter;
3013 HashTable_Unlock(context->pinCounters);
3017BOOL Emulate_IsPinBlocked(SmartcardEmulationContext* context,
const char* name)
3019 WINPR_ASSERT(context);
3022 HashTable_Lock(context->pinCounters);
3023 const SmartcardPinCounterEntry* val = HashTable_GetItemValue(context->pinCounters, name);
3025 rc = val->curRetryCounter == 0;
3026 HashTable_Unlock(context->pinCounters);
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
WINPR_ATTR_NODISCARD OBJECT_NEW_FN fnObjectNew