Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/libfreerdp/emu/scard/smartcard_emulate.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * Smart Card API emulation
4
 *
5
 * Copyright 2021 Armin Novak <armin.novak@thincast.com>
6
 * Copyright 2021 Thincast Technologies GmbH
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
#include <freerdp/config.h>
22
#include <freerdp/freerdp.h>
23
24
#include <winpr/crt.h>
25
#include <winpr/wlog.h>
26
#include <winpr/file.h>
27
#include <winpr/path.h>
28
#include <winpr/library.h>
29
#include <winpr/smartcard.h>
30
#include <winpr/collections.h>
31
#include <winpr/crypto.h>
32
33
#include <freerdp/emulate/scard/smartcard_emulate.h>
34
#include "FreeRDP.ico.h"
35
36
#include "smartcard_virtual_gids.h"
37
38
0
#define MAX_CACHE_ITEM_SIZE 4096
39
0
#define MAX_CACHE_ITEM_VALUES 4096
40
41
static CHAR g_ReaderNameA[] = { 'F', 'r', 'e', 'e', 'R', 'D', 'P', ' ',  'E',
42
                              'm', 'u', 'l', 'a', 't', 'o', 'r', '\0', '\0' };
43
static INIT_ONCE g_ReaderNameWGuard = INIT_ONCE_STATIC_INIT;
44
static WCHAR g_ReaderNameW[32] = { 0 };
45
static size_t g_ReaderNameWLen = 0;
46
47
static BOOL CALLBACK g_ReaderNameWInit(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context)
48
0
{
49
0
  WINPR_UNUSED(InitOnce);
50
0
  WINPR_UNUSED(Parameter);
51
0
  WINPR_UNUSED(Context);
52
0
  InitializeConstWCharFromUtf8(g_ReaderNameA, g_ReaderNameW, ARRAYSIZE(g_ReaderNameW));
53
0
  g_ReaderNameWLen = _wcsnlen(g_ReaderNameW, ARRAYSIZE(g_ReaderNameW) - 2) + 2;
54
0
  return TRUE;
55
0
}
56
57
struct smartcard_emulation_context
58
{
59
  const rdpSettings* settings;
60
  DWORD log_default_level;
61
  wLog* log;
62
  wHashTable* contexts;
63
  wHashTable* handles;
64
  BOOL configured;
65
  const char* pem;
66
  const char* key;
67
  const char* pin;
68
};
69
70
0
#define MAX_EMULATED_READERS 1
71
typedef struct
72
{
73
  ULONG readerState;
74
  SCARD_READERSTATEA readerStateA[MAX_EMULATED_READERS];
75
  SCARD_READERSTATEW readerStateW[MAX_EMULATED_READERS];
76
  wHashTable* cards;
77
  wArrayList* strings;
78
  wHashTable* cacheA;
79
  wHashTable* cacheW;
80
  BOOL canceled;
81
} SCardContext;
82
83
typedef struct
84
{
85
  union
86
  {
87
    void* pv;
88
    CHAR* pc;
89
    WCHAR* pw;
90
  } szReader;
91
  BOOL unicode;
92
  BOOL transaction;
93
  DWORD transmitcount;
94
  DWORD dwShareMode;
95
  DWORD dwActiveProtocol;
96
  SCARDCONTEXT hContext;
97
  SCARDHANDLE card;
98
  vgidsContext* vgids;
99
  size_t referencecount;
100
} SCardHandle;
101
102
typedef struct
103
{
104
  DWORD freshness;
105
  DWORD size;
106
  char data[MAX_CACHE_ITEM_SIZE];
107
} SCardCacheItem;
108
109
static SCardHandle* find_reader(SmartcardEmulationContext* smartcard, const void* szReader,
110
                                BOOL unicode);
111
112
static const BYTE ATR[] = { 0x3b, 0xf7, 0x18, 0x00, 0x00, 0x80, 0x31, 0xfe, 0x45,
113
                          0x73, 0x66, 0x74, 0x65, 0x2d, 0x6e, 0x66, 0xc4 };
114
115
static BOOL scard_status_transition(SCardContext* context)
116
0
{
117
0
  WINPR_ASSERT(context);
118
119
0
  switch (context->readerState)
120
0
  {
121
0
    default:
122
0
    case 0:
123
0
    {
124
0
      SCARD_READERSTATEA* reader = &context->readerStateA[0];
125
0
      reader->szReader = g_ReaderNameA;
126
0
      reader->dwEventState = SCARD_STATE_PRESENT;
127
0
      reader->cbAtr = sizeof(ATR);
128
0
      memcpy(reader->rgbAtr, ATR, sizeof(ATR));
129
0
    }
130
0
      {
131
0
        InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit, NULL, NULL);
132
0
        SCARD_READERSTATEW* reader = &context->readerStateW[0];
133
0
        reader->szReader = g_ReaderNameW;
134
0
        reader->dwEventState = SCARD_STATE_PRESENT;
135
0
        reader->cbAtr = sizeof(ATR);
136
0
        memcpy(reader->rgbAtr, ATR, sizeof(ATR));
137
0
      }
138
0
      context->readerState = 42;
139
0
      break;
140
0
  }
141
142
0
  return TRUE;
143
0
}
144
145
static UINT32 scard_copy_strings(SCardContext* ctx, void* dst, UINT32 dstSize, const void* src,
146
                                 UINT32 srcSize)
147
0
{
148
0
  WINPR_ASSERT(ctx);
149
0
  WINPR_ASSERT(dst);
150
151
0
  if (dstSize == SCARD_AUTOALLOCATE)
152
0
  {
153
0
    void* tmp = malloc(srcSize);
154
0
    memcpy(tmp, src, srcSize);
155
0
    ArrayList_Append(ctx->strings, tmp);
156
0
    *((void**)dst) = tmp;
157
0
    return srcSize;
158
0
  }
159
0
  else
160
0
  {
161
0
    UINT32 min = MIN(dstSize, srcSize);
162
0
    memcpy(dst, src, min);
163
0
    return min;
164
0
  }
165
0
}
166
167
static void scard_context_free(void* context)
168
0
{
169
0
  SCardContext* ctx = context;
170
0
  if (ctx)
171
0
  {
172
0
    HashTable_Free(ctx->cards);
173
0
    ArrayList_Free(ctx->strings);
174
0
    HashTable_Free(ctx->cacheA);
175
0
    HashTable_Free(ctx->cacheW);
176
0
  }
177
0
  free(ctx);
178
0
}
179
180
static BOOL char_compare(const void* a, const void* b)
181
0
{
182
0
  const CHAR* wa = a;
183
0
  const CHAR* wb = b;
184
185
0
  if (!a && !b)
186
0
    return TRUE;
187
0
  if (!a || !b)
188
0
    return FALSE;
189
0
  return strcmp(wa, wb) == 0;
190
0
}
191
192
static BOOL wchar_compare(const void* a, const void* b)
193
0
{
194
0
  const WCHAR* wa = a;
195
0
  const WCHAR* wb = b;
196
197
0
  if (!a && !b)
198
0
    return TRUE;
199
0
  if (!a || !b)
200
0
    return FALSE;
201
0
  return _wcscmp(wa, wb) == 0;
202
0
}
203
204
static SCardContext* scard_context_new(void)
205
0
{
206
0
  SCardContext* ctx = calloc(1, sizeof(SCardContext));
207
0
  if (!ctx)
208
0
    return NULL;
209
210
0
  ctx->strings = ArrayList_New(FALSE);
211
0
  if (!ctx->strings)
212
0
    goto fail;
213
0
  else
214
0
  {
215
0
    wObject* obj = ArrayList_Object(ctx->strings);
216
0
    WINPR_ASSERT(obj);
217
0
    obj->fnObjectFree = free;
218
0
  }
219
220
0
  ctx->cacheA = HashTable_New(FALSE);
221
0
  if (!ctx->cacheA)
222
0
    goto fail;
223
0
  else
224
0
  {
225
0
    wObject* key = HashTable_KeyObject(ctx->cacheA);
226
0
    wObject* val = HashTable_ValueObject(ctx->cacheA);
227
0
    WINPR_ASSERT(key);
228
0
    WINPR_ASSERT(val);
229
230
0
    key->fnObjectEquals = char_compare;
231
0
    key->fnObjectNew = winpr_ObjectStringClone;
232
0
    key->fnObjectFree = winpr_ObjectStringFree;
233
234
0
    val->fnObjectFree = free;
235
0
  }
236
237
0
  ctx->cacheW = HashTable_New(FALSE);
238
0
  if (!ctx->cacheW)
239
0
    goto fail;
240
0
  else
241
0
  {
242
0
    wObject* key = HashTable_KeyObject(ctx->cacheW);
243
0
    wObject* val = HashTable_ValueObject(ctx->cacheW);
244
0
    WINPR_ASSERT(key);
245
0
    WINPR_ASSERT(val);
246
247
0
    key->fnObjectEquals = wchar_compare;
248
0
    key->fnObjectNew = winpr_ObjectWStringClone;
249
0
    key->fnObjectFree = winpr_ObjectStringFree;
250
251
0
    val->fnObjectFree = free;
252
0
  }
253
254
0
  scard_status_transition(ctx);
255
0
  return ctx;
256
0
fail:
257
0
  scard_context_free(ctx);
258
0
  return NULL;
259
0
}
260
261
static void scard_handle_free(void* handle)
262
0
{
263
0
  SCardHandle* hdl = handle;
264
0
  if (hdl)
265
0
  {
266
0
    free(hdl->szReader.pv);
267
0
    vgids_free(hdl->vgids);
268
0
  }
269
0
  free(hdl);
270
0
}
271
272
static SCardHandle* scard_handle_new(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
273
                                     const void* name, BOOL unicode)
274
0
{
275
0
  SCardHandle* hdl = NULL;
276
277
0
  WINPR_ASSERT(smartcard);
278
279
0
  hdl = calloc(1, sizeof(SCardHandle));
280
0
  if (!hdl)
281
0
    goto fail;
282
283
  /* ATTENTION: Do not use _strdup or _wcsdup!
284
   * These strings are required to be double NULL terminated!
285
   */
286
0
  if (unicode)
287
0
  {
288
0
    size_t s = _wcslen(name);
289
290
0
    hdl->szReader.pw = calloc(s + 2, sizeof(WCHAR));
291
0
    if (!hdl->szReader.pw)
292
0
      goto fail;
293
0
    memcpy(hdl->szReader.pv, name, s * sizeof(WCHAR));
294
0
  }
295
0
  else
296
0
  {
297
0
    size_t s = strlen(name);
298
299
0
    hdl->szReader.pc = calloc(s + 2, sizeof(CHAR));
300
0
    if (!hdl->szReader.pc)
301
0
      goto fail;
302
0
    memcpy(hdl->szReader.pv, name, s * sizeof(CHAR));
303
0
  }
304
305
0
  if (!hdl->szReader.pv)
306
0
    goto fail;
307
308
0
  hdl->vgids = vgids_new();
309
0
  if (!hdl->vgids)
310
0
    goto fail;
311
312
0
  {
313
0
    const char* pem =
314
0
        freerdp_settings_get_string(smartcard->settings, FreeRDP_SmartcardCertificate);
315
0
    const char* key =
316
0
        freerdp_settings_get_string(smartcard->settings, FreeRDP_SmartcardPrivateKey);
317
318
0
    const char* pin = freerdp_settings_get_string(smartcard->settings, FreeRDP_Password);
319
320
0
    if (!vgids_init(hdl->vgids, pem, key, pin))
321
0
      goto fail;
322
0
  }
323
324
0
  hdl->unicode = unicode;
325
0
  hdl->hContext = context;
326
0
  return hdl;
327
328
0
fail:
329
0
  scard_handle_free(hdl);
330
0
  return NULL;
331
0
}
332
333
static LONG scard_handle_valid(SmartcardEmulationContext* smartcard, SCARDHANDLE handle)
334
0
{
335
0
  SCardHandle* ctx = NULL;
336
337
0
  WINPR_ASSERT(smartcard);
338
339
0
  ctx = HashTable_GetItemValue(smartcard->handles, (const void*)handle);
340
0
  if (!ctx)
341
0
    return SCARD_E_INVALID_HANDLE;
342
343
0
  return SCARD_S_SUCCESS;
344
0
}
345
346
static LONG scard_reader_name_valid_a(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
347
                                      const char* name)
