Coverage Report

Created: 2024-09-08 06:20

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