21#include <freerdp/config.h>
22#include <freerdp/freerdp.h>
25#include <winpr/wlog.h>
26#include <winpr/file.h>
27#include <winpr/path.h>
28#include <winpr/library.h>
29#include <winpr/smartcard.h>
30#include <winpr/collections.h>
31#include <winpr/crypto.h>
33#include <freerdp/emulate/scard/smartcard_emulate.h>
34#include "FreeRDP.ico.h"
36#include "smartcard_virtual_gids.h"
38#define MAX_CACHE_ITEM_SIZE 4096
39#define MAX_CACHE_ITEM_VALUES 4096
41static CHAR g_ReaderNameA[] = {
'F',
'r',
'e',
'e',
'R',
'D',
'P',
' ',
'E',
42 'm',
'u',
'l',
'a',
't',
'o',
'r',
'\0',
'\0' };
43static INIT_ONCE g_ReaderNameWGuard = INIT_ONCE_STATIC_INIT;
44static WCHAR g_ReaderNameW[32] = WINPR_C_ARRAY_INIT;
45static size_t g_ReaderNameWLen = 0;
47static char* card_id_and_name_a(
const UUID* CardIdentifier, LPCSTR LookupName)
49 WINPR_ASSERT(CardIdentifier);
50 WINPR_ASSERT(LookupName);
52 size_t len = strlen(LookupName) + 34;
53 char*
id = malloc(len);
57 (void)snprintf(
id, len,
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X\\%s",
58 CardIdentifier->Data1, CardIdentifier->Data2, CardIdentifier->Data3,
59 CardIdentifier->Data4[0], CardIdentifier->Data4[1], CardIdentifier->Data4[2],
60 CardIdentifier->Data4[3], CardIdentifier->Data4[4], CardIdentifier->Data4[5],
61 CardIdentifier->Data4[6], CardIdentifier->Data4[7], LookupName);
65static char* card_id_and_name_w(
const UUID* CardIdentifier, LPCWSTR LookupName)
68 char* tmp = ConvertWCharToUtf8Alloc(LookupName,
nullptr);
71 res = card_id_and_name_a(CardIdentifier, tmp);
76static BOOL CALLBACK g_ReaderNameWInit(
PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
78 WINPR_UNUSED(InitOnce);
79 WINPR_UNUSED(Parameter);
80 WINPR_UNUSED(Context);
81 InitializeConstWCharFromUtf8(g_ReaderNameA, g_ReaderNameW, ARRAYSIZE(g_ReaderNameW));
82 g_ReaderNameWLen = _wcsnlen(g_ReaderNameW, ARRAYSIZE(g_ReaderNameW) - 2) + 2;
86struct smartcard_emulation_context
88 const rdpSettings* settings;
89 DWORD log_default_level;
99#define MAX_EMULATED_READERS 1
123 DWORD dwActiveProtocol;
124 SCARDCONTEXT hContext;
127 size_t referencecount;
134 char data[MAX_CACHE_ITEM_SIZE];
137static SCardHandle* find_reader(SmartcardEmulationContext* smartcard,
const void* szReader,
140static const BYTE ATR[] = { 0x3b, 0xf7, 0x18, 0x00, 0x00, 0x80, 0x31, 0xfe, 0x45,
141 0x73, 0x66, 0x74, 0x65, 0x2d, 0x6e, 0x66, 0xc4 };
143static BOOL scard_status_transition(SCardContext* context)
145 WINPR_ASSERT(context);
147 switch (context->readerState)
153 reader->szReader = g_ReaderNameA;
154 reader->dwEventState = SCARD_STATE_PRESENT;
155 reader->cbAtr =
sizeof(ATR);
156 memcpy(reader->rgbAtr, ATR,
sizeof(ATR));
159 if (!InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit,
nullptr,
nullptr))
162 reader->szReader = g_ReaderNameW;
163 reader->dwEventState = SCARD_STATE_PRESENT;
164 reader->cbAtr =
sizeof(ATR);
165 memcpy(reader->rgbAtr, ATR,
sizeof(ATR));
167 context->readerState = 42;
174static UINT32 scard_copy_strings(SCardContext* ctx,
void* dst,
size_t dstSize,
const void* src,
180 WINPR_ASSERT(srcSize <= UINT32_MAX);
181 WINPR_ASSERT(dstSize <= UINT32_MAX);
183 if (dstSize == SCARD_AUTOALLOCATE)
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 UINT_PTR* keys =
nullptr;
1578 WINPR_ASSERT(smartcard);
1579 count = HashTable_GetKeys(smartcard->handles, &keys);
1580 for (
size_t x = 0; x < count; x++)
1582 SCardHandle* cur = HashTable_GetItemValue(smartcard->handles, (
const void*)keys[x]);
1585 if (cur->unicode != unicode)
1587 if (!unicode && (strcmp(cur->szReader.pc, szReader) != 0))
1589 if (unicode && (_wcscmp(cur->szReader.pw, szReader) != 0))
1598WINPR_ATTR_MALLOC(scard_handle_free, 1)
1599static SCardHandle* reader2handle(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1600 const
void* szReader, BOOL unicode, DWORD dwShareMode,
1601 SCARDHANDLE* phCard, DWORD dwPreferredProtocols,
1602 LPDWORD pdwActiveProtocol)
1604 SCardHandle* hdl =
nullptr;
1606 WINPR_ASSERT(phCard);
1609 if (Emulate_SCardIsValidContext(smartcard, hContext) != SCARD_S_SUCCESS)
1612 hdl = scard_handle_new(smartcard, hContext, szReader, unicode);
1615 if (winpr_RAND(&hdl->card,
sizeof(hdl->card)) < 0)
1617 scard_handle_free(hdl);
1620 hdl->dwActiveProtocol = SCARD_PROTOCOL_T1;
1621 hdl->dwShareMode = dwShareMode;
1623 if (!HashTable_Insert(smartcard->handles, (
const void*)hdl->card, hdl))
1625 scard_handle_free(hdl);
1630 if (pdwActiveProtocol)
1632 if ((hdl->dwActiveProtocol & dwPreferredProtocols) == 0)
1634 scard_handle_free(hdl);
1638 *pdwActiveProtocol = hdl->dwActiveProtocol;
1642 hdl->referencecount++;
1643 *phCard = hdl->card;
1647 WLog_Print(smartcard->log, smartcard->log_default_level,
"{ %p }", (
void*)*phCard);
1651LONG WINAPI Emulate_SCardConnectA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1652 LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1653 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1655 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1657 if (!phCard || !pdwActiveProtocol)
1658 status = SCARD_E_INVALID_PARAMETER;
1660 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectA { hContext: %p",
1663 if (status == SCARD_S_SUCCESS)
1665 if (!reader2handle(smartcard, hContext, szReader, FALSE, dwShareMode, phCard,
1666 dwPreferredProtocols, pdwActiveProtocol))
1667 status = SCARD_E_NO_MEMORY;
1670 WLog_Print(smartcard->log, smartcard->log_default_level,
1671 "SCardConnectA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1672 WINPR_CXX_COMPAT_CAST(UINT32, status));
1677LONG WINAPI Emulate_SCardConnectW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1678 LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1679 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1681 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1683 if (!phCard || !pdwActiveProtocol)
1684 status = SCARD_E_INVALID_PARAMETER;
1686 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectW { hContext: %p",
1689 if (status == SCARD_S_SUCCESS)
1691 if (!reader2handle(smartcard, hContext, szReader, TRUE, dwShareMode, phCard,
1692 dwPreferredProtocols, pdwActiveProtocol))
1693 status = SCARD_E_NO_MEMORY;
1696 WLog_Print(smartcard->log, smartcard->log_default_level,
1697 "SCardConnectW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1698 WINPR_CXX_COMPAT_CAST(UINT32, status));
1703LONG WINAPI Emulate_SCardReconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1704 DWORD dwShareMode, WINPR_ATTR_UNUSED DWORD dwPreferredProtocols,
1705 WINPR_ATTR_UNUSED DWORD dwInitialization,
1706 LPDWORD pdwActiveProtocol)
1708 LONG status = scard_handle_valid(smartcard, hCard);
1710 if (!pdwActiveProtocol)
1711 status = SCARD_E_INVALID_PARAMETER;
1713 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReconnect { hCard: %p",
1716 if (status == SCARD_S_SUCCESS)
1718 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1722 hdl->dwShareMode = dwShareMode;
1723 hdl->transaction = FALSE;
1725 *pdwActiveProtocol = hdl->dwActiveProtocol;
1728 WLog_Print(smartcard->log, smartcard->log_default_level,
1729 "SCardReconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1730 WINPR_CXX_COMPAT_CAST(UINT32, status));
1735LONG WINAPI Emulate_SCardDisconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1736 DWORD dwDisposition)
1738 LONG status = scard_handle_valid(smartcard, hCard);
1740 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDisconnect { hCard: %p",
1743 WINPR_UNUSED(dwDisposition);
1745 if (status == SCARD_S_SUCCESS)
1747 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1750 hdl->referencecount--;
1751 if (hdl->referencecount == 0)
1752 HashTable_Remove(smartcard->handles, (
const void*)hCard);
1755 WLog_Print(smartcard->log, smartcard->log_default_level,
1756 "SCardDisconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1757 WINPR_CXX_COMPAT_CAST(UINT32, status));
1762LONG WINAPI Emulate_SCardBeginTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1764 LONG status = scard_handle_valid(smartcard, hCard);
1766 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardBeginTransaction { hCard: %p",
1769 if (status == SCARD_S_SUCCESS)
1771 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1773 if (hdl->transaction)
1774 status = SCARD_E_INVALID_VALUE;
1776 hdl->transaction = TRUE;
1779 WLog_Print(smartcard->log, smartcard->log_default_level,
1780 "SCardBeginTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1781 WINPR_CXX_COMPAT_CAST(UINT32, status));
1786LONG WINAPI Emulate_SCardEndTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1787 DWORD dwDisposition)
1789 LONG status = scard_handle_valid(smartcard, hCard);
1791 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardEndTransaction { hCard: %p",
1794 WINPR_UNUSED(dwDisposition);
1796 if (status == SCARD_S_SUCCESS)
1798 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1800 if (!hdl->transaction)
1801 status = SCARD_E_NOT_TRANSACTED;
1803 hdl->transaction = FALSE;
1806 WLog_Print(smartcard->log, smartcard->log_default_level,
1807 "SCardEndTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1808 WINPR_CXX_COMPAT_CAST(UINT32, status));
1813LONG WINAPI Emulate_SCardCancelTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1815 LONG status = scard_handle_valid(smartcard, hCard);
1817 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancelTransaction { hCard: %p",
1820 if (status == SCARD_S_SUCCESS)
1822 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1824 if (!hdl->transaction)
1825 status = SCARD_E_NOT_TRANSACTED;
1827 hdl->transaction = FALSE;
1830 WLog_Print(smartcard->log, smartcard->log_default_level,
1831 "SCardCancelTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1832 WINPR_CXX_COMPAT_CAST(UINT32, status));
1837LONG WINAPI Emulate_SCardState(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1838 LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
1841 LONG status = scard_handle_valid(smartcard, hCard);
1843 if (!pdwState || !pdwProtocol)
1844 status = SCARD_E_INVALID_PARAMETER;
1846 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardState { hCard: %p",
1849 if (status == SCARD_S_SUCCESS)
1851 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1855 *pdwState = SCARD_SPECIFIC;
1857 *pdwProtocol = SCARD_PROTOCOL_T1;
1862 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1865 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1871 if (_wcscmp(readerW->szReader, hdl->szReader.pw) == 0)
1873 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerW->rgbAtr,
1879 if (strcmp(readerA->szReader, hdl->szReader.pc) == 0)
1881 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerA->rgbAtr,
1889 WLog_Print(smartcard->log, smartcard->log_default_level,
1890 "SCardState } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1891 WINPR_CXX_COMPAT_CAST(UINT32, status));
1896LONG WINAPI Emulate_SCardStatusA(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1897 LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1898 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1900 LONG status = scard_handle_valid(smartcard, hCard);
1902 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusA { hCard: %p",
1905 if (status == SCARD_S_SUCCESS)
1907 SCardContext* ctx =
nullptr;
1908 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1911 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1916 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pc,
1917 (UINT32)strlen(hdl->szReader.pc) + 2);
1920 *pdwState = SCARD_SPECIFIC;
1922 *pdwProtocol = SCARD_PROTOCOL_T1;
1926 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1929 if (strcmp(reader->szReader, hdl->szReader.pc) == 0)
1932 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1938 WLog_Print(smartcard->log, smartcard->log_default_level,
1939 "SCardStatusA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1940 WINPR_CXX_COMPAT_CAST(UINT32, status));
1945LONG WINAPI Emulate_SCardStatusW(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1946 LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1947 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1949 LONG status = scard_handle_valid(smartcard, hCard);
1951 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusW { hCard: %p",
1954 if (status == SCARD_S_SUCCESS)
1956 SCardContext* ctx =
nullptr;
1957 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1960 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1965 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pw,
1966 (UINT32)(_wcslen(hdl->szReader.pw) + 2) *
sizeof(WCHAR)) /
1970 *pdwState = SCARD_SPECIFIC;
1972 *pdwProtocol = SCARD_PROTOCOL_T1;
1976 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1979 if (_wcscmp(reader->szReader, hdl->szReader.pw) == 0)
1981 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1986 WLog_Print(smartcard->log, smartcard->log_default_level,
1987 "SCardStatusW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1988 WINPR_CXX_COMPAT_CAST(UINT32, status));
1993LONG WINAPI Emulate_SCardTransmit(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1996 LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
1998 LONG status = scard_handle_valid(smartcard, hCard);
2000 if (!pioSendPci || !pbSendBuffer || !pbRecvBuffer || !pcbRecvLength)
2001 status = SCARD_E_INVALID_PARAMETER;
2003 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardTransmit { hCard: %p",
2006 if (status == SCARD_S_SUCCESS)
2008 BYTE* response =
nullptr;
2009 DWORD responseSize = 0;
2010 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2013 hdl->transmitcount++;
2015 if (!vgids_process_apdu(hdl->vgids, pbSendBuffer, cbSendLength, &response, &responseSize))
2016 status = SCARD_E_NO_SMARTCARD;
2020 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
2024 scard_copy_strings(ctx, pbRecvBuffer, *pcbRecvLength, response, responseSize);
2029 pioRecvPci->dwProtocol = hdl->dwActiveProtocol;
2033 WLog_Print(smartcard->log, smartcard->log_default_level,
2034 "SCardTransmit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2035 WINPR_CXX_COMPAT_CAST(UINT32, status));
2040LONG WINAPI Emulate_SCardGetTransmitCount(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2041 LPDWORD pcTransmitCount)
2043 LONG status = scard_handle_valid(smartcard, hCard);
2045 if (!pcTransmitCount)
2046 status = SCARD_E_INVALID_PARAMETER;
2048 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetTransmitCount { hCard: %p",
2051 if (status == SCARD_S_SUCCESS)
2053 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2056 *pcTransmitCount = hdl->transmitcount;
2059 WLog_Print(smartcard->log, smartcard->log_default_level,
2060 "SCardGetTransmitCount } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2061 WINPR_CXX_COMPAT_CAST(UINT32, status));
2066LONG WINAPI Emulate_SCardControl(
2067 SmartcardEmulationContext* smartcard, SCARDHANDLE hCard, DWORD dwControlCode,
2068 LPCVOID lpInBuffer, DWORD cbInBufferSize, LPVOID lpOutBuffer, DWORD cbOutBufferSize,
2069 LPDWORD lpBytesReturned )
2071 LONG status = scard_handle_valid(smartcard, hCard);
2073 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardControl { hCard: %p",
2076 if (status == SCARD_S_SUCCESS)
2078 WINPR_UNUSED(dwControlCode);
2079 WINPR_UNUSED(lpInBuffer);
2080 WINPR_UNUSED(cbInBufferSize);
2081 WINPR_UNUSED(lpOutBuffer);
2082 WINPR_UNUSED(cbOutBufferSize);
2083 WINPR_UNUSED(lpBytesReturned);
2086 status = SCARD_E_UNSUPPORTED_FEATURE;
2089 WLog_Print(smartcard->log, smartcard->log_default_level,
2090 "SCardControl } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2091 WINPR_CXX_COMPAT_CAST(UINT32, status));
2096LONG WINAPI Emulate_SCardGetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2099 LPDWORD pcbAttrLen )
2101 LONG status = scard_handle_valid(smartcard, hCard);
2103 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetAttrib { hCard: %p",
2106 WINPR_UNUSED(dwAttrId);
2107 WINPR_UNUSED(pbAttr);
2108 WINPR_UNUSED(pcbAttrLen);
2111 if (status == SCARD_S_SUCCESS)
2112 status = SCARD_F_INTERNAL_ERROR;
2114 WLog_Print(smartcard->log, smartcard->log_default_level,
2115 "SCardGetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2116 WINPR_CXX_COMPAT_CAST(UINT32, status));
2121LONG WINAPI Emulate_SCardSetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2122 DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
2124 LONG status = scard_handle_valid(smartcard, hCard);
2126 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardSetAttrib { hCard: %p",
2129 WINPR_UNUSED(dwAttrId);
2130 WINPR_UNUSED(pbAttr);
2131 WINPR_UNUSED(cbAttrLen);
2134 if (status == SCARD_S_SUCCESS)
2135 status = SCARD_F_INTERNAL_ERROR;
2137 WLog_Print(smartcard->log, smartcard->log_default_level,
2138 "SCardSetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2139 WINPR_CXX_COMPAT_CAST(UINT32, status));
2144LONG WINAPI Emulate_SCardUIDlgSelectCardA(SmartcardEmulationContext* smartcard,
2145 LPOPENCARDNAMEA_EX pDlgStruc)
2149 WINPR_ASSERT(smartcard);
2151 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardA {");
2153 WINPR_UNUSED(pDlgStruc);
2156 status = SCARD_E_UNSUPPORTED_FEATURE;
2158 WLog_Print(smartcard->log, smartcard->log_default_level,
2159 "SCardUIDlgSelectCardA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2160 WINPR_CXX_COMPAT_CAST(UINT32, status));
2165LONG WINAPI Emulate_SCardUIDlgSelectCardW(SmartcardEmulationContext* smartcard,
2166 LPOPENCARDNAMEW_EX pDlgStruc)
2170 WINPR_ASSERT(smartcard);
2172 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardW {");
2174 WINPR_UNUSED(pDlgStruc);
2177 status = SCARD_E_UNSUPPORTED_FEATURE;
2179 WLog_Print(smartcard->log, smartcard->log_default_level,
2180 "SCardUIDlgSelectCardW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2181 WINPR_CXX_COMPAT_CAST(UINT32, status));
2186LONG WINAPI Emulate_GetOpenCardNameA(SmartcardEmulationContext* smartcard,
2191 WINPR_ASSERT(smartcard);
2193 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameA {");
2195 WINPR_UNUSED(pDlgStruc);
2198 status = SCARD_E_UNSUPPORTED_FEATURE;
2200 WLog_Print(smartcard->log, smartcard->log_default_level,
2201 "GetOpenCardNameA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2202 WINPR_CXX_COMPAT_CAST(UINT32, status));
2207LONG WINAPI Emulate_GetOpenCardNameW(SmartcardEmulationContext* smartcard,
2212 WINPR_ASSERT(smartcard);
2214 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameW {");
2216 WINPR_UNUSED(pDlgStruc);
2219 status = SCARD_E_UNSUPPORTED_FEATURE;
2221 WLog_Print(smartcard->log, smartcard->log_default_level,
2222 "GetOpenCardNameW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2223 WINPR_CXX_COMPAT_CAST(UINT32, status));
2228LONG WINAPI Emulate_SCardDlgExtendedError(SmartcardEmulationContext* smartcard)
2232 WINPR_ASSERT(smartcard);
2234 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDlgExtendedError {");
2237 status = SCARD_E_UNSUPPORTED_FEATURE;
2239 WLog_Print(smartcard->log, smartcard->log_default_level,
2240 "SCardDlgExtendedError } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2241 WINPR_CXX_COMPAT_CAST(UINT32, status));
2246LONG WINAPI Emulate_SCardReadCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2247 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2248 PBYTE Data, DWORD* DataLen)
2251 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2253 if (!CardIdentifier || !DataLen)
2254 status = SCARD_E_INVALID_PARAMETER;
2256 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheA { hContext: %p",
2265 if (status == SCARD_S_SUCCESS)
2267 SCardCacheItem* data =
nullptr;
2268 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2269 WINPR_ASSERT(value);
2271 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2272 data = HashTable_GetItemValue(value->cache,
id);
2276 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2277 else if (data->freshness != FreshnessCounter)
2278 status = SCARD_W_CACHE_ITEM_STALE;
2280 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2283 WLog_Print(smartcard->log, smartcard->log_default_level,
2284 "SCardReadCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2285 WINPR_CXX_COMPAT_CAST(UINT32, status));
2290LONG WINAPI Emulate_SCardReadCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2291 UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName,
2292 PBYTE Data, DWORD* DataLen)
2295 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2297 if (!CardIdentifier || !DataLen)
2298 status = SCARD_E_INVALID_PARAMETER;
2300 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheW { hContext: %p",
2309 if (status == SCARD_S_SUCCESS)
2311 SCardCacheItem* data =
nullptr;
2312 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2313 WINPR_ASSERT(value);
2315 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2316 data = HashTable_GetItemValue(value->cache,
id);
2319 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2320 else if (data->freshness != FreshnessCounter)
2321 status = SCARD_W_CACHE_ITEM_STALE;
2323 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2326 WLog_Print(smartcard->log, smartcard->log_default_level,
2327 "SCardReadCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2328 WINPR_CXX_COMPAT_CAST(UINT32, status));
2333static LONG insert_data(wHashTable* table, DWORD FreshnessCounter,
const char* key,
2334 const PBYTE Data, DWORD DataLen)
2337 SCardCacheItem* item =
nullptr;
2339 WINPR_ASSERT(table);
2342 if (DataLen > MAX_CACHE_ITEM_SIZE)
2343 return SCARD_W_CACHE_ITEM_TOO_BIG;
2345 if (HashTable_Count(table) > MAX_CACHE_ITEM_VALUES)
2346 return SCARD_E_WRITE_TOO_MANY;
2348 item = HashTable_GetItemValue(table, key);
2351 item = calloc(1,
sizeof(SCardCacheItem));
2353 return SCARD_E_NO_MEMORY;
2355 rc = HashTable_Insert(table, key, item);
2359 return SCARD_E_NO_MEMORY;
2363 if (item->freshness > FreshnessCounter)
2364 return SCARD_W_CACHE_ITEM_STALE;
2365 item->freshness = FreshnessCounter;
2366 item->size = DataLen;
2367 memcpy(item->data, Data, DataLen);
2370 return SCARD_S_SUCCESS;
2373LONG WINAPI Emulate_SCardWriteCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2374 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2375 PBYTE Data, DWORD DataLen)
2377 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2379 if (!CardIdentifier)
2380 status = SCARD_E_INVALID_PARAMETER;
2382 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheA { hContext: %p",
2385 if (status == SCARD_S_SUCCESS)
2387 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2388 WINPR_ASSERT(value);
2390 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2392 status = SCARD_E_NO_MEMORY;
2395 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2400 WLog_Print(smartcard->log, smartcard->log_default_level,
2401 "SCardWriteCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2402 WINPR_CXX_COMPAT_CAST(UINT32, status));
2407LONG WINAPI Emulate_SCardWriteCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2408 UUID* CardIdentifier, DWORD FreshnessCounter,
2409 LPWSTR LookupName, PBYTE Data, DWORD DataLen)
2411 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2413 if (!CardIdentifier)
2414 status = SCARD_E_INVALID_PARAMETER;
2416 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheW { hContext: %p",
2419 if (status == SCARD_S_SUCCESS)
2421 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2422 WINPR_ASSERT(value);
2424 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2426 status = SCARD_E_NO_MEMORY;
2429 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2434 WLog_Print(smartcard->log, smartcard->log_default_level,
2435 "SCardWriteCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2436 WINPR_CXX_COMPAT_CAST(UINT32, status));
2441LONG WINAPI Emulate_SCardGetReaderIconA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2442 LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2444 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2446 if (!szReaderName || !pcbIcon)
2447 status = SCARD_E_INVALID_PARAMETER;
2449 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconA { hContext: %p",
2452 if (status == SCARD_S_SUCCESS)
2453 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2455 if (status == SCARD_S_SUCCESS)
2457 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2461 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2462 resources_FreeRDP_ico_len);
2464 *pcbIcon = resources_FreeRDP_ico_len;
2467 WLog_Print(smartcard->log, smartcard->log_default_level,
2468 "SCardGetReaderIconA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2469 WINPR_CXX_COMPAT_CAST(UINT32, status));
2474LONG WINAPI Emulate_SCardGetReaderIconW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2475 LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2477 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2479 if (!szReaderName || !pcbIcon)
2480 status = SCARD_E_INVALID_PARAMETER;
2482 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconW { hContext: %p",
2485 if (status == SCARD_S_SUCCESS)
2486 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2488 if (status == SCARD_S_SUCCESS)
2490 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2494 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2495 resources_FreeRDP_ico_len);
2497 *pcbIcon = resources_FreeRDP_ico_len;
2500 WLog_Print(smartcard->log, smartcard->log_default_level,
2501 "SCardGetReaderIconW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2502 WINPR_CXX_COMPAT_CAST(UINT32, status));
2507LONG WINAPI Emulate_SCardGetDeviceTypeIdA(SmartcardEmulationContext* smartcard,
2508 SCARDCONTEXT hContext, LPCSTR szReaderName,
2509 LPDWORD pdwDeviceTypeId)
2511 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2513 if (!pdwDeviceTypeId)
2514 status = SCARD_E_INVALID_PARAMETER;
2516 if (status == SCARD_S_SUCCESS)
2517 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2519 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdA { hContext: %p",
2522 if (status == SCARD_S_SUCCESS)
2524 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2527 WLog_Print(smartcard->log, smartcard->log_default_level,
2528 "SCardGetDeviceTypeIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2529 WINPR_CXX_COMPAT_CAST(UINT32, status));
2534LONG WINAPI Emulate_SCardGetDeviceTypeIdW(SmartcardEmulationContext* smartcard,
2535 SCARDCONTEXT hContext, LPCWSTR szReaderName,
2536 LPDWORD pdwDeviceTypeId)
2538 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2540 if (!pdwDeviceTypeId)
2541 status = SCARD_E_INVALID_PARAMETER;
2543 if (status == SCARD_S_SUCCESS)
2544 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2546 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdW { hContext: %p",
2549 if (status == SCARD_S_SUCCESS)
2551 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2554 WLog_Print(smartcard->log, smartcard->log_default_level,
2555 "SCardGetDeviceTypeIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2556 WINPR_CXX_COMPAT_CAST(UINT32, status));
2561LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdA(
2562 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szReaderName,
2563 LPSTR szDeviceInstanceId ,
2564 LPDWORD pcchDeviceInstanceId )
2566 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2568 if (status == SCARD_S_SUCCESS)
2569 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2571 WLog_Print(smartcard->log, smartcard->log_default_level,
2572 "SCardGetReaderDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2574 WINPR_UNUSED(szDeviceInstanceId);
2575 WINPR_UNUSED(pcchDeviceInstanceId);
2578 if (status == SCARD_S_SUCCESS)
2579 status = SCARD_E_UNSUPPORTED_FEATURE;
2581 WLog_Print(smartcard->log, smartcard->log_default_level,
2582 "SCardGetReaderDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2583 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2588LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdW(
2589 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szReaderName,
2590 LPWSTR szDeviceInstanceId ,
2591 LPDWORD pcchDeviceInstanceId )
2593 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2595 if (status == SCARD_S_SUCCESS)
2596 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2598 WLog_Print(smartcard->log, smartcard->log_default_level,
2599 "SCardGetReaderDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2601 WINPR_UNUSED(szDeviceInstanceId);
2602 WINPR_UNUSED(pcchDeviceInstanceId);
2605 if (status == SCARD_S_SUCCESS)
2606 status = SCARD_E_UNSUPPORTED_FEATURE;
2608 WLog_Print(smartcard->log, smartcard->log_default_level,
2609 "SCardGetReaderDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2610 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2615LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdA(
2616 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szDeviceInstanceId,
2618 LPDWORD pcchReaders )
2620 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2622 WLog_Print(smartcard->log, smartcard->log_default_level,
2623 "SCardListReadersWithDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2625 WINPR_UNUSED(szDeviceInstanceId);
2626 WINPR_UNUSED(mszReaders);
2627 WINPR_UNUSED(pcchReaders);
2630 if (status == SCARD_S_SUCCESS)
2631 status = SCARD_E_UNSUPPORTED_FEATURE;
2633 WLog_Print(smartcard->log, smartcard->log_default_level,
2634 "SCardListReadersWithDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2635 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2640LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdW(
2641 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szDeviceInstanceId,
2642 LPWSTR mszReaders , LPDWORD pcchReaders)
2644 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2646 WLog_Print(smartcard->log, smartcard->log_default_level,
2647 "SCardListReadersWithDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2649 WINPR_UNUSED(szDeviceInstanceId);
2650 WINPR_UNUSED(mszReaders);
2651 WINPR_UNUSED(pcchReaders);
2654 if (status == SCARD_S_SUCCESS)
2655 status = SCARD_E_UNSUPPORTED_FEATURE;
2657 WLog_Print(smartcard->log, smartcard->log_default_level,
2658 "SCardListReadersWithDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2659 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2664LONG WINAPI Emulate_SCardAudit(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2667 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2669 WINPR_UNUSED(dwEvent);
2671 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAudit { hContext: %p",
2675 if (status == SCARD_S_SUCCESS)
2676 status = SCARD_E_UNSUPPORTED_FEATURE;
2678 WLog_Print(smartcard->log, smartcard->log_default_level,
2679 "SCardAudit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2680 WINPR_CXX_COMPAT_CAST(UINT32, status));
2685static BOOL context_equals(
const void* pva,
const void* pvb)
2687 const SCARDCONTEXT a = (
const SCARDCONTEXT)pva;
2688 const SCARDCONTEXT b = (
const SCARDCONTEXT)pvb;
2697static BOOL handle_equals(
const void* pva,
const void* pvb)
2699 const SCARDHANDLE a = (
const SCARDHANDLE)pva;
2700 const SCARDHANDLE b = (
const SCARDHANDLE)pvb;
2709SmartcardEmulationContext* Emulate_New(
const rdpSettings* settings)
2711 SmartcardEmulationContext* smartcard =
nullptr;
2713 WINPR_ASSERT(settings);
2715 smartcard = calloc(1,
sizeof(SmartcardEmulationContext));
2719 smartcard->settings = settings;
2720 smartcard->log = WLog_Get(
"EmulateSCard");
2721 if (!smartcard->log)
2723 smartcard->log_default_level = WLOG_TRACE;
2725 smartcard->contexts = HashTable_New(FALSE);
2726 if (!smartcard->contexts)
2730 wObject* obj = HashTable_KeyObject(smartcard->contexts);
2734 if (!smartcard->contexts)
2738 wObject* obj = HashTable_ValueObject(smartcard->contexts);
2743 smartcard->handles = HashTable_New(FALSE);
2744 if (!smartcard->handles)
2748 wObject* obj = HashTable_KeyObject(smartcard->handles);
2752 if (!smartcard->handles)
2756 wObject* obj = HashTable_ValueObject(smartcard->handles);
2764 WINPR_PRAGMA_DIAG_PUSH
2765 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2766 Emulate_Free(smartcard);
2767 WINPR_PRAGMA_DIAG_POP
2771void Emulate_Free(SmartcardEmulationContext* context)
2776 HashTable_Free(context->handles);
2777 HashTable_Free(context->contexts);
2781BOOL Emulate_IsConfigured(SmartcardEmulationContext* context)
2784 vgidsContext* vgids =
nullptr;
2785 const char* pem =
nullptr;
2786 const char* key =
nullptr;
2787 const char* pin =
nullptr;
2789 WINPR_ASSERT(context);
2796 if ((context->pem == pem) && (context->key == key) && (context->pin == pin))
2797 return context->configured;
2803 vgids = vgids_new();
2805 rc = vgids_init(vgids, context->pem, context->key, context->pin);
2808 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