348
0
{
349
0
  SCardContext* ctx = NULL;
350
351
0
  WINPR_ASSERT(smartcard);
352
0
  ctx = HashTable_GetItemValue(smartcard->contexts, (const void*)context);
353
354
0
  WINPR_ASSERT(name);
355
0
  WINPR_ASSERT(ctx);
356
357
0
  for (size_t x = 0; x < MAX_EMULATED_READERS; x++)
358
0
  {
359
0
    const SCARD_READERSTATEA* reader = &ctx->readerStateA[x];
360
0
    if (strcmp(reader->szReader, name) == 0)
361
0
      return SCARD_S_SUCCESS;
362
0
  }
363
364
0
  return SCARD_E_UNKNOWN_READER;
365
0
}
366
367
static LONG scard_reader_name_valid_w(SmartcardEmulationContext* smartcard, SCARDCONTEXT context,
368
                                      const WCHAR* name)
369
0
{
370
0
  SCardContext* ctx = NULL;
371
372
0
  WINPR_ASSERT(smartcard);
373
0
  ctx = HashTable_GetItemValue(smartcard->contexts, (const void*)context);
374
375
0
  WINPR_ASSERT(name);
376
0
  WINPR_ASSERT(ctx);
377
378
0
  for (size_t x = 0; x < MAX_EMULATED_READERS; x++)
379
0
  {
380
0
    const SCARD_READERSTATEW* reader = &ctx->readerStateW[x];
381
0
    if (_wcscmp(reader->szReader, name) == 0)
382
0
      return SCARD_S_SUCCESS;
383
0
  }
384
385
0
  return SCARD_E_UNKNOWN_READER;
386
0
}
387
388
/**
389
 * Standard Windows Smart Card API
390
 */
391
392
LONG WINAPI Emulate_SCardEstablishContext(SmartcardEmulationContext* smartcard, DWORD dwScope,
393
                                          LPCVOID pvReserved1, LPCVOID pvReserved2,
394
                                          LPSCARDCONTEXT phContext)
395
0
{
396
0
  LONG status = SCARD_E_NO_MEMORY;
397
0
  SCardContext* ctx = NULL;
398
399
0
  WINPR_ASSERT(smartcard);
400
401
0
  ctx = scard_context_new();
402
403
0
  WINPR_UNUSED(pvReserved1);
404
0
  WINPR_UNUSED(pvReserved2);
405
406
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
407
0
             "SCardEstablishContext { dwScope: %s (0x%08" PRIX32 ")",
408
0
             SCardGetScopeString(dwScope), dwScope);
409
410
0
  if (ctx)
411
0
  {
412
0
    SCARDCONTEXT context = { 0 };
413
414
0
    winpr_RAND(&context, sizeof(SCARDCONTEXT));
415
0
    if (HashTable_Insert(smartcard->contexts, (const void*)context, ctx))
416
0
    {
417
0
      *phContext = context;
418
0
      status = SCARD_S_SUCCESS;
419
0
    }
420
0
  }
421
422
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
423
0
             "SCardEstablishContext } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
424
0
             status);
425
426
0
  if (status != SCARD_S_SUCCESS)
427
0
    scard_context_free(ctx);
428
  // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of ctx
429
0
  return status;
430
0
}
431
432
LONG WINAPI Emulate_SCardReleaseContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
433
0
{
434
0
  LONG status = 0;
435
0
  SCardContext* value = NULL;
436
437
0
  WINPR_ASSERT(smartcard);
438
439
0
  value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
440
441
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardReleaseContext { hContext: %p",
442
0
             (void*)hContext);
443
444
0
  if (value)
445
0
    HashTable_Remove(smartcard->contexts, (const void*)hContext);
446
447
0
  status = SCARD_S_SUCCESS;
448
449
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
450
0
             "SCardReleaseContext } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
451
0
             status);
452
453
0
  return status;
454
0
}
455
456
LONG WINAPI Emulate_SCardIsValidContext(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
457
0
{
458
0
  LONG status = 0;
459
460
0
  WINPR_ASSERT(smartcard);
461
462
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardIsValidContext { hContext: %p",
463
0
             (void*)hContext);
464
465
0
  status = HashTable_Contains(smartcard->contexts, (const void*)hContext)
466
0
               ? SCARD_S_SUCCESS
467
0
               : SCARD_E_INVALID_HANDLE;
468
0
  if (status == SCARD_S_SUCCESS)
469
0
  {
470
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
471
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
472
0
  }
473
474
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
475
0
             "SCardIsValidContext } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
476
0
             status);
477
478
0
  return status;
479
0
}
480
481
LONG WINAPI Emulate_SCardListReaderGroupsA(SmartcardEmulationContext* smartcard,
482
                                           SCARDCONTEXT hContext, LPSTR mszGroups,
483
                                           LPDWORD pcchGroups)
484
0
{
485
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
486
487
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
488
0
             "SCardListReaderGroupsA { hContext: %p", (void*)hContext);
489
490
0
  WINPR_UNUSED(mszGroups);
491
0
  WINPR_UNUSED(pcchGroups);
492
493
  /* Not required, return not supported */
494
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
495
496
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
497
0
             "SCardListReaderGroupsA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
498
0
             status);
499
500
0
  return status;
501
0
}
502
503
LONG WINAPI Emulate_SCardListReaderGroupsW(SmartcardEmulationContext* smartcard,
504
                                           SCARDCONTEXT hContext, LPWSTR mszGroups,
505
                                           LPDWORD pcchGroups)
506
0
{
507
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
508
509
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
510
0
             "SCardListReaderGroupsW { hContext: %p", (void*)hContext);
511
512
0
  WINPR_UNUSED(mszGroups);
513
0
  WINPR_UNUSED(pcchGroups);
514
515
  /* Not required, return not supported */
516
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
517
518
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
519
0
             "SCardListReaderGroupsW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
520
0
             status);
521
522
0
  return status;
523
0
}
524
525
LONG WINAPI Emulate_SCardListReadersA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
526
                                      LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
527
0
{
528
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
529
0
  if (!pcchReaders)
530
0
    status = SCARD_E_INVALID_PARAMETER;
531
532
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardListReadersA { hContext: %p",
533
0
             (void*)hContext);
534
535
0
  WINPR_UNUSED(mszGroups); /* Not required */
536
537
0
  if (SCARD_S_SUCCESS == status)
538
0
  {
539
0
    SCardContext* value =
540
0
        (SCardContext*)HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
541
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
542
543
    // TODO: If emulator not ready return SCARD_E_NO_READERS_AVAILABLE
544
545
    // TODO: argument mszGrous
546
547
    /* Return length only */
548
0
    if (!mszReaders)
549
0
      *pcchReaders = ARRAYSIZE(g_ReaderNameA);
550
0
    else
551
0
    {
552
0
      *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameA,
553
0
                                        sizeof(g_ReaderNameA));
554
0
    }
555
0
  }
556
557
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
558
0
             "SCardListReadersA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
559
0
             status);
560
561
0
  return status;
562
0
}
563
564
LONG WINAPI Emulate_SCardListReadersW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
565
                                      LPCWSTR mszGroups, LPWSTR mszReaders, LPDWORD pcchReaders)
566
0
{
567
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
568
569
0
  if (!pcchReaders)
570
0
    status = SCARD_E_INVALID_PARAMETER;
571
572
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardListReadersW { hContext: %p",
573
0
             (void*)hContext);
574
575
0
  WINPR_UNUSED(mszGroups); /* Not required */
576
577
0
  InitOnceExecuteOnce(&g_ReaderNameWGuard, g_ReaderNameWInit, NULL, NULL);
578
0
  if (SCARD_S_SUCCESS == status)
579
0
  {
580
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
581
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
582
583
    // TODO: If emulator not ready return SCARD_E_NO_READERS_AVAILABLE
584
585
    // TODO: argument mszGrous
586
587
    /* Return length only */
588
0
    if (!mszReaders)
589
0
      *pcchReaders = g_ReaderNameWLen;
590
0
    else
591
0
    {
592
0
      *pcchReaders = scard_copy_strings(value, mszReaders, *pcchReaders, g_ReaderNameW,
593
0
                                        g_ReaderNameWLen * sizeof(WCHAR)) /
594
0
                     sizeof(WCHAR);
595
0
    }
596
0
  }
597
598
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
599
0
             "SCardListReadersW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
600
0
             status);
601
602
0
  return status;
603
0
}
604
605
LONG WINAPI Emulate_SCardListCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
606
                                    LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
607
                                    DWORD cguidInterfaceCount, CHAR* mszCards, LPDWORD pcchCards)
608
0
{
609
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
610
611
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardListCardsA { hContext: %p",
612
0
             (void*)hContext);
613
614
0
  WINPR_UNUSED(pbAtr);
615
0
  WINPR_UNUSED(rgquidInterfaces);
616
0
  WINPR_UNUSED(cguidInterfaceCount);
617
0
  WINPR_UNUSED(mszCards);
618
0
  WINPR_UNUSED(pcchCards);
619
620
  /* Not required, return not supported */
621
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
622
623
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
624
0
             "SCardListCardsA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
625
0
             status);
626
627
0
  return status;
628
0
}
629
630
LONG WINAPI Emulate_SCardListCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
631
                                    LPCBYTE pbAtr, LPCGUID rgquidInterfaces,
632
                                    DWORD cguidInterfaceCount, WCHAR* mszCards, LPDWORD pcchCards)
633
0
{
634
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
635
636
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardListCardsW { hContext: %p",
637
0
             (void*)hContext);
638
639
0
  WINPR_UNUSED(pbAtr);
640
0
  WINPR_UNUSED(rgquidInterfaces);
641
0
  WINPR_UNUSED(cguidInterfaceCount);
642
0
  WINPR_UNUSED(mszCards);
643
0
  WINPR_UNUSED(pcchCards);
644
645
  /* Not required, return not supported */
646
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
647
648
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
649
0
             "SCardListCardsW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
650
0
             status);
651
652
0
  return status;
653
0
}
654
655
LONG WINAPI Emulate_SCardListInterfacesA(SmartcardEmulationContext* smartcard,
656
                                         SCARDCONTEXT hContext, LPCSTR szCard,
657
                                         LPGUID pguidInterfaces, LPDWORD pcguidInterfaces)
658
0
{
659
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
660
661
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardListInterfacesA { hContext: %p",
662
0
             (void*)hContext);
663
664
0
  WINPR_UNUSED(szCard);
665
0
  WINPR_UNUSED(pguidInterfaces);
666
0
  WINPR_UNUSED(pcguidInterfaces);
667
668
  /* Not required, return not supported */
669
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
670
671
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
672
0
             "SCardListInterfacesA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
673
0
             status);
674
675
0
  return status;
676
0
}
677
678
LONG WINAPI Emulate_SCardListInterfacesW(SmartcardEmulationContext* smartcard,
679
                                         SCARDCONTEXT hContext, LPCWSTR szCard,
680
                                         LPGUID pguidInterfaces, LPDWORD pcguidInterfaces)
681
0
{
682
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
683
684
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardListInterfacesW { hContext: %p",
685
0
             (void*)hContext);
686
687
0
  WINPR_UNUSED(szCard);
688
0
  WINPR_UNUSED(pguidInterfaces);
689
0
  WINPR_UNUSED(pcguidInterfaces);
690
691
  /* Not required, return not supported */
692
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
693
694
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
695
0
             "SCardListInterfacesW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
696
0
             status);
697
698
0
  return status;
699
0
}
700
701
LONG WINAPI Emulate_SCardGetProviderIdA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
702
                                        LPCSTR szCard, LPGUID pguidProviderId)
