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 if (!CardIdentifier || !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)
188 void* tmp = malloc(srcSize);
191 memcpy(tmp, src, srcSize);
192 ArrayList_Append(ctx->strings, tmp);
193 *((
void**)dst) = tmp;
194 return (UINT32)srcSize;
198 const size_t min = MIN(dstSize, srcSize);
199 memcpy(dst, src, min);
204static void scard_context_free(
void* context)
206 SCardContext* ctx = context;
209 HashTable_Free(ctx->cards);
210 ArrayList_Free(ctx->strings);
211 HashTable_Free(ctx->cache);
216static SCardContext* scard_context_new(
void)
218 SCardContext* ctx = calloc(1,
sizeof(SCardContext));
222 ctx->strings = ArrayList_New(FALSE);
227 wObject* obj = ArrayList_Object(ctx->strings);
232 ctx->cache = HashTable_New(FALSE);
235 if (!HashTable_SetupForStringData(ctx->cache, FALSE))
239 wObject* val = HashTable_ValueObject(ctx->cache);
244 scard_status_transition(ctx);
247 scard_context_free(ctx);
251static void scard_handle_free(
void* handle)
253 SCardHandle* hdl = handle;
256 free(hdl->szReader.pv);
257 vgids_free(hdl->vgids);
262WINPR_ATTR_MALLOC(scard_handle_free, 1)
263static SCardHandle* scard_handle_new(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
264 const
void* name, BOOL unicode)
266 SCardHandle* hdl =
nullptr;
268 WINPR_ASSERT(smartcard);
270 hdl = calloc(1,
sizeof(SCardHandle));
279 size_t s = _wcslen(name);
281 hdl->szReader.pw = calloc(s + 2,
sizeof(WCHAR));
282 if (!hdl->szReader.pw)
284 memcpy(hdl->szReader.pv, name, s *
sizeof(WCHAR));
288 size_t s = strlen(name);
290 hdl->szReader.pc = calloc(s + 2,
sizeof(CHAR));
291 if (!hdl->szReader.pc)
293 memcpy(hdl->szReader.pv, name, s *
sizeof(CHAR));
296 if (!hdl->szReader.pv)
299 hdl->vgids = vgids_new();
311 if (!vgids_init(hdl->vgids, pem, key, pin))
315 hdl->unicode = unicode;
316 hdl->hContext = context;
320 scard_handle_free(hdl);
324static LONG scard_handle_valid(SmartcardEmulationContext* smartcard, SCARDHANDLE handle)
326 SCardHandle* ctx =
nullptr;
328 WINPR_ASSERT(smartcard);
330 ctx = HashTable_GetItemValue(smartcard->handles, (
const void*)handle);
332 return SCARD_E_INVALID_HANDLE;
334 return SCARD_S_SUCCESS;
337static LONG scard_reader_name_valid_a(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
340 SCardContext* ctx =
nullptr;
342 WINPR_ASSERT(smartcard);
343 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)context);
348 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
351 if (strcmp(reader->szReader, name) == 0)
352 return SCARD_S_SUCCESS;
355 return SCARD_E_UNKNOWN_READER;
358static LONG scard_reader_name_valid_w(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
361 SCardContext* ctx =
nullptr;
363 WINPR_ASSERT(smartcard);
364 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)context);
369 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
372 if (_wcscmp(reader->szReader, name) == 0)
373 return SCARD_S_SUCCESS;
376 return SCARD_E_UNKNOWN_READER;
383LONG WINAPI Emulate_SCardEstablishContext(SmartcardEmulationContext* smartcard, DWORD dwScope,
384 LPCVOID pvReserved1, LPCVOID pvReserved2,
385 LPSCARDCONTEXT phContext)
387 LONG status = SCARD_E_NO_MEMORY;
388 SCardContext* ctx =
nullptr;
390 WINPR_ASSERT(smartcard);
392 ctx = scard_context_new();
394 WINPR_UNUSED(pvReserved1);
395 WINPR_UNUSED(pvReserved2);
397 WLog_Print(smartcard->log, smartcard->log_default_level,
398 "SCardEstablishContext { dwScope: %s (0x%08" PRIX32
")",
399 SCardGetScopeString(dwScope), dwScope);
403 SCARDCONTEXT context = WINPR_C_ARRAY_INIT;
405 if (winpr_RAND(&context,
sizeof(SCARDCONTEXT)) >= 0)
407 if (HashTable_Insert(smartcard->contexts, (
const void*)context, ctx))
409 *phContext = context;
410 status = SCARD_S_SUCCESS;
415 WLog_Print(smartcard->log, smartcard->log_default_level,
416 "SCardEstablishContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
417 WINPR_CXX_COMPAT_CAST(UINT32, status));
419 if (status != SCARD_S_SUCCESS)
420 scard_context_free(ctx);
425LONG WINAPI Emulate_SCardReleaseContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
428 SCardContext* value =
nullptr;
430 WINPR_ASSERT(smartcard);
432 value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
434 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseContext { hContext: %p",
438 HashTable_Remove(smartcard->contexts, (
const void*)hContext);
440 status = SCARD_S_SUCCESS;
442 WLog_Print(smartcard->log, smartcard->log_default_level,
443 "SCardReleaseContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
444 WINPR_CXX_COMPAT_CAST(UINT32, status));
449LONG WINAPI Emulate_SCardIsValidContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
453 WINPR_ASSERT(smartcard);
455 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIsValidContext { hContext: %p",
458 status = HashTable_Contains(smartcard->contexts, (
const void*)hContext)
460 : SCARD_E_INVALID_HANDLE;
461 if (status == SCARD_S_SUCCESS)
463 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
466 return SCARD_F_INTERNAL_ERROR;
469 WLog_Print(smartcard->log, smartcard->log_default_level,
470 "SCardIsValidContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
471 WINPR_CXX_COMPAT_CAST(UINT32, status));
476LONG WINAPI Emulate_SCardListReaderGroupsA(
477 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
478 LPSTR mszGroups , LPDWORD pcchGroups)
480 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
482 WLog_Print(smartcard->log, smartcard->log_default_level,
483 "SCardListReaderGroupsA { hContext: %p", (
void*)hContext);
485 WINPR_UNUSED(mszGroups);
486 WINPR_UNUSED(pcchGroups);
489 if (status == SCARD_S_SUCCESS)
490 status = SCARD_E_UNSUPPORTED_FEATURE;
492 WLog_Print(smartcard->log, smartcard->log_default_level,
493 "SCardListReaderGroupsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
494 WINPR_CXX_COMPAT_CAST(UINT32, status));
499LONG WINAPI Emulate_SCardListReaderGroupsW(
500 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
501 LPWSTR mszGroups , LPDWORD pcchGroups)
503 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
505 WLog_Print(smartcard->log, smartcard->log_default_level,
506 "SCardListReaderGroupsW { hContext: %p", (
void*)hContext);
508 WINPR_UNUSED(mszGroups);
509 WINPR_UNUSED(pcchGroups);
512 if (status == SCARD_S_SUCCESS)
513 status = SCARD_E_UNSUPPORTED_FEATURE;
515 WLog_Print(smartcard->log, smartcard->log_default_level,
516 "SCardListReaderGroupsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
517 WINPR_CXX_COMPAT_CAST(UINT32, status));
522LONG WINAPI Emulate_SCardListReadersA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
523 LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
525 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
527 status = SCARD_E_INVALID_PARAMETER;
529 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListReadersA { hContext: %p",
532 WINPR_UNUSED(mszGroups);
534 if (SCARD_S_SUCCESS == status)
536 SCardContext* value =
537 (SCardContext*)HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
546 *pcchReaders = ARRAYSIZE(g_ReaderNameA);
549 *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameA,
550 sizeof(g_ReaderNameA));
554 WLog_Print(smartcard->log, smartcard->log_default_level,
555 "SCardListReadersA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
556 WINPR_CXX_COMPAT_CAST(UINT32, status));
561LONG WINAPI Emulate_SCardListReadersW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
562 LPCWSTR mszGroups, LPWSTR mszReaders, LPDWORD pcchReaders)
564 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
567 status = SCARD_E_INVALID_PARAMETER;
569 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListReadersW { hContext: %p",
572 WINPR_UNUSED(mszGroups);
574 if (!InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit,
nullptr,
nullptr))
576 if (SCARD_S_SUCCESS == status)
578 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
588 WINPR_ASSERT(g_ReaderNameWLen <= UINT32_MAX);
589 *pcchReaders = (UINT32)g_ReaderNameWLen;
593 *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameW,
594 g_ReaderNameWLen *
sizeof(WCHAR)) /
599 WLog_Print(smartcard->log, smartcard->log_default_level,
600 "SCardListReadersW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
601 WINPR_CXX_COMPAT_CAST(UINT32, status));
606LONG WINAPI Emulate_SCardListCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
607 LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
608 DWORD cguidInterfaceCount,
612 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
614 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListCardsA { hContext: %p",
618 WINPR_UNUSED(rgquidInterfaces);
619 WINPR_UNUSED(cguidInterfaceCount);
620 WINPR_UNUSED(mszCards);
621 WINPR_UNUSED(pcchCards);
624 if (status == SCARD_S_SUCCESS)
625 status = SCARD_E_UNSUPPORTED_FEATURE;
627 WLog_Print(smartcard->log, smartcard->log_default_level,
628 "SCardListCardsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
629 WINPR_CXX_COMPAT_CAST(UINT32, status));
634LONG WINAPI Emulate_SCardListCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
635 LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
636 DWORD cguidInterfaceCount,
640 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
642 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListCardsW { hContext: %p",
646 WINPR_UNUSED(rgquidInterfaces);
647 WINPR_UNUSED(cguidInterfaceCount);
648 WINPR_UNUSED(mszCards);
649 WINPR_UNUSED(pcchCards);
652 if (status == SCARD_S_SUCCESS)
653 status = SCARD_E_UNSUPPORTED_FEATURE;
655 WLog_Print(smartcard->log, smartcard->log_default_level,
656 "SCardListCardsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
657 WINPR_CXX_COMPAT_CAST(UINT32, status));
662LONG WINAPI Emulate_SCardListInterfacesA(
663 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szCard,
664 LPGUID pguidInterfaces, LPDWORD pcguidInterfaces )
666 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
668 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListInterfacesA { hContext: %p",
671 WINPR_UNUSED(szCard);
672 WINPR_UNUSED(pguidInterfaces);
673 WINPR_UNUSED(pcguidInterfaces);
676 if (status == SCARD_S_SUCCESS)
677 status = SCARD_E_UNSUPPORTED_FEATURE;
679 WLog_Print(smartcard->log, smartcard->log_default_level,
680 "SCardListInterfacesA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
681 WINPR_CXX_COMPAT_CAST(UINT32, status));
686LONG WINAPI Emulate_SCardListInterfacesW(
687 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szCard,
688 LPGUID pguidInterfaces, LPDWORD pcguidInterfaces )
690 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
692 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListInterfacesW { hContext: %p",
695 WINPR_UNUSED(szCard);
696 WINPR_UNUSED(pguidInterfaces);
697 WINPR_UNUSED(pcguidInterfaces);
700 if (status == SCARD_S_SUCCESS)
701 status = SCARD_E_UNSUPPORTED_FEATURE;
703 WLog_Print(smartcard->log, smartcard->log_default_level,
704 "SCardListInterfacesW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
705 WINPR_CXX_COMPAT_CAST(UINT32, status));
710LONG WINAPI Emulate_SCardGetProviderIdA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
711 LPCSTR szCard, LPGUID pguidProviderId)
713 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
715 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetProviderIdA { hContext: %p",
718 WINPR_UNUSED(szCard);
719 WINPR_UNUSED(pguidProviderId);
722 if (status == SCARD_S_SUCCESS)
723 status = SCARD_E_UNSUPPORTED_FEATURE;
725 WLog_Print(smartcard->log, smartcard->log_default_level,
726 "SCardGetProviderIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
727 WINPR_CXX_COMPAT_CAST(UINT32, status));
732LONG WINAPI Emulate_SCardGetProviderIdW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
733 LPCWSTR szCard, LPGUID pguidProviderId)
735 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
737 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetProviderIdW { hContext: %p",
740 WINPR_UNUSED(szCard);
741 WINPR_UNUSED(pguidProviderId);
744 if (status == SCARD_S_SUCCESS)
745 status = SCARD_E_UNSUPPORTED_FEATURE;
747 WLog_Print(smartcard->log, smartcard->log_default_level,
748 "SCardGetProviderIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
749 WINPR_CXX_COMPAT_CAST(UINT32, status));
754LONG WINAPI Emulate_SCardGetCardTypeProviderNameA(
755 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szCardName,
756 DWORD dwProviderId, CHAR* szProvider ,
757 LPDWORD pcchProvider )
759 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
761 WLog_Print(smartcard->log, smartcard->log_default_level,
762 "SCardGetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
764 WINPR_UNUSED(szCardName);
765 WINPR_UNUSED(dwProviderId);
766 WINPR_UNUSED(szProvider);
767 WINPR_UNUSED(pcchProvider);
770 if (status == SCARD_S_SUCCESS)
771 status = SCARD_E_UNSUPPORTED_FEATURE;
773 WLog_Print(smartcard->log, smartcard->log_default_level,
774 "SCardGetCardTypeProviderNameA } status: %s (0x%08" PRIX32
")",
775 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
780LONG WINAPI Emulate_SCardGetCardTypeProviderNameW(
781 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szCardName,
782 DWORD dwProviderId, WCHAR* szProvider ,
783 LPDWORD pcchProvider )
785 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
787 WLog_Print(smartcard->log, smartcard->log_default_level,
788 "SCardGetCardTypeProviderNameW { hContext: %p", (
void*)hContext);
790 WINPR_UNUSED(szCardName);
791 WINPR_UNUSED(dwProviderId);
792 WINPR_UNUSED(szProvider);
793 WINPR_UNUSED(pcchProvider);
796 if (status == SCARD_S_SUCCESS)
797 status = SCARD_E_UNSUPPORTED_FEATURE;
799 WLog_Print(smartcard->log, smartcard->log_default_level,
800 "SCardGetCardTypeProviderNameW } status: %s (0x%08" PRIX32
")",
801 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
806LONG WINAPI Emulate_SCardIntroduceReaderGroupA(SmartcardEmulationContext* smartcard,
807 SCARDCONTEXT hContext, LPCSTR szGroupName)
809 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
811 WLog_Print(smartcard->log, smartcard->log_default_level,
812 "SCardIntroduceReaderGroupA { hContext: %p", (
void*)hContext);
814 WINPR_UNUSED(szGroupName);
817 if (status == SCARD_S_SUCCESS)
818 status = SCARD_E_UNSUPPORTED_FEATURE;
820 WLog_Print(smartcard->log, smartcard->log_default_level,
821 "SCardIntroduceReaderGroupA } status: %s (0x%08" PRIX32
")",
822 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
827LONG WINAPI Emulate_SCardIntroduceReaderGroupW(SmartcardEmulationContext* smartcard,
828 SCARDCONTEXT hContext, LPCWSTR szGroupName)
830 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
832 WLog_Print(smartcard->log, smartcard->log_default_level,
833 "SCardIntroduceReaderGroupW { hContext: %p", (
void*)hContext);
835 WINPR_UNUSED(szGroupName);
838 if (status == SCARD_S_SUCCESS)
839 status = SCARD_E_UNSUPPORTED_FEATURE;
841 WLog_Print(smartcard->log, smartcard->log_default_level,
842 "SCardIntroduceReaderGroupW } status: %s (0x%08" PRIX32
")",
843 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
848LONG WINAPI Emulate_SCardForgetReaderGroupA(SmartcardEmulationContext* smartcard,
849 SCARDCONTEXT hContext, LPCSTR szGroupName)
851 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
853 WLog_Print(smartcard->log, smartcard->log_default_level,
854 "SCardForgetReaderGroupA { hContext: %p", (
void*)hContext);
856 WINPR_UNUSED(szGroupName);
859 if (status == SCARD_S_SUCCESS)
860 status = SCARD_E_UNSUPPORTED_FEATURE;
862 WLog_Print(smartcard->log, smartcard->log_default_level,
863 "SCardForgetReaderGroupA } status: %s (0x%08" PRIX32
")",
864 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
869LONG WINAPI Emulate_SCardForgetReaderGroupW(SmartcardEmulationContext* smartcard,
870 SCARDCONTEXT hContext, LPCWSTR szGroupName)
872 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
874 WLog_Print(smartcard->log, smartcard->log_default_level,
875 "SCardForgetReaderGroupW { hContext: %p", (
void*)hContext);
877 WINPR_UNUSED(szGroupName);
880 if (status == SCARD_S_SUCCESS)
881 status = SCARD_E_UNSUPPORTED_FEATURE;
883 WLog_Print(smartcard->log, smartcard->log_default_level,
884 "SCardForgetReaderGroupW } status: %s (0x%08" PRIX32
")",
885 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
890LONG WINAPI Emulate_SCardIntroduceReaderA(SmartcardEmulationContext* smartcard,
891 SCARDCONTEXT hContext, LPCSTR szReaderName,
894 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
896 if (status == SCARD_S_SUCCESS)
897 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
899 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIntroduceReaderA { hContext: %p",
902 WINPR_UNUSED(szDeviceName);
905 if (status == SCARD_S_SUCCESS)
906 status = SCARD_E_UNSUPPORTED_FEATURE;
908 WLog_Print(smartcard->log, smartcard->log_default_level,
909 "SCardIntroduceReaderA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
910 WINPR_CXX_COMPAT_CAST(UINT32, status));
915LONG WINAPI Emulate_SCardIntroduceReaderW(SmartcardEmulationContext* smartcard,
916 SCARDCONTEXT hContext, LPCWSTR szReaderName,
917 LPCWSTR szDeviceName)
919 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
921 if (status == SCARD_S_SUCCESS)
922 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
924 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIntroduceReaderW { hContext: %p",
927 WINPR_UNUSED(szDeviceName);
930 if (status == SCARD_S_SUCCESS)
931 status = SCARD_E_UNSUPPORTED_FEATURE;
933 WLog_Print(smartcard->log, smartcard->log_default_level,
934 "SCardIntroduceReaderW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
935 WINPR_CXX_COMPAT_CAST(UINT32, status));
940LONG WINAPI Emulate_SCardForgetReaderA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
943 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
945 if (status == SCARD_S_SUCCESS)
946 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
948 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetReaderA { hContext: %p",
952 if (status == SCARD_S_SUCCESS)
953 status = SCARD_E_UNSUPPORTED_FEATURE;
955 WLog_Print(smartcard->log, smartcard->log_default_level,
956 "SCardForgetReaderA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
957 WINPR_CXX_COMPAT_CAST(UINT32, status));
962LONG WINAPI Emulate_SCardForgetReaderW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
963 LPCWSTR szReaderName)
965 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
967 if (status == SCARD_S_SUCCESS)
968 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
970 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetReaderW { hContext: %p",
974 if (status == SCARD_S_SUCCESS)
975 status = SCARD_E_UNSUPPORTED_FEATURE;
977 WLog_Print(smartcard->log, smartcard->log_default_level,
978 "SCardForgetReaderW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
979 WINPR_CXX_COMPAT_CAST(UINT32, status));
984LONG WINAPI Emulate_SCardAddReaderToGroupA(SmartcardEmulationContext* smartcard,
985 SCARDCONTEXT hContext, LPCSTR szReaderName,
988 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
990 if (status == SCARD_S_SUCCESS)
991 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
993 WLog_Print(smartcard->log, smartcard->log_default_level,
994 "SCardAddReaderToGroupA { hContext: %p", (
void*)hContext);
996 WINPR_UNUSED(szGroupName);
999 if (status == SCARD_S_SUCCESS)
1000 status = SCARD_E_UNSUPPORTED_FEATURE;
1002 WLog_Print(smartcard->log, smartcard->log_default_level,
1003 "SCardAddReaderToGroupA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1004 WINPR_CXX_COMPAT_CAST(UINT32, status));
1009LONG WINAPI Emulate_SCardAddReaderToGroupW(SmartcardEmulationContext* smartcard,
1010 SCARDCONTEXT hContext, LPCWSTR szReaderName,
1011 LPCWSTR szGroupName)
1013 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1015 if (status == SCARD_S_SUCCESS)
1016 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1018 WLog_Print(smartcard->log, smartcard->log_default_level,
1019 "SCardAddReaderToGroupW { hContext: %p", (
void*)hContext);
1021 WINPR_UNUSED(szGroupName);
1024 if (status == SCARD_S_SUCCESS)
1025 status = SCARD_E_UNSUPPORTED_FEATURE;
1027 WLog_Print(smartcard->log, smartcard->log_default_level,
1028 "SCardAddReaderToGroupW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1029 WINPR_CXX_COMPAT_CAST(UINT32, status));
1034LONG WINAPI Emulate_SCardRemoveReaderFromGroupA(SmartcardEmulationContext* smartcard,
1035 SCARDCONTEXT hContext, LPCSTR szReaderName,
1038 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1040 if (status == SCARD_S_SUCCESS)
1041 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
1043 WLog_Print(smartcard->log, smartcard->log_default_level,
1044 "SCardRemoveReaderFromGroupA { hContext: %p", (
void*)hContext);
1046 WINPR_UNUSED(szGroupName);
1049 if (status == SCARD_S_SUCCESS)
1050 status = SCARD_E_UNSUPPORTED_FEATURE;
1052 WLog_Print(smartcard->log, smartcard->log_default_level,
1053 "SCardRemoveReaderFromGroupA } status: %s (0x%08" PRIX32
")",
1054 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1059LONG WINAPI Emulate_SCardRemoveReaderFromGroupW(SmartcardEmulationContext* smartcard,
1060 SCARDCONTEXT hContext, LPCWSTR szReaderName,
1061 LPCWSTR szGroupName)
1063 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1065 if (status == SCARD_S_SUCCESS)
1066 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1068 WLog_Print(smartcard->log, smartcard->log_default_level,
1069 "SCardRemoveReaderFromGroupW { hContext: %p", (
void*)hContext);
1071 WINPR_UNUSED(szGroupName);
1074 if (status == SCARD_S_SUCCESS)
1075 status = SCARD_E_UNSUPPORTED_FEATURE;
1077 WLog_Print(smartcard->log, smartcard->log_default_level,
1078 "SCardRemoveReaderFromGroupW } status: %s (0x%08" PRIX32
")",
1079 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1084LONG WINAPI Emulate_SCardIntroduceCardTypeA(SmartcardEmulationContext* smartcard,
1085 SCARDCONTEXT hContext, LPCSTR szCardName,
1086 LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1087 DWORD dwInterfaceCount, LPCBYTE pbAtr,
1088 LPCBYTE pbAtrMask, DWORD cbAtrLen)
1090 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1092 WLog_Print(smartcard->log, smartcard->log_default_level,
1093 "SCardIntroduceCardTypeA { hContext: %p", (
void*)hContext);
1095 WINPR_UNUSED(szCardName);
1096 WINPR_UNUSED(pguidPrimaryProvider);
1097 WINPR_UNUSED(rgguidInterfaces);
1098 WINPR_UNUSED(dwInterfaceCount);
1099 WINPR_UNUSED(pbAtr);
1100 WINPR_UNUSED(pbAtrMask);
1101 WINPR_UNUSED(cbAtrLen);
1104 if (status == SCARD_S_SUCCESS)
1105 status = SCARD_E_UNSUPPORTED_FEATURE;
1107 WLog_Print(smartcard->log, smartcard->log_default_level,
1108 "SCardIntroduceCardTypeA } status: %s (0x%08" PRIX32
")",
1109 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1114LONG WINAPI Emulate_SCardIntroduceCardTypeW(SmartcardEmulationContext* smartcard,
1115 SCARDCONTEXT hContext, LPCWSTR szCardName,
1116 LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1117 DWORD dwInterfaceCount, LPCBYTE pbAtr,
1118 LPCBYTE pbAtrMask, DWORD cbAtrLen)
1120 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1122 WLog_Print(smartcard->log, smartcard->log_default_level,
1123 "SCardIntroduceCardTypeW { hContext: %p", (
void*)hContext);
1125 WINPR_UNUSED(szCardName);
1126 WINPR_UNUSED(pguidPrimaryProvider);
1127 WINPR_UNUSED(rgguidInterfaces);
1128 WINPR_UNUSED(dwInterfaceCount);
1129 WINPR_UNUSED(pbAtr);
1130 WINPR_UNUSED(pbAtrMask);
1131 WINPR_UNUSED(cbAtrLen);
1134 if (status == SCARD_S_SUCCESS)
1135 status = SCARD_E_UNSUPPORTED_FEATURE;
1137 WLog_Print(smartcard->log, smartcard->log_default_level,
1138 "SCardIntroduceCardTypeW } status: %s (0x%08" PRIX32
")",
1139 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1144LONG WINAPI Emulate_SCardSetCardTypeProviderNameA(SmartcardEmulationContext* smartcard,
1145 SCARDCONTEXT hContext, LPCSTR szCardName,
1146 DWORD dwProviderId, LPCSTR szProvider)
1148 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1150 WLog_Print(smartcard->log, smartcard->log_default_level,
1151 "SCardSetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
1153 WINPR_UNUSED(szCardName);
1154 WINPR_UNUSED(dwProviderId);
1155 WINPR_UNUSED(szProvider);
1158 if (status == SCARD_S_SUCCESS)
1159 status = SCARD_E_UNSUPPORTED_FEATURE;
1161 WLog_Print(smartcard->log, smartcard->log_default_level,
1162 "SCardSetCardTypeProviderNameA } status: %s (0x%08" PRIX32
")",
1163 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1168LONG WINAPI Emulate_SCardSetCardTypeProviderNameW(SmartcardEmulationContext* smartcard,
1169 SCARDCONTEXT hContext, LPCWSTR szCardName,
1170 DWORD dwProviderId, LPCWSTR szProvider)
1172 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1174 WLog_Print(smartcard->log, smartcard->log_default_level,
1175 "SCardSetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
1177 WINPR_UNUSED(szCardName);
1178 WINPR_UNUSED(dwProviderId);
1179 WINPR_UNUSED(szProvider);
1182 if (status == SCARD_S_SUCCESS)
1183 status = SCARD_E_UNSUPPORTED_FEATURE;
1185 WLog_Print(smartcard->log, smartcard->log_default_level,
1186 "SCardSetCardTypeProviderNameW } status: %s (0x%08" PRIX32
")",
1187 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1192LONG WINAPI Emulate_SCardForgetCardTypeA(SmartcardEmulationContext* smartcard,
1193 SCARDCONTEXT hContext, LPCSTR szCardName)
1195 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1197 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetCardTypeA { hContext: %p",
1200 WINPR_UNUSED(szCardName);
1203 if (status == SCARD_S_SUCCESS)
1204 status = SCARD_E_UNSUPPORTED_FEATURE;
1206 WLog_Print(smartcard->log, smartcard->log_default_level,
1207 "SCardForgetCardTypeA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1208 WINPR_CXX_COMPAT_CAST(UINT32, status));
1213LONG WINAPI Emulate_SCardForgetCardTypeW(SmartcardEmulationContext* smartcard,
1214 SCARDCONTEXT hContext, LPCWSTR szCardName)
1216 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1218 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetCardTypeW { hContext: %p",
1221 WINPR_UNUSED(szCardName);
1224 if (status == SCARD_S_SUCCESS)
1225 status = SCARD_E_UNSUPPORTED_FEATURE;
1227 WLog_Print(smartcard->log, smartcard->log_default_level,
1228 "SCardForgetCardTypeW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1229 WINPR_CXX_COMPAT_CAST(UINT32, status));
1234LONG WINAPI Emulate_SCardFreeMemory(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1237 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1239 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardFreeMemory { hContext: %p",
1242 if (status == SCARD_S_SUCCESS)
1244 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1245 WINPR_ASSERT(value);
1247 ArrayList_Remove(value->strings, pvMem);
1250 WLog_Print(smartcard->log, smartcard->log_default_level,
1251 "SCardFreeMemory } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1252 WINPR_CXX_COMPAT_CAST(UINT32, status));
1257HANDLE WINAPI Emulate_SCardAccessStartedEvent(SmartcardEmulationContext* smartcard)
1259 HANDLE hEvent =
nullptr;
1261 WINPR_ASSERT(smartcard);
1263 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAccessStartedEvent {");
1266 if (winpr_RAND((
void*)&hEvent,
sizeof(hEvent)) < 0)
1268 (void)fprintf(stderr,
"winpr_RAND failed.\n");
1271 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAccessStartedEvent } hEvent: %p",
1277void WINAPI Emulate_SCardReleaseStartedEvent(SmartcardEmulationContext* smartcard)
1279 WINPR_ASSERT(smartcard);
1281 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseStartedEvent {");
1285 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseStartedEvent }");
1288LONG WINAPI Emulate_SCardLocateCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1292 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1294 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardLocateCardsA { hContext: %p",
1297 WINPR_UNUSED(mszCards);
1298 WINPR_UNUSED(rgReaderStates);
1299 WINPR_UNUSED(cReaders);
1302 if (status == SCARD_S_SUCCESS)
1303 status = SCARD_E_UNSUPPORTED_FEATURE;
1305 WLog_Print(smartcard->log, smartcard->log_default_level,
1306 "SCardLocateCardsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1307 WINPR_CXX_COMPAT_CAST(UINT32, status));
1312LONG WINAPI Emulate_SCardLocateCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1316 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1318 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardLocateCardsW { hContext: %p",
1321 WINPR_UNUSED(mszCards);
1322 WINPR_UNUSED(rgReaderStates);
1323 WINPR_UNUSED(cReaders);
1326 if (status == SCARD_S_SUCCESS)
1327 status = SCARD_E_UNSUPPORTED_FEATURE;
1329 WLog_Print(smartcard->log, smartcard->log_default_level,
1330 "SCardLocateCardsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1331 WINPR_CXX_COMPAT_CAST(UINT32, status));
1336LONG WINAPI Emulate_SCardLocateCardsByATRA(SmartcardEmulationContext* smartcard,
1341 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1343 WLog_Print(smartcard->log, smartcard->log_default_level,
1344 "SCardLocateCardsByATRA { hContext: %p", (
void*)hContext);
1346 WINPR_UNUSED(rgAtrMasks);
1347 WINPR_UNUSED(cAtrs);
1348 WINPR_UNUSED(rgReaderStates);
1349 WINPR_UNUSED(cReaders);
1352 if (status == SCARD_S_SUCCESS)
1353 status = SCARD_E_UNSUPPORTED_FEATURE;
1355 WLog_Print(smartcard->log, smartcard->log_default_level,
1356 "SCardLocateCardsByATRA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1357 WINPR_CXX_COMPAT_CAST(UINT32, status));
1362LONG WINAPI Emulate_SCardLocateCardsByATRW(SmartcardEmulationContext* smartcard,
1367 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1369 WLog_Print(smartcard->log, smartcard->log_default_level,
1370 "SCardLocateCardsByATRW { hContext: %p", (
void*)hContext);
1372 WINPR_UNUSED(rgAtrMasks);
1373 WINPR_UNUSED(cAtrs);
1374 WINPR_UNUSED(rgReaderStates);
1375 WINPR_UNUSED(cReaders);
1378 if (status == SCARD_S_SUCCESS)
1379 status = SCARD_E_UNSUPPORTED_FEATURE;
1381 WLog_Print(smartcard->log, smartcard->log_default_level,
1382 "SCardLocateCardsByATRW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1383 WINPR_CXX_COMPAT_CAST(UINT32, status));
1388LONG WINAPI Emulate_SCardGetStatusChangeA(SmartcardEmulationContext* smartcard,
1389 SCARDCONTEXT hContext, DWORD dwTimeout,
1392 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1394 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetStatusChangeA { hContext: %p",
1397 if (status == SCARD_S_SUCCESS)
1399 const DWORD diff = 100;
1400 size_t eventCount = 0;
1401 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1402 WINPR_ASSERT(value);
1407 status = SCARD_E_TIMEOUT;
1410 for (
size_t x = 0; x < cReaders; x++)
1414 for (
size_t y = 0; y < MAX_EMULATED_READERS; y++)
1417 if (strcmp(out->szReader, in->szReader) == 0)
1419 const SCardHandle* hdl = find_reader(smartcard, in->szReader, FALSE);
1420 out->dwEventState = in->dwEventState;
1423 out->dwEventState |= SCARD_STATE_INUSE;
1424 if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1425 out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1428 if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1429 (out->dwCurrentState & SCARD_STATE_EMPTY))
1430 out->dwEventState |= SCARD_STATE_CHANGED;
1431 if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1432 (out->dwCurrentState & SCARD_STATE_PRESENT))
1433 out->dwEventState |= SCARD_STATE_CHANGED;
1435 out->cbAtr = in->cbAtr;
1436 memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1437 if (out->dwEventState & SCARD_STATE_CHANGED)
1442 if (value->canceled)
1444 status = SCARD_E_CANCELLED;
1447 if (eventCount != 0)
1449 status = SCARD_S_SUCCESS;
1453 if (dwTimeout != INFINITE)
1454 dwTimeout -= MIN(dwTimeout, diff);
1455 if (freerdp_shall_disconnect_context(inst->context))
1457 status = SCARD_E_CANCELLED;
1460 }
while (dwTimeout > 0);
1463 WLog_Print(smartcard->log, smartcard->log_default_level,
1464 "SCardGetStatusChangeA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1465 WINPR_CXX_COMPAT_CAST(UINT32, status));
1470LONG WINAPI Emulate_SCardGetStatusChangeW(SmartcardEmulationContext* smartcard,
1471 SCARDCONTEXT hContext, DWORD dwTimeout,
1474 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1476 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetStatusChangeW { hContext: %p",
1479 if (status == SCARD_S_SUCCESS)
1481 const DWORD diff = 100;
1482 size_t eventCount = 0;
1483 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1484 WINPR_ASSERT(value);
1489 status = SCARD_E_TIMEOUT;
1492 for (
size_t x = 0; x < cReaders; x++)
1496 for (
size_t y = 0; y < MAX_EMULATED_READERS; y++)
1499 if (_wcscmp(out->szReader, in->szReader) == 0)
1501 const SCardHandle* hdl = find_reader(smartcard, in->szReader, TRUE);
1502 out->dwEventState = in->dwEventState;
1505 out->dwEventState |= SCARD_STATE_INUSE;
1506 if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1507 out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1509 if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1510 (out->dwCurrentState & SCARD_STATE_EMPTY))
1511 out->dwEventState |= SCARD_STATE_CHANGED;
1512 if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1513 (out->dwCurrentState & SCARD_STATE_PRESENT))
1514 out->dwEventState |= SCARD_STATE_CHANGED;
1515 out->cbAtr = in->cbAtr;
1516 memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1518 if (out->dwEventState & SCARD_STATE_CHANGED)
1523 if (value->canceled)
1525 status = SCARD_E_CANCELLED;
1528 if (eventCount != 0)
1530 status = SCARD_S_SUCCESS;
1534 if (dwTimeout != INFINITE)
1535 dwTimeout -= MIN(dwTimeout, diff);
1536 if (freerdp_shall_disconnect_context(inst->context))
1538 status = SCARD_E_CANCELLED;
1541 }
while (dwTimeout > 0);
1544 WLog_Print(smartcard->log, smartcard->log_default_level,
1545 "SCardGetStatusChangeW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1546 WINPR_CXX_COMPAT_CAST(UINT32, status));
1551LONG WINAPI Emulate_SCardCancel(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
1553 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1555 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancel { hContext: %p",
1558 if (status == SCARD_S_SUCCESS)
1560 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1561 WINPR_ASSERT(value);
1562 value->canceled = TRUE;
1565 WLog_Print(smartcard->log, smartcard->log_default_level,
1566 "SCardCancel } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1567 WINPR_CXX_COMPAT_CAST(UINT32, status));
1572SCardHandle* find_reader(SmartcardEmulationContext* smartcard,
const void* szReader, BOOL unicode)
1574 SCardHandle* hdl =
nullptr;
1575 ULONG_PTR* keys =
nullptr;
1577 WINPR_ASSERT(smartcard);
1578 const size_t count = HashTable_GetKeys(smartcard->handles, &keys);
1579 for (
size_t x = 0; x < count; x++)
1581 SCardHandle* cur = HashTable_GetItemValue(smartcard->handles, (
const void*)keys[x]);
1584 if (cur->unicode != unicode)
1586 if (!unicode && (strcmp(cur->szReader.pc, szReader) != 0))
1588 if (unicode && (_wcscmp(cur->szReader.pw, szReader) != 0))
1597WINPR_ATTR_MALLOC(scard_handle_free, 1)
1598static SCardHandle* reader2handle(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1599 const
void* szReader, BOOL unicode, DWORD dwShareMode,
1600 SCARDHANDLE* phCard, DWORD dwPreferredProtocols,
1601 LPDWORD pdwActiveProtocol)
1603 WINPR_ASSERT(phCard);
1604 SCardHandle* hdl =
nullptr;
1607 if (Emulate_SCardIsValidContext(smartcard, hContext) != SCARD_S_SUCCESS)
1610 hdl = scard_handle_new(smartcard, hContext, szReader, unicode);
1614 if (winpr_RAND(&hdl->card,
sizeof(hdl->card)) < 0)
1616 scard_handle_free(hdl);
1620 hdl->dwActiveProtocol = SCARD_PROTOCOL_T1;
1621 hdl->dwShareMode = dwShareMode;
1623 DWORD activeProtocol = 0;
1624 if (pdwActiveProtocol)
1626 if ((hdl->dwActiveProtocol & dwPreferredProtocols) == 0)
1628 scard_handle_free(hdl);
1633 activeProtocol = hdl->dwActiveProtocol;
1636 if (!HashTable_Insert(smartcard->handles, (
const void*)hdl->card, hdl))
1638 scard_handle_free(hdl);
1643 hdl->referencecount++;
1644 *pdwActiveProtocol = activeProtocol;
1645 *phCard = hdl->card;
1648 WLog_Print(smartcard->log, smartcard->log_default_level,
"{ %p }", (
void*)*phCard);
1652LONG WINAPI Emulate_SCardConnectA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1653 LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1654 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1656 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1658 if (!phCard || !pdwActiveProtocol)
1659 status = SCARD_E_INVALID_PARAMETER;
1661 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectA { hContext: %p",
1664 if (status == SCARD_S_SUCCESS)
1666 if (!reader2handle(smartcard, hContext, szReader, FALSE, dwShareMode, phCard,
1667 dwPreferredProtocols, pdwActiveProtocol))
1668 status = SCARD_E_NO_MEMORY;
1671 WLog_Print(smartcard->log, smartcard->log_default_level,
1672 "SCardConnectA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1673 WINPR_CXX_COMPAT_CAST(UINT32, status));
1678LONG WINAPI Emulate_SCardConnectW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1679 LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1680 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1682 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1684 if (!phCard || !pdwActiveProtocol)
1685 status = SCARD_E_INVALID_PARAMETER;
1687 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectW { hContext: %p",
1690 if (status == SCARD_S_SUCCESS)
1692 if (!reader2handle(smartcard, hContext, szReader, TRUE, dwShareMode, phCard,
1693 dwPreferredProtocols, pdwActiveProtocol))
1694 status = SCARD_E_NO_MEMORY;
1697 WLog_Print(smartcard->log, smartcard->log_default_level,
1698 "SCardConnectW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1699 WINPR_CXX_COMPAT_CAST(UINT32, status));
1704LONG WINAPI Emulate_SCardReconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1705 DWORD dwShareMode, WINPR_ATTR_UNUSED DWORD dwPreferredProtocols,
1706 WINPR_ATTR_UNUSED DWORD dwInitialization,
1707 LPDWORD pdwActiveProtocol)
1709 LONG status = scard_handle_valid(smartcard, hCard);
1711 if (!pdwActiveProtocol)
1712 status = SCARD_E_INVALID_PARAMETER;
1714 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReconnect { hCard: %p",
1717 if (status == SCARD_S_SUCCESS)
1719 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1723 hdl->dwShareMode = dwShareMode;
1724 hdl->transaction = FALSE;
1726 *pdwActiveProtocol = hdl->dwActiveProtocol;
1729 WLog_Print(smartcard->log, smartcard->log_default_level,
1730 "SCardReconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1731 WINPR_CXX_COMPAT_CAST(UINT32, status));
1736LONG WINAPI Emulate_SCardDisconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1737 DWORD dwDisposition)
1739 LONG status = scard_handle_valid(smartcard, hCard);
1741 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDisconnect { hCard: %p",
1744 WINPR_UNUSED(dwDisposition);
1746 if (status == SCARD_S_SUCCESS)
1748 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1751 hdl->referencecount--;
1752 if (hdl->referencecount == 0)
1753 HashTable_Remove(smartcard->handles, (
const void*)hCard);
1756 WLog_Print(smartcard->log, smartcard->log_default_level,
1757 "SCardDisconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1758 WINPR_CXX_COMPAT_CAST(UINT32, status));
1763LONG WINAPI Emulate_SCardBeginTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1765 LONG status = scard_handle_valid(smartcard, hCard);
1767 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardBeginTransaction { hCard: %p",
1770 if (status == SCARD_S_SUCCESS)
1772 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1774 if (hdl->transaction)
1775 status = SCARD_E_INVALID_VALUE;
1777 hdl->transaction = TRUE;
1780 WLog_Print(smartcard->log, smartcard->log_default_level,
1781 "SCardBeginTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1782 WINPR_CXX_COMPAT_CAST(UINT32, status));
1787LONG WINAPI Emulate_SCardEndTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1788 DWORD dwDisposition)
1790 LONG status = scard_handle_valid(smartcard, hCard);
1792 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardEndTransaction { hCard: %p",
1795 WINPR_UNUSED(dwDisposition);
1797 if (status == SCARD_S_SUCCESS)
1799 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1801 if (!hdl->transaction)
1802 status = SCARD_E_NOT_TRANSACTED;
1804 hdl->transaction = FALSE;
1807 WLog_Print(smartcard->log, smartcard->log_default_level,
1808 "SCardEndTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1809 WINPR_CXX_COMPAT_CAST(UINT32, status));
1814LONG WINAPI Emulate_SCardCancelTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1816 LONG status = scard_handle_valid(smartcard, hCard);
1818 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancelTransaction { hCard: %p",
1821 if (status == SCARD_S_SUCCESS)
1823 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1825 if (!hdl->transaction)
1826 status = SCARD_E_NOT_TRANSACTED;
1828 hdl->transaction = FALSE;
1831 WLog_Print(smartcard->log, smartcard->log_default_level,
1832 "SCardCancelTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1833 WINPR_CXX_COMPAT_CAST(UINT32, status));
1838LONG WINAPI Emulate_SCardState(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1839 LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
1842 LONG status = scard_handle_valid(smartcard, hCard);
1844 if (!pdwState || !pdwProtocol)
1845 status = SCARD_E_INVALID_PARAMETER;
1847 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardState { hCard: %p",
1850 if (status == SCARD_S_SUCCESS)
1852 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1856 *pdwState = SCARD_SPECIFIC;
1858 *pdwProtocol = SCARD_PROTOCOL_T1;
1863 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1866 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1872 if (_wcscmp(readerW->szReader, hdl->szReader.pw) == 0)
1874 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerW->rgbAtr,
1880 if (strcmp(readerA->szReader, hdl->szReader.pc) == 0)
1882 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerA->rgbAtr,
1890 WLog_Print(smartcard->log, smartcard->log_default_level,
1891 "SCardState } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1892 WINPR_CXX_COMPAT_CAST(UINT32, status));
1897LONG WINAPI Emulate_SCardStatusA(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1898 LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1899 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1901 LONG status = scard_handle_valid(smartcard, hCard);
1903 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusA { hCard: %p",
1906 if (status == SCARD_S_SUCCESS)
1908 SCardContext* ctx =
nullptr;
1909 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1912 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1917 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pc,
1918 (UINT32)strlen(hdl->szReader.pc) + 2);
1921 *pdwState = SCARD_SPECIFIC;
1923 *pdwProtocol = SCARD_PROTOCOL_T1;
1927 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1930 if (strcmp(reader->szReader, hdl->szReader.pc) == 0)
1933 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1939 WLog_Print(smartcard->log, smartcard->log_default_level,
1940 "SCardStatusA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1941 WINPR_CXX_COMPAT_CAST(UINT32, status));
1946LONG WINAPI Emulate_SCardStatusW(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1947 LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1948 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1950 LONG status = scard_handle_valid(smartcard, hCard);
1952 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusW { hCard: %p",
1955 if (status == SCARD_S_SUCCESS)
1957 SCardContext* ctx =
nullptr;
1958 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1961 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1966 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pw,
1967 (UINT32)(_wcslen(hdl->szReader.pw) + 2) *
sizeof(WCHAR)) /
1971 *pdwState = SCARD_SPECIFIC;
1973 *pdwProtocol = SCARD_PROTOCOL_T1;
1977 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1980 if (_wcscmp(reader->szReader, hdl->szReader.pw) == 0)
1982 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1987 WLog_Print(smartcard->log, smartcard->log_default_level,
1988 "SCardStatusW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1989 WINPR_CXX_COMPAT_CAST(UINT32, status));
1994LONG WINAPI Emulate_SCardTransmit(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1997 LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
1999 LONG status = scard_handle_valid(smartcard, hCard);
2001 if (!pioSendPci || !pbSendBuffer || !pbRecvBuffer || !pcbRecvLength)
2002 status = SCARD_E_INVALID_PARAMETER;
2004 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardTransmit { hCard: %p",
2007 if (status == SCARD_S_SUCCESS)
2009 BYTE* response =
nullptr;
2010 DWORD responseSize = 0;
2011 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2014 hdl->transmitcount++;
2016 if (!vgids_process_apdu(hdl->vgids, pbSendBuffer, cbSendLength, &response, &responseSize))
2017 status = SCARD_E_NO_SMARTCARD;
2021 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
2025 scard_copy_strings(ctx, pbRecvBuffer, *pcbRecvLength, response, responseSize);
2030 pioRecvPci->dwProtocol = hdl->dwActiveProtocol;
2034 WLog_Print(smartcard->log, smartcard->log_default_level,
2035 "SCardTransmit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2036 WINPR_CXX_COMPAT_CAST(UINT32, status));
2041LONG WINAPI Emulate_SCardGetTransmitCount(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2042 LPDWORD pcTransmitCount)
2044 LONG status = scard_handle_valid(smartcard, hCard);
2046 if (!pcTransmitCount)
2047 status = SCARD_E_INVALID_PARAMETER;
2049 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetTransmitCount { hCard: %p",
2052 if (status == SCARD_S_SUCCESS)
2054 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2057 *pcTransmitCount = hdl->transmitcount;
2060 WLog_Print(smartcard->log, smartcard->log_default_level,
2061 "SCardGetTransmitCount } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2062 WINPR_CXX_COMPAT_CAST(UINT32, status));
2067LONG WINAPI Emulate_SCardControl(
2068 SmartcardEmulationContext* smartcard, SCARDHANDLE hCard, DWORD dwControlCode,
2069 LPCVOID lpInBuffer, DWORD cbInBufferSize, LPVOID lpOutBuffer, DWORD cbOutBufferSize,
2070 LPDWORD lpBytesReturned )
2072 LONG status = scard_handle_valid(smartcard, hCard);
2074 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardControl { hCard: %p",
2077 if (status == SCARD_S_SUCCESS)
2079 WINPR_UNUSED(dwControlCode);
2080 WINPR_UNUSED(lpInBuffer);
2081 WINPR_UNUSED(cbInBufferSize);
2082 WINPR_UNUSED(lpOutBuffer);
2083 WINPR_UNUSED(cbOutBufferSize);
2084 WINPR_UNUSED(lpBytesReturned);
2087 status = SCARD_E_UNSUPPORTED_FEATURE;
2090 WLog_Print(smartcard->log, smartcard->log_default_level,
2091 "SCardControl } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2092 WINPR_CXX_COMPAT_CAST(UINT32, status));
2097LONG WINAPI Emulate_SCardGetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2100 LPDWORD pcbAttrLen )
2102 LONG status = scard_handle_valid(smartcard, hCard);
2104 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetAttrib { hCard: %p",
2107 WINPR_UNUSED(dwAttrId);
2108 WINPR_UNUSED(pbAttr);
2109 WINPR_UNUSED(pcbAttrLen);
2112 if (status == SCARD_S_SUCCESS)
2113 status = SCARD_F_INTERNAL_ERROR;
2115 WLog_Print(smartcard->log, smartcard->log_default_level,
2116 "SCardGetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2117 WINPR_CXX_COMPAT_CAST(UINT32, status));
2122LONG WINAPI Emulate_SCardSetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2123 DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
2125 LONG status = scard_handle_valid(smartcard, hCard);
2127 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardSetAttrib { hCard: %p",
2130 WINPR_UNUSED(dwAttrId);
2131 WINPR_UNUSED(pbAttr);
2132 WINPR_UNUSED(cbAttrLen);
2135 if (status == SCARD_S_SUCCESS)
2136 status = SCARD_F_INTERNAL_ERROR;
2138 WLog_Print(smartcard->log, smartcard->log_default_level,
2139 "SCardSetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2140 WINPR_CXX_COMPAT_CAST(UINT32, status));
2145LONG WINAPI Emulate_SCardUIDlgSelectCardA(SmartcardEmulationContext* smartcard,
2146 LPOPENCARDNAMEA_EX pDlgStruc)
2150 WINPR_ASSERT(smartcard);
2152 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardA {");
2154 WINPR_UNUSED(pDlgStruc);
2157 status = SCARD_E_UNSUPPORTED_FEATURE;
2159 WLog_Print(smartcard->log, smartcard->log_default_level,
2160 "SCardUIDlgSelectCardA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2161 WINPR_CXX_COMPAT_CAST(UINT32, status));
2166LONG WINAPI Emulate_SCardUIDlgSelectCardW(SmartcardEmulationContext* smartcard,
2167 LPOPENCARDNAMEW_EX pDlgStruc)
2171 WINPR_ASSERT(smartcard);
2173 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardW {");
2175 WINPR_UNUSED(pDlgStruc);
2178 status = SCARD_E_UNSUPPORTED_FEATURE;
2180 WLog_Print(smartcard->log, smartcard->log_default_level,
2181 "SCardUIDlgSelectCardW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2182 WINPR_CXX_COMPAT_CAST(UINT32, status));
2187LONG WINAPI Emulate_GetOpenCardNameA(SmartcardEmulationContext* smartcard,
2192 WINPR_ASSERT(smartcard);
2194 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameA {");
2196 WINPR_UNUSED(pDlgStruc);
2199 status = SCARD_E_UNSUPPORTED_FEATURE;
2201 WLog_Print(smartcard->log, smartcard->log_default_level,
2202 "GetOpenCardNameA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2203 WINPR_CXX_COMPAT_CAST(UINT32, status));
2208LONG WINAPI Emulate_GetOpenCardNameW(SmartcardEmulationContext* smartcard,
2213 WINPR_ASSERT(smartcard);
2215 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameW {");
2217 WINPR_UNUSED(pDlgStruc);
2220 status = SCARD_E_UNSUPPORTED_FEATURE;
2222 WLog_Print(smartcard->log, smartcard->log_default_level,
2223 "GetOpenCardNameW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2224 WINPR_CXX_COMPAT_CAST(UINT32, status));
2229LONG WINAPI Emulate_SCardDlgExtendedError(SmartcardEmulationContext* smartcard)
2233 WINPR_ASSERT(smartcard);
2235 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDlgExtendedError {");
2238 status = SCARD_E_UNSUPPORTED_FEATURE;
2240 WLog_Print(smartcard->log, smartcard->log_default_level,
2241 "SCardDlgExtendedError } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2242 WINPR_CXX_COMPAT_CAST(UINT32, status));
2247LONG WINAPI Emulate_SCardReadCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2248 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2249 PBYTE Data, DWORD* DataLen)
2252 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2254 if (!CardIdentifier || !DataLen)
2255 status = SCARD_E_INVALID_PARAMETER;
2257 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheA { hContext: %p",
2266 if (status == SCARD_S_SUCCESS)
2268 SCardCacheItem* data =
nullptr;
2269 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2270 WINPR_ASSERT(value);
2272 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2274 data = HashTable_GetItemValue(value->cache,
id);
2278 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2279 else if (data->freshness != FreshnessCounter)
2280 status = SCARD_W_CACHE_ITEM_STALE;
2282 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2285 WLog_Print(smartcard->log, smartcard->log_default_level,
2286 "SCardReadCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2287 WINPR_CXX_COMPAT_CAST(UINT32, status));
2292LONG WINAPI Emulate_SCardReadCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2293 UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName,
2294 PBYTE Data, DWORD* DataLen)
2297 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2299 if (!CardIdentifier || !DataLen)
2300 status = SCARD_E_INVALID_PARAMETER;
2302 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheW { hContext: %p",
2311 if (status == SCARD_S_SUCCESS)
2313 SCardCacheItem* data =
nullptr;
2314 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2315 WINPR_ASSERT(value);
2317 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2318 data = HashTable_GetItemValue(value->cache,
id);
2321 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2322 else if (data->freshness != FreshnessCounter)
2323 status = SCARD_W_CACHE_ITEM_STALE;
2325 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2328 WLog_Print(smartcard->log, smartcard->log_default_level,
2329 "SCardReadCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2330 WINPR_CXX_COMPAT_CAST(UINT32, status));
2335static LONG insert_data(wHashTable* table, DWORD FreshnessCounter,
const char* key,
2336 const PBYTE Data, DWORD DataLen)
2339 SCardCacheItem* item =
nullptr;
2341 WINPR_ASSERT(table);
2344 if (DataLen > MAX_CACHE_ITEM_SIZE)
2345 return SCARD_W_CACHE_ITEM_TOO_BIG;
2347 if (HashTable_Count(table) > MAX_CACHE_ITEM_VALUES)
2348 return SCARD_E_WRITE_TOO_MANY;
2350 item = HashTable_GetItemValue(table, key);
2353 item = calloc(1,
sizeof(SCardCacheItem));
2355 return SCARD_E_NO_MEMORY;
2357 rc = HashTable_Insert(table, key, item);
2361 return SCARD_E_NO_MEMORY;
2365 if (item->freshness > FreshnessCounter)
2366 return SCARD_W_CACHE_ITEM_STALE;
2367 item->freshness = FreshnessCounter;
2368 item->size = DataLen;
2369 memcpy(item->data, Data, DataLen);
2372 return SCARD_S_SUCCESS;
2375LONG WINAPI Emulate_SCardWriteCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2376 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2377 PBYTE Data, DWORD DataLen)
2379 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2381 if (!CardIdentifier)
2382 status = SCARD_E_INVALID_PARAMETER;
2384 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheA { hContext: %p",
2387 if (status == SCARD_S_SUCCESS)
2389 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2390 WINPR_ASSERT(value);
2392 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2394 status = SCARD_E_NO_MEMORY;
2397 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2402 WLog_Print(smartcard->log, smartcard->log_default_level,
2403 "SCardWriteCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2404 WINPR_CXX_COMPAT_CAST(UINT32, status));
2409LONG WINAPI Emulate_SCardWriteCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2410 UUID* CardIdentifier, DWORD FreshnessCounter,
2411 LPWSTR LookupName, PBYTE Data, DWORD DataLen)
2413 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2415 if (!CardIdentifier)
2416 status = SCARD_E_INVALID_PARAMETER;
2418 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheW { hContext: %p",
2421 if (status == SCARD_S_SUCCESS)
2423 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2424 WINPR_ASSERT(value);
2426 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2428 status = SCARD_E_NO_MEMORY;
2431 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2436 WLog_Print(smartcard->log, smartcard->log_default_level,
2437 "SCardWriteCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2438 WINPR_CXX_COMPAT_CAST(UINT32, status));
2443LONG WINAPI Emulate_SCardGetReaderIconA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2444 LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2446 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2448 if (!szReaderName || !pcbIcon)
2449 status = SCARD_E_INVALID_PARAMETER;
2451 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconA { hContext: %p",
2454 if (status == SCARD_S_SUCCESS)
2455 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2457 if (status == SCARD_S_SUCCESS)
2459 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2463 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2464 resources_FreeRDP_ico_len);
2466 *pcbIcon = resources_FreeRDP_ico_len;
2469 WLog_Print(smartcard->log, smartcard->log_default_level,
2470 "SCardGetReaderIconA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2471 WINPR_CXX_COMPAT_CAST(UINT32, status));
2476LONG WINAPI Emulate_SCardGetReaderIconW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2477 LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2479 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2481 if (!szReaderName || !pcbIcon)
2482 status = SCARD_E_INVALID_PARAMETER;
2484 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconW { hContext: %p",
2487 if (status == SCARD_S_SUCCESS)
2488 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2490 if (status == SCARD_S_SUCCESS)
2492 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2496 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2497 resources_FreeRDP_ico_len);
2499 *pcbIcon = resources_FreeRDP_ico_len;
2502 WLog_Print(smartcard->log, smartcard->log_default_level,
2503 "SCardGetReaderIconW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2504 WINPR_CXX_COMPAT_CAST(UINT32, status));
2509LONG WINAPI Emulate_SCardGetDeviceTypeIdA(SmartcardEmulationContext* smartcard,
2510 SCARDCONTEXT hContext, LPCSTR szReaderName,
2511 LPDWORD pdwDeviceTypeId)
2513 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2515 if (!pdwDeviceTypeId)
2516 status = SCARD_E_INVALID_PARAMETER;
2518 if (status == SCARD_S_SUCCESS)
2519 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2521 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdA { hContext: %p",
2524 if (status == SCARD_S_SUCCESS)
2526 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2529 WLog_Print(smartcard->log, smartcard->log_default_level,
2530 "SCardGetDeviceTypeIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2531 WINPR_CXX_COMPAT_CAST(UINT32, status));
2536LONG WINAPI Emulate_SCardGetDeviceTypeIdW(SmartcardEmulationContext* smartcard,
2537 SCARDCONTEXT hContext, LPCWSTR szReaderName,
2538 LPDWORD pdwDeviceTypeId)
2540 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2542 if (!pdwDeviceTypeId)
2543 status = SCARD_E_INVALID_PARAMETER;
2545 if (status == SCARD_S_SUCCESS)
2546 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2548 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdW { hContext: %p",
2551 if (status == SCARD_S_SUCCESS)
2553 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2556 WLog_Print(smartcard->log, smartcard->log_default_level,
2557 "SCardGetDeviceTypeIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2558 WINPR_CXX_COMPAT_CAST(UINT32, status));
2563LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdA(
2564 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szReaderName,
2565 LPSTR szDeviceInstanceId ,
2566 LPDWORD pcchDeviceInstanceId )
2568 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2570 if (status == SCARD_S_SUCCESS)
2571 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2573 WLog_Print(smartcard->log, smartcard->log_default_level,
2574 "SCardGetReaderDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2576 WINPR_UNUSED(szDeviceInstanceId);
2577 WINPR_UNUSED(pcchDeviceInstanceId);
2580 if (status == SCARD_S_SUCCESS)
2581 status = SCARD_E_UNSUPPORTED_FEATURE;
2583 WLog_Print(smartcard->log, smartcard->log_default_level,
2584 "SCardGetReaderDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2585 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2590LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdW(
2591 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szReaderName,
2592 LPWSTR szDeviceInstanceId ,
2593 LPDWORD pcchDeviceInstanceId )
2595 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2597 if (status == SCARD_S_SUCCESS)
2598 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2600 WLog_Print(smartcard->log, smartcard->log_default_level,
2601 "SCardGetReaderDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2603 WINPR_UNUSED(szDeviceInstanceId);
2604 WINPR_UNUSED(pcchDeviceInstanceId);
2607 if (status == SCARD_S_SUCCESS)
2608 status = SCARD_E_UNSUPPORTED_FEATURE;
2610 WLog_Print(smartcard->log, smartcard->log_default_level,
2611 "SCardGetReaderDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2612 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2617LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdA(
2618 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szDeviceInstanceId,
2620 LPDWORD pcchReaders )
2622 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2624 WLog_Print(smartcard->log, smartcard->log_default_level,
2625 "SCardListReadersWithDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2627 WINPR_UNUSED(szDeviceInstanceId);
2628 WINPR_UNUSED(mszReaders);
2629 WINPR_UNUSED(pcchReaders);
2632 if (status == SCARD_S_SUCCESS)
2633 status = SCARD_E_UNSUPPORTED_FEATURE;
2635 WLog_Print(smartcard->log, smartcard->log_default_level,
2636 "SCardListReadersWithDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2637 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2642LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdW(
2643 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szDeviceInstanceId,
2644 LPWSTR mszReaders , LPDWORD pcchReaders)
2646 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2648 WLog_Print(smartcard->log, smartcard->log_default_level,
2649 "SCardListReadersWithDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2651 WINPR_UNUSED(szDeviceInstanceId);
2652 WINPR_UNUSED(mszReaders);
2653 WINPR_UNUSED(pcchReaders);
2656 if (status == SCARD_S_SUCCESS)
2657 status = SCARD_E_UNSUPPORTED_FEATURE;
2659 WLog_Print(smartcard->log, smartcard->log_default_level,
2660 "SCardListReadersWithDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2661 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2666LONG WINAPI Emulate_SCardAudit(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2669 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2671 WINPR_UNUSED(dwEvent);
2673 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAudit { hContext: %p",
2677 if (status == SCARD_S_SUCCESS)
2678 status = SCARD_E_UNSUPPORTED_FEATURE;
2680 WLog_Print(smartcard->log, smartcard->log_default_level,
2681 "SCardAudit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2682 WINPR_CXX_COMPAT_CAST(UINT32, status));
2687static BOOL context_equals(
const void* pva,
const void* pvb)
2689 const SCARDCONTEXT a = (
const SCARDCONTEXT)pva;
2690 const SCARDCONTEXT b = (
const SCARDCONTEXT)pvb;
2699static BOOL handle_equals(
const void* pva,
const void* pvb)
2701 const SCARDHANDLE a = (
const SCARDHANDLE)pva;
2702 const SCARDHANDLE b = (
const SCARDHANDLE)pvb;
2711SmartcardEmulationContext* Emulate_New(
const rdpSettings* settings)
2713 SmartcardEmulationContext* smartcard =
nullptr;
2715 WINPR_ASSERT(settings);
2717 smartcard = calloc(1,
sizeof(SmartcardEmulationContext));
2721 smartcard->settings = settings;
2722 smartcard->log = WLog_Get(
"EmulateSCard");
2723 if (!smartcard->log)
2725 smartcard->log_default_level = WLOG_TRACE;
2727 smartcard->contexts = HashTable_New(FALSE);
2728 if (!smartcard->contexts)
2732 wObject* obj = HashTable_KeyObject(smartcard->contexts);
2736 if (!smartcard->contexts)
2740 wObject* obj = HashTable_ValueObject(smartcard->contexts);
2745 smartcard->handles = HashTable_New(FALSE);
2746 if (!smartcard->handles)
2750 wObject* obj = HashTable_KeyObject(smartcard->handles);
2754 if (!smartcard->handles)
2758 wObject* obj = HashTable_ValueObject(smartcard->handles);
2766 WINPR_PRAGMA_DIAG_PUSH
2767 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2768 Emulate_Free(smartcard);
2769 WINPR_PRAGMA_DIAG_POP
2773void Emulate_Free(SmartcardEmulationContext* context)
2778 HashTable_Free(context->handles);
2779 HashTable_Free(context->contexts);
2783BOOL Emulate_IsConfigured(SmartcardEmulationContext* context)
2786 vgidsContext* vgids =
nullptr;
2787 const char* pem =
nullptr;
2788 const char* key =
nullptr;
2789 const char* pin =
nullptr;
2791 WINPR_ASSERT(context);
2798 if ((context->pem == pem) && (context->key == key) && (context->pin == pin))
2799 return context->configured;
2805 vgids = vgids_new();
2807 rc = vgids_init(vgids, context->pem, context->key, context->pin);
2810 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