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] = { 0 };
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, NULL);
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 InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit, NULL, NULL);
161 reader->szReader = g_ReaderNameW;
162 reader->dwEventState = SCARD_STATE_PRESENT;
163 reader->cbAtr =
sizeof(ATR);
164 memcpy(reader->rgbAtr, ATR,
sizeof(ATR));
166 context->readerState = 42;
173static UINT32 scard_copy_strings(SCardContext* ctx,
void* dst,
size_t dstSize,
const void* src,
179 WINPR_ASSERT(srcSize <= UINT32_MAX);
180 WINPR_ASSERT(dstSize <= UINT32_MAX);
182 if (dstSize == SCARD_AUTOALLOCATE)
184 void* tmp = malloc(srcSize);
185 memcpy(tmp, src, srcSize);
186 ArrayList_Append(ctx->strings, tmp);
187 *((
void**)dst) = tmp;
188 return (UINT32)srcSize;
192 const size_t min = MIN(dstSize, srcSize);
193 memcpy(dst, src, min);
198static void scard_context_free(
void* context)
200 SCardContext* ctx = context;
203 HashTable_Free(ctx->cards);
204 ArrayList_Free(ctx->strings);
205 HashTable_Free(ctx->cache);
210static SCardContext* scard_context_new(
void)
212 SCardContext* ctx = calloc(1,
sizeof(SCardContext));
216 ctx->strings = ArrayList_New(FALSE);
221 wObject* obj = ArrayList_Object(ctx->strings);
223 obj->fnObjectFree = free;
226 ctx->cache = HashTable_New(FALSE);
229 if (!HashTable_SetupForStringData(ctx->cache, FALSE))
233 wObject* val = HashTable_ValueObject(ctx->cache);
235 val->fnObjectFree = free;
238 scard_status_transition(ctx);
241 scard_context_free(ctx);
245static void scard_handle_free(
void* handle)
247 SCardHandle* hdl = handle;
250 free(hdl->szReader.pv);
251 vgids_free(hdl->vgids);
256static SCardHandle* scard_handle_new(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
257 const void* name, BOOL unicode)
259 SCardHandle* hdl = NULL;
261 WINPR_ASSERT(smartcard);
263 hdl = calloc(1,
sizeof(SCardHandle));
272 size_t s = _wcslen(name);
274 hdl->szReader.pw = calloc(s + 2,
sizeof(WCHAR));
275 if (!hdl->szReader.pw)
277 memcpy(hdl->szReader.pv, name, s *
sizeof(WCHAR));
281 size_t s = strlen(name);
283 hdl->szReader.pc = calloc(s + 2,
sizeof(CHAR));
284 if (!hdl->szReader.pc)
286 memcpy(hdl->szReader.pv, name, s *
sizeof(CHAR));
289 if (!hdl->szReader.pv)
292 hdl->vgids = vgids_new();
304 if (!vgids_init(hdl->vgids, pem, key, pin))
308 hdl->unicode = unicode;
309 hdl->hContext = context;
313 scard_handle_free(hdl);
317static LONG scard_handle_valid(SmartcardEmulationContext* smartcard, SCARDHANDLE handle)
319 SCardHandle* ctx = NULL;
321 WINPR_ASSERT(smartcard);
323 ctx = HashTable_GetItemValue(smartcard->handles, (
const void*)handle);
325 return SCARD_E_INVALID_HANDLE;
327 return SCARD_S_SUCCESS;
330static LONG scard_reader_name_valid_a(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
333 SCardContext* ctx = NULL;
335 WINPR_ASSERT(smartcard);
336 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)context);
341 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
344 if (strcmp(reader->szReader, name) == 0)
345 return SCARD_S_SUCCESS;
348 return SCARD_E_UNKNOWN_READER;
351static LONG scard_reader_name_valid_w(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
354 SCardContext* ctx = NULL;
356 WINPR_ASSERT(smartcard);
357 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)context);
362 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
365 if (_wcscmp(reader->szReader, name) == 0)
366 return SCARD_S_SUCCESS;
369 return SCARD_E_UNKNOWN_READER;
376LONG WINAPI Emulate_SCardEstablishContext(SmartcardEmulationContext* smartcard, DWORD dwScope,
377 LPCVOID pvReserved1, LPCVOID pvReserved2,
378 LPSCARDCONTEXT phContext)
380 LONG status = SCARD_E_NO_MEMORY;
381 SCardContext* ctx = NULL;
383 WINPR_ASSERT(smartcard);
385 ctx = scard_context_new();
387 WINPR_UNUSED(pvReserved1);
388 WINPR_UNUSED(pvReserved2);
390 WLog_Print(smartcard->log, smartcard->log_default_level,
391 "SCardEstablishContext { dwScope: %s (0x%08" PRIX32
")",
392 SCardGetScopeString(dwScope), dwScope);
396 SCARDCONTEXT context = { 0 };
398 winpr_RAND(&context,
sizeof(SCARDCONTEXT));
399 if (HashTable_Insert(smartcard->contexts, (
const void*)context, ctx))
401 *phContext = context;
402 status = SCARD_S_SUCCESS;
406 WLog_Print(smartcard->log, smartcard->log_default_level,
407 "SCardEstablishContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
408 WINPR_CXX_COMPAT_CAST(UINT32, status));
410 if (status != SCARD_S_SUCCESS)
411 scard_context_free(ctx);
416LONG WINAPI Emulate_SCardReleaseContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
419 SCardContext* value = NULL;
421 WINPR_ASSERT(smartcard);
423 value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
425 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseContext { hContext: %p",
429 HashTable_Remove(smartcard->contexts, (
const void*)hContext);
431 status = SCARD_S_SUCCESS;
433 WLog_Print(smartcard->log, smartcard->log_default_level,
434 "SCardReleaseContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
435 WINPR_CXX_COMPAT_CAST(UINT32, status));
440LONG WINAPI Emulate_SCardIsValidContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
444 WINPR_ASSERT(smartcard);
446 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIsValidContext { hContext: %p",
449 status = HashTable_Contains(smartcard->contexts, (
const void*)hContext)
451 : SCARD_E_INVALID_HANDLE;
452 if (status == SCARD_S_SUCCESS)
454 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
457 return SCARD_F_INTERNAL_ERROR;
460 WLog_Print(smartcard->log, smartcard->log_default_level,
461 "SCardIsValidContext } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
462 WINPR_CXX_COMPAT_CAST(UINT32, status));
467LONG WINAPI Emulate_SCardListReaderGroupsA(
468 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
469 LPSTR mszGroups , LPDWORD pcchGroups)
471 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
473 WLog_Print(smartcard->log, smartcard->log_default_level,
474 "SCardListReaderGroupsA { hContext: %p", (
void*)hContext);
476 WINPR_UNUSED(mszGroups);
477 WINPR_UNUSED(pcchGroups);
480 if (status == SCARD_S_SUCCESS)
481 status = SCARD_E_UNSUPPORTED_FEATURE;
483 WLog_Print(smartcard->log, smartcard->log_default_level,
484 "SCardListReaderGroupsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
485 WINPR_CXX_COMPAT_CAST(UINT32, status));
490LONG WINAPI Emulate_SCardListReaderGroupsW(
491 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
492 LPWSTR mszGroups , LPDWORD pcchGroups)
494 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
496 WLog_Print(smartcard->log, smartcard->log_default_level,
497 "SCardListReaderGroupsW { hContext: %p", (
void*)hContext);
499 WINPR_UNUSED(mszGroups);
500 WINPR_UNUSED(pcchGroups);
503 if (status == SCARD_S_SUCCESS)
504 status = SCARD_E_UNSUPPORTED_FEATURE;
506 WLog_Print(smartcard->log, smartcard->log_default_level,
507 "SCardListReaderGroupsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
508 WINPR_CXX_COMPAT_CAST(UINT32, status));
513LONG WINAPI Emulate_SCardListReadersA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
514 LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
516 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
518 status = SCARD_E_INVALID_PARAMETER;
520 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListReadersA { hContext: %p",
523 WINPR_UNUSED(mszGroups);
525 if (SCARD_S_SUCCESS == status)
527 SCardContext* value =
528 (SCardContext*)HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
537 *pcchReaders = ARRAYSIZE(g_ReaderNameA);
540 *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameA,
541 sizeof(g_ReaderNameA));
545 WLog_Print(smartcard->log, smartcard->log_default_level,
546 "SCardListReadersA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
547 WINPR_CXX_COMPAT_CAST(UINT32, status));
552LONG WINAPI Emulate_SCardListReadersW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
553 LPCWSTR mszGroups, LPWSTR mszReaders, LPDWORD pcchReaders)
555 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
558 status = SCARD_E_INVALID_PARAMETER;
560 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListReadersW { hContext: %p",
563 WINPR_UNUSED(mszGroups);
565 InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit, NULL, NULL);
566 if (SCARD_S_SUCCESS == status)
568 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
578 WINPR_ASSERT(g_ReaderNameWLen <= UINT32_MAX);
579 *pcchReaders = (UINT32)g_ReaderNameWLen;
583 *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameW,
584 g_ReaderNameWLen *
sizeof(WCHAR)) /
589 WLog_Print(smartcard->log, smartcard->log_default_level,
590 "SCardListReadersW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
591 WINPR_CXX_COMPAT_CAST(UINT32, status));
596LONG WINAPI Emulate_SCardListCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
597 LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
598 DWORD cguidInterfaceCount,
602 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
604 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListCardsA { hContext: %p",
608 WINPR_UNUSED(rgquidInterfaces);
609 WINPR_UNUSED(cguidInterfaceCount);
610 WINPR_UNUSED(mszCards);
611 WINPR_UNUSED(pcchCards);
614 if (status == SCARD_S_SUCCESS)
615 status = SCARD_E_UNSUPPORTED_FEATURE;
617 WLog_Print(smartcard->log, smartcard->log_default_level,
618 "SCardListCardsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
619 WINPR_CXX_COMPAT_CAST(UINT32, status));
624LONG WINAPI Emulate_SCardListCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
625 LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
626 DWORD cguidInterfaceCount,
630 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
632 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListCardsW { hContext: %p",
636 WINPR_UNUSED(rgquidInterfaces);
637 WINPR_UNUSED(cguidInterfaceCount);
638 WINPR_UNUSED(mszCards);
639 WINPR_UNUSED(pcchCards);
642 if (status == SCARD_S_SUCCESS)
643 status = SCARD_E_UNSUPPORTED_FEATURE;
645 WLog_Print(smartcard->log, smartcard->log_default_level,
646 "SCardListCardsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
647 WINPR_CXX_COMPAT_CAST(UINT32, status));
652LONG WINAPI Emulate_SCardListInterfacesA(
653 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szCard,
654 LPGUID pguidInterfaces, LPDWORD pcguidInterfaces )
656 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
658 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListInterfacesA { hContext: %p",
661 WINPR_UNUSED(szCard);
662 WINPR_UNUSED(pguidInterfaces);
663 WINPR_UNUSED(pcguidInterfaces);
666 if (status == SCARD_S_SUCCESS)
667 status = SCARD_E_UNSUPPORTED_FEATURE;
669 WLog_Print(smartcard->log, smartcard->log_default_level,
670 "SCardListInterfacesA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
671 WINPR_CXX_COMPAT_CAST(UINT32, status));
676LONG WINAPI Emulate_SCardListInterfacesW(
677 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szCard,
678 LPGUID pguidInterfaces, LPDWORD pcguidInterfaces )
680 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
682 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardListInterfacesW { hContext: %p",
685 WINPR_UNUSED(szCard);
686 WINPR_UNUSED(pguidInterfaces);
687 WINPR_UNUSED(pcguidInterfaces);
690 if (status == SCARD_S_SUCCESS)
691 status = SCARD_E_UNSUPPORTED_FEATURE;
693 WLog_Print(smartcard->log, smartcard->log_default_level,
694 "SCardListInterfacesW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
695 WINPR_CXX_COMPAT_CAST(UINT32, status));
700LONG WINAPI Emulate_SCardGetProviderIdA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
701 LPCSTR szCard, LPGUID pguidProviderId)
703 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
705 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetProviderIdA { hContext: %p",
708 WINPR_UNUSED(szCard);
709 WINPR_UNUSED(pguidProviderId);
712 if (status == SCARD_S_SUCCESS)
713 status = SCARD_E_UNSUPPORTED_FEATURE;
715 WLog_Print(smartcard->log, smartcard->log_default_level,
716 "SCardGetProviderIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
717 WINPR_CXX_COMPAT_CAST(UINT32, status));
722LONG WINAPI Emulate_SCardGetProviderIdW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
723 LPCWSTR szCard, LPGUID pguidProviderId)
725 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
727 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetProviderIdW { hContext: %p",
730 WINPR_UNUSED(szCard);
731 WINPR_UNUSED(pguidProviderId);
734 if (status == SCARD_S_SUCCESS)
735 status = SCARD_E_UNSUPPORTED_FEATURE;
737 WLog_Print(smartcard->log, smartcard->log_default_level,
738 "SCardGetProviderIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
739 WINPR_CXX_COMPAT_CAST(UINT32, status));
744LONG WINAPI Emulate_SCardGetCardTypeProviderNameA(
745 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szCardName,
746 DWORD dwProviderId, CHAR* szProvider ,
747 LPDWORD pcchProvider )
749 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
751 WLog_Print(smartcard->log, smartcard->log_default_level,
752 "SCardGetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
754 WINPR_UNUSED(szCardName);
755 WINPR_UNUSED(dwProviderId);
756 WINPR_UNUSED(szProvider);
757 WINPR_UNUSED(pcchProvider);
760 if (status == SCARD_S_SUCCESS)
761 status = SCARD_E_UNSUPPORTED_FEATURE;
763 WLog_Print(smartcard->log, smartcard->log_default_level,
764 "SCardGetCardTypeProviderNameA } status: %s (0x%08" PRIX32
")",
765 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
770LONG WINAPI Emulate_SCardGetCardTypeProviderNameW(
771 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szCardName,
772 DWORD dwProviderId, WCHAR* szProvider ,
773 LPDWORD pcchProvider )
775 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
777 WLog_Print(smartcard->log, smartcard->log_default_level,
778 "SCardGetCardTypeProviderNameW { hContext: %p", (
void*)hContext);
780 WINPR_UNUSED(szCardName);
781 WINPR_UNUSED(dwProviderId);
782 WINPR_UNUSED(szProvider);
783 WINPR_UNUSED(pcchProvider);
786 if (status == SCARD_S_SUCCESS)
787 status = SCARD_E_UNSUPPORTED_FEATURE;
789 WLog_Print(smartcard->log, smartcard->log_default_level,
790 "SCardGetCardTypeProviderNameW } status: %s (0x%08" PRIX32
")",
791 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
796LONG WINAPI Emulate_SCardIntroduceReaderGroupA(SmartcardEmulationContext* smartcard,
797 SCARDCONTEXT hContext, LPCSTR szGroupName)
799 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
801 WLog_Print(smartcard->log, smartcard->log_default_level,
802 "SCardIntroduceReaderGroupA { hContext: %p", (
void*)hContext);
804 WINPR_UNUSED(szGroupName);
807 if (status == SCARD_S_SUCCESS)
808 status = SCARD_E_UNSUPPORTED_FEATURE;
810 WLog_Print(smartcard->log, smartcard->log_default_level,
811 "SCardIntroduceReaderGroupA } status: %s (0x%08" PRIX32
")",
812 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
817LONG WINAPI Emulate_SCardIntroduceReaderGroupW(SmartcardEmulationContext* smartcard,
818 SCARDCONTEXT hContext, LPCWSTR szGroupName)
820 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
822 WLog_Print(smartcard->log, smartcard->log_default_level,
823 "SCardIntroduceReaderGroupW { hContext: %p", (
void*)hContext);
825 WINPR_UNUSED(szGroupName);
828 if (status == SCARD_S_SUCCESS)
829 status = SCARD_E_UNSUPPORTED_FEATURE;
831 WLog_Print(smartcard->log, smartcard->log_default_level,
832 "SCardIntroduceReaderGroupW } status: %s (0x%08" PRIX32
")",
833 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
838LONG WINAPI Emulate_SCardForgetReaderGroupA(SmartcardEmulationContext* smartcard,
839 SCARDCONTEXT hContext, LPCSTR szGroupName)
841 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
843 WLog_Print(smartcard->log, smartcard->log_default_level,
844 "SCardForgetReaderGroupA { hContext: %p", (
void*)hContext);
846 WINPR_UNUSED(szGroupName);
849 if (status == SCARD_S_SUCCESS)
850 status = SCARD_E_UNSUPPORTED_FEATURE;
852 WLog_Print(smartcard->log, smartcard->log_default_level,
853 "SCardForgetReaderGroupA } status: %s (0x%08" PRIX32
")",
854 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
859LONG WINAPI Emulate_SCardForgetReaderGroupW(SmartcardEmulationContext* smartcard,
860 SCARDCONTEXT hContext, LPCWSTR szGroupName)
862 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
864 WLog_Print(smartcard->log, smartcard->log_default_level,
865 "SCardForgetReaderGroupW { hContext: %p", (
void*)hContext);
867 WINPR_UNUSED(szGroupName);
870 if (status == SCARD_S_SUCCESS)
871 status = SCARD_E_UNSUPPORTED_FEATURE;
873 WLog_Print(smartcard->log, smartcard->log_default_level,
874 "SCardForgetReaderGroupW } status: %s (0x%08" PRIX32
")",
875 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
880LONG WINAPI Emulate_SCardIntroduceReaderA(SmartcardEmulationContext* smartcard,
881 SCARDCONTEXT hContext, LPCSTR szReaderName,
884 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
886 if (status == SCARD_S_SUCCESS)
887 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
889 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIntroduceReaderA { hContext: %p",
892 WINPR_UNUSED(szDeviceName);
895 if (status == SCARD_S_SUCCESS)
896 status = SCARD_E_UNSUPPORTED_FEATURE;
898 WLog_Print(smartcard->log, smartcard->log_default_level,
899 "SCardIntroduceReaderA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
900 WINPR_CXX_COMPAT_CAST(UINT32, status));
905LONG WINAPI Emulate_SCardIntroduceReaderW(SmartcardEmulationContext* smartcard,
906 SCARDCONTEXT hContext, LPCWSTR szReaderName,
907 LPCWSTR szDeviceName)
909 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
911 if (status == SCARD_S_SUCCESS)
912 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
914 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardIntroduceReaderW { hContext: %p",
917 WINPR_UNUSED(szDeviceName);
920 if (status == SCARD_S_SUCCESS)
921 status = SCARD_E_UNSUPPORTED_FEATURE;
923 WLog_Print(smartcard->log, smartcard->log_default_level,
924 "SCardIntroduceReaderW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
925 WINPR_CXX_COMPAT_CAST(UINT32, status));
930LONG WINAPI Emulate_SCardForgetReaderA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
933 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
935 if (status == SCARD_S_SUCCESS)
936 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
938 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetReaderA { hContext: %p",
942 if (status == SCARD_S_SUCCESS)
943 status = SCARD_E_UNSUPPORTED_FEATURE;
945 WLog_Print(smartcard->log, smartcard->log_default_level,
946 "SCardForgetReaderA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
947 WINPR_CXX_COMPAT_CAST(UINT32, status));
952LONG WINAPI Emulate_SCardForgetReaderW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
953 LPCWSTR szReaderName)
955 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
957 if (status == SCARD_S_SUCCESS)
958 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
960 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetReaderW { hContext: %p",
964 if (status == SCARD_S_SUCCESS)
965 status = SCARD_E_UNSUPPORTED_FEATURE;
967 WLog_Print(smartcard->log, smartcard->log_default_level,
968 "SCardForgetReaderW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
969 WINPR_CXX_COMPAT_CAST(UINT32, status));
974LONG WINAPI Emulate_SCardAddReaderToGroupA(SmartcardEmulationContext* smartcard,
975 SCARDCONTEXT hContext, LPCSTR szReaderName,
978 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
980 if (status == SCARD_S_SUCCESS)
981 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
983 WLog_Print(smartcard->log, smartcard->log_default_level,
984 "SCardAddReaderToGroupA { hContext: %p", (
void*)hContext);
986 WINPR_UNUSED(szGroupName);
989 if (status == SCARD_S_SUCCESS)
990 status = SCARD_E_UNSUPPORTED_FEATURE;
992 WLog_Print(smartcard->log, smartcard->log_default_level,
993 "SCardAddReaderToGroupA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
994 WINPR_CXX_COMPAT_CAST(UINT32, status));
999LONG WINAPI Emulate_SCardAddReaderToGroupW(SmartcardEmulationContext* smartcard,
1000 SCARDCONTEXT hContext, LPCWSTR szReaderName,
1001 LPCWSTR szGroupName)
1003 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1005 if (status == SCARD_S_SUCCESS)
1006 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1008 WLog_Print(smartcard->log, smartcard->log_default_level,
1009 "SCardAddReaderToGroupW { hContext: %p", (
void*)hContext);
1011 WINPR_UNUSED(szGroupName);
1014 if (status == SCARD_S_SUCCESS)
1015 status = SCARD_E_UNSUPPORTED_FEATURE;
1017 WLog_Print(smartcard->log, smartcard->log_default_level,
1018 "SCardAddReaderToGroupW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1019 WINPR_CXX_COMPAT_CAST(UINT32, status));
1024LONG WINAPI Emulate_SCardRemoveReaderFromGroupA(SmartcardEmulationContext* smartcard,
1025 SCARDCONTEXT hContext, LPCSTR szReaderName,
1028 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1030 if (status == SCARD_S_SUCCESS)
1031 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
1033 WLog_Print(smartcard->log, smartcard->log_default_level,
1034 "SCardRemoveReaderFromGroupA { hContext: %p", (
void*)hContext);
1036 WINPR_UNUSED(szGroupName);
1039 if (status == SCARD_S_SUCCESS)
1040 status = SCARD_E_UNSUPPORTED_FEATURE;
1042 WLog_Print(smartcard->log, smartcard->log_default_level,
1043 "SCardRemoveReaderFromGroupA } status: %s (0x%08" PRIX32
")",
1044 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1049LONG WINAPI Emulate_SCardRemoveReaderFromGroupW(SmartcardEmulationContext* smartcard,
1050 SCARDCONTEXT hContext, LPCWSTR szReaderName,
1051 LPCWSTR szGroupName)
1053 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1055 if (status == SCARD_S_SUCCESS)
1056 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1058 WLog_Print(smartcard->log, smartcard->log_default_level,
1059 "SCardRemoveReaderFromGroupW { hContext: %p", (
void*)hContext);
1061 WINPR_UNUSED(szGroupName);
1064 if (status == SCARD_S_SUCCESS)
1065 status = SCARD_E_UNSUPPORTED_FEATURE;
1067 WLog_Print(smartcard->log, smartcard->log_default_level,
1068 "SCardRemoveReaderFromGroupW } status: %s (0x%08" PRIX32
")",
1069 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1074LONG WINAPI Emulate_SCardIntroduceCardTypeA(SmartcardEmulationContext* smartcard,
1075 SCARDCONTEXT hContext, LPCSTR szCardName,
1076 LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1077 DWORD dwInterfaceCount, LPCBYTE pbAtr,
1078 LPCBYTE pbAtrMask, DWORD cbAtrLen)
1080 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1082 WLog_Print(smartcard->log, smartcard->log_default_level,
1083 "SCardIntroduceCardTypeA { hContext: %p", (
void*)hContext);
1085 WINPR_UNUSED(szCardName);
1086 WINPR_UNUSED(pguidPrimaryProvider);
1087 WINPR_UNUSED(rgguidInterfaces);
1088 WINPR_UNUSED(dwInterfaceCount);
1089 WINPR_UNUSED(pbAtr);
1090 WINPR_UNUSED(pbAtrMask);
1091 WINPR_UNUSED(cbAtrLen);
1094 if (status == SCARD_S_SUCCESS)
1095 status = SCARD_E_UNSUPPORTED_FEATURE;
1097 WLog_Print(smartcard->log, smartcard->log_default_level,
1098 "SCardIntroduceCardTypeA } status: %s (0x%08" PRIX32
")",
1099 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1104LONG WINAPI Emulate_SCardIntroduceCardTypeW(SmartcardEmulationContext* smartcard,
1105 SCARDCONTEXT hContext, LPCWSTR szCardName,
1106 LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1107 DWORD dwInterfaceCount, LPCBYTE pbAtr,
1108 LPCBYTE pbAtrMask, DWORD cbAtrLen)
1110 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1112 WLog_Print(smartcard->log, smartcard->log_default_level,
1113 "SCardIntroduceCardTypeW { hContext: %p", (
void*)hContext);
1115 WINPR_UNUSED(szCardName);
1116 WINPR_UNUSED(pguidPrimaryProvider);
1117 WINPR_UNUSED(rgguidInterfaces);
1118 WINPR_UNUSED(dwInterfaceCount);
1119 WINPR_UNUSED(pbAtr);
1120 WINPR_UNUSED(pbAtrMask);
1121 WINPR_UNUSED(cbAtrLen);
1124 if (status == SCARD_S_SUCCESS)
1125 status = SCARD_E_UNSUPPORTED_FEATURE;
1127 WLog_Print(smartcard->log, smartcard->log_default_level,
1128 "SCardIntroduceCardTypeW } status: %s (0x%08" PRIX32
")",
1129 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1134LONG WINAPI Emulate_SCardSetCardTypeProviderNameA(SmartcardEmulationContext* smartcard,
1135 SCARDCONTEXT hContext, LPCSTR szCardName,
1136 DWORD dwProviderId, LPCSTR szProvider)
1138 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1140 WLog_Print(smartcard->log, smartcard->log_default_level,
1141 "SCardSetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
1143 WINPR_UNUSED(szCardName);
1144 WINPR_UNUSED(dwProviderId);
1145 WINPR_UNUSED(szProvider);
1148 if (status == SCARD_S_SUCCESS)
1149 status = SCARD_E_UNSUPPORTED_FEATURE;
1151 WLog_Print(smartcard->log, smartcard->log_default_level,
1152 "SCardSetCardTypeProviderNameA } status: %s (0x%08" PRIX32
")",
1153 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1158LONG WINAPI Emulate_SCardSetCardTypeProviderNameW(SmartcardEmulationContext* smartcard,
1159 SCARDCONTEXT hContext, LPCWSTR szCardName,
1160 DWORD dwProviderId, LPCWSTR szProvider)
1162 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1164 WLog_Print(smartcard->log, smartcard->log_default_level,
1165 "SCardSetCardTypeProviderNameA { hContext: %p", (
void*)hContext);
1167 WINPR_UNUSED(szCardName);
1168 WINPR_UNUSED(dwProviderId);
1169 WINPR_UNUSED(szProvider);
1172 if (status == SCARD_S_SUCCESS)
1173 status = SCARD_E_UNSUPPORTED_FEATURE;
1175 WLog_Print(smartcard->log, smartcard->log_default_level,
1176 "SCardSetCardTypeProviderNameW } status: %s (0x%08" PRIX32
")",
1177 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
1182LONG WINAPI Emulate_SCardForgetCardTypeA(SmartcardEmulationContext* smartcard,
1183 SCARDCONTEXT hContext, LPCSTR szCardName)
1185 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1187 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetCardTypeA { hContext: %p",
1190 WINPR_UNUSED(szCardName);
1193 if (status == SCARD_S_SUCCESS)
1194 status = SCARD_E_UNSUPPORTED_FEATURE;
1196 WLog_Print(smartcard->log, smartcard->log_default_level,
1197 "SCardForgetCardTypeA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1198 WINPR_CXX_COMPAT_CAST(UINT32, status));
1203LONG WINAPI Emulate_SCardForgetCardTypeW(SmartcardEmulationContext* smartcard,
1204 SCARDCONTEXT hContext, LPCWSTR szCardName)
1206 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1208 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardForgetCardTypeW { hContext: %p",
1211 WINPR_UNUSED(szCardName);
1214 if (status == SCARD_S_SUCCESS)
1215 status = SCARD_E_UNSUPPORTED_FEATURE;
1217 WLog_Print(smartcard->log, smartcard->log_default_level,
1218 "SCardForgetCardTypeW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1219 WINPR_CXX_COMPAT_CAST(UINT32, status));
1224LONG WINAPI Emulate_SCardFreeMemory(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1227 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1229 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardFreeMemory { hContext: %p",
1232 if (status == SCARD_S_SUCCESS)
1234 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1235 WINPR_ASSERT(value);
1237 ArrayList_Remove(value->strings, pvMem);
1240 WLog_Print(smartcard->log, smartcard->log_default_level,
1241 "SCardFreeMemory } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1242 WINPR_CXX_COMPAT_CAST(UINT32, status));
1247HANDLE WINAPI Emulate_SCardAccessStartedEvent(SmartcardEmulationContext* smartcard)
1249 HANDLE hEvent = NULL;
1251 WINPR_ASSERT(smartcard);
1253 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAccessStartedEvent {");
1256 winpr_RAND((
void*)&hEvent,
sizeof(hEvent));
1258 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAccessStartedEvent } hEvent: %p",
1264void WINAPI Emulate_SCardReleaseStartedEvent(SmartcardEmulationContext* smartcard)
1266 WINPR_ASSERT(smartcard);
1268 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseStartedEvent {");
1272 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReleaseStartedEvent }");
1275LONG WINAPI Emulate_SCardLocateCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1279 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1281 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardLocateCardsA { hContext: %p",
1284 WINPR_UNUSED(mszCards);
1285 WINPR_UNUSED(rgReaderStates);
1286 WINPR_UNUSED(cReaders);
1289 if (status == SCARD_S_SUCCESS)
1290 status = SCARD_E_UNSUPPORTED_FEATURE;
1292 WLog_Print(smartcard->log, smartcard->log_default_level,
1293 "SCardLocateCardsA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1294 WINPR_CXX_COMPAT_CAST(UINT32, status));
1299LONG WINAPI Emulate_SCardLocateCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1303 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1305 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardLocateCardsW { hContext: %p",
1308 WINPR_UNUSED(mszCards);
1309 WINPR_UNUSED(rgReaderStates);
1310 WINPR_UNUSED(cReaders);
1313 if (status == SCARD_S_SUCCESS)
1314 status = SCARD_E_UNSUPPORTED_FEATURE;
1316 WLog_Print(smartcard->log, smartcard->log_default_level,
1317 "SCardLocateCardsW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1318 WINPR_CXX_COMPAT_CAST(UINT32, status));
1323LONG WINAPI Emulate_SCardLocateCardsByATRA(SmartcardEmulationContext* smartcard,
1328 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1330 WLog_Print(smartcard->log, smartcard->log_default_level,
1331 "SCardLocateCardsByATRA { hContext: %p", (
void*)hContext);
1333 WINPR_UNUSED(rgAtrMasks);
1334 WINPR_UNUSED(cAtrs);
1335 WINPR_UNUSED(rgReaderStates);
1336 WINPR_UNUSED(cReaders);
1339 if (status == SCARD_S_SUCCESS)
1340 status = SCARD_E_UNSUPPORTED_FEATURE;
1342 WLog_Print(smartcard->log, smartcard->log_default_level,
1343 "SCardLocateCardsByATRA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1344 WINPR_CXX_COMPAT_CAST(UINT32, status));
1349LONG WINAPI Emulate_SCardLocateCardsByATRW(SmartcardEmulationContext* smartcard,
1354 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1356 WLog_Print(smartcard->log, smartcard->log_default_level,
1357 "SCardLocateCardsByATRW { hContext: %p", (
void*)hContext);
1359 WINPR_UNUSED(rgAtrMasks);
1360 WINPR_UNUSED(cAtrs);
1361 WINPR_UNUSED(rgReaderStates);
1362 WINPR_UNUSED(cReaders);
1365 if (status == SCARD_S_SUCCESS)
1366 status = SCARD_E_UNSUPPORTED_FEATURE;
1368 WLog_Print(smartcard->log, smartcard->log_default_level,
1369 "SCardLocateCardsByATRW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1370 WINPR_CXX_COMPAT_CAST(UINT32, status));
1375LONG WINAPI Emulate_SCardGetStatusChangeA(SmartcardEmulationContext* smartcard,
1376 SCARDCONTEXT hContext, DWORD dwTimeout,
1379 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1381 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetStatusChangeA { hContext: %p",
1384 if (status == SCARD_S_SUCCESS)
1386 const DWORD diff = 100;
1387 size_t eventCount = 0;
1388 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1389 WINPR_ASSERT(value);
1394 status = SCARD_E_TIMEOUT;
1397 for (
size_t x = 0; x < cReaders; x++)
1401 for (
size_t y = 0; y < MAX_EMULATED_READERS; y++)
1404 if (strcmp(out->szReader, in->szReader) == 0)
1406 const SCardHandle* hdl = find_reader(smartcard, in->szReader, FALSE);
1407 out->dwEventState = in->dwEventState;
1410 out->dwEventState |= SCARD_STATE_INUSE;
1411 if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1412 out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1415 if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1416 (out->dwCurrentState & SCARD_STATE_EMPTY))
1417 out->dwEventState |= SCARD_STATE_CHANGED;
1418 if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1419 (out->dwCurrentState & SCARD_STATE_PRESENT))
1420 out->dwEventState |= SCARD_STATE_CHANGED;
1422 out->cbAtr = in->cbAtr;
1423 memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1424 if (out->dwEventState & SCARD_STATE_CHANGED)
1429 if (value->canceled)
1431 status = SCARD_E_CANCELLED;
1434 if (eventCount != 0)
1436 status = SCARD_S_SUCCESS;
1440 if (dwTimeout != INFINITE)
1441 dwTimeout -= MIN(dwTimeout, diff);
1442 if (freerdp_shall_disconnect_context(inst->context))
1444 status = SCARD_E_CANCELLED;
1447 }
while (dwTimeout > 0);
1450 WLog_Print(smartcard->log, smartcard->log_default_level,
1451 "SCardGetStatusChangeA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1452 WINPR_CXX_COMPAT_CAST(UINT32, status));
1457LONG WINAPI Emulate_SCardGetStatusChangeW(SmartcardEmulationContext* smartcard,
1458 SCARDCONTEXT hContext, DWORD dwTimeout,
1461 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1463 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetStatusChangeW { hContext: %p",
1466 if (status == SCARD_S_SUCCESS)
1468 const DWORD diff = 100;
1469 size_t eventCount = 0;
1470 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1471 WINPR_ASSERT(value);
1476 status = SCARD_E_TIMEOUT;
1479 for (
size_t x = 0; x < cReaders; x++)
1483 for (
size_t y = 0; y < MAX_EMULATED_READERS; y++)
1486 if (_wcscmp(out->szReader, in->szReader) == 0)
1488 const SCardHandle* hdl = find_reader(smartcard, in->szReader, TRUE);
1489 out->dwEventState = in->dwEventState;
1492 out->dwEventState |= SCARD_STATE_INUSE;
1493 if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1494 out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1496 if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1497 (out->dwCurrentState & SCARD_STATE_EMPTY))
1498 out->dwEventState |= SCARD_STATE_CHANGED;
1499 if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1500 (out->dwCurrentState & SCARD_STATE_PRESENT))
1501 out->dwEventState |= SCARD_STATE_CHANGED;
1502 out->cbAtr = in->cbAtr;
1503 memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1505 if (out->dwEventState & SCARD_STATE_CHANGED)
1510 if (value->canceled)
1512 status = SCARD_E_CANCELLED;
1515 if (eventCount != 0)
1517 status = SCARD_S_SUCCESS;
1521 if (dwTimeout != INFINITE)
1522 dwTimeout -= MIN(dwTimeout, diff);
1523 if (freerdp_shall_disconnect_context(inst->context))
1525 status = SCARD_E_CANCELLED;
1528 }
while (dwTimeout > 0);
1531 WLog_Print(smartcard->log, smartcard->log_default_level,
1532 "SCardGetStatusChangeW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1533 WINPR_CXX_COMPAT_CAST(UINT32, status));
1538LONG WINAPI Emulate_SCardCancel(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
1540 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1542 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancel { hContext: %p",
1545 if (status == SCARD_S_SUCCESS)
1547 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
1548 WINPR_ASSERT(value);
1549 value->canceled = TRUE;
1552 WLog_Print(smartcard->log, smartcard->log_default_level,
1553 "SCardCancel } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1554 WINPR_CXX_COMPAT_CAST(UINT32, status));
1559SCardHandle* find_reader(SmartcardEmulationContext* smartcard,
const void* szReader, BOOL unicode)
1561 SCardHandle* hdl = NULL;
1562 UINT_PTR* keys = NULL;
1565 WINPR_ASSERT(smartcard);
1566 count = HashTable_GetKeys(smartcard->handles, &keys);
1567 for (
size_t x = 0; x < count; x++)
1569 SCardHandle* cur = HashTable_GetItemValue(smartcard->handles, (
const void*)keys[x]);
1572 if (cur->unicode != unicode)
1574 if (!unicode && (strcmp(cur->szReader.pc, szReader) != 0))
1576 if (unicode && (_wcscmp(cur->szReader.pw, szReader) != 0))
1585static SCardHandle* reader2handle(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1586 const void* szReader, BOOL unicode, DWORD dwShareMode,
1587 SCARDHANDLE* phCard, DWORD dwPreferredProtocols,
1588 LPDWORD pdwActiveProtocol)
1590 SCardHandle* hdl = NULL;
1592 WINPR_ASSERT(phCard);
1595 if (Emulate_SCardIsValidContext(smartcard, hContext) != SCARD_S_SUCCESS)
1598 hdl = scard_handle_new(smartcard, hContext, szReader, unicode);
1601 winpr_RAND(&hdl->card,
sizeof(hdl->card));
1602 hdl->dwActiveProtocol = SCARD_PROTOCOL_T1;
1603 hdl->dwShareMode = dwShareMode;
1605 if (!HashTable_Insert(smartcard->handles, (
const void*)hdl->card, hdl))
1607 scard_handle_free(hdl);
1612 if (pdwActiveProtocol)
1614 if ((hdl->dwActiveProtocol & dwPreferredProtocols) == 0)
1616 scard_handle_free(hdl);
1620 *pdwActiveProtocol = hdl->dwActiveProtocol;
1624 hdl->referencecount++;
1625 *phCard = hdl->card;
1629 WLog_Print(smartcard->log, smartcard->log_default_level,
"{ %p }", (
void*)*phCard);
1633LONG WINAPI Emulate_SCardConnectA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1634 LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1635 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1637 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1639 if (!phCard || !pdwActiveProtocol)
1640 status = SCARD_E_INVALID_PARAMETER;
1642 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectA { hContext: %p",
1645 if (status == SCARD_S_SUCCESS)
1647 if (!reader2handle(smartcard, hContext, szReader, FALSE, dwShareMode, phCard,
1648 dwPreferredProtocols, pdwActiveProtocol))
1649 status = SCARD_E_NO_MEMORY;
1652 WLog_Print(smartcard->log, smartcard->log_default_level,
1653 "SCardConnectA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1654 WINPR_CXX_COMPAT_CAST(UINT32, status));
1659LONG WINAPI Emulate_SCardConnectW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1660 LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1661 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1663 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1665 if (!phCard || !pdwActiveProtocol)
1666 status = SCARD_E_INVALID_PARAMETER;
1668 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardConnectW { hContext: %p",
1671 if (status == SCARD_S_SUCCESS)
1673 if (!reader2handle(smartcard, hContext, szReader, TRUE, dwShareMode, phCard,
1674 dwPreferredProtocols, pdwActiveProtocol))
1675 status = SCARD_E_NO_MEMORY;
1678 WLog_Print(smartcard->log, smartcard->log_default_level,
1679 "SCardConnectW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1680 WINPR_CXX_COMPAT_CAST(UINT32, status));
1685LONG WINAPI Emulate_SCardReconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1686 DWORD dwShareMode, WINPR_ATTR_UNUSED DWORD dwPreferredProtocols,
1687 WINPR_ATTR_UNUSED DWORD dwInitialization,
1688 LPDWORD pdwActiveProtocol)
1690 LONG status = scard_handle_valid(smartcard, hCard);
1692 if (!pdwActiveProtocol)
1693 status = SCARD_E_INVALID_PARAMETER;
1695 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReconnect { hCard: %p",
1698 if (status == SCARD_S_SUCCESS)
1700 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1704 hdl->dwShareMode = dwShareMode;
1705 hdl->transaction = FALSE;
1707 *pdwActiveProtocol = hdl->dwActiveProtocol;
1710 WLog_Print(smartcard->log, smartcard->log_default_level,
1711 "SCardReconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1712 WINPR_CXX_COMPAT_CAST(UINT32, status));
1717LONG WINAPI Emulate_SCardDisconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1718 DWORD dwDisposition)
1720 LONG status = scard_handle_valid(smartcard, hCard);
1722 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDisconnect { hCard: %p",
1725 WINPR_UNUSED(dwDisposition);
1727 if (status == SCARD_S_SUCCESS)
1729 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1732 hdl->referencecount--;
1733 if (hdl->referencecount == 0)
1734 HashTable_Remove(smartcard->handles, (
const void*)hCard);
1737 WLog_Print(smartcard->log, smartcard->log_default_level,
1738 "SCardDisconnect } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1739 WINPR_CXX_COMPAT_CAST(UINT32, status));
1744LONG WINAPI Emulate_SCardBeginTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1746 LONG status = scard_handle_valid(smartcard, hCard);
1748 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardBeginTransaction { hCard: %p",
1751 if (status == SCARD_S_SUCCESS)
1753 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1755 if (hdl->transaction)
1756 status = SCARD_E_INVALID_VALUE;
1758 hdl->transaction = TRUE;
1761 WLog_Print(smartcard->log, smartcard->log_default_level,
1762 "SCardBeginTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1763 WINPR_CXX_COMPAT_CAST(UINT32, status));
1768LONG WINAPI Emulate_SCardEndTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1769 DWORD dwDisposition)
1771 LONG status = scard_handle_valid(smartcard, hCard);
1773 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardEndTransaction { hCard: %p",
1776 WINPR_UNUSED(dwDisposition);
1778 if (status == SCARD_S_SUCCESS)
1780 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1782 if (!hdl->transaction)
1783 status = SCARD_E_NOT_TRANSACTED;
1785 hdl->transaction = FALSE;
1788 WLog_Print(smartcard->log, smartcard->log_default_level,
1789 "SCardEndTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1790 WINPR_CXX_COMPAT_CAST(UINT32, status));
1795LONG WINAPI Emulate_SCardCancelTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1797 LONG status = scard_handle_valid(smartcard, hCard);
1799 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardCancelTransaction { hCard: %p",
1802 if (status == SCARD_S_SUCCESS)
1804 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1806 if (!hdl->transaction)
1807 status = SCARD_E_NOT_TRANSACTED;
1809 hdl->transaction = FALSE;
1812 WLog_Print(smartcard->log, smartcard->log_default_level,
1813 "SCardCancelTransaction } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1814 WINPR_CXX_COMPAT_CAST(UINT32, status));
1819LONG WINAPI Emulate_SCardState(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1820 LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
1823 LONG status = scard_handle_valid(smartcard, hCard);
1825 if (!pdwState || !pdwProtocol)
1826 status = SCARD_E_INVALID_PARAMETER;
1828 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardState { hCard: %p",
1831 if (status == SCARD_S_SUCCESS)
1833 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1837 *pdwState = SCARD_SPECIFIC;
1839 *pdwProtocol = SCARD_PROTOCOL_T1;
1844 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1847 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1853 if (_wcscmp(readerW->szReader, hdl->szReader.pw) == 0)
1855 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerW->rgbAtr,
1861 if (strcmp(readerA->szReader, hdl->szReader.pc) == 0)
1863 *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerA->rgbAtr,
1871 WLog_Print(smartcard->log, smartcard->log_default_level,
1872 "SCardState } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1873 WINPR_CXX_COMPAT_CAST(UINT32, status));
1878LONG WINAPI Emulate_SCardStatusA(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1879 LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1880 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1882 LONG status = scard_handle_valid(smartcard, hCard);
1884 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusA { hCard: %p",
1887 if (status == SCARD_S_SUCCESS)
1889 SCardContext* ctx = NULL;
1890 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1893 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1898 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pc,
1899 (UINT32)strlen(hdl->szReader.pc) + 2);
1902 *pdwState = SCARD_SPECIFIC;
1904 *pdwProtocol = SCARD_PROTOCOL_T1;
1908 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1911 if (strcmp(reader->szReader, hdl->szReader.pc) == 0)
1914 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1920 WLog_Print(smartcard->log, smartcard->log_default_level,
1921 "SCardStatusA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1922 WINPR_CXX_COMPAT_CAST(UINT32, status));
1927LONG WINAPI Emulate_SCardStatusW(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1928 LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1929 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1931 LONG status = scard_handle_valid(smartcard, hCard);
1933 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardStatusW { hCard: %p",
1936 if (status == SCARD_S_SUCCESS)
1938 SCardContext* ctx = NULL;
1939 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1942 ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
1947 scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pw,
1948 (UINT32)(_wcslen(hdl->szReader.pw) + 2) *
sizeof(WCHAR)) /
1952 *pdwState = SCARD_SPECIFIC;
1954 *pdwProtocol = SCARD_PROTOCOL_T1;
1958 for (
size_t x = 0; x < MAX_EMULATED_READERS; x++)
1961 if (_wcscmp(reader->szReader, hdl->szReader.pw) == 0)
1963 scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1968 WLog_Print(smartcard->log, smartcard->log_default_level,
1969 "SCardStatusW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
1970 WINPR_CXX_COMPAT_CAST(UINT32, status));
1975LONG WINAPI Emulate_SCardTransmit(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1978 LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
1980 LONG status = scard_handle_valid(smartcard, hCard);
1982 if (!pioSendPci || !pbSendBuffer || !pbRecvBuffer || !pcbRecvLength)
1983 status = SCARD_E_INVALID_PARAMETER;
1985 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardTransmit { hCard: %p",
1988 if (status == SCARD_S_SUCCESS)
1990 BYTE* response = NULL;
1991 DWORD responseSize = 0;
1992 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
1995 hdl->transmitcount++;
1997 if (!vgids_process_apdu(hdl->vgids, pbSendBuffer, cbSendLength, &response, &responseSize))
1998 status = SCARD_E_NO_SMARTCARD;
2002 HashTable_GetItemValue(smartcard->contexts, (
const void*)hdl->hContext);
2006 scard_copy_strings(ctx, pbRecvBuffer, *pcbRecvLength, response, responseSize);
2011 pioRecvPci->dwProtocol = hdl->dwActiveProtocol;
2015 WLog_Print(smartcard->log, smartcard->log_default_level,
2016 "SCardTransmit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2017 WINPR_CXX_COMPAT_CAST(UINT32, status));
2022LONG WINAPI Emulate_SCardGetTransmitCount(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2023 LPDWORD pcTransmitCount)
2025 LONG status = scard_handle_valid(smartcard, hCard);
2027 if (!pcTransmitCount)
2028 status = SCARD_E_INVALID_PARAMETER;
2030 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetTransmitCount { hCard: %p",
2033 if (status == SCARD_S_SUCCESS)
2035 SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (
const void*)hCard);
2038 *pcTransmitCount = hdl->transmitcount;
2041 WLog_Print(smartcard->log, smartcard->log_default_level,
2042 "SCardGetTransmitCount } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2043 WINPR_CXX_COMPAT_CAST(UINT32, status));
2048LONG WINAPI Emulate_SCardControl(
2049 SmartcardEmulationContext* smartcard, SCARDHANDLE hCard, DWORD dwControlCode,
2050 LPCVOID lpInBuffer, DWORD cbInBufferSize, LPVOID lpOutBuffer, DWORD cbOutBufferSize,
2051 LPDWORD lpBytesReturned )
2053 LONG status = scard_handle_valid(smartcard, hCard);
2055 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardControl { hCard: %p",
2058 if (status == SCARD_S_SUCCESS)
2060 WINPR_UNUSED(dwControlCode);
2061 WINPR_UNUSED(lpInBuffer);
2062 WINPR_UNUSED(cbInBufferSize);
2063 WINPR_UNUSED(lpOutBuffer);
2064 WINPR_UNUSED(cbOutBufferSize);
2065 WINPR_UNUSED(lpBytesReturned);
2068 status = SCARD_E_UNSUPPORTED_FEATURE;
2071 WLog_Print(smartcard->log, smartcard->log_default_level,
2072 "SCardControl } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2073 WINPR_CXX_COMPAT_CAST(UINT32, status));
2078LONG WINAPI Emulate_SCardGetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2081 LPDWORD pcbAttrLen )
2083 LONG status = scard_handle_valid(smartcard, hCard);
2085 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetAttrib { hCard: %p",
2088 WINPR_UNUSED(dwAttrId);
2089 WINPR_UNUSED(pbAttr);
2090 WINPR_UNUSED(pcbAttrLen);
2093 if (status == SCARD_S_SUCCESS)
2094 status = SCARD_F_INTERNAL_ERROR;
2096 WLog_Print(smartcard->log, smartcard->log_default_level,
2097 "SCardGetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2098 WINPR_CXX_COMPAT_CAST(UINT32, status));
2103LONG WINAPI Emulate_SCardSetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2104 DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
2106 LONG status = scard_handle_valid(smartcard, hCard);
2108 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardSetAttrib { hCard: %p",
2111 WINPR_UNUSED(dwAttrId);
2112 WINPR_UNUSED(pbAttr);
2113 WINPR_UNUSED(cbAttrLen);
2116 if (status == SCARD_S_SUCCESS)
2117 status = SCARD_F_INTERNAL_ERROR;
2119 WLog_Print(smartcard->log, smartcard->log_default_level,
2120 "SCardSetAttrib } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2121 WINPR_CXX_COMPAT_CAST(UINT32, status));
2126LONG WINAPI Emulate_SCardUIDlgSelectCardA(SmartcardEmulationContext* smartcard,
2127 LPOPENCARDNAMEA_EX pDlgStruc)
2131 WINPR_ASSERT(smartcard);
2133 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardA {");
2135 WINPR_UNUSED(pDlgStruc);
2138 status = SCARD_E_UNSUPPORTED_FEATURE;
2140 WLog_Print(smartcard->log, smartcard->log_default_level,
2141 "SCardUIDlgSelectCardA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2142 WINPR_CXX_COMPAT_CAST(UINT32, status));
2147LONG WINAPI Emulate_SCardUIDlgSelectCardW(SmartcardEmulationContext* smartcard,
2148 LPOPENCARDNAMEW_EX pDlgStruc)
2152 WINPR_ASSERT(smartcard);
2154 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardUIDlgSelectCardW {");
2156 WINPR_UNUSED(pDlgStruc);
2159 status = SCARD_E_UNSUPPORTED_FEATURE;
2161 WLog_Print(smartcard->log, smartcard->log_default_level,
2162 "SCardUIDlgSelectCardW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2163 WINPR_CXX_COMPAT_CAST(UINT32, status));
2168LONG WINAPI Emulate_GetOpenCardNameA(SmartcardEmulationContext* smartcard,
2173 WINPR_ASSERT(smartcard);
2175 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameA {");
2177 WINPR_UNUSED(pDlgStruc);
2180 status = SCARD_E_UNSUPPORTED_FEATURE;
2182 WLog_Print(smartcard->log, smartcard->log_default_level,
2183 "GetOpenCardNameA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2184 WINPR_CXX_COMPAT_CAST(UINT32, status));
2189LONG WINAPI Emulate_GetOpenCardNameW(SmartcardEmulationContext* smartcard,
2194 WINPR_ASSERT(smartcard);
2196 WLog_Print(smartcard->log, smartcard->log_default_level,
"GetOpenCardNameW {");
2198 WINPR_UNUSED(pDlgStruc);
2201 status = SCARD_E_UNSUPPORTED_FEATURE;
2203 WLog_Print(smartcard->log, smartcard->log_default_level,
2204 "GetOpenCardNameW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2205 WINPR_CXX_COMPAT_CAST(UINT32, status));
2210LONG WINAPI Emulate_SCardDlgExtendedError(SmartcardEmulationContext* smartcard)
2214 WINPR_ASSERT(smartcard);
2216 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardDlgExtendedError {");
2219 status = SCARD_E_UNSUPPORTED_FEATURE;
2221 WLog_Print(smartcard->log, smartcard->log_default_level,
2222 "SCardDlgExtendedError } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2223 WINPR_CXX_COMPAT_CAST(UINT32, status));
2228LONG WINAPI Emulate_SCardReadCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2229 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2230 PBYTE Data, DWORD* DataLen)
2233 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2235 if (!CardIdentifier || !DataLen)
2236 status = SCARD_E_INVALID_PARAMETER;
2238 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheA { hContext: %p",
2247 if (status == SCARD_S_SUCCESS)
2249 SCardCacheItem* data = NULL;
2250 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2251 WINPR_ASSERT(value);
2253 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2254 data = HashTable_GetItemValue(value->cache,
id);
2258 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2259 else if (data->freshness != FreshnessCounter)
2260 status = SCARD_W_CACHE_ITEM_STALE;
2262 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2265 WLog_Print(smartcard->log, smartcard->log_default_level,
2266 "SCardReadCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2267 WINPR_CXX_COMPAT_CAST(UINT32, status));
2272LONG WINAPI Emulate_SCardReadCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2273 UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName,
2274 PBYTE Data, DWORD* DataLen)
2277 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2279 if (!CardIdentifier || !DataLen)
2280 status = SCARD_E_INVALID_PARAMETER;
2282 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardReadCacheW { hContext: %p",
2291 if (status == SCARD_S_SUCCESS)
2293 SCardCacheItem* data = NULL;
2294 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2295 WINPR_ASSERT(value);
2297 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2298 data = HashTable_GetItemValue(value->cache,
id);
2301 status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2302 else if (data->freshness != FreshnessCounter)
2303 status = SCARD_W_CACHE_ITEM_STALE;
2305 *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2308 WLog_Print(smartcard->log, smartcard->log_default_level,
2309 "SCardReadCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2310 WINPR_CXX_COMPAT_CAST(UINT32, status));
2315static LONG insert_data(wHashTable* table, DWORD FreshnessCounter,
const char* key,
2316 const PBYTE Data, DWORD DataLen)
2319 SCardCacheItem* item = NULL;
2321 WINPR_ASSERT(table);
2324 if (DataLen > MAX_CACHE_ITEM_SIZE)
2325 return SCARD_W_CACHE_ITEM_TOO_BIG;
2327 if (HashTable_Count(table) > MAX_CACHE_ITEM_VALUES)
2328 return SCARD_E_WRITE_TOO_MANY;
2330 item = HashTable_GetItemValue(table, key);
2333 item = calloc(1,
sizeof(SCardCacheItem));
2335 return SCARD_E_NO_MEMORY;
2337 rc = HashTable_Insert(table, key, item);
2341 return SCARD_E_NO_MEMORY;
2345 if (item->freshness > FreshnessCounter)
2346 return SCARD_W_CACHE_ITEM_STALE;
2347 item->freshness = FreshnessCounter;
2348 item->size = DataLen;
2349 memcpy(item->data, Data, DataLen);
2352 return SCARD_S_SUCCESS;
2355LONG WINAPI Emulate_SCardWriteCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2356 UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2357 PBYTE Data, DWORD DataLen)
2359 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2361 if (!CardIdentifier)
2362 status = SCARD_E_INVALID_PARAMETER;
2364 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheA { hContext: %p",
2367 if (status == SCARD_S_SUCCESS)
2369 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2370 WINPR_ASSERT(value);
2372 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2374 status = SCARD_E_NO_MEMORY;
2377 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2382 WLog_Print(smartcard->log, smartcard->log_default_level,
2383 "SCardWriteCacheA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2384 WINPR_CXX_COMPAT_CAST(UINT32, status));
2389LONG WINAPI Emulate_SCardWriteCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2390 UUID* CardIdentifier, DWORD FreshnessCounter,
2391 LPWSTR LookupName, PBYTE Data, DWORD DataLen)
2393 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2395 if (!CardIdentifier)
2396 status = SCARD_E_INVALID_PARAMETER;
2398 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardWriteCacheW { hContext: %p",
2401 if (status == SCARD_S_SUCCESS)
2403 SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2404 WINPR_ASSERT(value);
2406 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2408 status = SCARD_E_NO_MEMORY;
2411 status = insert_data(value->cache, FreshnessCounter,
id, Data, DataLen);
2416 WLog_Print(smartcard->log, smartcard->log_default_level,
2417 "SCardWriteCacheW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2418 WINPR_CXX_COMPAT_CAST(UINT32, status));
2423LONG WINAPI Emulate_SCardGetReaderIconA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2424 LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2426 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2428 if (!szReaderName || !pcbIcon)
2429 status = SCARD_E_INVALID_PARAMETER;
2431 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconA { hContext: %p",
2434 if (status == SCARD_S_SUCCESS)
2435 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2437 if (status == SCARD_S_SUCCESS)
2439 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2443 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2444 resources_FreeRDP_ico_len);
2446 *pcbIcon = resources_FreeRDP_ico_len;
2449 WLog_Print(smartcard->log, smartcard->log_default_level,
2450 "SCardGetReaderIconA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2451 WINPR_CXX_COMPAT_CAST(UINT32, status));
2456LONG WINAPI Emulate_SCardGetReaderIconW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2457 LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2459 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2461 if (!szReaderName || !pcbIcon)
2462 status = SCARD_E_INVALID_PARAMETER;
2464 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetReaderIconW { hContext: %p",
2467 if (status == SCARD_S_SUCCESS)
2468 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2470 if (status == SCARD_S_SUCCESS)
2472 SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (
const void*)hContext);
2476 *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2477 resources_FreeRDP_ico_len);
2479 *pcbIcon = resources_FreeRDP_ico_len;
2482 WLog_Print(smartcard->log, smartcard->log_default_level,
2483 "SCardGetReaderIconW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2484 WINPR_CXX_COMPAT_CAST(UINT32, status));
2489LONG WINAPI Emulate_SCardGetDeviceTypeIdA(SmartcardEmulationContext* smartcard,
2490 SCARDCONTEXT hContext, LPCSTR szReaderName,
2491 LPDWORD pdwDeviceTypeId)
2493 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2495 if (!pdwDeviceTypeId)
2496 status = SCARD_E_INVALID_PARAMETER;
2498 if (status == SCARD_S_SUCCESS)
2499 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2501 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdA { hContext: %p",
2504 if (status == SCARD_S_SUCCESS)
2506 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2509 WLog_Print(smartcard->log, smartcard->log_default_level,
2510 "SCardGetDeviceTypeIdA } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2511 WINPR_CXX_COMPAT_CAST(UINT32, status));
2516LONG WINAPI Emulate_SCardGetDeviceTypeIdW(SmartcardEmulationContext* smartcard,
2517 SCARDCONTEXT hContext, LPCWSTR szReaderName,
2518 LPDWORD pdwDeviceTypeId)
2520 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2522 if (!pdwDeviceTypeId)
2523 status = SCARD_E_INVALID_PARAMETER;
2525 if (status == SCARD_S_SUCCESS)
2526 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2528 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardGetDeviceTypeIdW { hContext: %p",
2531 if (status == SCARD_S_SUCCESS)
2533 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2536 WLog_Print(smartcard->log, smartcard->log_default_level,
2537 "SCardGetDeviceTypeIdW } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2538 WINPR_CXX_COMPAT_CAST(UINT32, status));
2543LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdA(
2544 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szReaderName,
2545 LPSTR szDeviceInstanceId ,
2546 LPDWORD pcchDeviceInstanceId )
2548 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2550 if (status == SCARD_S_SUCCESS)
2551 status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2553 WLog_Print(smartcard->log, smartcard->log_default_level,
2554 "SCardGetReaderDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2556 WINPR_UNUSED(szDeviceInstanceId);
2557 WINPR_UNUSED(pcchDeviceInstanceId);
2560 if (status == SCARD_S_SUCCESS)
2561 status = SCARD_E_UNSUPPORTED_FEATURE;
2563 WLog_Print(smartcard->log, smartcard->log_default_level,
2564 "SCardGetReaderDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2565 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2570LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdW(
2571 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szReaderName,
2572 LPWSTR szDeviceInstanceId ,
2573 LPDWORD pcchDeviceInstanceId )
2575 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2577 if (status == SCARD_S_SUCCESS)
2578 status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2580 WLog_Print(smartcard->log, smartcard->log_default_level,
2581 "SCardGetReaderDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2583 WINPR_UNUSED(szDeviceInstanceId);
2584 WINPR_UNUSED(pcchDeviceInstanceId);
2587 if (status == SCARD_S_SUCCESS)
2588 status = SCARD_E_UNSUPPORTED_FEATURE;
2590 WLog_Print(smartcard->log, smartcard->log_default_level,
2591 "SCardGetReaderDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2592 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2597LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdA(
2598 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCSTR szDeviceInstanceId,
2600 LPDWORD pcchReaders )
2602 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2604 WLog_Print(smartcard->log, smartcard->log_default_level,
2605 "SCardListReadersWithDeviceInstanceIdA { hContext: %p", (
void*)hContext);
2607 WINPR_UNUSED(szDeviceInstanceId);
2608 WINPR_UNUSED(mszReaders);
2609 WINPR_UNUSED(pcchReaders);
2612 if (status == SCARD_S_SUCCESS)
2613 status = SCARD_E_UNSUPPORTED_FEATURE;
2615 WLog_Print(smartcard->log, smartcard->log_default_level,
2616 "SCardListReadersWithDeviceInstanceIdA } status: %s (0x%08" PRIX32
")",
2617 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2622LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdW(
2623 SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext, LPCWSTR szDeviceInstanceId,
2624 LPWSTR mszReaders , LPDWORD pcchReaders)
2626 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2628 WLog_Print(smartcard->log, smartcard->log_default_level,
2629 "SCardListReadersWithDeviceInstanceIdW { hContext: %p", (
void*)hContext);
2631 WINPR_UNUSED(szDeviceInstanceId);
2632 WINPR_UNUSED(mszReaders);
2633 WINPR_UNUSED(pcchReaders);
2636 if (status == SCARD_S_SUCCESS)
2637 status = SCARD_E_UNSUPPORTED_FEATURE;
2639 WLog_Print(smartcard->log, smartcard->log_default_level,
2640 "SCardListReadersWithDeviceInstanceIdW } status: %s (0x%08" PRIX32
")",
2641 SCardGetErrorString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
2646LONG WINAPI Emulate_SCardAudit(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2649 LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2651 WINPR_UNUSED(dwEvent);
2653 WLog_Print(smartcard->log, smartcard->log_default_level,
"SCardAudit { hContext: %p",
2657 if (status == SCARD_S_SUCCESS)
2658 status = SCARD_E_UNSUPPORTED_FEATURE;
2660 WLog_Print(smartcard->log, smartcard->log_default_level,
2661 "SCardAudit } status: %s (0x%08" PRIX32
")", SCardGetErrorString(status),
2662 WINPR_CXX_COMPAT_CAST(UINT32, status));
2667static BOOL context_equals(
const void* pva,
const void* pvb)
2669 const SCARDCONTEXT a = (
const SCARDCONTEXT)pva;
2670 const SCARDCONTEXT b = (
const SCARDCONTEXT)pvb;
2679static BOOL handle_equals(
const void* pva,
const void* pvb)
2681 const SCARDHANDLE a = (
const SCARDHANDLE)pva;
2682 const SCARDHANDLE b = (
const SCARDHANDLE)pvb;
2691SmartcardEmulationContext* Emulate_New(
const rdpSettings* settings)
2693 SmartcardEmulationContext* smartcard = NULL;
2695 WINPR_ASSERT(settings);
2697 smartcard = calloc(1,
sizeof(SmartcardEmulationContext));
2701 smartcard->settings = settings;
2702 smartcard->log = WLog_Get(
"EmulateSCard");
2703 if (!smartcard->log)
2705 smartcard->log_default_level = WLOG_TRACE;
2707 smartcard->contexts = HashTable_New(FALSE);
2708 if (!smartcard->contexts)
2712 wObject* obj = HashTable_KeyObject(smartcard->contexts);
2714 obj->fnObjectEquals = context_equals;
2716 if (!smartcard->contexts)
2720 wObject* obj = HashTable_ValueObject(smartcard->contexts);
2722 obj->fnObjectFree = scard_context_free;
2725 smartcard->handles = HashTable_New(FALSE);
2726 if (!smartcard->handles)
2730 wObject* obj = HashTable_KeyObject(smartcard->handles);
2732 obj->fnObjectEquals = handle_equals;
2734 if (!smartcard->handles)
2738 wObject* obj = HashTable_ValueObject(smartcard->handles);
2740 obj->fnObjectFree = scard_handle_free;
2746 WINPR_PRAGMA_DIAG_PUSH
2747 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2748 Emulate_Free(smartcard);
2749 WINPR_PRAGMA_DIAG_POP
2753void Emulate_Free(SmartcardEmulationContext* context)
2758 HashTable_Free(context->handles);
2759 HashTable_Free(context->contexts);
2763BOOL Emulate_IsConfigured(SmartcardEmulationContext* context)
2766 vgidsContext* vgids = NULL;
2767 const char* pem = NULL;
2768 const char* key = NULL;
2769 const char* pin = NULL;
2771 WINPR_ASSERT(context);
2778 if ((context->pem == pem) && (context->key == key) && (context->pin == pin))
2779 return context->configured;
2785 vgids = vgids_new();
2787 rc = vgids_init(vgids, context->pem, context->key, context->pin);
2790 context->configured = rc;
FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
This struct contains function pointer to initialize/free objects.