703
0
{
704
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
705
706
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetProviderIdA { hContext: %p",
707
0
             (void*)hContext);
708
709
0
  WINPR_UNUSED(szCard);
710
0
  WINPR_UNUSED(pguidProviderId);
711
712
  /* Not required, return not supported */
713
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
714
715
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
716
0
             "SCardGetProviderIdA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
717
0
             status);
718
719
0
  return status;
720
0
}
721
722
LONG WINAPI Emulate_SCardGetProviderIdW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
723
                                        LPCWSTR szCard, LPGUID pguidProviderId)
724
0
{
725
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
726
727
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetProviderIdW { hContext: %p",
728
0
             (void*)hContext);
729
730
0
  WINPR_UNUSED(szCard);
731
0
  WINPR_UNUSED(pguidProviderId);
732
733
  /* Not required, return not supported */
734
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
735
736
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
737
0
             "SCardGetProviderIdW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
738
0
             status);
739
740
0
  return status;
741
0
}
742
743
LONG WINAPI Emulate_SCardGetCardTypeProviderNameA(SmartcardEmulationContext* smartcard,
744
                                                  SCARDCONTEXT hContext, LPCSTR szCardName,
745
                                                  DWORD dwProviderId, CHAR* szProvider,
746
                                                  LPDWORD pcchProvider)
747
0
{
748
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
749
750
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
751
0
             "SCardGetCardTypeProviderNameA { hContext: %p", (void*)hContext);
752
753
0
  WINPR_UNUSED(szCardName);
754
0
  WINPR_UNUSED(dwProviderId);
755
0
  WINPR_UNUSED(szProvider);
756
0
  WINPR_UNUSED(pcchProvider);
757
758
  /* Not required, return not supported */
759
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
760
761
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
762
0
             "SCardGetCardTypeProviderNameA } status: %s (0x%08" PRIX32 ")",
763
0
             SCardGetErrorString(status), status);
764
765
0
  return status;
766
0
}
767
768
LONG WINAPI Emulate_SCardGetCardTypeProviderNameW(SmartcardEmulationContext* smartcard,
769
                                                  SCARDCONTEXT hContext, LPCWSTR szCardName,
770
                                                  DWORD dwProviderId, WCHAR* szProvider,
771
                                                  LPDWORD pcchProvider)
772
0
{
773
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
774
775
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
776
0
             "SCardGetCardTypeProviderNameW { hContext: %p", (void*)hContext);
777
778
0
  WINPR_UNUSED(szCardName);
779
0
  WINPR_UNUSED(dwProviderId);
780
0
  WINPR_UNUSED(szProvider);
781
0
  WINPR_UNUSED(pcchProvider);
782
783
  /* Not required, return not supported */
784
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
785
786
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
787
0
             "SCardGetCardTypeProviderNameW } status: %s (0x%08" PRIX32 ")",
788
0
             SCardGetErrorString(status), status);
789
790
0
  return status;
791
0
}
792
793
LONG WINAPI Emulate_SCardIntroduceReaderGroupA(SmartcardEmulationContext* smartcard,
794
                                               SCARDCONTEXT hContext, LPCSTR szGroupName)
795
0
{
796
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
797
798
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
799
0
             "SCardIntroduceReaderGroupA { hContext: %p", (void*)hContext);
800
801
0
  WINPR_UNUSED(szGroupName);
802
803
  /* Not required, return not supported */
804
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
805
806
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
807
0
             "SCardIntroduceReaderGroupA } status: %s (0x%08" PRIX32 ")",
808
0
             SCardGetErrorString(status), status);
809
810
0
  return status;
811
0
}
812
813
LONG WINAPI Emulate_SCardIntroduceReaderGroupW(SmartcardEmulationContext* smartcard,
814
                                               SCARDCONTEXT hContext, LPCWSTR szGroupName)
815
0
{
816
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
817
818
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
819
0
             "SCardIntroduceReaderGroupW { hContext: %p", (void*)hContext);
820
821
0
  WINPR_UNUSED(szGroupName);
822
823
  /* Not required, return not supported */
824
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
825
826
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
827
0
             "SCardIntroduceReaderGroupW } status: %s (0x%08" PRIX32 ")",
828
0
             SCardGetErrorString(status), status);
829
830
0
  return status;
831
0
}
832
833
LONG WINAPI Emulate_SCardForgetReaderGroupA(SmartcardEmulationContext* smartcard,
834
                                            SCARDCONTEXT hContext, LPCSTR szGroupName)
835
0
{
836
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
837
838
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
839
0
             "SCardForgetReaderGroupA { hContext: %p", (void*)hContext);
840
841
0
  WINPR_UNUSED(szGroupName);
842
843
  /* Not required, return not supported */
844
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
845
846
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
847
0
             "SCardForgetReaderGroupA } status: %s (0x%08" PRIX32 ")",
848
0
             SCardGetErrorString(status), status);
849
850
0
  return status;
851
0
}
852
853
LONG WINAPI Emulate_SCardForgetReaderGroupW(SmartcardEmulationContext* smartcard,
854
                                            SCARDCONTEXT hContext, LPCWSTR szGroupName)
855
0
{
856
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
857
858
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
859
0
             "SCardForgetReaderGroupW { hContext: %p", (void*)hContext);
860
861
0
  WINPR_UNUSED(szGroupName);
862
863
  /* Not required, return not supported */
864
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
865
866
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
867
0
             "SCardForgetReaderGroupW } status: %s (0x%08" PRIX32 ")",
868
0
             SCardGetErrorString(status), status);
869
870
0
  return status;
871
0
}
872
873
LONG WINAPI Emulate_SCardIntroduceReaderA(SmartcardEmulationContext* smartcard,
874
                                          SCARDCONTEXT hContext, LPCSTR szReaderName,
875
                                          LPCSTR szDeviceName)
876
0
{
877
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
878
879
0
  if (status == SCARD_S_SUCCESS)
880
0
    status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
881
882
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardIntroduceReaderA { hContext: %p",
883
0
             (void*)hContext);
884
885
0
  WINPR_UNUSED(szDeviceName);
886
887
  /* Not required, return not supported */
888
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
889
890
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
891
0
             "SCardIntroduceReaderA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
892
0
             status);
893
894
0
  return status;
895
0
}
896
897
LONG WINAPI Emulate_SCardIntroduceReaderW(SmartcardEmulationContext* smartcard,
898
                                          SCARDCONTEXT hContext, LPCWSTR szReaderName,
899
                                          LPCWSTR szDeviceName)
900
0
{
901
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
902
903
0
  if (status == SCARD_S_SUCCESS)
904
0
    status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
905
906
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardIntroduceReaderW { hContext: %p",
907
0
             (void*)hContext);
908
909
0
  WINPR_UNUSED(szDeviceName);
910
911
  /* Not required, return not supported */
912
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
913
914
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
915
0
             "SCardIntroduceReaderW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
916
0
             status);
917
918
0
  return status;
919
0
}
920
921
LONG WINAPI Emulate_SCardForgetReaderA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
922
                                       LPCSTR szReaderName)
923
0
{
924
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
925
926
0
  if (status == SCARD_S_SUCCESS)
927
0
    status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
928
929
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardForgetReaderA { hContext: %p",
930
0
             (void*)hContext);
931
932
  /* Not required, return not supported */
933
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
934
935
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
936
0
             "SCardForgetReaderA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
937
0
             status);
938
939
0
  return status;
940
0
}
941
942
LONG WINAPI Emulate_SCardForgetReaderW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
943
                                       LPCWSTR szReaderName)
944
0
{
945
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
946
947
0
  if (status == SCARD_S_SUCCESS)
948
0
    status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
949
950
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardForgetReaderW { hContext: %p",
951
0
             (void*)hContext);
952
953
  /* Not required, return not supported */
954
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
955
956
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
957
0
             "SCardForgetReaderW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
958
0
             status);
959
960
0
  return status;
961
0
}
962
963
LONG WINAPI Emulate_SCardAddReaderToGroupA(SmartcardEmulationContext* smartcard,
964
                                           SCARDCONTEXT hContext, LPCSTR szReaderName,
965
                                           LPCSTR szGroupName)
966
0
{
967
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
968
969
0
  if (status == SCARD_S_SUCCESS)
970
0
    status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
971
972
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
973
0
             "SCardAddReaderToGroupA { hContext: %p", (void*)hContext);
974
975
0
  WINPR_UNUSED(szGroupName);
976
977
  /* Not required, return not supported */
978
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
979
980
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
981
0
             "SCardAddReaderToGroupA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
982
0
             status);
983
984
0
  return status;
985
0
}
986
987
LONG WINAPI Emulate_SCardAddReaderToGroupW(SmartcardEmulationContext* smartcard,
988
                                           SCARDCONTEXT hContext, LPCWSTR szReaderName,
989
                                           LPCWSTR szGroupName)
990
0
{
991
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
992
993
0
  if (status == SCARD_S_SUCCESS)
994
0
    status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
995
996
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
997
0
             "SCardAddReaderToGroupW { hContext: %p", (void*)hContext);
998
999
0
  WINPR_UNUSED(szGroupName);
1000
1001
  /* Not required, return not supported */
1002
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1003
1004
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1005
0
             "SCardAddReaderToGroupW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1006
0
             status);
1007
1008
0
  return status;
1009
0
}
1010
1011
LONG WINAPI Emulate_SCardRemoveReaderFromGroupA(SmartcardEmulationContext* smartcard,
1012
                                                SCARDCONTEXT hContext, LPCSTR szReaderName,
1013
                                                LPCSTR szGroupName)
1014
0
{
1015
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1016
1017
0
  if (status == SCARD_S_SUCCESS)
1018
0
    status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
1019
1020
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1021
0
             "SCardRemoveReaderFromGroupA { hContext: %p", (void*)hContext);
1022
1023
0
  WINPR_UNUSED(szGroupName);
1024
1025
  /* Not required, return not supported */
1026
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1027
1028
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1029
0
             "SCardRemoveReaderFromGroupA } status: %s (0x%08" PRIX32 ")",
1030
0
             SCardGetErrorString(status), status);
1031
1032
0
  return status;
1033
0
}
1034
1035
LONG WINAPI Emulate_SCardRemoveReaderFromGroupW(SmartcardEmulationContext* smartcard,
1036
                                                SCARDCONTEXT hContext, LPCWSTR szReaderName,
1037
                                                LPCWSTR szGroupName)
1038
0
{
1039
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1040
1041
0
  if (status == SCARD_S_SUCCESS)
1042
0
    status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
1043
1044
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1045
0
             "SCardRemoveReaderFromGroupW { hContext: %p", (void*)hContext);
1046
1047
0
  WINPR_UNUSED(szGroupName);
1048
1049
  /* Not required, return not supported */
1050
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1051
1052
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1053
0
             "SCardRemoveReaderFromGroupW } status: %s (0x%08" PRIX32 ")",
1054
0
             SCardGetErrorString(status), status);
1055
1056
0
  return status;
1057
0
}
1058
1059
LONG WINAPI Emulate_SCardIntroduceCardTypeA(SmartcardEmulationContext* smartcard,
1060
                                            SCARDCONTEXT hContext, LPCSTR szCardName,
1061
                                            LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1062
                                            DWORD dwInterfaceCount, LPCBYTE pbAtr,
1063
                                            LPCBYTE pbAtrMask, DWORD cbAtrLen)
1064
0
{
1065
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1066
1067
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1068
0
             "SCardIntroduceCardTypeA { hContext: %p", (void*)hContext);
1069
1070
0
  WINPR_UNUSED(szCardName);
1071
0
  WINPR_UNUSED(pguidPrimaryProvider);
1072
0
  WINPR_UNUSED(rgguidInterfaces);
1073
0
  WINPR_UNUSED(dwInterfaceCount);
1074
0
  WINPR_UNUSED(pbAtr);
1075
0
  WINPR_UNUSED(pbAtrMask);
1076
0
  WINPR_UNUSED(cbAtrLen);
1077
1078
  /* Not required, return not supported */
1079
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1080
1081
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1082
0
             "SCardIntroduceCardTypeA } status: %s (0x%08" PRIX32 ")",
1083
0
             SCardGetErrorString(status), status);
1084
1085
0
  return status;
1086
0
}
1087
1088
LONG WINAPI Emulate_SCardIntroduceCardTypeW(SmartcardEmulationContext* smartcard,
1089
                                            SCARDCONTEXT hContext, LPCWSTR szCardName,
1090
                                            LPCGUID pguidPrimaryProvider, LPCGUID rgguidInterfaces,
1091
                                            DWORD dwInterfaceCount, LPCBYTE pbAtr,
1092
                                            LPCBYTE pbAtrMask, DWORD cbAtrLen)
1093
0
{
1094
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1095
1096
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1097
0
             "SCardIntroduceCardTypeW { hContext: %p", (void*)hContext);
1098
1099
0
  WINPR_UNUSED(szCardName);
1100
0
  WINPR_UNUSED(pguidPrimaryProvider);
1101
0
  WINPR_UNUSED(rgguidInterfaces);
1102
0
  WINPR_UNUSED(dwInterfaceCount);
1103
0
  WINPR_UNUSED(pbAtr);
1104
0
  WINPR_UNUSED(pbAtrMask);
1105
0
  WINPR_UNUSED(cbAtrLen);
1106
1107
  /* Not required, return not supported */
1108
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1109
1110
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1111
0
             "SCardIntroduceCardTypeW } status: %s (0x%08" PRIX32 ")",
1112
0
             SCardGetErrorString(status), status);
1113
1114
0
  return status;
1115
0
}
1116
1117
LONG WINAPI Emulate_SCardSetCardTypeProviderNameA(SmartcardEmulationContext* smartcard,
1118
                                                  SCARDCONTEXT hContext, LPCSTR szCardName,
1119
                                                  DWORD dwProviderId, LPCSTR szProvider)
1120
0
{
1121
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1122
1123
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1124
0
             "SCardSetCardTypeProviderNameA { hContext: %p", (void*)hContext);
1125
1126
0
  WINPR_UNUSED(szCardName);
1127
0
  WINPR_UNUSED(dwProviderId);
1128
0
  WINPR_UNUSED(szProvider);
1129
1130
  /* Not required, return not supported */
1131
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1132
1133
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1134
0
             "SCardSetCardTypeProviderNameA } status: %s (0x%08" PRIX32 ")",
1135
0
             SCardGetErrorString(status), status);
1136
1137
0
  return status;
1138
0
}
1139
1140
LONG WINAPI Emulate_SCardSetCardTypeProviderNameW(SmartcardEmulationContext* smartcard,
1141
                                                  SCARDCONTEXT hContext, LPCWSTR szCardName,
1142
                                                  DWORD dwProviderId, LPCWSTR szProvider)
1143
0
{
1144
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1145
1146
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1147
0
             "SCardSetCardTypeProviderNameA { hContext: %p", (void*)hContext);
1148
1149
0
  WINPR_UNUSED(szCardName);
1150
0
  WINPR_UNUSED(dwProviderId);
1151
0
  WINPR_UNUSED(szProvider);
1152
1153
  /* Not required, return not supported */
1154
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1155
1156
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1157
0
             "SCardSetCardTypeProviderNameW } status: %s (0x%08" PRIX32 ")",
1158
0
             SCardGetErrorString(status), status);
1159
1160
0
  return status;
1161
0
}
1162
1163
LONG WINAPI Emulate_SCardForgetCardTypeA(SmartcardEmulationContext* smartcard,
1164
                                         SCARDCONTEXT hContext, LPCSTR szCardName)
1165
0
{
1166
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1167
1168
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardForgetCardTypeA { hContext: %p",
1169
0
             (void*)hContext);
1170
1171
0
  WINPR_UNUSED(szCardName);
1172
1173
  /* Not required, return not supported */
1174
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1175
1176
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1177
0
             "SCardForgetCardTypeA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1178
0
             status);
1179
1180
0
  return status;
1181
0
}
1182
1183
LONG WINAPI Emulate_SCardForgetCardTypeW(SmartcardEmulationContext* smartcard,
1184
                                         SCARDCONTEXT hContext, LPCWSTR szCardName)
1185
0
{
1186
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1187
1188
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardForgetCardTypeW { hContext: %p",
1189
0
             (void*)hContext);
1190
1191
0
  WINPR_UNUSED(szCardName);
1192
1193
  /* Not required, return not supported */
1194
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1195
1196
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1197
0
             "SCardForgetCardTypeW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1198
0
             status);
1199
1200
0
  return status;
1201
0
}
1202
1203
LONG WINAPI Emulate_SCardFreeMemory(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1204
                                    LPVOID pvMem)
1205
0
{
1206
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1207
1208
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardFreeMemory { hContext: %p",
1209
0
             (void*)hContext);
1210
1211
0
  if (status == SCARD_S_SUCCESS)
1212
0
  {
1213
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
1214
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
1215
1216
0
    ArrayList_Remove(value->strings, pvMem);
1217
0
  }
1218
1219
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1220
0
             "SCardFreeMemory } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1221
0
             status);
1222
1223
0
  return status;
1224
0
}
1225
1226
HANDLE WINAPI Emulate_SCardAccessStartedEvent(SmartcardEmulationContext* smartcard)
1227
0
{
1228
0
  HANDLE hEvent = NULL;
1229
1230
0
  WINPR_ASSERT(smartcard);
1231
1232
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardAccessStartedEvent {");
1233
1234
  /* Not required, return random */
1235
0
  winpr_RAND(&hEvent, sizeof(hEvent));
1236
1237
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardAccessStartedEvent } hEvent: %p",
1238
0
             hEvent);
1239
1240
0
  return hEvent;
1241
0
}
1242
1243
void WINAPI Emulate_SCardReleaseStartedEvent(SmartcardEmulationContext* smartcard)
1244
0
{
1245
0
  WINPR_ASSERT(smartcard);
1246
1247
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardReleaseStartedEvent {");
1248
1249
  /* Not required, return not supported */
1250
1251
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardReleaseStartedEvent }");
1252
0
}
1253
1254
LONG WINAPI Emulate_SCardLocateCardsA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1255
                                      LPCSTR mszCards, LPSCARD_READERSTATEA rgReaderStates,
1256
                                      DWORD cReaders)
1257
0
{
1258
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1259
1260
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardLocateCardsA { hContext: %p",
1261
0
             (void*)hContext);
1262
1263
0
  WINPR_UNUSED(mszCards);
1264
0
  WINPR_UNUSED(rgReaderStates);
1265
0
  WINPR_UNUSED(cReaders);
1266
1267
  /* Not required, return not supported */
1268
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1269
1270
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1271
0
             "SCardLocateCardsA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1272
0
             status);
1273
1274
0
  return status;
1275
0
}
1276
1277
LONG WINAPI Emulate_SCardLocateCardsW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1278
                                      LPCWSTR mszCards, LPSCARD_READERSTATEW rgReaderStates,
1279
                                      DWORD cReaders)
1280
0
{
1281
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1282
1283
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardLocateCardsW { hContext: %p",
1284
0
             (void*)hContext);
1285
1286
0
  WINPR_UNUSED(mszCards);
1287
0
  WINPR_UNUSED(rgReaderStates);
1288
0
  WINPR_UNUSED(cReaders);
1289
1290
  /* Not required, return not supported */
1291
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1292
1293
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1294
0
             "SCardLocateCardsW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1295
0
             status);
1296
1297
0
  return status;
1298
0
}
1299
1300
LONG WINAPI Emulate_SCardLocateCardsByATRA(SmartcardEmulationContext* smartcard,
1301
                                           SCARDCONTEXT hContext, LPSCARD_ATRMASK rgAtrMasks,
1302
                                           DWORD cAtrs, LPSCARD_READERSTATEA rgReaderStates,
1303
                                           DWORD cReaders)
1304
0
{
1305
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1306
1307
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1308
0
             "SCardLocateCardsByATRA { hContext: %p", (void*)hContext);
1309
1310
0
  WINPR_UNUSED(rgAtrMasks);
1311
0
  WINPR_UNUSED(cAtrs);
1312
0
  WINPR_UNUSED(rgReaderStates);
1313
0
  WINPR_UNUSED(cReaders);
1314
1315
  /* Not required, return not supported */
1316
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1317
1318
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1319
0
             "SCardLocateCardsByATRA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1320
0
             status);
1321
1322
0
  return status;
1323
0
}
1324
1325
LONG WINAPI Emulate_SCardLocateCardsByATRW(SmartcardEmulationContext* smartcard,
1326
                                           SCARDCONTEXT hContext, LPSCARD_ATRMASK rgAtrMasks,
1327
                                           DWORD cAtrs, LPSCARD_READERSTATEW rgReaderStates,
1328
                                           DWORD cReaders)
1329
0
{
1330
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1331
1332
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1333
0
             "SCardLocateCardsByATRW { hContext: %p", (void*)hContext);
1334
1335
0
  WINPR_UNUSED(rgAtrMasks);
1336
0
  WINPR_UNUSED(cAtrs);
1337
0
  WINPR_UNUSED(rgReaderStates);
1338
0
  WINPR_UNUSED(cReaders);
1339
1340
  /* Not required, return not supported */
1341
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
1342
1343
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1344
0
             "SCardLocateCardsByATRW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1345
0
             status);
1346
1347
0
  return status;
1348
0
}
1349
1350
LONG WINAPI Emulate_SCardGetStatusChangeA(SmartcardEmulationContext* smartcard,
1351
                                          SCARDCONTEXT hContext, DWORD dwTimeout,
1352
                                          LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders)
1353
0
{
1354
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1355
1356
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetStatusChangeA { hContext: %p",
1357
0
             (void*)hContext);
1358
1359
0
  if (status == SCARD_S_SUCCESS)
1360
0
  {
1361
0
    const DWORD diff = 100;
1362
0
    size_t eventCount = 0;
1363
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
1364
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
1365
1366
0
    freerdp* inst =
1367
0
        freerdp_settings_get_pointer_writable(smartcard->settings, FreeRDP_instance);
1368
0
    WINPR_ASSERT(inst);
1369
1370
0
    status = SCARD_E_TIMEOUT;
1371
0
    do
1372
0
    {
1373
0
      for (size_t x = 0; x < cReaders; x++)
1374
0
      {
1375
0
        LPSCARD_READERSTATEA out = &rgReaderStates[x];
1376
1377
0
        for (size_t y = 0; y < MAX_EMULATED_READERS; y++)
1378
0
        {
1379
0
          const LPSCARD_READERSTATEA in = &value->readerStateA[y];
1380
0
          if (strcmp(out->szReader, in->szReader) == 0)
1381
0
          {
1382
0
            const SCardHandle* hdl = find_reader(smartcard, in->szReader, FALSE);
1383
0
            out->dwEventState = in->dwEventState;
1384
0
            if (hdl)
1385
0
            {
1386
0
              out->dwEventState |= SCARD_STATE_INUSE;
1387
0
              if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1388
0
                out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1389
0
            }
1390
1391
0
            if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1392
0
                (out->dwCurrentState & SCARD_STATE_EMPTY))
1393
0
              out->dwEventState |= SCARD_STATE_CHANGED;
1394
0
            if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1395
0
                (out->dwCurrentState & SCARD_STATE_PRESENT))
1396
0
              out->dwEventState |= SCARD_STATE_CHANGED;
1397
1398
0
            out->cbAtr = in->cbAtr;
1399
0
            memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1400
0
            if (out->dwEventState & SCARD_STATE_CHANGED)
1401
0
              eventCount++;
1402
0
          }
1403
0
        }
1404
0
      }
1405
0
      if (value->canceled)
1406
0
      {
1407
0
        status = SCARD_E_CANCELLED;
1408
0
        break;
1409
0
      }
1410
0
      if (eventCount != 0)
1411
0
      {
1412
0
        status = SCARD_S_SUCCESS;
1413
0
        break;
1414
0
      }
1415
0
      Sleep(diff);
1416
0
      if (dwTimeout != INFINITE)
1417
0
        dwTimeout -= MIN(dwTimeout, diff);
1418
0
      if (freerdp_shall_disconnect_context(inst->context))
1419
0
      {
1420
0
        status = SCARD_E_CANCELLED;
1421
0
        break;
1422
0
      }
1423
0
    } while (dwTimeout > 0);
1424
0
  }
1425
1426
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1427
0
             "SCardGetStatusChangeA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1428
0
             status);
1429
1430
0
  return status;
1431
0
}
1432
1433
LONG WINAPI Emulate_SCardGetStatusChangeW(SmartcardEmulationContext* smartcard,
1434
                                          SCARDCONTEXT hContext, DWORD dwTimeout,
1435
                                          LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders)
1436
0
{
1437
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1438
1439
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetStatusChangeW { hContext: %p",
1440
0
             (void*)hContext);
1441
1442
0
  if (status == SCARD_S_SUCCESS)
1443
0
  {
1444
0
    const DWORD diff = 100;
1445
0
    size_t eventCount = 0;
1446
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
1447
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
1448
1449
0
    freerdp* inst =
1450
0
        freerdp_settings_get_pointer_writable(smartcard->settings, FreeRDP_instance);
1451
0
    WINPR_ASSERT(inst);
1452
1453
0
    status = SCARD_E_TIMEOUT;
1454
0
    do
1455
0
    {
1456
0
      for (size_t x = 0; x < cReaders; x++)
1457
0
      {
1458
0
        LPSCARD_READERSTATEW out = &rgReaderStates[x];
1459
1460
0
        for (size_t y = 0; y < MAX_EMULATED_READERS; y++)
1461
0
        {
1462
0
          const LPSCARD_READERSTATEW in = &value->readerStateW[y];
1463
0
          if (_wcscmp(out->szReader, in->szReader) == 0)
1464
0
          {
1465
0
            const SCardHandle* hdl = find_reader(smartcard, in->szReader, TRUE);
1466
0
            out->dwEventState = in->dwEventState;
1467
0
            if (hdl)
1468
0
            {
1469
0
              out->dwEventState |= SCARD_STATE_INUSE;
1470
0
              if (hdl->dwShareMode == SCARD_SHARE_EXCLUSIVE)
1471
0
                out->dwEventState |= SCARD_STATE_EXCLUSIVE;
1472
0
            }
1473
0
            if ((out->dwEventState & SCARD_STATE_EMPTY) !=
1474
0
                (out->dwCurrentState & SCARD_STATE_EMPTY))
1475
0
              out->dwEventState |= SCARD_STATE_CHANGED;
1476
0
            if ((out->dwEventState & SCARD_STATE_PRESENT) !=
1477
0
                (out->dwCurrentState & SCARD_STATE_PRESENT))
1478
0
              out->dwEventState |= SCARD_STATE_CHANGED;
1479
0
            out->cbAtr = in->cbAtr;
1480
0
            memcpy(out->rgbAtr, in->rgbAtr, out->cbAtr);
1481
1482
0
            if (out->dwEventState & SCARD_STATE_CHANGED)
1483
0
              eventCount++;
1484
0
          }
1485
0
        }
1486
0
      }
1487
0
      if (value->canceled)
1488
0
      {
1489
0
        status = SCARD_E_CANCELLED;
1490
0
        break;
1491
0
      }
1492
0
      if (eventCount != 0)
1493
0
      {
1494
0
        status = SCARD_S_SUCCESS;
1495
0
        break;
1496
0
      }
1497
0
      Sleep(diff);
1498
0
      if (dwTimeout != INFINITE)
1499
0
        dwTimeout -= MIN(dwTimeout, diff);
1500
0
      if (freerdp_shall_disconnect_context(inst->context))
1501
0
      {
1502
0
        status = SCARD_E_CANCELLED;
1503
0
        break;
1504
0
      }
1505
0
    } while (dwTimeout > 0);
1506
0
  }
1507
1508
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1509
0
             "SCardGetStatusChangeW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1510
0
             status);
1511
1512
0
  return status;
1513
0
}
1514
1515
LONG WINAPI Emulate_SCardCancel(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext)
1516
0
{
1517
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1518
1519
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardCancel { hContext: %p",
1520
0
             (void*)hContext);
1521
1522
0
  if (status == SCARD_S_SUCCESS)
1523
0
  {
1524
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
1525
0
    WINPR_ASSERT(value);
1526
0
    value->canceled = TRUE;
1527
0
  }
1528
1529
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1530
0
             "SCardCancel } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
1531
1532
0
  return status;
1533
0
}
1534
1535
SCardHandle* find_reader(SmartcardEmulationContext* smartcard, const void* szReader, BOOL unicode)
1536
0
{
1537
0
  SCardHandle* hdl = NULL;
1538
0
  UINT_PTR* keys = NULL;
1539
0
  size_t count = 0;
1540
1541
0
  WINPR_ASSERT(smartcard);
1542
0
  count = HashTable_GetKeys(smartcard->handles, &keys);
1543
0
  for (size_t x = 0; x < count; x++)
1544
0
  {
1545
0
    SCardHandle* cur = HashTable_GetItemValue(smartcard->handles, (const void*)keys[x]);
1546
0
    WINPR_ASSERT(cur);
1547
1548
0
    if (cur->unicode != unicode)
1549
0
      continue;
1550
0
    if (!unicode && (strcmp(cur->szReader.pc, szReader) != 0))
1551
0
      continue;
1552
0
    if (unicode && (_wcscmp(cur->szReader.pw, szReader) != 0))
1553
0
      continue;
1554
0
    hdl = cur;
1555
0
    break;
1556
0
  }
1557
0
  free(keys);
1558
0
  return hdl;
1559
0
}
1560
1561
static SCardHandle* reader2handle(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1562
                                  const void* szReader, BOOL unicode, DWORD dwShareMode,
1563
                                  SCARDHANDLE* phCard, DWORD dwPreferredProtocols,
1564
                                  LPDWORD pdwActiveProtocol)
1565
0
{
1566
0
  SCardHandle* hdl = NULL;
1567
1568
0
  WINPR_ASSERT(phCard);
1569
1570
0
  *phCard = 0;
1571
0
  if (Emulate_SCardIsValidContext(smartcard, hContext) != SCARD_S_SUCCESS)
1572
0
    return NULL;
1573
1574
0
  hdl = scard_handle_new(smartcard, hContext, szReader, unicode);
1575
0
  if (hdl)
1576
0
  {
1577
0
    winpr_RAND(&hdl->card, sizeof(hdl->card));
1578
0
    hdl->dwActiveProtocol = SCARD_PROTOCOL_T1;
1579
0
    hdl->dwShareMode = dwShareMode;
1580
1581
0
    if (!HashTable_Insert(smartcard->handles, (const void*)hdl->card, hdl))
1582
0
    {
1583
0
      scard_handle_free(hdl);
1584
0
      hdl = NULL;
1585
0
    }
1586
0
    else
1587
0
    {
1588
0
      if (pdwActiveProtocol)
1589
0
      {
1590
0
        if ((hdl->dwActiveProtocol & dwPreferredProtocols) == 0)
1591
0
        {
1592
0
          scard_handle_free(hdl);
1593
0
          hdl = NULL;
1594
0
        }
1595
0
        else
1596
0
          *pdwActiveProtocol = hdl->dwActiveProtocol;
1597
0
      }
1598
0
      if (hdl)
1599
0
      {
1600
0
        hdl->referencecount++;
1601
0
        *phCard = hdl->card;
1602
0
      }
1603
0
    }
1604
0
  }
1605
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "{ %p }", (void*)*phCard);
1606
0
  return hdl;
1607
0
}
1608
1609
LONG WINAPI Emulate_SCardConnectA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1610
                                  LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1611
                                  LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1612
0
{
1613
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1614
1615
0
  if (!phCard || !pdwActiveProtocol)
1616
0
    status = SCARD_E_INVALID_PARAMETER;
1617
1618
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardConnectA { hContext: %p",
1619
0
             (void*)hContext);
1620
1621
0
  if (status == SCARD_S_SUCCESS)
1622
0
  {
1623
0
    if (!reader2handle(smartcard, hContext, szReader, FALSE, dwShareMode, phCard,
1624
0
                       dwPreferredProtocols, pdwActiveProtocol))
1625
0
      status = SCARD_E_NO_MEMORY;
1626
0
  }
1627
1628
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1629
0
             "SCardConnectA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
1630
1631
0
  return status;
1632
0
}
1633
1634
LONG WINAPI Emulate_SCardConnectW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
1635
                                  LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
1636
                                  LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1637
0
{
1638
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
1639
1640
0
  if (!phCard || !pdwActiveProtocol)
1641
0
    status = SCARD_E_INVALID_PARAMETER;
1642
1643
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardConnectW { hContext: %p",
1644
0
             (void*)hContext);
1645
1646
0
  if (status == SCARD_S_SUCCESS)
1647
0
  {
1648
0
    if (!reader2handle(smartcard, hContext, szReader, TRUE, dwShareMode, phCard,
1649
0
                       dwPreferredProtocols, pdwActiveProtocol))
1650
0
      status = SCARD_E_NO_MEMORY;
1651
0
  }
1652
1653
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1654
0
             "SCardConnectW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
1655
1656
0
  return status;
1657
0
}
1658
1659
LONG WINAPI Emulate_SCardReconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1660
                                   DWORD dwShareMode, DWORD dwPreferredProtocols,
1661
                                   DWORD dwInitialization, LPDWORD pdwActiveProtocol)
1662
0
{
1663
0
  LONG status = scard_handle_valid(smartcard, hCard);
1664
1665
0
  if (!pdwActiveProtocol)
1666
0
    status = SCARD_E_INVALID_PARAMETER;
1667
1668
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardReconnect { hCard: %p",
1669
0
             (void*)hCard);
1670
1671
0
  if (status == SCARD_S_SUCCESS)
1672
0
  {
1673
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1674
0
    WINPR_ASSERT(hdl);
1675
1676
    // TODO: Implement
1677
0
    hdl->dwShareMode = dwShareMode;
1678
0
    hdl->transaction = FALSE;
1679
1680
0
    *pdwActiveProtocol = hdl->dwActiveProtocol;
1681
0
  }
1682
1683
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1684
0
             "SCardReconnect } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1685
0
             status);
1686
1687
0
  return status;
1688
0
}
1689
1690
LONG WINAPI Emulate_SCardDisconnect(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1691
                                    DWORD dwDisposition)
1692
0
{
1693
0
  LONG status = scard_handle_valid(smartcard, hCard);
1694
1695
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardDisconnect { hCard: %p",
1696
0
             (void*)hCard);
1697
1698
0
  WINPR_UNUSED(dwDisposition); /* We just ignore this. All return values are static anyway */
1699
1700
0
  if (status == SCARD_S_SUCCESS)
1701
0
  {
1702
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1703
0
    WINPR_ASSERT(hdl);
1704
1705
0
    hdl->referencecount--;
1706
0
    if (hdl->referencecount == 0)
1707
0
      HashTable_Remove(smartcard->handles, (const void*)hCard);
1708
0
  }
1709
1710
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1711
0
             "SCardDisconnect } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1712
0
             status);
1713
1714
0
  return status;
1715
0
}
1716
1717
LONG WINAPI Emulate_SCardBeginTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1718
0
{
1719
0
  LONG status = scard_handle_valid(smartcard, hCard);
1720
1721
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardBeginTransaction { hCard: %p",
1722
0
             (void*)hCard);
1723
1724
0
  if (status == SCARD_S_SUCCESS)
1725
0
  {
1726
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1727
0
    WINPR_ASSERT(hdl);
1728
0
    if (hdl->transaction)
1729
0
      status = SCARD_E_INVALID_VALUE;
1730
0
    else
1731
0
      hdl->transaction = TRUE;
1732
0
  }
1733
1734
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1735
0
             "SCardBeginTransaction } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1736
0
             status);
1737
1738
0
  return status;
1739
0
}
1740
1741
LONG WINAPI Emulate_SCardEndTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1742
                                        DWORD dwDisposition)
1743
0
{
1744
0
  LONG status = scard_handle_valid(smartcard, hCard);
1745
1746
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardEndTransaction { hCard: %p",
1747
0
             (void*)hCard);
1748
1749
0
  WINPR_UNUSED(dwDisposition); /* We just ignore this. All return values are static anyway */
1750
1751
0
  if (status == SCARD_S_SUCCESS)
1752
0
  {
1753
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1754
0
    WINPR_ASSERT(hdl);
1755
0
    if (!hdl->transaction)
1756
0
      status = SCARD_E_NOT_TRANSACTED;
1757
0
    else
1758
0
      hdl->transaction = FALSE;
1759
0
  }
1760
1761
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1762
0
             "SCardEndTransaction } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1763
0
             status);
1764
1765
0
  return status;
1766
0
}
1767
1768
LONG WINAPI Emulate_SCardCancelTransaction(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard)
1769
0
{
1770
0
  LONG status = scard_handle_valid(smartcard, hCard);
1771
1772
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardCancelTransaction { hCard: %p",
1773
0
             (void*)hCard);
1774
1775
0
  if (status == SCARD_S_SUCCESS)
1776
0
  {
1777
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1778
0
    WINPR_ASSERT(hdl);
1779
0
    if (!hdl->transaction)
1780
0
      status = SCARD_E_NOT_TRANSACTED;
1781
0
    else
1782
0
      hdl->transaction = FALSE;
1783
0
  }
1784
1785
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1786
0
             "SCardCancelTransaction } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
1787
0
             status);
1788
1789
0
  return status;
1790
0
}
1791
1792
LONG WINAPI Emulate_SCardState(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1793
                               LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
1794
                               LPDWORD pcbAtrLen)
1795
0
{
1796
0
  LONG status = scard_handle_valid(smartcard, hCard);
1797
1798
0
  if (!pdwState || !pdwProtocol)
1799
0
    status = SCARD_E_INVALID_PARAMETER;
1800
1801
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardState { hCard: %p",
1802
0
             (void*)hCard);
1803
1804
0
  if (status == SCARD_S_SUCCESS)
1805
0
  {
1806
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1807
0
    WINPR_ASSERT(hdl);
1808
1809
0
    if (pdwState)
1810
0
      *pdwState = SCARD_SPECIFIC;
1811
0
    if (pdwProtocol)
1812
0
      *pdwProtocol = SCARD_PROTOCOL_T1;
1813
1814
0
    if (pcbAtrLen)
1815
0
    {
1816
0
      SCardContext* ctx =
1817
0
          HashTable_GetItemValue(smartcard->contexts, (const void*)hdl->hContext);
1818
0
      WINPR_ASSERT(ctx);
1819
1820
0
      for (size_t x = 0; x < MAX_EMULATED_READERS; x++)
1821
0
      {
1822
0
        const SCARD_READERSTATEA* readerA = &ctx->readerStateA[x];
1823
0
        const SCARD_READERSTATEW* readerW = &ctx->readerStateW[x];
1824
0
        if (hdl->unicode)
1825
0
        {
1826
0
          if (_wcscmp(readerW->szReader, hdl->szReader.pw) == 0)
1827
0
          {
1828
0
            *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerW->rgbAtr,
1829
0
                                            readerW->cbAtr);
1830
0
          }
1831
0
        }
1832
0
        else
1833
0
        {
1834
0
          if (strcmp(readerA->szReader, hdl->szReader.pc) == 0)
1835
0
          {
1836
0
            *pcbAtrLen = scard_copy_strings(ctx, pbAtr, *pcbAtrLen, readerA->rgbAtr,
1837
0
                                            readerA->cbAtr);
1838
0
          }
1839
0
        }
1840
0
      }
1841
0
    }
1842
0
  }
1843
1844
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1845
0
             "SCardState } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
1846
1847
0
  return status;
1848
0
}
1849
1850
LONG WINAPI Emulate_SCardStatusA(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1851
                                 LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1852
                                 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1853
0
{
1854
0
  LONG status = scard_handle_valid(smartcard, hCard);
1855
1856
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardStatusA { hCard: %p",
1857
0
             (void*)hCard);
1858
1859
0
  if (status == SCARD_S_SUCCESS)
1860
0
  {
1861
0
    SCardContext* ctx = NULL;
1862
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1863
0
    WINPR_ASSERT(hdl);
1864
1865
0
    ctx = HashTable_GetItemValue(smartcard->contexts, (const void*)hdl->hContext);
1866
0
    WINPR_ASSERT(ctx);
1867
1868
0
    if (pcchReaderLen)
1869
0
      *pcchReaderLen =
1870
0
          scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pc,
1871
0
                             (UINT32)strlen(hdl->szReader.pc) + 2);
1872
1873
0
    if (pdwState)
1874
0
      *pdwState = SCARD_SPECIFIC;
1875
0
    if (pdwProtocol)
1876
0
      *pdwProtocol = SCARD_PROTOCOL_T1;
1877
1878
0
    if (pcbAtrLen)
1879
0
    {
1880
0
      for (size_t x = 0; x < MAX_EMULATED_READERS; x++)
1881
0
      {
1882
0
        const SCARD_READERSTATEA* reader = &ctx->readerStateA[x];
1883
0
        if (strcmp(reader->szReader, hdl->szReader.pc) == 0)
1884
0
        {
1885
0
          *pcbAtrLen =
1886
0
              scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1887
0
        }
1888
0
      }
1889
0
    }
1890
0
  }
1891
1892
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1893
0
             "SCardStatusA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
1894
1895
0
  return status;
1896
0
}
1897
1898
LONG WINAPI Emulate_SCardStatusW(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1899
                                 LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
1900
                                 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
1901
0
{
1902
0
  LONG status = scard_handle_valid(smartcard, hCard);
1903
1904
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardStatusW { hCard: %p",
1905
0
             (void*)hCard);
1906
1907
0
  if (status == SCARD_S_SUCCESS)
1908
0
  {
1909
0
    SCardContext* ctx = NULL;
1910
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1911
0
    WINPR_ASSERT(hdl);
1912
1913
0
    ctx = HashTable_GetItemValue(smartcard->contexts, (const void*)hdl->hContext);
1914
0
    WINPR_ASSERT(ctx);
1915
1916
0
    if (pcchReaderLen)
1917
0
      *pcchReaderLen =
1918
0
          scard_copy_strings(ctx, mszReaderNames, *pcchReaderLen, hdl->szReader.pw,
1919
0
                             (UINT32)(_wcslen(hdl->szReader.pw) + 2) * sizeof(WCHAR)) /
1920
0
          sizeof(WCHAR);
1921
1922
0
    if (pdwState)
1923
0
      *pdwState = SCARD_SPECIFIC;
1924
0
    if (pdwProtocol)
1925
0
      *pdwProtocol = SCARD_PROTOCOL_T1;
1926
1927
0
    if (pcbAtrLen)
1928
0
    {
1929
0
      for (size_t x = 0; x < MAX_EMULATED_READERS; x++)
1930
0
      {
1931
0
        const SCARD_READERSTATEW* reader = &ctx->readerStateW[x];
1932
0
        if (_wcscmp(reader->szReader, hdl->szReader.pw) == 0)
1933
0
          *pcbAtrLen =
1934
0
              scard_copy_strings(ctx, pbAtr, *pcbAtrLen, reader->rgbAtr, reader->cbAtr);
1935
0
      }
1936
0
    }
1937
0
  }
1938
1939
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1940
0
             "SCardStatusW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
1941
1942
0
  return status;
1943
0
}
1944
1945
LONG WINAPI Emulate_SCardTransmit(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1946
                                  LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer,
1947
                                  DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci,
1948
                                  LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
1949
0
{
1950
0
  LONG status = scard_handle_valid(smartcard, hCard);
1951
1952
0
  if (!pioSendPci || !pbSendBuffer || !pbRecvBuffer || !pcbRecvLength)
1953
0
    status = SCARD_E_INVALID_PARAMETER;
1954
1955
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardTransmit { hCard: %p",
1956
0
             (void*)hCard);
1957
1958
0
  if (status == SCARD_S_SUCCESS)
1959
0
  {
1960
0
    BYTE* response = NULL;
1961
0
    DWORD responseSize = 0;
1962
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
1963
0
    WINPR_ASSERT(hdl);
1964
1965
0
    hdl->transmitcount++;
1966
1967
0
    if (!vgids_process_apdu(hdl->vgids, pbSendBuffer, cbSendLength, &response, &responseSize))
1968
0
      status = SCARD_E_NO_SMARTCARD;
1969
0
    else
1970
0
    {
1971
0
      SCardContext* ctx =
1972
0
          HashTable_GetItemValue(smartcard->contexts, (const void*)hdl->hContext);
1973
0
      WINPR_ASSERT(ctx);
1974
1975
0
      *pcbRecvLength =
1976
0
          scard_copy_strings(ctx, pbRecvBuffer, *pcbRecvLength, response, responseSize);
1977
0
      free(response);
1978
1979
      /* Required */
1980
0
      if (pioRecvPci)
1981
0
        pioRecvPci->dwProtocol = hdl->dwActiveProtocol;
1982
0
    }
1983
0
  }
1984
1985
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
1986
0
             "SCardTransmit } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
1987
1988
0
  return status;
1989
0
}
1990
1991
LONG WINAPI Emulate_SCardGetTransmitCount(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
1992
                                          LPDWORD pcTransmitCount)
1993
0
{
1994
0
  LONG status = scard_handle_valid(smartcard, hCard);
1995
1996
0
  if (!pcTransmitCount)
1997
0
    status = SCARD_E_INVALID_PARAMETER;
1998
1999
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetTransmitCount { hCard: %p",
2000
0
             (void*)hCard);
2001
2002
0
  if (status == SCARD_S_SUCCESS)
2003
0
  {
2004
0
    SCardHandle* hdl = HashTable_GetItemValue(smartcard->handles, (const void*)hCard);
2005
0
    WINPR_ASSERT(hdl);
2006
2007
0
    *pcTransmitCount = hdl->transmitcount;
2008
0
  }
2009
2010
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2011
0
             "SCardGetTransmitCount } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2012
0
             status);
2013
2014
0
  return status;
2015
0
}
2016
2017
LONG WINAPI Emulate_SCardControl(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2018
                                 DWORD dwControlCode, LPCVOID lpInBuffer, DWORD cbInBufferSize,
2019
                                 LPVOID lpOutBuffer, DWORD cbOutBufferSize, LPDWORD lpBytesReturned)
2020
0
{
2021
0
  LONG status = scard_handle_valid(smartcard, hCard);
2022
2023
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardControl { hCard: %p",
2024
0
             (void*)hCard);
2025
2026
0
  if (status == SCARD_S_SUCCESS)
2027
0
  {
2028
0
    WINPR_UNUSED(dwControlCode);
2029
0
    WINPR_UNUSED(lpInBuffer);
2030
0
    WINPR_UNUSED(cbInBufferSize);
2031
0
    WINPR_UNUSED(lpOutBuffer);
2032
0
    WINPR_UNUSED(cbOutBufferSize);
2033
0
    WINPR_UNUSED(lpBytesReturned);
2034
2035
    /* Not required, return not supported */
2036
0
    status = SCARD_E_UNSUPPORTED_FEATURE;
2037
0
  }
2038
2039
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2040
0
             "SCardControl } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
2041
2042
0
  return status;
2043
0
}
2044
2045
LONG WINAPI Emulate_SCardGetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2046
                                   DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
2047
0
{
2048
0
  LONG status = scard_handle_valid(smartcard, hCard);
2049
2050
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetAttrib { hCard: %p",
2051
0
             (void*)hCard);
2052
2053
0
  WINPR_UNUSED(dwAttrId);
2054
0
  WINPR_UNUSED(pbAttr);
2055
0
  WINPR_UNUSED(pcbAttrLen);
2056
2057
  /* Not required, return not supported */
2058
0
  status = SCARD_F_INTERNAL_ERROR;
2059
2060
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2061
0
             "SCardGetAttrib } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2062
0
             status);
2063
2064
0
  return status;
2065
0
}
2066
2067
LONG WINAPI Emulate_SCardSetAttrib(SmartcardEmulationContext* smartcard, SCARDHANDLE hCard,
2068
                                   DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
2069
0
{
2070
0
  LONG status = scard_handle_valid(smartcard, hCard);
2071
2072
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardSetAttrib { hCard: %p",
2073
0
             (void*)hCard);
2074
2075
0
  WINPR_UNUSED(dwAttrId);
2076
0
  WINPR_UNUSED(pbAttr);
2077
0
  WINPR_UNUSED(cbAttrLen);
2078
2079
  /* Not required, return not supported */
2080
0
  status = SCARD_F_INTERNAL_ERROR;
2081
2082
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2083
0
             "SCardSetAttrib } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2084
0
             status);
2085
2086
0
  return status;
2087
0
}
2088
2089
LONG WINAPI Emulate_SCardUIDlgSelectCardA(SmartcardEmulationContext* smartcard,
2090
                                          LPOPENCARDNAMEA_EX pDlgStruc)
2091
0
{
2092
0
  LONG status = 0;
2093
2094
0
  WINPR_ASSERT(smartcard);
2095
2096
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardUIDlgSelectCardA {");
2097
2098
0
  WINPR_UNUSED(pDlgStruc);
2099
2100
  /* Not required, return not supported */
2101
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2102
2103
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2104
0
             "SCardUIDlgSelectCardA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2105
0
             status);
2106
2107
0
  return status;
2108
0
}
2109
2110
LONG WINAPI Emulate_SCardUIDlgSelectCardW(SmartcardEmulationContext* smartcard,
2111
                                          LPOPENCARDNAMEW_EX pDlgStruc)
2112
0
{
2113
0
  LONG status = 0;
2114
2115
0
  WINPR_ASSERT(smartcard);
2116
2117
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardUIDlgSelectCardW {");
2118
2119
0
  WINPR_UNUSED(pDlgStruc);
2120
2121
  /* Not required, return not supported */
2122
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2123
2124
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2125
0
             "SCardUIDlgSelectCardW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2126
0
             status);
2127
2128
0
  return status;
2129
0
}
2130
2131
LONG WINAPI Emulate_GetOpenCardNameA(SmartcardEmulationContext* smartcard,
2132
                                     LPOPENCARDNAMEA pDlgStruc)
2133
0
{
2134
0
  LONG status = 0;
2135
2136
0
  WINPR_ASSERT(smartcard);
2137
2138
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "GetOpenCardNameA {");
2139
2140
0
  WINPR_UNUSED(pDlgStruc);
2141
2142
  /* Not required, return not supported */
2143
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2144
2145
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2146
0
             "GetOpenCardNameA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2147
0
             status);
2148
2149
0
  return status;
2150
0
}
2151
2152
LONG WINAPI Emulate_GetOpenCardNameW(SmartcardEmulationContext* smartcard,
2153
                                     LPOPENCARDNAMEW pDlgStruc)
2154
0
{
2155
0
  LONG status = 0;
2156
2157
0
  WINPR_ASSERT(smartcard);
2158
2159
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "GetOpenCardNameW {");
2160
2161
0
  WINPR_UNUSED(pDlgStruc);
2162
2163
  /* Not required, return not supported */
2164
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2165
2166
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2167
0
             "GetOpenCardNameW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2168
0
             status);
2169
2170
0
  return status;
2171
0
}
2172
2173
LONG WINAPI Emulate_SCardDlgExtendedError(SmartcardEmulationContext* smartcard)
2174
0
{
2175
0
  LONG status = 0;
2176
2177
0
  WINPR_ASSERT(smartcard);
2178
2179
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardDlgExtendedError {");
2180
2181
  /* Not required, return not supported */
2182
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2183
2184
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2185
0
             "SCardDlgExtendedError } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2186
0
             status);
2187
2188
0
  return status;
2189
0
}
2190
2191
LONG WINAPI Emulate_SCardReadCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2192
                                    UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2193
                                    PBYTE Data, DWORD* DataLen)
2194
0
{
2195
0
  DWORD count = 0;
2196
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2197
2198
0
  if (!CardIdentifier || !DataLen)
2199
0
    status = SCARD_E_INVALID_PARAMETER;
2200
2201
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardReadCacheA { hContext: %p",
2202
0
             (void*)hContext);
2203
2204
0
  if (DataLen)
2205
0
  {
2206
0
    count = *DataLen;
2207
0
    *DataLen = 0;
2208
0
  }
2209
2210
0
  if (status == SCARD_S_SUCCESS)
2211
0
  {
2212
0
    SCardCacheItem* data = NULL;
2213
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
2214
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
2215
2216
0
    data = HashTable_GetItemValue(value->cacheA, LookupName);
2217
0
    if (!data)
2218
0
      status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2219
0
    else if (data->freshness != FreshnessCounter)
2220
0
      status = SCARD_W_CACHE_ITEM_STALE;
2221
0
    else
2222
0
      *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2223
0
  }
2224
2225
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2226
0
             "SCardReadCacheA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2227
0
             status);
2228
2229
0
  return status;
2230
0
}
2231
2232
LONG WINAPI Emulate_SCardReadCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2233
                                    UUID* CardIdentifier, DWORD FreshnessCounter, LPWSTR LookupName,
2234
                                    PBYTE Data, DWORD* DataLen)
2235
0
{
2236
0
  DWORD count = 0;
2237
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2238
2239
0
  if (!CardIdentifier || !DataLen)
2240
0
    status = SCARD_E_INVALID_PARAMETER;
2241
2242
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardReadCacheW { hContext: %p",
2243
0
             (void*)hContext);
2244
2245
0
  if (DataLen)
2246
0
  {
2247
0
    count = *DataLen;
2248
0
    *DataLen = 0;
2249
0
  }
2250
2251
0
  if (status == SCARD_S_SUCCESS)
2252
0
  {
2253
0
    SCardCacheItem* data = NULL;
2254
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
2255
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
2256
2257
0
    data = HashTable_GetItemValue(value->cacheW, LookupName);
2258
0
    if (!data)
2259
0
      status = SCARD_W_CACHE_ITEM_NOT_FOUND;
2260
0
    else if (data->freshness != FreshnessCounter)
2261
0
      status = SCARD_W_CACHE_ITEM_STALE;
2262
0
    else
2263
0
      *DataLen = scard_copy_strings(value, Data, count, data->data, data->size);
2264
0
  }
2265
2266
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2267
0
             "SCardReadCacheW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2268
0
             status);
2269
2270
0
  return status;
2271
0
}
2272
2273
static LONG insert_data(wHashTable* table, DWORD FreshnessCounter, const void* key,
2274
                        const PBYTE Data, DWORD DataLen)
2275
0
{
2276
0
  BOOL rc = 0;
2277
0
  SCardCacheItem* item = NULL;
2278
2279
0
  WINPR_ASSERT(table);
2280
0
  WINPR_ASSERT(key);
2281
2282
0
  if (DataLen > MAX_CACHE_ITEM_SIZE)
2283
0
    return SCARD_W_CACHE_ITEM_TOO_BIG;
2284
2285
0
  if (HashTable_Count(table) > MAX_CACHE_ITEM_VALUES)
2286
0
    return SCARD_E_WRITE_TOO_MANY;
2287
2288
0
  item = HashTable_GetItemValue(table, key);
2289
0
  if (!item)
2290
0
  {
2291
0
    item = calloc(1, sizeof(SCardCacheItem));
2292
0
    if (!item)
2293
0
      return SCARD_E_NO_MEMORY;
2294
2295
0
    rc = HashTable_Insert(table, key, item);
2296
0
    if (!rc)
2297
0
    {
2298
0
      free(item);
2299
0
      return SCARD_E_NO_MEMORY;
2300
0
    }
2301
0
  }
2302
2303
0
  if (item->freshness > FreshnessCounter)
2304
0
    return SCARD_W_CACHE_ITEM_STALE;
2305
0
  item->freshness = FreshnessCounter;
2306
0
  item->size = DataLen;
2307
0
  memcpy(item->data, Data, DataLen);
2308
2309
  // NOLINTNEXTLINE(clang-analyzer-unix.Malloc): HashTable_Insert takes ownership of item
2310
0
  return SCARD_S_SUCCESS;
2311
0
}
2312
2313
LONG WINAPI Emulate_SCardWriteCacheA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2314
                                     UUID* CardIdentifier, DWORD FreshnessCounter, LPSTR LookupName,
2315
                                     PBYTE Data, DWORD DataLen)
2316
0
{
2317
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2318
2319
0
  if (!CardIdentifier)
2320
0
    status = SCARD_E_INVALID_PARAMETER;
2321
2322
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardWriteCacheA { hContext: %p",
2323
0
             (void*)hContext);
2324
2325
0
  if (status == SCARD_S_SUCCESS)
2326
0
  {
2327
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
2328
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
2329
2330
0
    status = insert_data(value->cacheA, FreshnessCounter, LookupName, Data, DataLen);
2331
0
  }
2332
2333
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2334
0
             "SCardWriteCacheA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2335
0
             status);
2336
2337
0
  return status;
2338
0
}
2339
2340
LONG WINAPI Emulate_SCardWriteCacheW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2341
                                     UUID* CardIdentifier, DWORD FreshnessCounter,
2342
                                     LPWSTR LookupName, PBYTE Data, DWORD DataLen)
2343
0
{
2344
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2345
2346
0
  if (!CardIdentifier)
2347
0
    status = SCARD_E_INVALID_PARAMETER;
2348
2349
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardWriteCacheW { hContext: %p",
2350
0
             (void*)hContext);
2351
2352
0
  if (status == SCARD_S_SUCCESS)
2353
0
  {
2354
0
    SCardContext* value = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
2355
0
    WINPR_ASSERT(value); /* Must be valid after Emulate_SCardIsValidContext */
2356
2357
0
    status = insert_data(value->cacheW, FreshnessCounter, LookupName, Data, DataLen);
2358
0
  }
2359
2360
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2361
0
             "SCardWriteCacheW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2362
0
             status);
2363
2364
0
  return status;
2365
0
}
2366
2367
LONG WINAPI Emulate_SCardGetReaderIconA(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2368
                                        LPCSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2369
0
{
2370
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2371
2372
0
  if (!szReaderName || !pcbIcon)
2373
0
    status = SCARD_E_INVALID_PARAMETER;
2374
2375
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetReaderIconA { hContext: %p",
2376
0
             (void*)hContext);
2377
2378
0
  if (status == SCARD_S_SUCCESS)
2379
0
    status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2380
2381
0
  if (status == SCARD_S_SUCCESS)
2382
0
  {
2383
0
    SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
2384
0
    WINPR_ASSERT(ctx);
2385
2386
0
    if (pbIcon)
2387
0
      *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2388
0
                                    resources_FreeRDP_ico_len);
2389
0
    else
2390
0
      *pcbIcon = resources_FreeRDP_ico_len;
2391
0
  }
2392
2393
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2394
0
             "SCardGetReaderIconA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2395
0
             status);
2396
2397
0
  return status;
2398
0
}
2399
2400
LONG WINAPI Emulate_SCardGetReaderIconW(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2401
                                        LPCWSTR szReaderName, LPBYTE pbIcon, LPDWORD pcbIcon)
2402
0
{
2403
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2404
2405
0
  if (!szReaderName || !pcbIcon)
2406
0
    status = SCARD_E_INVALID_PARAMETER;
2407
2408
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetReaderIconW { hContext: %p",
2409
0
             (void*)hContext);
2410
2411
0
  if (status == SCARD_S_SUCCESS)
2412
0
    status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2413
2414
0
  if (status == SCARD_S_SUCCESS)
2415
0
  {
2416
0
    SCardContext* ctx = HashTable_GetItemValue(smartcard->contexts, (const void*)hContext);
2417
0
    WINPR_ASSERT(ctx);
2418
2419
0
    if (pbIcon)
2420
0
      *pcbIcon = scard_copy_strings(ctx, pbIcon, *pcbIcon, resources_FreeRDP_ico,
2421
0
                                    resources_FreeRDP_ico_len);
2422
0
    else
2423
0
      *pcbIcon = resources_FreeRDP_ico_len;
2424
0
  }
2425
2426
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2427
0
             "SCardGetReaderIconW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2428
0
             status);
2429
2430
0
  return status;
2431
0
}
2432
2433
LONG WINAPI Emulate_SCardGetDeviceTypeIdA(SmartcardEmulationContext* smartcard,
2434
                                          SCARDCONTEXT hContext, LPCSTR szReaderName,
2435
                                          LPDWORD pdwDeviceTypeId)
2436
0
{
2437
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2438
2439
0
  if (!pdwDeviceTypeId)
2440
0
    status = SCARD_E_INVALID_PARAMETER;
2441
2442
0
  if (status == SCARD_S_SUCCESS)
2443
0
    status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2444
2445
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetDeviceTypeIdA { hContext: %p",
2446
0
             (void*)hContext);
2447
2448
0
  if (status == SCARD_S_SUCCESS)
2449
0
  {
2450
0
    *pdwDeviceTypeId = SCARD_READER_TYPE_USB; // SCARD_READER_TYPE_TPM
2451
0
  }
2452
2453
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2454
0
             "SCardGetDeviceTypeIdA } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2455
0
             status);
2456
2457
0
  return status;
2458
0
}
2459
2460
LONG WINAPI Emulate_SCardGetDeviceTypeIdW(SmartcardEmulationContext* smartcard,
2461
                                          SCARDCONTEXT hContext, LPCWSTR szReaderName,
2462
                                          LPDWORD pdwDeviceTypeId)
2463
0
{
2464
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2465
2466
0
  if (!pdwDeviceTypeId)
2467
0
    status = SCARD_E_INVALID_PARAMETER;
2468
2469
0
  if (status == SCARD_S_SUCCESS)
2470
0
    status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2471
2472
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardGetDeviceTypeIdW { hContext: %p",
2473
0
             (void*)hContext);
2474
2475
0
  if (status == SCARD_S_SUCCESS)
2476
0
  {
2477
0
    *pdwDeviceTypeId = SCARD_READER_TYPE_USB; // SCARD_READER_TYPE_TPM
2478
0
  }
2479
2480
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2481
0
             "SCardGetDeviceTypeIdW } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status),
2482
0
             status);
2483
2484
0
  return status;
2485
0
}
2486
2487
LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdA(SmartcardEmulationContext* smartcard,
2488
                                                    SCARDCONTEXT hContext, LPCSTR szReaderName,
2489
                                                    LPSTR szDeviceInstanceId,
2490
                                                    LPDWORD pcchDeviceInstanceId)
2491
0
{
2492
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2493
2494
0
  if (status == SCARD_S_SUCCESS)
2495
0
    status = scard_reader_name_valid_a(smartcard, hContext, szReaderName);
2496
2497
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2498
0
             "SCardGetReaderDeviceInstanceIdA { hContext: %p", (void*)hContext);
2499
2500
0
  WINPR_UNUSED(szDeviceInstanceId);
2501
0
  WINPR_UNUSED(pcchDeviceInstanceId);
2502
2503
  /* Not required, return not supported */
2504
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2505
2506
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2507
0
             "SCardGetReaderDeviceInstanceIdA } status: %s (0x%08" PRIX32 ")",
2508
0
             SCardGetErrorString(status), status);
2509
2510
0
  return status;
2511
0
}
2512
2513
LONG WINAPI Emulate_SCardGetReaderDeviceInstanceIdW(SmartcardEmulationContext* smartcard,
2514
                                                    SCARDCONTEXT hContext, LPCWSTR szReaderName,
2515
                                                    LPWSTR szDeviceInstanceId,
2516
                                                    LPDWORD pcchDeviceInstanceId)
2517
0
{
2518
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2519
2520
0
  if (status == SCARD_S_SUCCESS)
2521
0
    status = scard_reader_name_valid_w(smartcard, hContext, szReaderName);
2522
2523
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2524
0
             "SCardGetReaderDeviceInstanceIdW { hContext: %p", (void*)hContext);
2525
2526
0
  WINPR_UNUSED(szDeviceInstanceId);
2527
0
  WINPR_UNUSED(pcchDeviceInstanceId);
2528
2529
  /* Not required, return not supported */
2530
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2531
2532
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2533
0
             "SCardGetReaderDeviceInstanceIdW } status: %s (0x%08" PRIX32 ")",
2534
0
             SCardGetErrorString(status), status);
2535
2536
0
  return status;
2537
0
}
2538
2539
LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdA(SmartcardEmulationContext* smartcard,
2540
                                                          SCARDCONTEXT hContext,
2541
                                                          LPCSTR szDeviceInstanceId,
2542
                                                          LPSTR mszReaders, LPDWORD pcchReaders)
2543
0
{
2544
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2545
2546
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2547
0
             "SCardListReadersWithDeviceInstanceIdA { hContext: %p", (void*)hContext);
2548
2549
0
  WINPR_UNUSED(szDeviceInstanceId);
2550
0
  WINPR_UNUSED(mszReaders);
2551
0
  WINPR_UNUSED(pcchReaders);
2552
2553
  /* Not required, return not supported */
2554
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2555
2556
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2557
0
             "SCardListReadersWithDeviceInstanceIdA } status: %s (0x%08" PRIX32 ")",
2558
0
             SCardGetErrorString(status), status);
2559
2560
0
  return status;
2561
0
}
2562
2563
LONG WINAPI Emulate_SCardListReadersWithDeviceInstanceIdW(SmartcardEmulationContext* smartcard,
2564
                                                          SCARDCONTEXT hContext,
2565
                                                          LPCWSTR szDeviceInstanceId,
2566
                                                          LPWSTR mszReaders, LPDWORD pcchReaders)
2567
0
{
2568
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2569
2570
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2571
0
             "SCardListReadersWithDeviceInstanceIdW { hContext: %p", (void*)hContext);
2572
2573
0
  WINPR_UNUSED(szDeviceInstanceId);
2574
0
  WINPR_UNUSED(mszReaders);
2575
0
  WINPR_UNUSED(pcchReaders);
2576
2577
  /* Not required, return not supported */
2578
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2579
2580
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2581
0
             "SCardListReadersWithDeviceInstanceIdW } status: %s (0x%08" PRIX32 ")",
2582
0
             SCardGetErrorString(status), status);
2583
2584
0
  return status;
2585
0
}
2586
2587
LONG WINAPI Emulate_SCardAudit(SmartcardEmulationContext* smartcard, SCARDCONTEXT hContext,
2588
                               DWORD dwEvent)
2589
0
{
2590
0
  LONG status = Emulate_SCardIsValidContext(smartcard, hContext);
2591
2592
0
  WINPR_UNUSED(dwEvent);
2593
2594
0
  WLog_Print(smartcard->log, smartcard->log_default_level, "SCardAudit { hContext: %p",
2595
0
             (void*)hContext);
2596
2597
  // TODO: Implement
2598
0
  status = SCARD_E_UNSUPPORTED_FEATURE;
2599
2600
0
  WLog_Print(smartcard->log, smartcard->log_default_level,
2601
0
             "SCardAudit } status: %s (0x%08" PRIX32 ")", SCardGetErrorString(status), status);
2602
2603
0
  return status;
2604
0
}
2605
2606
static BOOL context_equals(const void* pva, const void* pvb)
2607
0
{
2608
0
  const SCARDCONTEXT a = (const SCARDCONTEXT)pva;
2609
0
  const SCARDCONTEXT b = (const SCARDCONTEXT)pvb;
2610
0
  if (!a && !b)
2611
0
    return TRUE;
2612
0
  if (!a || !b)
2613
0
    return FALSE;
2614
2615
0
  return a == b;
2616
0
}
2617
2618
static BOOL handle_equals(const void* pva, const void* pvb)
2619
0
{
2620
0
  const SCARDHANDLE a = (const SCARDHANDLE)pva;
2621
0
  const SCARDHANDLE b = (const SCARDHANDLE)pvb;
2622
0
  if (!a && !b)
2623
0
    return TRUE;
2624
0
  if (!a || !b)
2625
0
    return FALSE;
2626
2627
0
  return a == b;
2628
0
}
2629
2630
SmartcardEmulationContext* Emulate_New(const rdpSettings* settings)
2631
0
{
2632
0
  SmartcardEmulationContext* smartcard = NULL;
2633
2634
0
  WINPR_ASSERT(settings);
2635
2636
0
  smartcard = calloc(1, sizeof(SmartcardEmulationContext));
2637
0
  if (!smartcard)
2638
0
    goto fail;
2639
2640
0
  smartcard->settings = settings;
2641
0
  smartcard->log = WLog_Get("EmulateSCard");
2642
0
  if (!smartcard->log)
2643
0
    goto fail;
2644
0
  smartcard->log_default_level = WLOG_TRACE;
2645
2646
0
  smartcard->contexts = HashTable_New(FALSE);
2647
0
  if (!smartcard->contexts)
2648
0
    goto fail;
2649
0
  else
2650
0
  {
2651
0
    wObject* obj = HashTable_KeyObject(smartcard->contexts);
2652
0
    WINPR_ASSERT(obj);
2653
0
    obj->fnObjectEquals = context_equals;
2654
0
  }
2655
0
  if (!smartcard->contexts)
2656
0
    goto fail;
2657
0
  else
2658
0
  {
2659
0
    wObject* obj = HashTable_ValueObject(smartcard->contexts);
2660
0
    WINPR_ASSERT(obj);
2661
0
    obj->fnObjectFree = scard_context_free;
2662
0
  }
2663
2664
0
  smartcard->handles = HashTable_New(FALSE);
2665
0
  if (!smartcard->handles)
2666
0
    goto fail;
2667
0
  else
2668
0
  {
2669
0
    wObject* obj = HashTable_KeyObject(smartcard->handles);
2670
0
    WINPR_ASSERT(obj);
2671
0
    obj->fnObjectEquals = handle_equals;
2672
0
  }
2673
0
  if (!smartcard->handles)
2674
0
    goto fail;
2675
0
  else
2676
0
  {
2677
0
    wObject* obj = HashTable_ValueObject(smartcard->handles);
2678
0
    WINPR_ASSERT(obj);
2679
0
    obj->fnObjectFree = scard_handle_free;
2680
0
  }
2681
2682
0
  return smartcard;
2683
2684
0
fail:
2685
0
  WINPR_PRAGMA_DIAG_PUSH
2686
0
  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
2687
0
  Emulate_Free(smartcard);
2688
0
  WINPR_PRAGMA_DIAG_POP
2689
0
  return NULL;
2690
0
}
2691
2692
void Emulate_Free(SmartcardEmulationContext* context)
2693
0
{
2694
0
  if (!context)
2695
0
    return;
2696
2697
0
  HashTable_Free(context->handles);
2698
0
  HashTable_Free(context->contexts);
2699
0
  free(context);
2700
0
}
2701
2702
BOOL Emulate_IsConfigured(SmartcardEmulationContext* context)
2703
0
{
2704
0
  BOOL rc = FALSE;
2705
0
  vgidsContext* vgids = NULL;
2706
0
  const char* pem = NULL;
2707
0
  const char* key = NULL;
2708
0
  const char* pin = NULL;
2709
2710
0
  WINPR_ASSERT(context);
2711
2712
0
  pem = freerdp_settings_get_string(context->settings, FreeRDP_SmartcardCertificate);
2713
0
  key = freerdp_settings_get_string(context->settings, FreeRDP_SmartcardPrivateKey);
2714
0
  pin = freerdp_settings_get_string(context->settings, FreeRDP_Password);
2715
2716
  /* Cache result only, if no initialization arguments changed. */
2717
0
  if ((context->pem == pem) && (context->key == key) && (context->pin == pin))
2718
0
    return context->configured;
2719
2720
0
  context->pem = pem;
2721
0
  context->key = key;
2722
0
  context->pin = pin;
2723
2724
0
  vgids = vgids_new();
2725
0
  if (vgids)
2726
0
    rc = vgids_init(vgids, context->pem, context->key, context->pin);
2727
0
  vgids_free(vgids);
2728
2729
0
  context->configured = rc;
2730
0
  return rc;
2731
0
}