Coverage Report

Created: 2026-02-26 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/libfreerdp/utils/smartcard_pack.c
Line
Count
Source
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Smart Card Structure Packing
4
 *
5
 * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2015 Thincast Technologies GmbH
7
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8
 * Copyright 2020 Armin Novak <armin.novak@thincast.com>
9
 * Copyright 2020 Thincast Technologies GmbH
10
 *
11
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14
 *
15
 *     http://www.apache.org/licenses/LICENSE-2.0
16
 *
17
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22
 */
23
24
#include <freerdp/config.h>
25
26
#include <winpr/crt.h>
27
#include <winpr/print.h>
28
29
#include <freerdp/channels/scard.h>
30
#include <freerdp/utils/smartcard_pack.h>
31
#include "smartcard_pack.h"
32
33
#include <freerdp/log.h>
34
0
#define SCARD_TAG FREERDP_TAG("scard.pack")
35
36
static const DWORD g_LogLevel = WLOG_DEBUG;
37
38
static wLog* scard_log(void)
39
0
{
40
0
  static wLog* log = NULL;
41
0
  if (!log)
42
0
    log = WLog_Get(SCARD_TAG);
43
0
  return log;
44
0
}
45
46
#define smartcard_unpack_redir_scard_context(log, s, context, index, ndr)                  \
47
0
  smartcard_unpack_redir_scard_context_((log), (s), (context), (index), (ndr), __FILE__, \
48
0
                                        __func__, __LINE__)
49
#define smartcard_unpack_redir_scard_handle(log, s, context, index)                          \
50
0
  smartcard_unpack_redir_scard_handle_((log), (s), (context), (index), __FILE__, __func__, \
51
0
                                       __LINE__)
52
53
static LONG smartcard_unpack_redir_scard_context_(wLog* log, wStream* s,
54
                                                  REDIR_SCARDCONTEXT* context, UINT32* index,
55
                                                  UINT32* ppbContextNdrPtr, const char* file,
56
                                                  const char* function, size_t line);
57
static LONG smartcard_pack_redir_scard_context(wLog* log, wStream* s,
58
                                               const REDIR_SCARDCONTEXT* context, DWORD* index);
59
static LONG smartcard_unpack_redir_scard_handle_(wLog* log, wStream* s, REDIR_SCARDHANDLE* handle,
60
                                                 UINT32* index, const char* file,
61
                                                 const char* function, size_t line);
62
static LONG smartcard_pack_redir_scard_handle(wLog* log, wStream* s,
63
                                              const REDIR_SCARDHANDLE* handle, DWORD* index);
64
static LONG smartcard_unpack_redir_scard_context_ref(wLog* log, wStream* s, UINT32 pbContextNdrPtr,
65
                                                     REDIR_SCARDCONTEXT* context);
66
static LONG smartcard_pack_redir_scard_context_ref(wLog* log, wStream* s,
67
                                                   const REDIR_SCARDCONTEXT* context);
68
69
static LONG smartcard_unpack_redir_scard_handle_ref(wLog* log, wStream* s,
70
                                                    REDIR_SCARDHANDLE* handle);
71
static LONG smartcard_pack_redir_scard_handle_ref(wLog* log, wStream* s,
72
                                                  const REDIR_SCARDHANDLE* handle);
73
74
typedef enum
75
{
76
  NDR_PTR_FULL,
77
  NDR_PTR_SIMPLE,
78
  NDR_PTR_FIXED
79
} ndr_ptr_t;
80
81
/* Reads a NDR pointer and checks if the value read has the expected relative
82
 * addressing */
83
#define smartcard_ndr_pointer_read(log, s, index, ptr) \
84
0
  smartcard_ndr_pointer_read_((log), (s), (index), (ptr), __FILE__, __func__, __LINE__)
85
static BOOL smartcard_ndr_pointer_read_(wLog* log, wStream* s, UINT32* index, UINT32* ptr,
86
                                        const char* file, const char* fkt, size_t line)
87
0
{
88
0
  const UINT32 expect = 0x20000 + (*index) * 4;
89
0
  UINT32 ndrPtr = 0;
90
0
  WINPR_UNUSED(file);
91
0
  if (!s)
92
0
    return FALSE;
93
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
94
0
    return FALSE;
95
96
0
  Stream_Read_UINT32(s, ndrPtr); /* mszGroupsNdrPtr (4 bytes) */
97
0
  if (ptr)
98
0
    *ptr = ndrPtr;
99
0
  if (expect != ndrPtr)
100
0
  {
101
    /* Allow NULL pointer if we read the result */
102
0
    if (ptr && (ndrPtr == 0))
103
0
      return TRUE;
104
0
    WLog_Print(log, WLOG_WARN,
105
0
               "[%s:%" PRIuz "] Read context pointer 0x%08" PRIx32 ", expected 0x%08" PRIx32,
106
0
               fkt, line, ndrPtr, expect);
107
0
    return FALSE;
108
0
  }
109
110
0
  (*index) = (*index) + 1;
111
0
  return TRUE;
112
0
}
113
114
static LONG smartcard_ndr_read_ex(wLog* log, wStream* s, BYTE** data, size_t min,
115
                                  size_t elementSize, ndr_ptr_t type, size_t* plen)
116
0
{
117
0
  size_t len = 0;
118
0
  size_t offset = 0;
119
0
  size_t len2 = 0;
120
0
  void* r = NULL;
121
0
  size_t required = 0;
122
123
0
  *data = NULL;
124
0
  if (plen)
125
0
    *plen = 0;
126
127
0
  switch (type)
128
0
  {
129
0
    case NDR_PTR_FULL:
130
0
      required = 12;
131
0
      break;
132
0
    case NDR_PTR_SIMPLE:
133
0
      required = 4;
134
0
      break;
135
0
    case NDR_PTR_FIXED:
136
0
      required = min;
137
0
      break;
138
0
    default:
139
0
      return STATUS_INVALID_PARAMETER;
140
0
  }
141
142
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, required))
143
0
    return STATUS_BUFFER_TOO_SMALL;
144
145
0
  switch (type)
146
0
  {
147
0
    case NDR_PTR_FULL:
148
0
      Stream_Read_UINT32(s, len);
149
0
      Stream_Read_UINT32(s, offset);
150
0
      Stream_Read_UINT32(s, len2);
151
0
      if (len != offset + len2)
152
0
      {
153
0
        WLog_Print(log, WLOG_ERROR,
154
0
                   "Invalid data when reading full NDR pointer: total=%" PRIuz
155
0
                   ", offset=%" PRIuz ", remaining=%" PRIuz,
156
0
                   len, offset, len2);
157
0
        return STATUS_BUFFER_TOO_SMALL;
158
0
      }
159
0
      break;
160
0
    case NDR_PTR_SIMPLE:
161
0
      Stream_Read_UINT32(s, len);
162
163
0
      if ((len != min) && (min > 0))
164
0
      {
165
0
        WLog_Print(log, WLOG_ERROR,
166
0
                   "Invalid data when reading simple NDR pointer: total=%" PRIuz
167
0
                   ", expected=%" PRIuz,
168
0
                   len, min);
169
0
        return STATUS_BUFFER_TOO_SMALL;
170
0
      }
171
0
      break;
172
0
    case NDR_PTR_FIXED:
173
0
      len = (UINT32)min;
174
0
      break;
175
0
    default:
176
0
      return STATUS_INVALID_PARAMETER;
177
0
  }
178
179
0
  if (min > len)
180
0
  {
181
0
    WLog_Print(log, WLOG_ERROR,
182
0
               "Invalid length read from NDR pointer, minimum %" PRIuz ", got %" PRIuz, min,
183
0
               len);
184
0
    return STATUS_DATA_ERROR;
185
0
  }
186
187
0
  if (len > SIZE_MAX / 2)
188
0
    return STATUS_BUFFER_TOO_SMALL;
189
190
0
  if (!Stream_CheckAndLogRequiredLengthOfSizeWLog(log, s, len, elementSize))
191
0
    return STATUS_BUFFER_TOO_SMALL;
192
193
0
  len *= elementSize;
194
195
  /* Ensure proper '\0' termination for all kinds of unicode strings
196
   * as we do not know if the data from the wire contains one.
197
   */
198
0
  r = calloc(len + sizeof(WCHAR), sizeof(CHAR));
199
0
  if (!r)
200
0
    return SCARD_E_NO_MEMORY;
201
0
  Stream_Read(s, r, len);
202
0
  const LONG pad = smartcard_unpack_read_size_align(s, len, 4);
203
0
  if (pad < 0)
204
0
  {
205
0
    free(r);
206
0
    return STATUS_INVALID_PARAMETER;
207
0
  }
208
0
  len += (size_t)pad;
209
0
  *data = r;
210
0
  if (plen)
211
0
    *plen = len;
212
0
  return STATUS_SUCCESS;
213
0
}
214
215
static LONG smartcard_ndr_read(wLog* log, wStream* s, BYTE** data, size_t min, size_t elementSize,
216
                               ndr_ptr_t type)
217
0
{
218
0
  return smartcard_ndr_read_ex(log, s, data, min, elementSize, type, NULL);
219
0
}
220
221
static BOOL smartcard_ndr_pointer_write(wStream* s, UINT32* index, DWORD length)
222
0
{
223
0
  const UINT32 ndrPtr = 0x20000 + (*index) * 4;
224
225
0
  if (!s)
226
0
    return FALSE;
227
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
228
0
    return FALSE;
229
230
0
  if (length > 0)
231
0
  {
232
0
    Stream_Write_UINT32(s, ndrPtr); /* mszGroupsNdrPtr (4 bytes) */
233
0
    (*index) = (*index) + 1;
234
0
  }
235
0
  else
236
0
    Stream_Write_UINT32(s, 0);
237
0
  return TRUE;
238
0
}
239
240
static LONG smartcard_ndr_write(wStream* s, const BYTE* data, UINT32 size, UINT32 elementSize,
241
                                ndr_ptr_t type)
242
0
{
243
0
  const UINT32 offset = 0;
244
0
  const UINT32 len = size;
245
0
  const UINT32 dataLen = size * elementSize;
246
0
  size_t required = 0;
247
248
0
  if (size == 0)
249
0
    return SCARD_S_SUCCESS;
250
251
0
  switch (type)
252
0
  {
253
0
    case NDR_PTR_FULL:
254
0
      required = 12;
255
0
      break;
256
0
    case NDR_PTR_SIMPLE:
257
0
      required = 4;
258
0
      break;
259
0
    case NDR_PTR_FIXED:
260
0
      required = 0;
261
0
      break;
262
0
    default:
263
0
      return SCARD_E_INVALID_PARAMETER;
264
0
  }
265
266
0
  if (!Stream_EnsureRemainingCapacity(s, required + dataLen + 4))
267
0
    return STATUS_BUFFER_TOO_SMALL;
268
269
0
  switch (type)
270
0
  {
271
0
    case NDR_PTR_FULL:
272
0
      Stream_Write_UINT32(s, len);
273
0
      Stream_Write_UINT32(s, offset);
274
0
      Stream_Write_UINT32(s, len);
275
0
      break;
276
0
    case NDR_PTR_SIMPLE:
277
0
      Stream_Write_UINT32(s, len);
278
0
      break;
279
0
    case NDR_PTR_FIXED:
280
0
      break;
281
0
    default:
282
0
      return SCARD_E_INVALID_PARAMETER;
283
0
  }
284
285
0
  if (data)
286
0
    Stream_Write(s, data, dataLen);
287
0
  else
288
0
    Stream_Zero(s, dataLen);
289
0
  return smartcard_pack_write_size_align(s, len, 4);
290
0
}
291
292
static LONG smartcard_ndr_write_state(wStream* s, const ReaderState_Return* data, UINT32 size,
293
                                      ndr_ptr_t type)
294
0
{
295
0
  union
296
0
  {
297
0
    const ReaderState_Return* reader;
298
0
    const BYTE* data;
299
0
  } cnv;
300
301
0
  WINPR_ASSERT(data || (size == 0));
302
0
  cnv.reader = data;
303
0
  return smartcard_ndr_write(s, cnv.data, size, sizeof(ReaderState_Return), type);
304
0
}
305
306
static LONG smartcard_ndr_read_atrmask(wLog* log, wStream* s, LocateCards_ATRMask** data,
307
                                       size_t min, ndr_ptr_t type)
308
0
{
309
0
  union
310
0
  {
311
0
    LocateCards_ATRMask** ppc;
312
0
    BYTE** ppv;
313
0
  } u;
314
0
  u.ppc = data;
315
0
  return smartcard_ndr_read(log, s, u.ppv, min, sizeof(LocateCards_ATRMask), type);
316
0
}
317
318
static LONG smartcard_ndr_read_fixed_string_a(wLog* log, wStream* s, CHAR** data, size_t min,
319
                                              ndr_ptr_t type)
320
0
{
321
0
  union
322
0
  {
323
0
    CHAR** ppc;
324
0
    BYTE** ppv;
325
0
  } u;
326
0
  u.ppc = data;
327
0
  return smartcard_ndr_read(log, s, u.ppv, min, sizeof(CHAR), type);
328
0
}
329
330
static LONG smartcard_ndr_read_fixed_string_w(wLog* log, wStream* s, WCHAR** data, size_t min,
331
                                              ndr_ptr_t type)
332
0
{
333
0
  union
334
0
  {
335
0
    WCHAR** ppc;
336
0
    BYTE** ppv;
337
0
  } u;
338
0
  u.ppc = data;
339
0
  return smartcard_ndr_read(log, s, u.ppv, min, sizeof(WCHAR), type);
340
0
}
341
342
static LONG smartcard_ndr_read_a(wLog* log, wStream* s, CHAR** data, ndr_ptr_t type)
343
0
{
344
0
  union
345
0
  {
346
0
    CHAR** ppc;
347
0
    BYTE** ppv;
348
0
  } u;
349
0
  u.ppc = data;
350
0
  return smartcard_ndr_read(log, s, u.ppv, 0, sizeof(CHAR), type);
351
0
}
352
353
static LONG smartcard_ndr_read_w(wLog* log, wStream* s, WCHAR** data, ndr_ptr_t type)
354
0
{
355
0
  union
356
0
  {
357
0
    WCHAR** ppc;
358
0
    BYTE** ppv;
359
0
  } u;
360
0
  u.ppc = data;
361
0
  return smartcard_ndr_read(log, s, u.ppv, 0, sizeof(WCHAR), type);
362
0
}
363
364
static LONG smartcard_ndr_read_u(wLog* log, wStream* s, UUID** data)
365
0
{
366
0
  union
367
0
  {
368
0
    UUID** ppc;
369
0
    BYTE** ppv;
370
0
  } u;
371
0
  u.ppc = data;
372
0
  return smartcard_ndr_read(log, s, u.ppv, 1, sizeof(UUID), NDR_PTR_FIXED);
373
0
}
374
375
static char* smartcard_convert_string_list(const void* in, size_t bytes, BOOL unicode)
376
0
{
377
0
  size_t length = 0;
378
0
  union
379
0
  {
380
0
    const void* pv;
381
0
    const char* sz;
382
0
    const WCHAR* wz;
383
0
  } string;
384
0
  char* mszA = NULL;
385
386
0
  string.pv = in;
387
388
0
  if (bytes < 1)
389
0
    return NULL;
390
391
0
  if (in == NULL)
392
0
    return NULL;
393
394
0
  if (unicode)
395
0
  {
396
0
    mszA = ConvertMszWCharNToUtf8Alloc(string.wz, bytes / sizeof(WCHAR), &length);
397
0
    if (!mszA)
398
0
      return NULL;
399
0
  }
400
0
  else
401
0
  {
402
0
    mszA = (char*)calloc(bytes, sizeof(char));
403
0
    if (!mszA)
404
0
      return NULL;
405
0
    CopyMemory(mszA, string.sz, bytes - 1);
406
0
    length = bytes;
407
0
  }
408
409
0
  if (length < 1)
410
0
  {
411
0
    free(mszA);
412
0
    return NULL;
413
0
  }
414
0
  for (size_t index = 0; index < length - 1; index++)
415
0
  {
416
0
    if (mszA[index] == '\0')
417
0
      mszA[index] = ',';
418
0
  }
419
420
0
  return mszA;
421
0
}
422
423
static char* smartcard_msz_dump_a(const char* msz, size_t len, char* buffer, size_t bufferLen)
424
0
{
425
0
  char* buf = buffer;
426
0
  const char* cur = msz;
427
428
0
  while ((len > 0) && cur && cur[0] != '\0' && (bufferLen > 0))
429
0
  {
430
0
    size_t clen = strnlen(cur, len);
431
0
    int rc = _snprintf(buf, bufferLen, "%s", cur);
432
0
    bufferLen -= (size_t)rc;
433
0
    buf += rc;
434
435
0
    cur += clen;
436
0
  }
437
438
0
  return buffer;
439
0
}
440
441
static char* smartcard_msz_dump_w(const WCHAR* msz, size_t len, char* buffer, size_t bufferLen)
442
0
{
443
0
  size_t szlen = 0;
444
0
  if (!msz)
445
0
    return NULL;
446
0
  char* sz = ConvertMszWCharNToUtf8Alloc(msz, len, &szlen);
447
0
  if (!sz)
448
0
    return NULL;
449
450
0
  smartcard_msz_dump_a(sz, szlen, buffer, bufferLen);
451
0
  free(sz);
452
0
  return buffer;
453
0
}
454
455
static char* smartcard_array_dump(const void* pd, size_t len, char* buffer, size_t bufferLen)
456
0
{
457
0
  const BYTE* data = pd;
458
0
  int rc = 0;
459
0
  char* start = buffer;
460
461
0
  WINPR_ASSERT(buffer || (bufferLen == 0));
462
463
0
  if (!data && (len > 0))
464
0
  {
465
0
    (void)_snprintf(buffer, bufferLen, "{ NULL [%" PRIuz "] }", len);
466
0
    goto fail;
467
0
  }
468
469
0
  rc = _snprintf(buffer, bufferLen, "{ ");
470
0
  if ((rc < 0) || ((size_t)rc >= bufferLen))
471
0
    goto fail;
472
0
  buffer += rc;
473
0
  bufferLen -= (size_t)rc;
474
475
0
  for (size_t x = 0; x < len; x++)
476
0
  {
477
0
    rc = _snprintf(buffer, bufferLen, "%02X", data[x]);
478
0
    if ((rc < 0) || ((size_t)rc >= bufferLen))
479
0
      goto fail;
480
0
    buffer += rc;
481
0
    bufferLen -= (size_t)rc;
482
0
  }
483
484
0
  rc = _snprintf(buffer, bufferLen, " }");
485
0
  if ((rc < 0) || ((size_t)rc >= bufferLen))
486
0
    goto fail;
487
488
0
fail:
489
0
  return start;
490
0
}
491
492
static void smartcard_log_redir_handle(wLog* log, const REDIR_SCARDHANDLE* pHandle)
493
0
{
494
0
  char buffer[128] = WINPR_C_ARRAY_INIT;
495
496
0
  WINPR_ASSERT(pHandle);
497
0
  WLog_Print(log, g_LogLevel, "  hContext: %s",
498
0
             smartcard_array_dump(pHandle->pbHandle, pHandle->cbHandle, buffer, sizeof(buffer)));
499
0
}
500
501
static void smartcard_log_context(wLog* log, const REDIR_SCARDCONTEXT* phContext)
502
0
{
503
0
  char buffer[128] = WINPR_C_ARRAY_INIT;
504
505
0
  WINPR_ASSERT(phContext);
506
0
  WLog_Print(
507
0
      log, g_LogLevel, "hContext: %s",
508
0
      smartcard_array_dump(phContext->pbContext, phContext->cbContext, buffer, sizeof(buffer)));
509
0
}
510
511
static void smartcard_trace_context_and_string_call_a(wLog* log, const char* name,
512
                                                      const REDIR_SCARDCONTEXT* phContext,
513
                                                      const CHAR* sz)
514
0
{
515
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
516
0
    return;
517
518
0
  WLog_Print(log, g_LogLevel, "%s {", name);
519
0
  smartcard_log_context(log, phContext);
520
0
  WLog_Print(log, g_LogLevel, "  sz=%s", sz);
521
522
0
  WLog_Print(log, g_LogLevel, "}");
523
0
}
524
525
static void smartcard_trace_context_and_string_call_w(wLog* log, const char* name,
526
                                                      const REDIR_SCARDCONTEXT* phContext,
527
                                                      const WCHAR* sz)
528
0
{
529
0
  char tmp[1024] = WINPR_C_ARRAY_INIT;
530
531
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
532
0
    return;
533
534
0
  if (sz)
535
0
    (void)ConvertWCharToUtf8(sz, tmp, ARRAYSIZE(tmp));
536
537
0
  WLog_Print(log, g_LogLevel, "%s {", name);
538
0
  smartcard_log_context(log, phContext);
539
0
  WLog_Print(log, g_LogLevel, "  sz=%s", tmp);
540
0
  WLog_Print(log, g_LogLevel, "}");
541
0
}
542
543
static void smartcard_trace_context_call(wLog* log, const Context_Call* call, const char* name)
544
0
{
545
0
  WINPR_ASSERT(call);
546
547
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
548
0
    return;
549
550
0
  WLog_Print(log, g_LogLevel, "%s_Call {", name);
551
0
  smartcard_log_context(log, &call->handles.hContext);
552
553
0
  WLog_Print(log, g_LogLevel, "}");
554
0
}
555
556
static void smartcard_trace_list_reader_groups_call(wLog* log, const ListReaderGroups_Call* call,
557
                                                    BOOL unicode)
558
0
{
559
0
  WINPR_ASSERT(call);
560
561
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
562
0
    return;
563
564
0
  WLog_Print(log, g_LogLevel, "ListReaderGroups%s_Call {", unicode ? "W" : "A");
565
0
  smartcard_log_context(log, &call->handles.hContext);
566
567
0
  WLog_Print(log, g_LogLevel, "fmszGroupsIsNULL: %" PRId32 " cchGroups: 0x%08" PRIx32,
568
0
             call->fmszGroupsIsNULL, call->cchGroups);
569
0
  WLog_Print(log, g_LogLevel, "}");
570
0
}
571
572
static void dump_reader_states_return(wLog* log, const ReaderState_Return* rgReaderStates,
573
                                      UINT32 cReaders)
574
0
{
575
0
  WINPR_ASSERT(rgReaderStates || (cReaders == 0));
576
0
  for (UINT32 index = 0; index < cReaders; index++)
577
0
  {
578
0
    char buffer[1024] = WINPR_C_ARRAY_INIT;
579
580
0
    const ReaderState_Return* readerState = &rgReaderStates[index];
581
0
    char* szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState);
582
0
    char* szEventState = SCardGetReaderStateString(readerState->dwEventState);
583
0
    WLog_Print(log, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index,
584
0
               szCurrentState, readerState->dwCurrentState);
585
0
    WLog_Print(log, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index,
586
0
               szEventState, readerState->dwEventState);
587
0
    free(szCurrentState);
588
0
    free(szEventState);
589
590
0
    WLog_Print(
591
0
        log, g_LogLevel, "\t[%" PRIu32 "]: cbAttr: %" PRIu32 " { %s }", index,
592
0
        readerState->cbAtr,
593
0
        smartcard_array_dump(readerState->rgbAtr, readerState->cbAtr, buffer, sizeof(buffer)));
594
0
  }
595
0
}
596
597
static void dump_reader_states_a(wLog* log, const SCARD_READERSTATEA* rgReaderStates,
598
                                 UINT32 cReaders)
599
0
{
600
0
  WINPR_ASSERT(rgReaderStates || (cReaders == 0));
601
0
  for (UINT32 index = 0; index < cReaders; index++)
602
0
  {
603
0
    char buffer[1024] = WINPR_C_ARRAY_INIT;
604
605
0
    const SCARD_READERSTATEA* readerState = &rgReaderStates[index];
606
607
0
    WLog_Print(log, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index,
608
0
               readerState->szReader, readerState->cbAtr);
609
0
    char* szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState);
610
0
    char* szEventState = SCardGetReaderStateString(readerState->dwEventState);
611
0
    WLog_Print(log, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index,
612
0
               szCurrentState, readerState->dwCurrentState);
613
0
    WLog_Print(log, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index,
614
0
               szEventState, readerState->dwEventState);
615
0
    free(szCurrentState);
616
0
    free(szEventState);
617
618
0
    WLog_Print(
619
0
        log, g_LogLevel, "\t[%" PRIu32 "]: cbAttr: %" PRIu32 " { %s }", index,
620
0
        readerState->cbAtr,
621
0
        smartcard_array_dump(readerState->rgbAtr, readerState->cbAtr, buffer, sizeof(buffer)));
622
0
  }
623
0
}
624
625
static void dump_reader_states_w(wLog* log, const SCARD_READERSTATEW* rgReaderStates,
626
                                 UINT32 cReaders)
627
0
{
628
0
  WINPR_ASSERT(rgReaderStates || (cReaders == 0));
629
0
  for (UINT32 index = 0; index < cReaders; index++)
630
0
  {
631
0
    char buffer[1024] = WINPR_C_ARRAY_INIT;
632
633
0
    const SCARD_READERSTATEW* readerState = &rgReaderStates[index];
634
0
    (void)ConvertWCharToUtf8(readerState->szReader, buffer, sizeof(buffer));
635
0
    WLog_Print(log, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index,
636
0
               buffer, readerState->cbAtr);
637
0
    char* szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState);
638
0
    char* szEventState = SCardGetReaderStateString(readerState->dwEventState);
639
0
    WLog_Print(log, g_LogLevel, "\t[%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")", index,
640
0
               szCurrentState, readerState->dwCurrentState);
641
0
    WLog_Print(log, g_LogLevel, "\t[%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")", index,
642
0
               szEventState, readerState->dwEventState);
643
0
    free(szCurrentState);
644
0
    free(szEventState);
645
646
0
    WLog_Print(
647
0
        log, g_LogLevel, "\t[%" PRIu32 "]: cbAttr: %" PRIu32 " { %s }", index,
648
0
        readerState->cbAtr,
649
0
        smartcard_array_dump(readerState->rgbAtr, readerState->cbAtr, buffer, sizeof(buffer)));
650
0
  }
651
0
}
652
653
static void smartcard_trace_get_status_change_w_call(wLog* log, const GetStatusChangeW_Call* call)
654
0
{
655
0
  WINPR_ASSERT(call);
656
657
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
658
0
    return;
659
660
0
  WLog_Print(log, g_LogLevel, "GetStatusChangeW_Call {");
661
0
  smartcard_log_context(log, &call->handles.hContext);
662
663
0
  WLog_Print(log, g_LogLevel, "dwTimeOut: 0x%08" PRIX32 " cReaders: %" PRIu32 "", call->dwTimeOut,
664
0
             call->cReaders);
665
666
0
  dump_reader_states_w(log, call->rgReaderStates, call->cReaders);
667
668
0
  WLog_Print(log, g_LogLevel, "}");
669
0
}
670
671
static void smartcard_trace_list_reader_groups_return(wLog* log, const ListReaderGroups_Return* ret,
672
                                                      BOOL unicode)
673
0
{
674
0
  WINPR_ASSERT(ret);
675
676
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
677
0
    return;
678
679
0
  char* mszA = smartcard_convert_string_list(ret->msz, ret->cBytes, unicode);
680
681
0
  WLog_Print(log, g_LogLevel, "ListReaderGroups%s_Return {", unicode ? "W" : "A");
682
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIx32 ")",
683
0
             SCardGetErrorString(ret->ReturnCode),
684
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
685
0
  WLog_Print(log, g_LogLevel, "  cBytes: %" PRIu32 " msz: %s", ret->cBytes, mszA);
686
0
  WLog_Print(log, g_LogLevel, "}");
687
0
  free(mszA);
688
0
}
689
690
static void smartcard_trace_list_readers_call(wLog* log, const ListReaders_Call* call, BOOL unicode)
691
0
{
692
0
  WINPR_ASSERT(call);
693
694
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
695
0
    return;
696
697
0
  char* mszGroupsA = smartcard_convert_string_list(call->mszGroups, call->cBytes, unicode);
698
699
0
  WLog_Print(log, g_LogLevel, "ListReaders%s_Call {", unicode ? "W" : "A");
700
0
  smartcard_log_context(log, &call->handles.hContext);
701
702
0
  WLog_Print(log, g_LogLevel,
703
0
             "cBytes: %" PRIu32 " mszGroups: %s fmszReadersIsNULL: %" PRId32
704
0
             " cchReaders: 0x%08" PRIX32 "",
705
0
             call->cBytes, mszGroupsA, call->fmszReadersIsNULL, call->cchReaders);
706
0
  WLog_Print(log, g_LogLevel, "}");
707
708
0
  free(mszGroupsA);
709
0
}
710
711
static void smartcard_trace_locate_cards_by_atr_a_call(wLog* log,
712
                                                       const LocateCardsByATRA_Call* call)
713
0
{
714
0
  WINPR_ASSERT(call);
715
716
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
717
0
    return;
718
719
0
  WLog_Print(log, g_LogLevel, "LocateCardsByATRA_Call {");
720
0
  smartcard_log_context(log, &call->handles.hContext);
721
722
0
  dump_reader_states_a(log, call->rgReaderStates, call->cReaders);
723
724
0
  WLog_Print(log, g_LogLevel, "}");
725
0
}
726
727
static void smartcard_trace_locate_cards_a_call(wLog* log, const LocateCardsA_Call* call)
728
0
{
729
0
  char buffer[8192] = WINPR_C_ARRAY_INIT;
730
731
0
  WINPR_ASSERT(call);
732
733
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
734
0
    return;
735
736
0
  WLog_Print(log, g_LogLevel, "LocateCardsA_Call {");
737
0
  smartcard_log_context(log, &call->handles.hContext);
738
0
  WLog_Print(log, g_LogLevel, " cBytes=%" PRIu32, call->cBytes);
739
0
  WLog_Print(log, g_LogLevel, " mszCards=%s",
740
0
             smartcard_msz_dump_a(call->mszCards, call->cBytes, buffer, sizeof(buffer)));
741
0
  WLog_Print(log, g_LogLevel, " cReaders=%" PRIu32, call->cReaders);
742
0
  dump_reader_states_a(log, call->rgReaderStates, call->cReaders);
743
744
0
  WLog_Print(log, g_LogLevel, "}");
745
0
}
746
747
static void smartcard_trace_locate_cards_return(wLog* log, const LocateCards_Return* ret)
748
0
{
749
0
  WINPR_ASSERT(ret);
750
751
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
752
0
    return;
753
754
0
  WLog_Print(log, g_LogLevel, "LocateCards_Return {");
755
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
756
0
             SCardGetErrorString(ret->ReturnCode),
757
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
758
759
0
  if (ret->ReturnCode == SCARD_S_SUCCESS)
760
0
  {
761
0
    WLog_Print(log, g_LogLevel, "  cReaders=%" PRIu32, ret->cReaders);
762
0
  }
763
0
  WLog_Print(log, g_LogLevel, "}");
764
0
}
765
766
static void smartcard_trace_get_reader_icon_return(wLog* log, const GetReaderIcon_Return* ret)
767
0
{
768
0
  WINPR_ASSERT(ret);
769
770
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
771
0
    return;
772
773
0
  WLog_Print(log, g_LogLevel, "GetReaderIcon_Return {");
774
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
775
0
             SCardGetErrorString(ret->ReturnCode),
776
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
777
778
0
  if (ret->ReturnCode == SCARD_S_SUCCESS)
779
0
  {
780
0
    WLog_Print(log, g_LogLevel, "  cbDataLen=%" PRIu32, ret->cbDataLen);
781
0
  }
782
0
  WLog_Print(log, g_LogLevel, "}");
783
0
}
784
785
static void smartcard_trace_get_transmit_count_return(wLog* log, const GetTransmitCount_Return* ret)
786
0
{
787
0
  WINPR_ASSERT(ret);
788
789
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
790
0
    return;
791
792
0
  WLog_Print(log, g_LogLevel, "GetTransmitCount_Return {");
793
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
794
0
             SCardGetErrorString(ret->ReturnCode),
795
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
796
797
0
  WLog_Print(log, g_LogLevel, "  cTransmitCount=%" PRIu32, ret->cTransmitCount);
798
0
  WLog_Print(log, g_LogLevel, "}");
799
0
}
800
801
static void smartcard_trace_read_cache_return(wLog* log, const ReadCache_Return* ret)
802
0
{
803
0
  WINPR_ASSERT(ret);
804
805
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
806
0
    return;
807
808
0
  WLog_Print(log, g_LogLevel, "ReadCache_Return {");
809
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
810
0
             SCardGetErrorString(ret->ReturnCode),
811
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
812
813
0
  if (ret->ReturnCode == SCARD_S_SUCCESS)
814
0
  {
815
0
    char buffer[1024] = WINPR_C_ARRAY_INIT;
816
0
    WLog_Print(log, g_LogLevel, " cbDataLen=%" PRIu32, ret->cbDataLen);
817
0
    WLog_Print(log, g_LogLevel, "  cbData: %s",
818
0
               smartcard_array_dump(ret->pbData, ret->cbDataLen, buffer, sizeof(buffer)));
819
0
  }
820
0
  WLog_Print(log, g_LogLevel, "}");
821
0
}
822
823
static void smartcard_trace_locate_cards_w_call(wLog* log, const LocateCardsW_Call* call)
824
0
{
825
0
  WINPR_ASSERT(call);
826
0
  char buffer[8192] = WINPR_C_ARRAY_INIT;
827
828
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
829
0
    return;
830
831
0
  WLog_Print(log, g_LogLevel, "LocateCardsW_Call {");
832
0
  smartcard_log_context(log, &call->handles.hContext);
833
0
  WLog_Print(log, g_LogLevel, " cBytes=%" PRIu32, call->cBytes);
834
0
  WLog_Print(log, g_LogLevel, " sz2=%s",
835
0
             smartcard_msz_dump_w(call->mszCards, call->cBytes, buffer, sizeof(buffer)));
836
0
  WLog_Print(log, g_LogLevel, " cReaders=%" PRIu32, call->cReaders);
837
0
  dump_reader_states_w(log, call->rgReaderStates, call->cReaders);
838
0
  WLog_Print(log, g_LogLevel, "}");
839
0
}
840
841
static void smartcard_trace_list_readers_return(wLog* log, const ListReaders_Return* ret,
842
                                                BOOL unicode)
843
0
{
844
0
  WINPR_ASSERT(ret);
845
846
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
847
0
    return;
848
849
0
  WLog_Print(log, g_LogLevel, "ListReaders%s_Return {", unicode ? "W" : "A");
850
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
851
0
             SCardGetErrorString(ret->ReturnCode),
852
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
853
854
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
855
0
  {
856
0
    WLog_Print(log, g_LogLevel, "}");
857
0
    return;
858
0
  }
859
860
0
  char* mszA = smartcard_convert_string_list(ret->msz, ret->cBytes, unicode);
861
862
0
  WLog_Print(log, g_LogLevel, "  cBytes: %" PRIu32 " msz: %s", ret->cBytes, mszA);
863
0
  WLog_Print(log, g_LogLevel, "}");
864
0
  free(mszA);
865
0
}
866
867
static void smartcard_trace_get_status_change_return(wLog* log, const GetStatusChange_Return* ret,
868
                                                     BOOL unicode)
869
0
{
870
0
  WINPR_ASSERT(ret);
871
872
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
873
0
    return;
874
875
0
  WLog_Print(log, g_LogLevel, "GetStatusChange%s_Return {", unicode ? "W" : "A");
876
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
877
0
             SCardGetErrorString(ret->ReturnCode),
878
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
879
0
  WLog_Print(log, g_LogLevel, "  cReaders: %" PRIu32 "", ret->cReaders);
880
881
0
  dump_reader_states_return(log, ret->rgReaderStates, ret->cReaders);
882
883
0
  if (!ret->rgReaderStates && (ret->cReaders > 0))
884
0
  {
885
0
    WLog_Print(log, g_LogLevel, "    [INVALID STATE] rgReaderStates=NULL, cReaders=%" PRIu32,
886
0
               ret->cReaders);
887
0
  }
888
0
  else if (ret->ReturnCode != SCARD_S_SUCCESS)
889
0
  {
890
0
    WLog_Print(log, g_LogLevel, "    [INVALID RETURN] rgReaderStates, cReaders=%" PRIu32,
891
0
               ret->cReaders);
892
0
  }
893
0
  else
894
0
  {
895
0
    for (UINT32 index = 0; index < ret->cReaders; index++)
896
0
    {
897
0
      char buffer[1024] = WINPR_C_ARRAY_INIT;
898
0
      const ReaderState_Return* rgReaderState = &(ret->rgReaderStates[index]);
899
0
      char* szCurrentState = SCardGetReaderStateString(rgReaderState->dwCurrentState);
900
0
      char* szEventState = SCardGetReaderStateString(rgReaderState->dwEventState);
901
0
      WLog_Print(log, g_LogLevel, "    [%" PRIu32 "]: dwCurrentState: %s (0x%08" PRIX32 ")",
902
0
                 index, szCurrentState, rgReaderState->dwCurrentState);
903
0
      WLog_Print(log, g_LogLevel, "    [%" PRIu32 "]: dwEventState: %s (0x%08" PRIX32 ")",
904
0
                 index, szEventState, rgReaderState->dwEventState);
905
0
      WLog_Print(log, g_LogLevel, "    [%" PRIu32 "]: cbAtr: %" PRIu32 " rgbAtr: %s", index,
906
0
                 rgReaderState->cbAtr,
907
0
                 smartcard_array_dump(rgReaderState->rgbAtr, rgReaderState->cbAtr, buffer,
908
0
                                      sizeof(buffer)));
909
0
      free(szCurrentState);
910
0
      free(szEventState);
911
0
    }
912
0
  }
913
914
0
  WLog_Print(log, g_LogLevel, "}");
915
0
}
916
917
static void smartcard_trace_context_and_two_strings_a_call(wLog* log,
918
                                                           const ContextAndTwoStringA_Call* call)
919
0
{
920
0
  WINPR_ASSERT(call);
921
922
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
923
0
    return;
924
925
0
  WLog_Print(log, g_LogLevel, "ContextAndTwoStringW_Call {");
926
0
  smartcard_log_context(log, &call->handles.hContext);
927
0
  WLog_Print(log, g_LogLevel, " sz1=%s", call->sz1);
928
0
  WLog_Print(log, g_LogLevel, " sz2=%s", call->sz2);
929
0
  WLog_Print(log, g_LogLevel, "}");
930
0
}
931
932
static void smartcard_trace_context_and_two_strings_w_call(wLog* log,
933
                                                           const ContextAndTwoStringW_Call* call)
934
0
{
935
0
  WINPR_ASSERT(call);
936
0
  char sz1[1024] = WINPR_C_ARRAY_INIT;
937
0
  char sz2[1024] = WINPR_C_ARRAY_INIT;
938
939
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
940
0
    return;
941
0
  if (call->sz1)
942
0
    (void)ConvertWCharToUtf8(call->sz1, sz1, ARRAYSIZE(sz1));
943
0
  if (call->sz2)
944
0
    (void)ConvertWCharToUtf8(call->sz2, sz2, ARRAYSIZE(sz2));
945
946
0
  WLog_Print(log, g_LogLevel, "ContextAndTwoStringW_Call {");
947
0
  smartcard_log_context(log, &call->handles.hContext);
948
0
  WLog_Print(log, g_LogLevel, " sz1=%s", sz1);
949
0
  WLog_Print(log, g_LogLevel, " sz2=%s", sz2);
950
0
  WLog_Print(log, g_LogLevel, "}");
951
0
}
952
953
static void smartcard_trace_get_transmit_count_call(wLog* log, const GetTransmitCount_Call* call)
954
0
{
955
0
  WINPR_ASSERT(call);
956
957
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
958
0
    return;
959
960
0
  WLog_Print(log, g_LogLevel, "GetTransmitCount_Call {");
961
0
  smartcard_log_context(log, &call->handles.hContext);
962
0
  smartcard_log_redir_handle(log, &call->handles.hCard);
963
964
0
  WLog_Print(log, g_LogLevel, "}");
965
0
}
966
967
static void smartcard_trace_write_cache_a_call(wLog* log, const WriteCacheA_Call* call)
968
0
{
969
0
  WINPR_ASSERT(call);
970
0
  char buffer[1024] = WINPR_C_ARRAY_INIT;
971
972
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
973
0
    return;
974
975
0
  WLog_Print(log, g_LogLevel, "WriteCacheA_Call {");
976
977
0
  WLog_Print(log, g_LogLevel, "  szLookupName=%s", call->szLookupName);
978
979
0
  smartcard_log_context(log, &call->Common.handles.hContext);
980
0
  WLog_Print(
981
0
      log, g_LogLevel, "..CardIdentifier=%s",
982
0
      smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer)));
983
0
  WLog_Print(log, g_LogLevel, "  FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter);
984
0
  WLog_Print(log, g_LogLevel, "  cbDataLen=%" PRIu32, call->Common.cbDataLen);
985
0
  WLog_Print(
986
0
      log, g_LogLevel, "  pbData=%s",
987
0
      smartcard_array_dump(call->Common.pbData, call->Common.cbDataLen, buffer, sizeof(buffer)));
988
0
  WLog_Print(log, g_LogLevel, "}");
989
0
}
990
991
static void smartcard_trace_write_cache_w_call(wLog* log, const WriteCacheW_Call* call)
992
0
{
993
0
  WINPR_ASSERT(call);
994
0
  char tmp[1024] = WINPR_C_ARRAY_INIT;
995
0
  char buffer[1024] = WINPR_C_ARRAY_INIT;
996
997
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
998
0
    return;
999
1000
0
  WLog_Print(log, g_LogLevel, "WriteCacheW_Call {");
1001
1002
0
  if (call->szLookupName)
1003
0
    (void)ConvertWCharToUtf8(call->szLookupName, tmp, ARRAYSIZE(tmp));
1004
0
  WLog_Print(log, g_LogLevel, "  szLookupName=%s", tmp);
1005
1006
0
  smartcard_log_context(log, &call->Common.handles.hContext);
1007
0
  WLog_Print(
1008
0
      log, g_LogLevel, "..CardIdentifier=%s",
1009
0
      smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer)));
1010
0
  WLog_Print(log, g_LogLevel, "  FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter);
1011
0
  WLog_Print(log, g_LogLevel, "  cbDataLen=%" PRIu32, call->Common.cbDataLen);
1012
0
  WLog_Print(
1013
0
      log, g_LogLevel, "  pbData=%s",
1014
0
      smartcard_array_dump(call->Common.pbData, call->Common.cbDataLen, buffer, sizeof(buffer)));
1015
0
  WLog_Print(log, g_LogLevel, "}");
1016
0
}
1017
1018
static void smartcard_trace_read_cache_a_call(wLog* log, const ReadCacheA_Call* call)
1019
0
{
1020
0
  WINPR_ASSERT(call);
1021
0
  char buffer[1024] = WINPR_C_ARRAY_INIT;
1022
1023
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1024
0
    return;
1025
1026
0
  WLog_Print(log, g_LogLevel, "ReadCacheA_Call {");
1027
1028
0
  WLog_Print(log, g_LogLevel, "  szLookupName=%s", call->szLookupName);
1029
0
  smartcard_log_context(log, &call->Common.handles.hContext);
1030
0
  WLog_Print(
1031
0
      log, g_LogLevel, "..CardIdentifier=%s",
1032
0
      smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer)));
1033
0
  WLog_Print(log, g_LogLevel, "  FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter);
1034
0
  WLog_Print(log, g_LogLevel, "  fPbDataIsNULL=%" PRId32, call->Common.fPbDataIsNULL);
1035
0
  WLog_Print(log, g_LogLevel, "  cbDataLen=%" PRIu32, call->Common.cbDataLen);
1036
1037
0
  WLog_Print(log, g_LogLevel, "}");
1038
0
}
1039
1040
static void smartcard_trace_read_cache_w_call(wLog* log, const ReadCacheW_Call* call)
1041
0
{
1042
0
  WINPR_ASSERT(call);
1043
0
  char tmp[1024] = WINPR_C_ARRAY_INIT;
1044
0
  char buffer[1024] = WINPR_C_ARRAY_INIT;
1045
1046
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1047
0
    return;
1048
1049
0
  WLog_Print(log, g_LogLevel, "ReadCacheW_Call {");
1050
0
  if (call->szLookupName)
1051
0
    (void)ConvertWCharToUtf8(call->szLookupName, tmp, ARRAYSIZE(tmp));
1052
0
  WLog_Print(log, g_LogLevel, "  szLookupName=%s", tmp);
1053
1054
0
  smartcard_log_context(log, &call->Common.handles.hContext);
1055
0
  WLog_Print(
1056
0
      log, g_LogLevel, "..CardIdentifier=%s",
1057
0
      smartcard_array_dump(call->Common.CardIdentifier, sizeof(UUID), buffer, sizeof(buffer)));
1058
0
  WLog_Print(log, g_LogLevel, "  FreshnessCounter=%" PRIu32, call->Common.FreshnessCounter);
1059
0
  WLog_Print(log, g_LogLevel, "  fPbDataIsNULL=%" PRId32, call->Common.fPbDataIsNULL);
1060
0
  WLog_Print(log, g_LogLevel, "  cbDataLen=%" PRIu32, call->Common.cbDataLen);
1061
1062
0
  WLog_Print(log, g_LogLevel, "}");
1063
0
}
1064
1065
static void smartcard_trace_transmit_call(wLog* log, const Transmit_Call* call)
1066
0
{
1067
0
  WINPR_ASSERT(call);
1068
0
  UINT32 cbExtraBytes = 0;
1069
0
  BYTE* pbExtraBytes = NULL;
1070
1071
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1072
0
    return;
1073
1074
0
  WLog_Print(log, g_LogLevel, "Transmit_Call {");
1075
0
  smartcard_log_context(log, &call->handles.hContext);
1076
0
  smartcard_log_redir_handle(log, &call->handles.hCard);
1077
1078
0
  if (call->pioSendPci)
1079
0
  {
1080
0
    cbExtraBytes = (UINT32)(call->pioSendPci->cbPciLength - sizeof(SCARD_IO_REQUEST));
1081
0
    pbExtraBytes = &((BYTE*)call->pioSendPci)[sizeof(SCARD_IO_REQUEST)];
1082
0
    WLog_Print(log, g_LogLevel, "pioSendPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "",
1083
0
               call->pioSendPci->dwProtocol, cbExtraBytes);
1084
1085
0
    if (cbExtraBytes)
1086
0
    {
1087
0
      char buffer[1024] = WINPR_C_ARRAY_INIT;
1088
0
      WLog_Print(log, g_LogLevel, "pbExtraBytes: %s",
1089
0
                 smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer)));
1090
0
    }
1091
0
  }
1092
0
  else
1093
0
  {
1094
0
    WLog_Print(log, g_LogLevel, "pioSendPci: null");
1095
0
  }
1096
1097
0
  WLog_Print(log, g_LogLevel, "cbSendLength: %" PRIu32 "", call->cbSendLength);
1098
1099
0
  if (call->pbSendBuffer)
1100
0
  {
1101
0
    char buffer[1024] = WINPR_C_ARRAY_INIT;
1102
0
    WLog_Print(
1103
0
        log, g_LogLevel, "pbSendBuffer: %s",
1104
0
        smartcard_array_dump(call->pbSendBuffer, call->cbSendLength, buffer, sizeof(buffer)));
1105
0
  }
1106
0
  else
1107
0
  {
1108
0
    WLog_Print(log, g_LogLevel, "pbSendBuffer: null");
1109
0
  }
1110
1111
0
  if (call->pioRecvPci)
1112
0
  {
1113
0
    cbExtraBytes = (UINT32)(call->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST));
1114
0
    pbExtraBytes = &((BYTE*)call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
1115
0
    WLog_Print(log, g_LogLevel, "pioRecvPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "",
1116
0
               call->pioRecvPci->dwProtocol, cbExtraBytes);
1117
1118
0
    if (cbExtraBytes)
1119
0
    {
1120
0
      char buffer[1024] = WINPR_C_ARRAY_INIT;
1121
0
      WLog_Print(log, g_LogLevel, "pbExtraBytes: %s",
1122
0
                 smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer)));
1123
0
    }
1124
0
  }
1125
0
  else
1126
0
  {
1127
0
    WLog_Print(log, g_LogLevel, "pioRecvPci: null");
1128
0
  }
1129
1130
0
  WLog_Print(log, g_LogLevel, "fpbRecvBufferIsNULL: %" PRId32 " cbRecvLength: %" PRIu32 "",
1131
0
             call->fpbRecvBufferIsNULL, call->cbRecvLength);
1132
0
  WLog_Print(log, g_LogLevel, "}");
1133
0
}
1134
1135
static void smartcard_trace_locate_cards_by_atr_w_call(wLog* log,
1136
                                                       const LocateCardsByATRW_Call* call)
1137
0
{
1138
0
  WINPR_ASSERT(call);
1139
1140
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1141
0
    return;
1142
1143
0
  WLog_Print(log, g_LogLevel, "LocateCardsByATRW_Call {");
1144
0
  smartcard_log_context(log, &call->handles.hContext);
1145
1146
0
  dump_reader_states_w(log, call->rgReaderStates, call->cReaders);
1147
1148
0
  WLog_Print(log, g_LogLevel, "}");
1149
0
}
1150
1151
static void smartcard_trace_transmit_return(wLog* log, const Transmit_Return* ret)
1152
0
{
1153
0
  WINPR_ASSERT(ret);
1154
0
  UINT32 cbExtraBytes = 0;
1155
0
  BYTE* pbExtraBytes = NULL;
1156
1157
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1158
0
    return;
1159
1160
0
  WLog_Print(log, g_LogLevel, "Transmit_Return {");
1161
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1162
0
             SCardGetErrorString(ret->ReturnCode),
1163
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1164
1165
0
  if (ret->pioRecvPci)
1166
0
  {
1167
0
    cbExtraBytes = (UINT32)(ret->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST));
1168
0
    pbExtraBytes = &((BYTE*)ret->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
1169
0
    WLog_Print(log, g_LogLevel,
1170
0
               "  pioRecvPci: dwProtocol: %" PRIu32 " cbExtraBytes: %" PRIu32 "",
1171
0
               ret->pioRecvPci->dwProtocol, cbExtraBytes);
1172
1173
0
    if (cbExtraBytes)
1174
0
    {
1175
0
      char buffer[1024] = WINPR_C_ARRAY_INIT;
1176
0
      WLog_Print(log, g_LogLevel, "  pbExtraBytes: %s",
1177
0
                 smartcard_array_dump(pbExtraBytes, cbExtraBytes, buffer, sizeof(buffer)));
1178
0
    }
1179
0
  }
1180
0
  else
1181
0
  {
1182
0
    WLog_Print(log, g_LogLevel, "  pioRecvPci: null");
1183
0
  }
1184
1185
0
  WLog_Print(log, g_LogLevel, "  cbRecvLength: %" PRIu32 "", ret->cbRecvLength);
1186
1187
0
  if (ret->pbRecvBuffer)
1188
0
  {
1189
0
    char buffer[1024] = WINPR_C_ARRAY_INIT;
1190
0
    WLog_Print(
1191
0
        log, g_LogLevel, "  pbRecvBuffer: %s",
1192
0
        smartcard_array_dump(ret->pbRecvBuffer, ret->cbRecvLength, buffer, sizeof(buffer)));
1193
0
  }
1194
0
  else
1195
0
  {
1196
0
    WLog_Print(log, g_LogLevel, "  pbRecvBuffer: null");
1197
0
  }
1198
1199
0
  WLog_Print(log, g_LogLevel, "}");
1200
0
}
1201
1202
static void smartcard_trace_control_return(wLog* log, const Control_Return* ret)
1203
0
{
1204
0
  WINPR_ASSERT(ret);
1205
1206
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1207
0
    return;
1208
1209
0
  WLog_Print(log, g_LogLevel, "Control_Return {");
1210
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1211
0
             SCardGetErrorString(ret->ReturnCode),
1212
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1213
0
  WLog_Print(log, g_LogLevel, "  cbOutBufferSize: %" PRIu32 "", ret->cbOutBufferSize);
1214
1215
0
  if (ret->pvOutBuffer)
1216
0
  {
1217
0
    char buffer[1024] = WINPR_C_ARRAY_INIT;
1218
0
    WLog_Print(
1219
0
        log, g_LogLevel, "pvOutBuffer: %s",
1220
0
        smartcard_array_dump(ret->pvOutBuffer, ret->cbOutBufferSize, buffer, sizeof(buffer)));
1221
0
  }
1222
0
  else
1223
0
  {
1224
0
    WLog_Print(log, g_LogLevel, "pvOutBuffer: null");
1225
0
  }
1226
1227
0
  WLog_Print(log, g_LogLevel, "}");
1228
0
}
1229
1230
static void smartcard_trace_control_call(wLog* log, const Control_Call* call)
1231
0
{
1232
0
  WINPR_ASSERT(call);
1233
1234
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1235
0
    return;
1236
1237
0
  WLog_Print(log, g_LogLevel, "Control_Call {");
1238
0
  smartcard_log_context(log, &call->handles.hContext);
1239
0
  smartcard_log_redir_handle(log, &call->handles.hCard);
1240
1241
0
  WLog_Print(log, g_LogLevel,
1242
0
             "dwControlCode: 0x%08" PRIX32 " cbInBufferSize: %" PRIu32
1243
0
             " fpvOutBufferIsNULL: %" PRId32 " cbOutBufferSize: %" PRIu32 "",
1244
0
             call->dwControlCode, call->cbInBufferSize, call->fpvOutBufferIsNULL,
1245
0
             call->cbOutBufferSize);
1246
1247
0
  if (call->pvInBuffer)
1248
0
  {
1249
0
    char buffer[1024] = WINPR_C_ARRAY_INIT;
1250
0
    WLog_Print(
1251
0
        log, WLOG_DEBUG, "pbInBuffer: %s",
1252
0
        smartcard_array_dump(call->pvInBuffer, call->cbInBufferSize, buffer, sizeof(buffer)));
1253
0
  }
1254
0
  else
1255
0
  {
1256
0
    WLog_Print(log, g_LogLevel, "pvInBuffer: null");
1257
0
  }
1258
1259
0
  WLog_Print(log, g_LogLevel, "}");
1260
0
}
1261
1262
static void smartcard_trace_set_attrib_call(wLog* log, const SetAttrib_Call* call)
1263
0
{
1264
0
  WINPR_ASSERT(call);
1265
0
  char buffer[8192] = WINPR_C_ARRAY_INIT;
1266
1267
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1268
0
    return;
1269
1270
0
  WLog_Print(log, g_LogLevel, "GetAttrib_Call {");
1271
0
  smartcard_log_context(log, &call->handles.hContext);
1272
0
  smartcard_log_redir_handle(log, &call->handles.hCard);
1273
0
  WLog_Print(log, g_LogLevel, "dwAttrId: 0x%08" PRIX32, call->dwAttrId);
1274
0
  WLog_Print(log, g_LogLevel, "cbAttrLen: 0x%08" PRIx32, call->cbAttrLen);
1275
0
  WLog_Print(log, g_LogLevel, "pbAttr: %s",
1276
0
             smartcard_array_dump(call->pbAttr, call->cbAttrLen, buffer, sizeof(buffer)));
1277
0
  WLog_Print(log, g_LogLevel, "}");
1278
0
}
1279
1280
static void smartcard_trace_get_attrib_return(wLog* log, const GetAttrib_Return* ret,
1281
                                              DWORD dwAttrId)
1282
0
{
1283
0
  WINPR_ASSERT(ret);
1284
0
  char buffer[1024] = WINPR_C_ARRAY_INIT;
1285
1286
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1287
0
    return;
1288
1289
0
  WLog_Print(log, g_LogLevel, "GetAttrib_Return {");
1290
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1291
0
             SCardGetErrorString(ret->ReturnCode),
1292
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1293
0
  WLog_Print(log, g_LogLevel, "  dwAttrId: %s (0x%08" PRIX32 ") cbAttrLen: 0x%08" PRIX32 "",
1294
0
             SCardGetAttributeString(dwAttrId), dwAttrId, ret->cbAttrLen);
1295
0
  WLog_Print(log, g_LogLevel, "  %s",
1296
0
             smartcard_array_dump(ret->pbAttr, ret->cbAttrLen, buffer, sizeof(buffer)));
1297
1298
0
  WLog_Print(log, g_LogLevel, "}");
1299
0
}
1300
1301
static void smartcard_trace_get_attrib_call(wLog* log, const GetAttrib_Call* call)
1302
0
{
1303
0
  WINPR_ASSERT(call);
1304
1305
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1306
0
    return;
1307
1308
0
  WLog_Print(log, g_LogLevel, "GetAttrib_Call {");
1309
0
  smartcard_log_context(log, &call->handles.hContext);
1310
0
  smartcard_log_redir_handle(log, &call->handles.hCard);
1311
1312
0
  WLog_Print(log, g_LogLevel,
1313
0
             "dwAttrId: %s (0x%08" PRIX32 ") fpbAttrIsNULL: %" PRId32 " cbAttrLen: 0x%08" PRIX32
1314
0
             "",
1315
0
             SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->fpbAttrIsNULL,
1316
0
             call->cbAttrLen);
1317
0
  WLog_Print(log, g_LogLevel, "}");
1318
0
}
1319
1320
static void smartcard_trace_status_call(wLog* log, const Status_Call* call, BOOL unicode)
1321
0
{
1322
0
  WINPR_ASSERT(call);
1323
1324
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1325
0
    return;
1326
1327
0
  WLog_Print(log, g_LogLevel, "Status%s_Call {", unicode ? "W" : "A");
1328
0
  smartcard_log_context(log, &call->handles.hContext);
1329
0
  smartcard_log_redir_handle(log, &call->handles.hCard);
1330
1331
0
  WLog_Print(log, g_LogLevel,
1332
0
             "fmszReaderNamesIsNULL: %" PRId32 " cchReaderLen: %" PRIu32 " cbAtrLen: %" PRIu32 "",
1333
0
             call->fmszReaderNamesIsNULL, call->cchReaderLen, call->cbAtrLen);
1334
0
  WLog_Print(log, g_LogLevel, "}");
1335
0
}
1336
1337
static void smartcard_trace_status_return(wLog* log, const Status_Return* ret, BOOL unicode)
1338
0
{
1339
0
  WINPR_ASSERT(ret);
1340
0
  char* mszReaderNamesA = NULL;
1341
0
  char buffer[1024] = WINPR_C_ARRAY_INIT;
1342
0
  DWORD cBytes = 0;
1343
1344
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1345
0
    return;
1346
0
  cBytes = ret->cBytes;
1347
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
1348
0
    cBytes = 0;
1349
0
  if (cBytes == SCARD_AUTOALLOCATE)
1350
0
    cBytes = 0;
1351
0
  mszReaderNamesA = smartcard_convert_string_list(ret->mszReaderNames, cBytes, unicode);
1352
1353
0
  WLog_Print(log, g_LogLevel, "Status%s_Return {", unicode ? "W" : "A");
1354
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1355
0
             SCardGetErrorString(ret->ReturnCode),
1356
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1357
0
  WLog_Print(log, g_LogLevel, "  dwState: %s (0x%08" PRIX32 ") dwProtocol: %s (0x%08" PRIX32 ")",
1358
0
             SCardGetCardStateString(ret->dwState), ret->dwState,
1359
0
             SCardGetProtocolString(ret->dwProtocol), ret->dwProtocol);
1360
1361
0
  WLog_Print(log, g_LogLevel, "  cBytes: %" PRIu32 " mszReaderNames: %s", ret->cBytes,
1362
0
             mszReaderNamesA);
1363
1364
0
  WLog_Print(log, g_LogLevel, "  cbAtrLen: %" PRIu32 " pbAtr: %s", ret->cbAtrLen,
1365
0
             smartcard_array_dump(ret->pbAtr, ret->cbAtrLen, buffer, sizeof(buffer)));
1366
0
  WLog_Print(log, g_LogLevel, "}");
1367
0
  free(mszReaderNamesA);
1368
0
}
1369
1370
static void smartcard_trace_state_return(wLog* log, const State_Return* ret)
1371
0
{
1372
0
  WINPR_ASSERT(ret);
1373
0
  char buffer[1024] = WINPR_C_ARRAY_INIT;
1374
0
  char* state = NULL;
1375
1376
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1377
0
    return;
1378
1379
0
  state = SCardGetReaderStateString(ret->dwState);
1380
0
  WLog_Print(log, g_LogLevel, "Reconnect_Return {");
1381
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1382
0
             SCardGetErrorString(ret->ReturnCode),
1383
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1384
0
  WLog_Print(log, g_LogLevel, "  dwState:    %s (0x%08" PRIX32 ")", state, ret->dwState);
1385
0
  WLog_Print(log, g_LogLevel, "  dwProtocol: %s (0x%08" PRIX32 ")",
1386
0
             SCardGetProtocolString(ret->dwProtocol), ret->dwProtocol);
1387
0
  WLog_Print(log, g_LogLevel, "  cbAtrLen:      (0x%08" PRIX32 ")", ret->cbAtrLen);
1388
0
  WLog_Print(log, g_LogLevel, "  rgAtr:      %s",
1389
0
             smartcard_array_dump(ret->rgAtr, sizeof(ret->rgAtr), buffer, sizeof(buffer)));
1390
0
  WLog_Print(log, g_LogLevel, "}");
1391
0
  free(state);
1392
0
}
1393
1394
static void smartcard_trace_reconnect_return(wLog* log, const Reconnect_Return* ret)
1395
0
{
1396
0
  WINPR_ASSERT(ret);
1397
1398
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1399
0
    return;
1400
1401
0
  WLog_Print(log, g_LogLevel, "Reconnect_Return {");
1402
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1403
0
             SCardGetErrorString(ret->ReturnCode),
1404
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1405
0
  WLog_Print(log, g_LogLevel, "  dwActiveProtocol: %s (0x%08" PRIX32 ")",
1406
0
             SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol);
1407
0
  WLog_Print(log, g_LogLevel, "}");
1408
0
}
1409
1410
static void smartcard_trace_connect_a_call(wLog* log, const ConnectA_Call* call)
1411
0
{
1412
0
  WINPR_ASSERT(call);
1413
1414
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1415
0
    return;
1416
1417
0
  WLog_Print(log, g_LogLevel, "ConnectA_Call {");
1418
0
  smartcard_log_context(log, &call->Common.handles.hContext);
1419
1420
0
  WLog_Print(log, g_LogLevel,
1421
0
             "szReader: %s dwShareMode: %s (0x%08" PRIX32
1422
0
             ") dwPreferredProtocols: %s (0x%08" PRIX32 ")",
1423
0
             call->szReader, SCardGetShareModeString(call->Common.dwShareMode),
1424
0
             call->Common.dwShareMode, SCardGetProtocolString(call->Common.dwPreferredProtocols),
1425
0
             call->Common.dwPreferredProtocols);
1426
0
  WLog_Print(log, g_LogLevel, "}");
1427
0
}
1428
1429
static void smartcard_trace_connect_w_call(wLog* log, const ConnectW_Call* call)
1430
0
{
1431
0
  WINPR_ASSERT(call);
1432
0
  char szReaderA[1024] = WINPR_C_ARRAY_INIT;
1433
1434
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1435
0
    return;
1436
1437
0
  if (call->szReader)
1438
0
    (void)ConvertWCharToUtf8(call->szReader, szReaderA, ARRAYSIZE(szReaderA));
1439
0
  WLog_Print(log, g_LogLevel, "ConnectW_Call {");
1440
0
  smartcard_log_context(log, &call->Common.handles.hContext);
1441
1442
0
  WLog_Print(log, g_LogLevel,
1443
0
             "szReader: %s dwShareMode: %s (0x%08" PRIX32
1444
0
             ") dwPreferredProtocols: %s (0x%08" PRIX32 ")",
1445
0
             szReaderA, SCardGetShareModeString(call->Common.dwShareMode),
1446
0
             call->Common.dwShareMode, SCardGetProtocolString(call->Common.dwPreferredProtocols),
1447
0
             call->Common.dwPreferredProtocols);
1448
0
  WLog_Print(log, g_LogLevel, "}");
1449
0
}
1450
1451
static void smartcard_trace_hcard_and_disposition_call(wLog* log,
1452
                                                       const HCardAndDisposition_Call* call,
1453
                                                       const char* name)
1454
0
{
1455
0
  WINPR_ASSERT(call);
1456
1457
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1458
0
    return;
1459
1460
0
  WLog_Print(log, g_LogLevel, "%s_Call {", name);
1461
0
  smartcard_log_context(log, &call->handles.hContext);
1462
0
  smartcard_log_redir_handle(log, &call->handles.hCard);
1463
1464
0
  WLog_Print(log, g_LogLevel, "dwDisposition: %s (0x%08" PRIX32 ")",
1465
0
             SCardGetDispositionString(call->dwDisposition), call->dwDisposition);
1466
0
  WLog_Print(log, g_LogLevel, "}");
1467
0
}
1468
1469
static void smartcard_trace_establish_context_call(wLog* log, const EstablishContext_Call* call)
1470
0
{
1471
0
  WINPR_ASSERT(call);
1472
1473
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1474
0
    return;
1475
1476
0
  WLog_Print(log, g_LogLevel, "EstablishContext_Call {");
1477
0
  WLog_Print(log, g_LogLevel, "dwScope: %s (0x%08" PRIX32 ")", SCardGetScopeString(call->dwScope),
1478
0
             call->dwScope);
1479
0
  WLog_Print(log, g_LogLevel, "}");
1480
0
}
1481
1482
static void smartcard_trace_establish_context_return(wLog* log, const EstablishContext_Return* ret)
1483
0
{
1484
0
  WINPR_ASSERT(ret);
1485
1486
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1487
0
    return;
1488
1489
0
  WLog_Print(log, g_LogLevel, "EstablishContext_Return {");
1490
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1491
0
             SCardGetErrorString(ret->ReturnCode),
1492
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1493
0
  smartcard_log_context(log, &ret->hContext);
1494
1495
0
  WLog_Print(log, g_LogLevel, "}");
1496
0
}
1497
1498
void smartcard_trace_long_return(const Long_Return* ret, const char* name)
1499
0
{
1500
0
  wLog* log = scard_log();
1501
0
  smartcard_trace_long_return_int(log, ret, name);
1502
0
}
1503
1504
void smartcard_trace_long_return_int(wLog* log, const Long_Return* ret, const char* name)
1505
0
{
1506
0
  WINPR_ASSERT(ret);
1507
1508
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1509
0
    return;
1510
1511
0
  WLog_Print(log, g_LogLevel, "%s_Return {", name);
1512
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1513
0
             SCardGetErrorString(ret->ReturnCode),
1514
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1515
0
  WLog_Print(log, g_LogLevel, "}");
1516
0
}
1517
1518
static void smartcard_trace_connect_return(wLog* log, const Connect_Return* ret)
1519
0
{
1520
0
  WINPR_ASSERT(ret);
1521
1522
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1523
0
    return;
1524
1525
0
  WLog_Print(log, g_LogLevel, "Connect_Return {");
1526
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1527
0
             SCardGetErrorString(ret->ReturnCode),
1528
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1529
0
  smartcard_log_context(log, &ret->hContext);
1530
0
  smartcard_log_redir_handle(log, &ret->hCard);
1531
1532
0
  WLog_Print(log, g_LogLevel, "  dwActiveProtocol: %s (0x%08" PRIX32 ")",
1533
0
             SCardGetProtocolString(ret->dwActiveProtocol), ret->dwActiveProtocol);
1534
0
  WLog_Print(log, g_LogLevel, "}");
1535
0
}
1536
1537
static void smartcard_trace_reconnect_call(wLog* log, const Reconnect_Call* call)
1538
0
{
1539
0
  WINPR_ASSERT(call);
1540
1541
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1542
0
    return;
1543
1544
0
  WLog_Print(log, g_LogLevel, "Reconnect_Call {");
1545
0
  smartcard_log_context(log, &call->handles.hContext);
1546
0
  smartcard_log_redir_handle(log, &call->handles.hCard);
1547
1548
0
  WLog_Print(log, g_LogLevel,
1549
0
             "dwShareMode: %s (0x%08" PRIX32 ") dwPreferredProtocols: %s (0x%08" PRIX32
1550
0
             ") dwInitialization: %s (0x%08" PRIX32 ")",
1551
0
             SCardGetShareModeString(call->dwShareMode), call->dwShareMode,
1552
0
             SCardGetProtocolString(call->dwPreferredProtocols), call->dwPreferredProtocols,
1553
0
             SCardGetDispositionString(call->dwInitialization), call->dwInitialization);
1554
0
  WLog_Print(log, g_LogLevel, "}");
1555
0
}
1556
1557
static void smartcard_trace_device_type_id_return(wLog* log, const GetDeviceTypeId_Return* ret)
1558
0
{
1559
0
  WINPR_ASSERT(ret);
1560
1561
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
1562
0
    return;
1563
1564
0
  WLog_Print(log, g_LogLevel, "GetDeviceTypeId_Return {");
1565
0
  WLog_Print(log, g_LogLevel, "  ReturnCode: %s (0x%08" PRIX32 ")",
1566
0
             SCardGetErrorString(ret->ReturnCode),
1567
0
             WINPR_CXX_COMPAT_CAST(UINT32, ret->ReturnCode));
1568
0
  WLog_Print(log, g_LogLevel, "  dwDeviceId=%08" PRIx32, ret->dwDeviceId);
1569
1570
0
  WLog_Print(log, g_LogLevel, "}");
1571
0
}
1572
1573
static LONG smartcard_unpack_common_context_and_string_a(wLog* log, wStream* s,
1574
                                                         REDIR_SCARDCONTEXT* phContext,
1575
                                                         CHAR** pszReaderName)
1576
0
{
1577
0
  UINT32 index = 0;
1578
0
  UINT32 pbContextNdrPtr = 0;
1579
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, phContext, &index, &pbContextNdrPtr);
1580
0
  if (status != SCARD_S_SUCCESS)
1581
0
    return status;
1582
1583
0
  if (!smartcard_ndr_pointer_read(log, s, &index, NULL))
1584
0
    return ERROR_INVALID_DATA;
1585
1586
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr, phContext);
1587
0
  if (status != SCARD_S_SUCCESS)
1588
0
    return status;
1589
1590
0
  status = smartcard_ndr_read_a(log, s, pszReaderName, NDR_PTR_FULL);
1591
0
  if (status != SCARD_S_SUCCESS)
1592
0
    return status;
1593
1594
0
  smartcard_trace_context_and_string_call_a(log, __func__, phContext, *pszReaderName);
1595
0
  return SCARD_S_SUCCESS;
1596
0
}
1597
1598
static LONG smartcard_unpack_common_context_and_string_w(wLog* log, wStream* s,
1599
                                                         REDIR_SCARDCONTEXT* phContext,
1600
                                                         WCHAR** pszReaderName)
1601
0
{
1602
0
  UINT32 index = 0;
1603
0
  UINT32 pbContextNdrPtr = 0;
1604
1605
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, phContext, &index, &pbContextNdrPtr);
1606
0
  if (status != SCARD_S_SUCCESS)
1607
0
    return status;
1608
1609
0
  if (!smartcard_ndr_pointer_read(log, s, &index, NULL))
1610
0
    return ERROR_INVALID_DATA;
1611
1612
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr, phContext);
1613
0
  if (status != SCARD_S_SUCCESS)
1614
0
    return status;
1615
1616
0
  status = smartcard_ndr_read_w(log, s, pszReaderName, NDR_PTR_FULL);
1617
0
  if (status != SCARD_S_SUCCESS)
1618
0
    return status;
1619
1620
0
  smartcard_trace_context_and_string_call_w(log, __func__, phContext, *pszReaderName);
1621
0
  return SCARD_S_SUCCESS;
1622
0
}
1623
1624
LONG smartcard_unpack_common_type_header(wStream* s)
1625
0
{
1626
0
  wLog* log = scard_log();
1627
0
  UINT8 version = 0;
1628
0
  UINT32 filler = 0;
1629
0
  UINT8 endianness = 0;
1630
0
  UINT16 commonHeaderLength = 0;
1631
1632
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1633
0
    return STATUS_BUFFER_TOO_SMALL;
1634
1635
  /* Process CommonTypeHeader */
1636
0
  Stream_Read_UINT8(s, version);             /* Version (1 byte) */
1637
0
  Stream_Read_UINT8(s, endianness);          /* Endianness (1 byte) */
1638
0
  Stream_Read_UINT16(s, commonHeaderLength); /* CommonHeaderLength (2 bytes) */
1639
0
  Stream_Read_UINT32(s, filler);             /* Filler (4 bytes), should be 0xCCCCCCCC */
1640
1641
0
  if (version != 1)
1642
0
  {
1643
0
    WLog_Print(log, WLOG_WARN, "Unsupported CommonTypeHeader Version %" PRIu8 "", version);
1644
0
    return STATUS_INVALID_PARAMETER;
1645
0
  }
1646
1647
0
  if (endianness != 0x10)
1648
0
  {
1649
0
    WLog_Print(log, WLOG_WARN, "Unsupported CommonTypeHeader Endianness %" PRIu8 "",
1650
0
               endianness);
1651
0
    return STATUS_INVALID_PARAMETER;
1652
0
  }
1653
1654
0
  if (commonHeaderLength != 8)
1655
0
  {
1656
0
    WLog_Print(log, WLOG_WARN, "Unsupported CommonTypeHeader CommonHeaderLength %" PRIu16 "",
1657
0
               commonHeaderLength);
1658
0
    return STATUS_INVALID_PARAMETER;
1659
0
  }
1660
1661
0
  if (filler != 0xCCCCCCCC)
1662
0
  {
1663
0
    WLog_Print(log, WLOG_WARN, "Unexpected CommonTypeHeader Filler 0x%08" PRIX32 "", filler);
1664
0
    return STATUS_INVALID_PARAMETER;
1665
0
  }
1666
1667
0
  return SCARD_S_SUCCESS;
1668
0
}
1669
1670
void smartcard_pack_common_type_header(wStream* s)
1671
0
{
1672
0
  Stream_Write_UINT8(s, 1);           /* Version (1 byte) */
1673
0
  Stream_Write_UINT8(s, 0x10);        /* Endianness (1 byte) */
1674
0
  Stream_Write_UINT16(s, 8);          /* CommonHeaderLength (2 bytes) */
1675
0
  Stream_Write_UINT32(s, 0xCCCCCCCC); /* Filler (4 bytes), should be 0xCCCCCCCC */
1676
0
}
1677
1678
LONG smartcard_unpack_private_type_header(wStream* s)
1679
0
{
1680
0
  wLog* log = scard_log();
1681
0
  UINT32 filler = 0;
1682
0
  UINT32 objectBufferLength = 0;
1683
1684
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
1685
0
    return STATUS_BUFFER_TOO_SMALL;
1686
1687
0
  Stream_Read_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */
1688
0
  Stream_Read_UINT32(s, filler);             /* Filler (4 bytes), should be 0x00000000 */
1689
1690
0
  if (filler != 0x00000000)
1691
0
  {
1692
0
    WLog_Print(log, WLOG_WARN, "Unexpected PrivateTypeHeader Filler 0x%08" PRIX32 "", filler);
1693
0
    return STATUS_INVALID_PARAMETER;
1694
0
  }
1695
1696
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, objectBufferLength))
1697
0
    return STATUS_INVALID_PARAMETER;
1698
1699
0
  return SCARD_S_SUCCESS;
1700
0
}
1701
1702
void smartcard_pack_private_type_header(wStream* s, UINT32 objectBufferLength)
1703
0
{
1704
0
  Stream_Write_UINT32(s, objectBufferLength); /* ObjectBufferLength (4 bytes) */
1705
0
  Stream_Write_UINT32(s, 0x00000000);         /* Filler (4 bytes), should be 0x00000000 */
1706
0
}
1707
1708
LONG smartcard_unpack_read_size_align(wStream* s, size_t size, UINT32 alignment)
1709
0
{
1710
0
  const size_t padsize = (size + alignment - 1) & ~(alignment - 1);
1711
0
  const size_t pad = padsize - size;
1712
1713
0
  if (pad > 0)
1714
0
  {
1715
0
    if (!Stream_SafeSeek(s, pad))
1716
0
      return -1;
1717
0
  }
1718
1719
0
  return (LONG)pad;
1720
0
}
1721
1722
LONG smartcard_pack_write_size_align(wStream* s, size_t size, UINT32 alignment)
1723
0
{
1724
0
  const size_t padsize = (size + alignment - 1) & ~(alignment - 1);
1725
0
  const size_t pad = padsize - size;
1726
1727
0
  if (pad)
1728
0
  {
1729
0
    if (!Stream_EnsureRemainingCapacity(s, pad))
1730
0
    {
1731
0
      wLog* log = scard_log();
1732
0
      WLog_Print(log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
1733
0
      return SCARD_F_INTERNAL_ERROR;
1734
0
    }
1735
1736
0
    Stream_Zero(s, pad);
1737
0
  }
1738
1739
0
  return SCARD_S_SUCCESS;
1740
0
}
1741
1742
SCARDCONTEXT smartcard_scard_context_native_from_redir(REDIR_SCARDCONTEXT* context)
1743
0
{
1744
0
  SCARDCONTEXT hContext = WINPR_C_ARRAY_INIT;
1745
1746
0
  WINPR_ASSERT(context);
1747
0
  if ((context->cbContext != sizeof(ULONG_PTR)) && (context->cbContext != 0))
1748
0
  {
1749
0
    wLog* log = scard_log();
1750
0
    WLog_Print(log, WLOG_WARN,
1751
0
               "REDIR_SCARDCONTEXT does not match native size: Actual: %" PRIu32
1752
0
               ", Expected: %" PRIuz "",
1753
0
               context->cbContext, sizeof(ULONG_PTR));
1754
0
    return 0;
1755
0
  }
1756
1757
0
  if (context->cbContext)
1758
0
    CopyMemory(&hContext, &(context->pbContext), context->cbContext);
1759
1760
0
  return hContext;
1761
0
}
1762
1763
void smartcard_scard_context_native_to_redir(REDIR_SCARDCONTEXT* context, SCARDCONTEXT hContext)
1764
0
{
1765
0
  WINPR_ASSERT(context);
1766
0
  ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT));
1767
0
  context->cbContext = sizeof(ULONG_PTR);
1768
0
  CopyMemory(&(context->pbContext), &hContext, context->cbContext);
1769
0
}
1770
1771
SCARDHANDLE smartcard_scard_handle_native_from_redir(REDIR_SCARDHANDLE* handle)
1772
0
{
1773
0
  SCARDHANDLE hCard = 0;
1774
1775
0
  WINPR_ASSERT(handle);
1776
0
  if (handle->cbHandle == 0)
1777
0
    return hCard;
1778
1779
0
  if (handle->cbHandle != sizeof(ULONG_PTR))
1780
0
  {
1781
0
    wLog* log = scard_log();
1782
0
    WLog_Print(log, WLOG_WARN,
1783
0
               "REDIR_SCARDHANDLE does not match native size: Actual: %" PRIu32
1784
0
               ", Expected: %" PRIuz "",
1785
0
               handle->cbHandle, sizeof(ULONG_PTR));
1786
0
    return 0;
1787
0
  }
1788
1789
0
  if (handle->cbHandle)
1790
0
    CopyMemory(&hCard, &(handle->pbHandle), handle->cbHandle);
1791
1792
0
  return hCard;
1793
0
}
1794
1795
void smartcard_scard_handle_native_to_redir(REDIR_SCARDHANDLE* handle, SCARDHANDLE hCard)
1796
0
{
1797
0
  WINPR_ASSERT(handle);
1798
0
  ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE));
1799
0
  handle->cbHandle = sizeof(ULONG_PTR);
1800
0
  CopyMemory(&(handle->pbHandle), &hCard, handle->cbHandle);
1801
0
}
1802
1803
#define smartcard_context_supported(log, size) \
1804
0
  smartcard_context_supported_((log), (size), __FILE__, __func__, __LINE__)
1805
static LONG smartcard_context_supported_(wLog* log, uint32_t size, const char* file,
1806
                                         const char* fkt, size_t line)
1807
0
{
1808
0
  switch (size)
1809
0
  {
1810
0
    case 0:
1811
0
    case 4:
1812
0
    case 8:
1813
0
      return SCARD_S_SUCCESS;
1814
0
    default:
1815
0
    {
1816
0
      const uint32_t level = WLOG_WARN;
1817
0
      if (WLog_IsLevelActive(log, level))
1818
0
      {
1819
0
        WLog_PrintTextMessage(log, level, line, file, fkt,
1820
0
                              "REDIR_SCARDCONTEXT length is not 0, 4 or 8: %" PRIu32 "",
1821
0
                              size);
1822
0
      }
1823
0
      return STATUS_INVALID_PARAMETER;
1824
0
    }
1825
0
  }
1826
0
}
1827
1828
LONG smartcard_unpack_redir_scard_context_(wLog* log, wStream* s, REDIR_SCARDCONTEXT* context,
1829
                                           UINT32* index, UINT32* ppbContextNdrPtr,
1830
                                           const char* file, const char* function, size_t line)
1831
0
{
1832
0
  UINT32 pbContextNdrPtr = 0;
1833
1834
0
  WINPR_UNUSED(file);
1835
0
  WINPR_ASSERT(context);
1836
1837
0
  ZeroMemory(context, sizeof(REDIR_SCARDCONTEXT));
1838
1839
0
  if (!Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, 4, 1, "%s(%s:%" PRIuz ")", file,
1840
0
                                              function, line))
1841
0
    return STATUS_BUFFER_TOO_SMALL;
1842
1843
0
  const LONG status = smartcard_context_supported_(log, context->cbContext, file, function, line);
1844
0
  if (status != SCARD_S_SUCCESS)
1845
0
    return status;
1846
1847
0
  Stream_Read_UINT32(s, context->cbContext); /* cbContext (4 bytes) */
1848
1849
0
  if (!smartcard_ndr_pointer_read_(log, s, index, &pbContextNdrPtr, file, function, line))
1850
0
    return ERROR_INVALID_DATA;
1851
1852
0
  if (((context->cbContext == 0) && pbContextNdrPtr) ||
1853
0
      ((context->cbContext != 0) && !pbContextNdrPtr))
1854
0
  {
1855
0
    WLog_Print(log, WLOG_WARN,
1856
0
               "REDIR_SCARDCONTEXT cbContext (%" PRIu32 ") pbContextNdrPtr (%" PRIu32
1857
0
               ") inconsistency",
1858
0
               context->cbContext, pbContextNdrPtr);
1859
0
    return STATUS_INVALID_PARAMETER;
1860
0
  }
1861
1862
0
  if (!Stream_CheckAndLogRequiredLengthWLogEx(log, WLOG_WARN, s, context->cbContext, 1,
1863
0
                                              "%s(%s:%" PRIuz ")", file, function, line))
1864
0
    return STATUS_INVALID_PARAMETER;
1865
1866
0
  *ppbContextNdrPtr = pbContextNdrPtr;
1867
0
  return SCARD_S_SUCCESS;
1868
0
}
1869
1870
LONG smartcard_pack_redir_scard_context(WINPR_ATTR_UNUSED wLog* log, wStream* s,
1871
                                        const REDIR_SCARDCONTEXT* context, DWORD* index)
1872
0
{
1873
0
  const UINT32 pbContextNdrPtr = 0x00020000 + *index * 4;
1874
1875
0
  WINPR_ASSERT(context);
1876
0
  if (context->cbContext != 0)
1877
0
  {
1878
0
    Stream_Write_UINT32(s, context->cbContext); /* cbContext (4 bytes) */
1879
0
    Stream_Write_UINT32(s, pbContextNdrPtr);    /* pbContextNdrPtr (4 bytes) */
1880
0
    *index = *index + 1;
1881
0
  }
1882
0
  else
1883
0
    Stream_Zero(s, 8);
1884
1885
0
  return SCARD_S_SUCCESS;
1886
0
}
1887
1888
LONG smartcard_unpack_redir_scard_context_ref(wLog* log, wStream* s,
1889
                                              WINPR_ATTR_UNUSED UINT32 pbContextNdrPtr,
1890
                                              REDIR_SCARDCONTEXT* context)
1891
0
{
1892
0
  UINT32 length = 0;
1893
1894
0
  WINPR_ASSERT(context);
1895
0
  if (context->cbContext == 0)
1896
0
    return SCARD_S_SUCCESS;
1897
1898
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1899
0
    return STATUS_BUFFER_TOO_SMALL;
1900
1901
0
  Stream_Read_UINT32(s, length); /* Length (4 bytes) */
1902
1903
0
  if (length != context->cbContext)
1904
0
  {
1905
0
    WLog_Print(log, WLOG_WARN,
1906
0
               "REDIR_SCARDCONTEXT length (%" PRIu32 ") cbContext (%" PRIu32 ") mismatch",
1907
0
               length, context->cbContext);
1908
0
    return STATUS_INVALID_PARAMETER;
1909
0
  }
1910
1911
0
  const LONG status = smartcard_context_supported(log, context->cbContext);
1912
0
  if (status != SCARD_S_SUCCESS)
1913
0
    return status;
1914
1915
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, context->cbContext))
1916
0
    return STATUS_BUFFER_TOO_SMALL;
1917
1918
0
  if (context->cbContext)
1919
0
    Stream_Read(s, &(context->pbContext), context->cbContext);
1920
0
  else
1921
0
    ZeroMemory(&(context->pbContext), sizeof(context->pbContext));
1922
1923
0
  return SCARD_S_SUCCESS;
1924
0
}
1925
1926
LONG smartcard_pack_redir_scard_context_ref(WINPR_ATTR_UNUSED wLog* log, wStream* s,
1927
                                            const REDIR_SCARDCONTEXT* context)
1928
0
{
1929
0
  WINPR_ASSERT(context);
1930
0
  Stream_Write_UINT32(s, context->cbContext); /* Length (4 bytes) */
1931
1932
0
  if (context->cbContext)
1933
0
  {
1934
0
    Stream_Write(s, &(context->pbContext), context->cbContext);
1935
0
  }
1936
1937
0
  return SCARD_S_SUCCESS;
1938
0
}
1939
1940
LONG smartcard_unpack_redir_scard_handle_(wLog* log, wStream* s, REDIR_SCARDHANDLE* handle,
1941
                                          UINT32* index, const char* file, const char* function,
1942
                                          size_t line)
1943
0
{
1944
0
  WINPR_ASSERT(handle);
1945
0
  ZeroMemory(handle, sizeof(REDIR_SCARDHANDLE));
1946
1947
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1948
0
    return STATUS_BUFFER_TOO_SMALL;
1949
1950
0
  Stream_Read_UINT32(s, handle->cbHandle); /* Length (4 bytes) */
1951
1952
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, handle->cbHandle))
1953
0
    return STATUS_BUFFER_TOO_SMALL;
1954
1955
0
  if (!smartcard_ndr_pointer_read_(log, s, index, NULL, file, function, line))
1956
0
    return ERROR_INVALID_DATA;
1957
1958
0
  return SCARD_S_SUCCESS;
1959
0
}
1960
1961
LONG smartcard_pack_redir_scard_handle(WINPR_ATTR_UNUSED wLog* log, wStream* s,
1962
                                       const REDIR_SCARDHANDLE* handle, DWORD* index)
1963
0
{
1964
0
  const UINT32 pbContextNdrPtr = 0x00020000 + *index * 4;
1965
1966
0
  WINPR_ASSERT(handle);
1967
0
  if (handle->cbHandle != 0)
1968
0
  {
1969
0
    Stream_Write_UINT32(s, handle->cbHandle); /* cbContext (4 bytes) */
1970
0
    Stream_Write_UINT32(s, pbContextNdrPtr);  /* pbContextNdrPtr (4 bytes) */
1971
0
    *index = *index + 1;
1972
0
  }
1973
0
  else
1974
0
    Stream_Zero(s, 8);
1975
0
  return SCARD_S_SUCCESS;
1976
0
}
1977
1978
LONG smartcard_unpack_redir_scard_handle_ref(wLog* log, wStream* s, REDIR_SCARDHANDLE* handle)
1979
0
{
1980
0
  UINT32 length = 0;
1981
1982
0
  WINPR_ASSERT(handle);
1983
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
1984
0
    return STATUS_BUFFER_TOO_SMALL;
1985
1986
0
  Stream_Read_UINT32(s, length); /* Length (4 bytes) */
1987
1988
0
  if (length != handle->cbHandle)
1989
0
  {
1990
0
    WLog_Print(log, WLOG_WARN,
1991
0
               "REDIR_SCARDHANDLE length (%" PRIu32 ") cbHandle (%" PRIu32 ") mismatch", length,
1992
0
               handle->cbHandle);
1993
0
    return STATUS_INVALID_PARAMETER;
1994
0
  }
1995
1996
0
  if ((handle->cbHandle != 4) && (handle->cbHandle != 8))
1997
0
  {
1998
0
    WLog_Print(log, WLOG_WARN, "REDIR_SCARDHANDLE length is not 4 or 8: %" PRIu32 "",
1999
0
               handle->cbHandle);
2000
0
    return STATUS_INVALID_PARAMETER;
2001
0
  }
2002
2003
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, handle->cbHandle))
2004
0
    return STATUS_BUFFER_TOO_SMALL;
2005
2006
0
  if (handle->cbHandle)
2007
0
    Stream_Read(s, &(handle->pbHandle), handle->cbHandle);
2008
2009
0
  return SCARD_S_SUCCESS;
2010
0
}
2011
2012
LONG smartcard_pack_redir_scard_handle_ref(WINPR_ATTR_UNUSED wLog* log, wStream* s,
2013
                                           const REDIR_SCARDHANDLE* handle)
2014
0
{
2015
0
  WINPR_ASSERT(handle);
2016
0
  Stream_Write_UINT32(s, handle->cbHandle); /* Length (4 bytes) */
2017
2018
0
  if (handle->cbHandle)
2019
0
    Stream_Write(s, &(handle->pbHandle), handle->cbHandle);
2020
2021
0
  return SCARD_S_SUCCESS;
2022
0
}
2023
2024
LONG smartcard_unpack_establish_context_call(wStream* s, EstablishContext_Call* call)
2025
0
{
2026
0
  WINPR_ASSERT(call);
2027
0
  wLog* log = scard_log();
2028
2029
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2030
0
    return STATUS_BUFFER_TOO_SMALL;
2031
2032
0
  Stream_Read_UINT32(s, call->dwScope); /* dwScope (4 bytes) */
2033
0
  smartcard_trace_establish_context_call(log, call);
2034
0
  return SCARD_S_SUCCESS;
2035
0
}
2036
2037
LONG smartcard_pack_establish_context_return(wStream* s, const EstablishContext_Return* ret)
2038
0
{
2039
0
  WINPR_ASSERT(ret);
2040
0
  wLog* log = scard_log();
2041
0
  LONG status = 0;
2042
0
  DWORD index = 0;
2043
2044
0
  smartcard_trace_establish_context_return(log, ret);
2045
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
2046
0
    return ret->ReturnCode;
2047
2048
0
  status = smartcard_pack_redir_scard_context(log, s, &(ret->hContext), &index);
2049
0
  if (status != SCARD_S_SUCCESS)
2050
0
    return status;
2051
2052
0
  return smartcard_pack_redir_scard_context_ref(log, s, &(ret->hContext));
2053
0
}
2054
2055
LONG smartcard_unpack_context_call(wStream* s, Context_Call* call, const char* name)
2056
0
{
2057
0
  UINT32 index = 0;
2058
0
  UINT32 pbContextNdrPtr = 0;
2059
0
  wLog* log = scard_log();
2060
2061
0
  WINPR_ASSERT(call);
2062
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2063
0
                                                     &pbContextNdrPtr);
2064
0
  if (status != SCARD_S_SUCCESS)
2065
0
    return status;
2066
2067
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2068
0
                                                    &(call->handles.hContext));
2069
0
  if (status != SCARD_S_SUCCESS)
2070
0
    WLog_Print(log, WLOG_ERROR,
2071
0
               "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
2072
0
               status);
2073
2074
0
  smartcard_trace_context_call(log, call, name);
2075
0
  return status;
2076
0
}
2077
2078
LONG smartcard_unpack_list_reader_groups_call(wStream* s, ListReaderGroups_Call* call, BOOL unicode)
2079
0
{
2080
0
  UINT32 index = 0;
2081
0
  UINT32 pbContextNdrPtr = 0;
2082
0
  wLog* log = scard_log();
2083
2084
0
  WINPR_ASSERT(call);
2085
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2086
0
                                                     &pbContextNdrPtr);
2087
2088
0
  if (status != SCARD_S_SUCCESS)
2089
0
    return status;
2090
2091
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2092
0
    return STATUS_BUFFER_TOO_SMALL;
2093
2094
0
  Stream_Read_INT32(s, call->fmszGroupsIsNULL); /* fmszGroupsIsNULL (4 bytes) */
2095
0
  Stream_Read_UINT32(s, call->cchGroups);       /* cchGroups (4 bytes) */
2096
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2097
0
                                                    &(call->handles.hContext));
2098
2099
0
  if (status != SCARD_S_SUCCESS)
2100
0
    return status;
2101
2102
0
  smartcard_trace_list_reader_groups_call(log, call, unicode);
2103
0
  return SCARD_S_SUCCESS;
2104
0
}
2105
2106
LONG smartcard_pack_list_reader_groups_return(wStream* s, const ListReaderGroups_Return* ret,
2107
                                              BOOL unicode)
2108
0
{
2109
0
  WINPR_ASSERT(ret);
2110
0
  wLog* log = scard_log();
2111
0
  LONG status = 0;
2112
0
  DWORD cBytes = ret->cBytes;
2113
0
  UINT32 index = 0;
2114
2115
0
  smartcard_trace_list_reader_groups_return(log, ret, unicode);
2116
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
2117
0
    cBytes = 0;
2118
0
  if (cBytes == SCARD_AUTOALLOCATE)
2119
0
    cBytes = 0;
2120
2121
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
2122
0
    return SCARD_E_NO_MEMORY;
2123
2124
0
  Stream_Write_UINT32(s, cBytes); /* cBytes (4 bytes) */
2125
0
  if (!smartcard_ndr_pointer_write(s, &index, cBytes))
2126
0
    return SCARD_E_NO_MEMORY;
2127
2128
0
  status = smartcard_ndr_write(s, ret->msz, cBytes, 1, NDR_PTR_SIMPLE);
2129
0
  if (status != SCARD_S_SUCCESS)
2130
0
    return status;
2131
0
  return ret->ReturnCode;
2132
0
}
2133
2134
LONG smartcard_unpack_list_readers_call(wStream* s, ListReaders_Call* call, BOOL unicode)
2135
0
{
2136
0
  UINT32 index = 0;
2137
0
  UINT32 mszGroupsNdrPtr = 0;
2138
0
  UINT32 pbContextNdrPtr = 0;
2139
0
  wLog* log = scard_log();
2140
2141
0
  WINPR_ASSERT(call);
2142
0
  call->mszGroups = NULL;
2143
2144
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2145
0
                                                     &pbContextNdrPtr);
2146
0
  if (status != SCARD_S_SUCCESS)
2147
0
    return status;
2148
2149
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2150
0
    return STATUS_BUFFER_TOO_SMALL;
2151
2152
0
  Stream_Read_UINT32(s, call->cBytes); /* cBytes (4 bytes) */
2153
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &mszGroupsNdrPtr))
2154
0
    return ERROR_INVALID_DATA;
2155
2156
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2157
0
    return STATUS_BUFFER_TOO_SMALL;
2158
0
  Stream_Read_INT32(s, call->fmszReadersIsNULL); /* fmszReadersIsNULL (4 bytes) */
2159
0
  Stream_Read_UINT32(s, call->cchReaders);       /* cchReaders (4 bytes) */
2160
2161
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2162
0
                                                    &(call->handles.hContext));
2163
0
  if (status != SCARD_S_SUCCESS)
2164
0
    return status;
2165
2166
0
  if (mszGroupsNdrPtr)
2167
0
  {
2168
0
    status = smartcard_ndr_read(log, s, &call->mszGroups, call->cBytes, 1, NDR_PTR_SIMPLE);
2169
0
    if (status != SCARD_S_SUCCESS)
2170
0
      return status;
2171
0
  }
2172
2173
0
  smartcard_trace_list_readers_call(log, call, unicode);
2174
0
  return SCARD_S_SUCCESS;
2175
0
}
2176
2177
LONG smartcard_pack_list_readers_return(wStream* s, const ListReaders_Return* ret, BOOL unicode)
2178
0
{
2179
0
  WINPR_ASSERT(ret);
2180
0
  wLog* log = scard_log();
2181
0
  LONG status = 0;
2182
0
  UINT32 index = 0;
2183
0
  UINT32 size = ret->cBytes;
2184
2185
0
  smartcard_trace_list_readers_return(log, ret, unicode);
2186
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
2187
0
    size = 0;
2188
2189
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
2190
0
  {
2191
0
    WLog_Print(log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
2192
0
    return SCARD_F_INTERNAL_ERROR;
2193
0
  }
2194
2195
0
  Stream_Write_UINT32(s, size); /* cBytes (4 bytes) */
2196
0
  if (!smartcard_ndr_pointer_write(s, &index, size))
2197
0
    return SCARD_E_NO_MEMORY;
2198
2199
0
  status = smartcard_ndr_write(s, ret->msz, size, 1, NDR_PTR_SIMPLE);
2200
0
  if (status != SCARD_S_SUCCESS)
2201
0
    return status;
2202
0
  return ret->ReturnCode;
2203
0
}
2204
2205
static LONG smartcard_unpack_connect_common(wLog* log, wStream* s, Connect_Common_Call* common,
2206
                                            UINT32* index, UINT32* ppbContextNdrPtr)
2207
0
{
2208
0
  WINPR_ASSERT(common);
2209
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(common->handles.hContext), index,
2210
0
                                                     ppbContextNdrPtr);
2211
0
  if (status != SCARD_S_SUCCESS)
2212
0
    return status;
2213
2214
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2215
0
    return STATUS_BUFFER_TOO_SMALL;
2216
2217
0
  Stream_Read_UINT32(s, common->dwShareMode);          /* dwShareMode (4 bytes) */
2218
0
  Stream_Read_UINT32(s, common->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */
2219
0
  return SCARD_S_SUCCESS;
2220
0
}
2221
2222
LONG smartcard_unpack_connect_a_call(wStream* s, ConnectA_Call* call)
2223
0
{
2224
0
  LONG status = 0;
2225
0
  UINT32 index = 0;
2226
0
  UINT32 pbContextNdrPtr = 0;
2227
2228
0
  WINPR_ASSERT(call);
2229
0
  wLog* log = scard_log();
2230
2231
0
  call->szReader = NULL;
2232
2233
0
  if (!smartcard_ndr_pointer_read(log, s, &index, NULL))
2234
0
    return ERROR_INVALID_DATA;
2235
2236
0
  status = smartcard_unpack_connect_common(log, s, &(call->Common), &index, &pbContextNdrPtr);
2237
0
  if (status != SCARD_S_SUCCESS)
2238
0
  {
2239
0
    WLog_Print(log, WLOG_ERROR, "smartcard_unpack_connect_common failed with error %" PRId32 "",
2240
0
               status);
2241
0
    return status;
2242
0
  }
2243
2244
0
  status = smartcard_ndr_read_a(log, s, &call->szReader, NDR_PTR_FULL);
2245
0
  if (status != SCARD_S_SUCCESS)
2246
0
    return status;
2247
2248
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2249
0
                                                    &(call->Common.handles.hContext));
2250
0
  if (status != SCARD_S_SUCCESS)
2251
0
    WLog_Print(log, WLOG_ERROR,
2252
0
               "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
2253
0
               status);
2254
2255
0
  smartcard_trace_connect_a_call(log, call);
2256
0
  return status;
2257
0
}
2258
2259
LONG smartcard_unpack_connect_w_call(wStream* s, ConnectW_Call* call)
2260
0
{
2261
0
  LONG status = 0;
2262
0
  UINT32 index = 0;
2263
0
  UINT32 pbContextNdrPtr = 0;
2264
2265
0
  WINPR_ASSERT(call);
2266
0
  wLog* log = scard_log();
2267
0
  call->szReader = NULL;
2268
2269
0
  if (!smartcard_ndr_pointer_read(log, s, &index, NULL))
2270
0
    return ERROR_INVALID_DATA;
2271
2272
0
  status = smartcard_unpack_connect_common(log, s, &(call->Common), &index, &pbContextNdrPtr);
2273
0
  if (status != SCARD_S_SUCCESS)
2274
0
  {
2275
0
    WLog_Print(log, WLOG_ERROR, "smartcard_unpack_connect_common failed with error %" PRId32 "",
2276
0
               status);
2277
0
    return status;
2278
0
  }
2279
2280
0
  status = smartcard_ndr_read_w(log, s, &call->szReader, NDR_PTR_FULL);
2281
0
  if (status != SCARD_S_SUCCESS)
2282
0
    return status;
2283
2284
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2285
0
                                                    &(call->Common.handles.hContext));
2286
0
  if (status != SCARD_S_SUCCESS)
2287
0
    WLog_Print(log, WLOG_ERROR,
2288
0
               "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
2289
0
               status);
2290
2291
0
  smartcard_trace_connect_w_call(log, call);
2292
0
  return status;
2293
0
}
2294
2295
LONG smartcard_pack_connect_return(wStream* s, const Connect_Return* ret)
2296
0
{
2297
0
  LONG status = 0;
2298
0
  DWORD index = 0;
2299
2300
0
  WINPR_ASSERT(ret);
2301
0
  wLog* log = scard_log();
2302
0
  smartcard_trace_connect_return(log, ret);
2303
2304
0
  status = smartcard_pack_redir_scard_context(log, s, &ret->hContext, &index);
2305
0
  if (status != SCARD_S_SUCCESS)
2306
0
    return status;
2307
2308
0
  status = smartcard_pack_redir_scard_handle(log, s, &ret->hCard, &index);
2309
0
  if (status != SCARD_S_SUCCESS)
2310
0
    return status;
2311
2312
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
2313
0
    return SCARD_E_NO_MEMORY;
2314
2315
0
  Stream_Write_UINT32(s, ret->dwActiveProtocol); /* dwActiveProtocol (4 bytes) */
2316
0
  status = smartcard_pack_redir_scard_context_ref(log, s, &ret->hContext);
2317
0
  if (status != SCARD_S_SUCCESS)
2318
0
    return status;
2319
0
  return smartcard_pack_redir_scard_handle_ref(log, s, &(ret->hCard));
2320
0
}
2321
2322
LONG smartcard_unpack_reconnect_call(wStream* s, Reconnect_Call* call)
2323
0
{
2324
0
  UINT32 index = 0;
2325
0
  UINT32 pbContextNdrPtr = 0;
2326
2327
0
  WINPR_ASSERT(call);
2328
0
  wLog* log = scard_log();
2329
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2330
0
                                                     &pbContextNdrPtr);
2331
0
  if (status != SCARD_S_SUCCESS)
2332
0
    return status;
2333
2334
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
2335
0
  if (status != SCARD_S_SUCCESS)
2336
0
    return status;
2337
2338
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 12))
2339
0
    return STATUS_BUFFER_TOO_SMALL;
2340
2341
0
  Stream_Read_UINT32(s, call->dwShareMode);          /* dwShareMode (4 bytes) */
2342
0
  Stream_Read_UINT32(s, call->dwPreferredProtocols); /* dwPreferredProtocols (4 bytes) */
2343
0
  Stream_Read_UINT32(s, call->dwInitialization);     /* dwInitialization (4 bytes) */
2344
2345
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2346
0
                                                    &(call->handles.hContext));
2347
0
  if (status != SCARD_S_SUCCESS)
2348
0
  {
2349
0
    WLog_Print(log, WLOG_ERROR,
2350
0
               "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
2351
0
               status);
2352
0
    return status;
2353
0
  }
2354
2355
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
2356
0
  if (status != SCARD_S_SUCCESS)
2357
0
    WLog_Print(log, WLOG_ERROR,
2358
0
               "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", status);
2359
2360
0
  smartcard_trace_reconnect_call(log, call);
2361
0
  return status;
2362
0
}
2363
2364
LONG smartcard_pack_reconnect_return(wStream* s, const Reconnect_Return* ret)
2365
0
{
2366
0
  WINPR_ASSERT(ret);
2367
0
  wLog* log = scard_log();
2368
0
  smartcard_trace_reconnect_return(log, ret);
2369
2370
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
2371
0
    return SCARD_E_NO_MEMORY;
2372
0
  Stream_Write_UINT32(s, ret->dwActiveProtocol); /* dwActiveProtocol (4 bytes) */
2373
0
  return ret->ReturnCode;
2374
0
}
2375
2376
LONG smartcard_unpack_hcard_and_disposition_call(wStream* s, HCardAndDisposition_Call* call,
2377
                                                 const char* name)
2378
0
{
2379
0
  UINT32 index = 0;
2380
0
  UINT32 pbContextNdrPtr = 0;
2381
2382
0
  WINPR_ASSERT(call);
2383
0
  wLog* log = scard_log();
2384
2385
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2386
0
                                                     &pbContextNdrPtr);
2387
0
  if (status != SCARD_S_SUCCESS)
2388
0
    return status;
2389
2390
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
2391
0
  if (status != SCARD_S_SUCCESS)
2392
0
    return status;
2393
2394
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2395
0
    return STATUS_BUFFER_TOO_SMALL;
2396
2397
0
  Stream_Read_UINT32(s, call->dwDisposition); /* dwDisposition (4 bytes) */
2398
2399
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2400
0
                                                    &(call->handles.hContext));
2401
0
  if (status != SCARD_S_SUCCESS)
2402
0
    return status;
2403
2404
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
2405
0
  if (status != SCARD_S_SUCCESS)
2406
0
    return status;
2407
2408
0
  smartcard_trace_hcard_and_disposition_call(log, call, name);
2409
0
  return status;
2410
0
}
2411
2412
static void smartcard_trace_get_status_change_a_call(wLog* log, const GetStatusChangeA_Call* call)
2413
0
{
2414
0
  WINPR_ASSERT(call);
2415
2416
0
  if (!WLog_IsLevelActive(log, g_LogLevel))
2417
0
    return;
2418
2419
0
  WLog_Print(log, g_LogLevel, "GetStatusChangeA_Call {");
2420
0
  smartcard_log_context(log, &call->handles.hContext);
2421
2422
0
  WLog_Print(log, g_LogLevel, "dwTimeOut: 0x%08" PRIX32 " cReaders: %" PRIu32 "", call->dwTimeOut,
2423
0
             call->cReaders);
2424
2425
0
  dump_reader_states_a(log, call->rgReaderStates, call->cReaders);
2426
2427
0
  WLog_Print(log, g_LogLevel, "}");
2428
0
}
2429
2430
static LONG smartcard_unpack_reader_state_a(wLog* log, wStream* s, LPSCARD_READERSTATEA* ppcReaders,
2431
                                            UINT32 cReaders, UINT32* ptrIndex)
2432
0
{
2433
0
  LONG status = SCARD_E_NO_MEMORY;
2434
2435
0
  WINPR_ASSERT(ppcReaders || (cReaders == 0));
2436
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2437
0
    return status;
2438
2439
0
  const UINT32 len = Stream_Get_UINT32(s);
2440
0
  if (len != cReaders)
2441
0
  {
2442
0
    WLog_Print(log, WLOG_ERROR, "Count mismatch when reading LPSCARD_READERSTATEA");
2443
0
    return status;
2444
0
  }
2445
2446
0
  LPSCARD_READERSTATEA rgReaderStates =
2447
0
      (LPSCARD_READERSTATEA)calloc(cReaders, sizeof(SCARD_READERSTATEA));
2448
0
  BOOL* states = calloc(cReaders, sizeof(BOOL));
2449
0
  if (!rgReaderStates || !states)
2450
0
    goto fail;
2451
0
  status = ERROR_INVALID_DATA;
2452
2453
0
  for (UINT32 index = 0; index < cReaders; index++)
2454
0
  {
2455
0
    UINT32 ptr = UINT32_MAX;
2456
0
    LPSCARD_READERSTATEA readerState = &rgReaderStates[index];
2457
2458
0
    if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 52))
2459
0
      goto fail;
2460
2461
0
    if (!smartcard_ndr_pointer_read(log, s, ptrIndex, &ptr))
2462
0
    {
2463
0
      if (ptr != 0)
2464
0
        goto fail;
2465
0
    }
2466
    /* Ignore NULL length strings */
2467
0
    states[index] = ptr != 0;
2468
0
    Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */
2469
0
    Stream_Read_UINT32(s, readerState->dwEventState);   /* dwEventState (4 bytes) */
2470
0
    Stream_Read_UINT32(s, readerState->cbAtr);          /* cbAtr (4 bytes) */
2471
0
    Stream_Read(s, readerState->rgbAtr, 36);            /* rgbAtr [0..36] (36 bytes) */
2472
0
  }
2473
2474
0
  for (UINT32 index = 0; index < cReaders; index++)
2475
0
  {
2476
0
    LPSCARD_READERSTATEA readerState = &rgReaderStates[index];
2477
2478
    /* Ignore empty strings */
2479
0
    if (!states[index])
2480
0
      continue;
2481
0
    status = smartcard_ndr_read_a(log, s, &readerState->szReader, NDR_PTR_FULL);
2482
0
    if (status != SCARD_S_SUCCESS)
2483
0
      goto fail;
2484
0
  }
2485
2486
0
  *ppcReaders = rgReaderStates;
2487
0
  free(states);
2488
0
  return SCARD_S_SUCCESS;
2489
0
fail:
2490
0
  if (rgReaderStates)
2491
0
  {
2492
0
    for (UINT32 index = 0; index < cReaders; index++)
2493
0
    {
2494
0
      LPSCARD_READERSTATEA readerState = &rgReaderStates[index];
2495
0
      free(readerState->szReader);
2496
0
    }
2497
0
  }
2498
0
  free(rgReaderStates);
2499
0
  free(states);
2500
0
  return status;
2501
0
}
2502
2503
static LONG smartcard_unpack_reader_state_w(wLog* log, wStream* s, LPSCARD_READERSTATEW* ppcReaders,
2504
                                            UINT32 cReaders, UINT32* ptrIndex)
2505
0
{
2506
0
  LONG status = SCARD_E_NO_MEMORY;
2507
2508
0
  WINPR_ASSERT(ppcReaders || (cReaders == 0));
2509
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
2510
0
    return status;
2511
2512
0
  const UINT32 len = Stream_Get_UINT32(s);
2513
0
  if (len != cReaders)
2514
0
  {
2515
0
    WLog_Print(log, WLOG_ERROR, "Count mismatch when reading LPSCARD_READERSTATEW");
2516
0
    return status;
2517
0
  }
2518
2519
0
  LPSCARD_READERSTATEW rgReaderStates =
2520
0
      (LPSCARD_READERSTATEW)calloc(cReaders, sizeof(SCARD_READERSTATEW));
2521
0
  BOOL* states = calloc(cReaders, sizeof(BOOL));
2522
2523
0
  if (!rgReaderStates || !states)
2524
0
    goto fail;
2525
2526
0
  status = ERROR_INVALID_DATA;
2527
0
  for (UINT32 index = 0; index < cReaders; index++)
2528
0
  {
2529
0
    UINT32 ptr = UINT32_MAX;
2530
0
    LPSCARD_READERSTATEW readerState = &rgReaderStates[index];
2531
2532
0
    if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 52))
2533
0
      goto fail;
2534
2535
0
    if (!smartcard_ndr_pointer_read(log, s, ptrIndex, &ptr))
2536
0
    {
2537
0
      if (ptr != 0)
2538
0
        goto fail;
2539
0
    }
2540
    /* Ignore NULL length strings */
2541
0
    states[index] = ptr != 0;
2542
0
    Stream_Read_UINT32(s, readerState->dwCurrentState); /* dwCurrentState (4 bytes) */
2543
0
    Stream_Read_UINT32(s, readerState->dwEventState);   /* dwEventState (4 bytes) */
2544
0
    Stream_Read_UINT32(s, readerState->cbAtr);          /* cbAtr (4 bytes) */
2545
0
    Stream_Read(s, readerState->rgbAtr, 36);            /* rgbAtr [0..36] (36 bytes) */
2546
0
  }
2547
2548
0
  for (UINT32 index = 0; index < cReaders; index++)
2549
0
  {
2550
0
    LPSCARD_READERSTATEW readerState = &rgReaderStates[index];
2551
2552
    /* Skip NULL pointers */
2553
0
    if (!states[index])
2554
0
      continue;
2555
2556
0
    status = smartcard_ndr_read_w(log, s, &readerState->szReader, NDR_PTR_FULL);
2557
0
    if (status != SCARD_S_SUCCESS)
2558
0
      goto fail;
2559
0
  }
2560
2561
0
  *ppcReaders = rgReaderStates;
2562
0
  free(states);
2563
0
  return SCARD_S_SUCCESS;
2564
0
fail:
2565
0
  if (rgReaderStates)
2566
0
  {
2567
0
    for (UINT32 index = 0; index < cReaders; index++)
2568
0
    {
2569
0
      LPSCARD_READERSTATEW readerState = &rgReaderStates[index];
2570
0
      free(readerState->szReader);
2571
0
    }
2572
0
  }
2573
0
  free(rgReaderStates);
2574
0
  free(states);
2575
0
  return status;
2576
0
}
2577
2578
/******************************************************************************/
2579
/************************************* End Trace Functions ********************/
2580
/******************************************************************************/
2581
2582
LONG smartcard_unpack_get_status_change_a_call(wStream* s, GetStatusChangeA_Call* call)
2583
0
{
2584
0
  UINT32 ndrPtr = 0;
2585
0
  UINT32 index = 0;
2586
0
  UINT32 pbContextNdrPtr = 0;
2587
2588
0
  WINPR_ASSERT(call);
2589
0
  wLog* log = scard_log();
2590
2591
0
  call->rgReaderStates = NULL;
2592
2593
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2594
0
                                                     &pbContextNdrPtr);
2595
0
  if (status != SCARD_S_SUCCESS)
2596
0
    return status;
2597
2598
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2599
0
    return STATUS_BUFFER_TOO_SMALL;
2600
2601
0
  Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */
2602
0
  Stream_Read_UINT32(s, call->cReaders);  /* cReaders (4 bytes) */
2603
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &ndrPtr))
2604
0
    return ERROR_INVALID_DATA;
2605
2606
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2607
0
                                                    &(call->handles.hContext));
2608
0
  if (status != SCARD_S_SUCCESS)
2609
0
    return status;
2610
2611
0
  if (ndrPtr)
2612
0
  {
2613
0
    status =
2614
0
        smartcard_unpack_reader_state_a(log, s, &call->rgReaderStates, call->cReaders, &index);
2615
0
    if (status != SCARD_S_SUCCESS)
2616
0
      return status;
2617
0
  }
2618
0
  else
2619
0
  {
2620
0
    WLog_Print(log, WLOG_WARN, "ndrPtr=0x%08" PRIx32 ", can not read rgReaderStates", ndrPtr);
2621
0
    return SCARD_E_UNEXPECTED;
2622
0
  }
2623
2624
0
  smartcard_trace_get_status_change_a_call(log, call);
2625
0
  return SCARD_S_SUCCESS;
2626
0
}
2627
2628
LONG smartcard_unpack_get_status_change_w_call(wStream* s, GetStatusChangeW_Call* call)
2629
0
{
2630
0
  UINT32 ndrPtr = 0;
2631
0
  UINT32 index = 0;
2632
0
  UINT32 pbContextNdrPtr = 0;
2633
2634
0
  WINPR_ASSERT(call);
2635
0
  wLog* log = scard_log();
2636
0
  call->rgReaderStates = NULL;
2637
2638
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2639
0
                                                     &pbContextNdrPtr);
2640
0
  if (status != SCARD_S_SUCCESS)
2641
0
    return status;
2642
2643
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2644
0
    return STATUS_BUFFER_TOO_SMALL;
2645
2646
0
  Stream_Read_UINT32(s, call->dwTimeOut); /* dwTimeOut (4 bytes) */
2647
0
  Stream_Read_UINT32(s, call->cReaders);  /* cReaders (4 bytes) */
2648
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &ndrPtr))
2649
0
    return ERROR_INVALID_DATA;
2650
2651
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2652
0
                                                    &(call->handles.hContext));
2653
0
  if (status != SCARD_S_SUCCESS)
2654
0
    return status;
2655
2656
0
  if (ndrPtr)
2657
0
  {
2658
0
    status =
2659
0
        smartcard_unpack_reader_state_w(log, s, &call->rgReaderStates, call->cReaders, &index);
2660
0
    if (status != SCARD_S_SUCCESS)
2661
0
      return status;
2662
0
  }
2663
0
  else
2664
0
  {
2665
0
    WLog_Print(log, WLOG_WARN, "ndrPtr=0x%08" PRIx32 ", can not read rgReaderStates", ndrPtr);
2666
0
    return SCARD_E_UNEXPECTED;
2667
0
  }
2668
2669
0
  smartcard_trace_get_status_change_w_call(log, call);
2670
0
  return SCARD_S_SUCCESS;
2671
0
}
2672
2673
LONG smartcard_pack_get_status_change_return(wStream* s, const GetStatusChange_Return* ret,
2674
                                             BOOL unicode)
2675
0
{
2676
0
  WINPR_ASSERT(ret);
2677
0
  wLog* log = scard_log();
2678
2679
0
  LONG status = 0;
2680
0
  DWORD cReaders = ret->cReaders;
2681
0
  UINT32 index = 0;
2682
2683
0
  smartcard_trace_get_status_change_return(log, ret, unicode);
2684
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
2685
0
    cReaders = 0;
2686
0
  if (cReaders == SCARD_AUTOALLOCATE)
2687
0
    cReaders = 0;
2688
2689
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
2690
0
    return SCARD_E_NO_MEMORY;
2691
2692
0
  Stream_Write_UINT32(s, cReaders); /* cReaders (4 bytes) */
2693
0
  if (!smartcard_ndr_pointer_write(s, &index, cReaders))
2694
0
    return SCARD_E_NO_MEMORY;
2695
0
  status = smartcard_ndr_write_state(s, ret->rgReaderStates, cReaders, NDR_PTR_SIMPLE);
2696
0
  if (status != SCARD_S_SUCCESS)
2697
0
    return status;
2698
0
  return ret->ReturnCode;
2699
0
}
2700
2701
LONG smartcard_unpack_state_call(wStream* s, State_Call* call)
2702
0
{
2703
0
  UINT32 index = 0;
2704
0
  UINT32 pbContextNdrPtr = 0;
2705
2706
0
  wLog* log = scard_log();
2707
2708
0
  WINPR_ASSERT(call);
2709
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2710
0
                                                     &pbContextNdrPtr);
2711
0
  if (status != SCARD_S_SUCCESS)
2712
0
    return status;
2713
2714
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
2715
0
  if (status != SCARD_S_SUCCESS)
2716
0
    return status;
2717
2718
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
2719
0
    return STATUS_BUFFER_TOO_SMALL;
2720
2721
0
  Stream_Read_INT32(s, call->fpbAtrIsNULL); /* fpbAtrIsNULL (4 bytes) */
2722
0
  Stream_Read_UINT32(s, call->cbAtrLen);    /* cbAtrLen (4 bytes) */
2723
2724
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2725
0
                                                    &(call->handles.hContext));
2726
0
  if (status != SCARD_S_SUCCESS)
2727
0
    return status;
2728
2729
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
2730
0
  if (status != SCARD_S_SUCCESS)
2731
0
    return status;
2732
2733
0
  return status;
2734
0
}
2735
2736
LONG smartcard_pack_state_return(wStream* s, const State_Return* ret)
2737
0
{
2738
0
  WINPR_ASSERT(ret);
2739
0
  wLog* log = scard_log();
2740
0
  LONG status = 0;
2741
0
  DWORD cbAtrLen = ret->cbAtrLen;
2742
0
  UINT32 index = 0;
2743
2744
0
  smartcard_trace_state_return(log, ret);
2745
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
2746
0
    cbAtrLen = 0;
2747
0
  if (cbAtrLen == SCARD_AUTOALLOCATE)
2748
0
    cbAtrLen = 0;
2749
2750
0
  Stream_Write_UINT32(s, ret->dwState);    /* dwState (4 bytes) */
2751
0
  Stream_Write_UINT32(s, ret->dwProtocol); /* dwProtocol (4 bytes) */
2752
0
  Stream_Write_UINT32(s, cbAtrLen);        /* cbAtrLen (4 bytes) */
2753
0
  if (!smartcard_ndr_pointer_write(s, &index, cbAtrLen))
2754
0
    return SCARD_E_NO_MEMORY;
2755
0
  status = smartcard_ndr_write(s, ret->rgAtr, cbAtrLen, 1, NDR_PTR_SIMPLE);
2756
0
  if (status != SCARD_S_SUCCESS)
2757
0
    return status;
2758
0
  return ret->ReturnCode;
2759
0
}
2760
2761
LONG smartcard_unpack_status_call(wStream* s, Status_Call* call, BOOL unicode)
2762
0
{
2763
0
  UINT32 index = 0;
2764
0
  UINT32 pbContextNdrPtr = 0;
2765
2766
0
  WINPR_ASSERT(call);
2767
0
  wLog* log = scard_log();
2768
2769
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2770
0
                                                     &pbContextNdrPtr);
2771
0
  if (status != SCARD_S_SUCCESS)
2772
0
    return status;
2773
2774
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
2775
0
  if (status != SCARD_S_SUCCESS)
2776
0
    return status;
2777
2778
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 12))
2779
0
    return STATUS_BUFFER_TOO_SMALL;
2780
2781
0
  Stream_Read_INT32(s, call->fmszReaderNamesIsNULL); /* fmszReaderNamesIsNULL (4 bytes) */
2782
0
  Stream_Read_UINT32(s, call->cchReaderLen);         /* cchReaderLen (4 bytes) */
2783
0
  Stream_Read_UINT32(s, call->cbAtrLen);             /* cbAtrLen (4 bytes) */
2784
2785
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2786
0
                                                    &(call->handles.hContext));
2787
0
  if (status != SCARD_S_SUCCESS)
2788
0
    return status;
2789
2790
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
2791
0
  if (status != SCARD_S_SUCCESS)
2792
0
    return status;
2793
2794
0
  smartcard_trace_status_call(log, call, unicode);
2795
0
  return status;
2796
0
}
2797
2798
LONG smartcard_pack_status_return(wStream* s, const Status_Return* ret, BOOL unicode)
2799
0
{
2800
0
  WINPR_ASSERT(ret);
2801
0
  wLog* log = scard_log();
2802
2803
0
  LONG status = 0;
2804
0
  UINT32 index = 0;
2805
0
  DWORD cBytes = ret->cBytes;
2806
2807
0
  smartcard_trace_status_return(log, ret, unicode);
2808
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
2809
0
    cBytes = 0;
2810
0
  if (cBytes == SCARD_AUTOALLOCATE)
2811
0
    cBytes = 0;
2812
2813
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
2814
0
    return SCARD_F_INTERNAL_ERROR;
2815
2816
0
  Stream_Write_UINT32(s, cBytes); /* cBytes (4 bytes) */
2817
0
  if (!smartcard_ndr_pointer_write(s, &index, cBytes))
2818
0
    return SCARD_E_NO_MEMORY;
2819
2820
0
  if (!Stream_EnsureRemainingCapacity(s, 44))
2821
0
    return SCARD_F_INTERNAL_ERROR;
2822
2823
0
  Stream_Write_UINT32(s, ret->dwState);            /* dwState (4 bytes) */
2824
0
  Stream_Write_UINT32(s, ret->dwProtocol);         /* dwProtocol (4 bytes) */
2825
0
  Stream_Write(s, ret->pbAtr, sizeof(ret->pbAtr)); /* pbAtr (32 bytes) */
2826
0
  Stream_Write_UINT32(s, ret->cbAtrLen);           /* cbAtrLen (4 bytes) */
2827
0
  status = smartcard_ndr_write(s, ret->mszReaderNames, cBytes, 1, NDR_PTR_SIMPLE);
2828
0
  if (status != SCARD_S_SUCCESS)
2829
0
    return status;
2830
0
  return ret->ReturnCode;
2831
0
}
2832
2833
LONG smartcard_unpack_get_attrib_call(wStream* s, GetAttrib_Call* call)
2834
0
{
2835
0
  WINPR_ASSERT(call);
2836
0
  wLog* log = scard_log();
2837
0
  UINT32 index = 0;
2838
0
  UINT32 pbContextNdrPtr = 0;
2839
2840
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2841
0
                                                     &pbContextNdrPtr);
2842
0
  if (status != SCARD_S_SUCCESS)
2843
0
    return status;
2844
2845
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
2846
0
  if (status != SCARD_S_SUCCESS)
2847
0
    return status;
2848
2849
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 12))
2850
0
    return STATUS_BUFFER_TOO_SMALL;
2851
2852
0
  Stream_Read_UINT32(s, call->dwAttrId);     /* dwAttrId (4 bytes) */
2853
0
  Stream_Read_INT32(s, call->fpbAttrIsNULL); /* fpbAttrIsNULL (4 bytes) */
2854
0
  Stream_Read_UINT32(s, call->cbAttrLen);    /* cbAttrLen (4 bytes) */
2855
2856
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2857
0
                                                    &(call->handles.hContext));
2858
0
  if (status != SCARD_S_SUCCESS)
2859
0
    return status;
2860
2861
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
2862
0
  if (status != SCARD_S_SUCCESS)
2863
0
    return status;
2864
2865
0
  smartcard_trace_get_attrib_call(log, call);
2866
0
  return status;
2867
0
}
2868
2869
LONG smartcard_pack_get_attrib_return(wStream* s, const GetAttrib_Return* ret, DWORD dwAttrId,
2870
                                      DWORD cbAttrCallLen)
2871
0
{
2872
0
  WINPR_ASSERT(ret);
2873
0
  wLog* log = scard_log();
2874
0
  LONG status = 0;
2875
0
  DWORD cbAttrLen = 0;
2876
0
  UINT32 index = 0;
2877
0
  smartcard_trace_get_attrib_return(log, ret, dwAttrId);
2878
2879
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
2880
0
    return SCARD_F_INTERNAL_ERROR;
2881
2882
0
  cbAttrLen = ret->cbAttrLen;
2883
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
2884
0
    cbAttrLen = 0;
2885
0
  if (cbAttrLen == SCARD_AUTOALLOCATE)
2886
0
    cbAttrLen = 0;
2887
2888
0
  if (ret->pbAttr)
2889
0
  {
2890
0
    if (cbAttrCallLen < cbAttrLen)
2891
0
      cbAttrLen = cbAttrCallLen;
2892
0
  }
2893
0
  Stream_Write_UINT32(s, cbAttrLen); /* cbAttrLen (4 bytes) */
2894
0
  if (!smartcard_ndr_pointer_write(s, &index, cbAttrLen))
2895
0
    return SCARD_E_NO_MEMORY;
2896
2897
0
  status = smartcard_ndr_write(s, ret->pbAttr, cbAttrLen, 1, NDR_PTR_SIMPLE);
2898
0
  if (status != SCARD_S_SUCCESS)
2899
0
    return status;
2900
0
  return ret->ReturnCode;
2901
0
}
2902
2903
LONG smartcard_unpack_control_call(wStream* s, Control_Call* call)
2904
0
{
2905
0
  WINPR_ASSERT(call);
2906
0
  wLog* log = scard_log();
2907
2908
0
  UINT32 index = 0;
2909
0
  UINT32 pvInBufferNdrPtr = 0;
2910
0
  UINT32 pbContextNdrPtr = 0;
2911
2912
0
  call->pvInBuffer = NULL;
2913
2914
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
2915
0
                                                     &pbContextNdrPtr);
2916
0
  if (status != SCARD_S_SUCCESS)
2917
0
    return status;
2918
2919
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
2920
0
  if (status != SCARD_S_SUCCESS)
2921
0
    return status;
2922
2923
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 20))
2924
0
    return STATUS_BUFFER_TOO_SMALL;
2925
2926
0
  Stream_Read_UINT32(s, call->dwControlCode);                    /* dwControlCode (4 bytes) */
2927
0
  Stream_Read_UINT32(s, call->cbInBufferSize);                   /* cbInBufferSize (4 bytes) */
2928
0
  if (!smartcard_ndr_pointer_read(log, s, &index,
2929
0
                                  &pvInBufferNdrPtr)) /* pvInBufferNdrPtr (4 bytes) */
2930
0
    return ERROR_INVALID_DATA;
2931
0
  Stream_Read_INT32(s, call->fpvOutBufferIsNULL); /* fpvOutBufferIsNULL (4 bytes) */
2932
0
  Stream_Read_UINT32(s, call->cbOutBufferSize);   /* cbOutBufferSize (4 bytes) */
2933
2934
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
2935
0
                                                    &(call->handles.hContext));
2936
0
  if (status != SCARD_S_SUCCESS)
2937
0
    return status;
2938
2939
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
2940
0
  if (status != SCARD_S_SUCCESS)
2941
0
    return status;
2942
2943
0
  if (pvInBufferNdrPtr)
2944
0
  {
2945
0
    status =
2946
0
        smartcard_ndr_read(log, s, &call->pvInBuffer, call->cbInBufferSize, 1, NDR_PTR_SIMPLE);
2947
0
    if (status != SCARD_S_SUCCESS)
2948
0
      return status;
2949
0
  }
2950
2951
0
  smartcard_trace_control_call(log, call);
2952
0
  return SCARD_S_SUCCESS;
2953
0
}
2954
2955
LONG smartcard_pack_control_return(wStream* s, const Control_Return* ret)
2956
0
{
2957
0
  WINPR_ASSERT(ret);
2958
0
  wLog* log = scard_log();
2959
2960
0
  LONG status = 0;
2961
0
  DWORD cbDataLen = ret->cbOutBufferSize;
2962
0
  UINT32 index = 0;
2963
2964
0
  smartcard_trace_control_return(log, ret);
2965
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
2966
0
    cbDataLen = 0;
2967
0
  if (cbDataLen == SCARD_AUTOALLOCATE)
2968
0
    cbDataLen = 0;
2969
2970
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
2971
0
    return SCARD_F_INTERNAL_ERROR;
2972
2973
0
  Stream_Write_UINT32(s, cbDataLen); /* cbOutBufferSize (4 bytes) */
2974
0
  if (!smartcard_ndr_pointer_write(s, &index, cbDataLen))
2975
0
    return SCARD_E_NO_MEMORY;
2976
2977
0
  status = smartcard_ndr_write(s, ret->pvOutBuffer, cbDataLen, 1, NDR_PTR_SIMPLE);
2978
0
  if (status != SCARD_S_SUCCESS)
2979
0
    return status;
2980
0
  return ret->ReturnCode;
2981
0
}
2982
2983
LONG smartcard_unpack_transmit_call(wStream* s, Transmit_Call* call)
2984
0
{
2985
0
  UINT32 length = 0;
2986
0
  BYTE* pbExtraBytes = NULL;
2987
0
  UINT32 pbExtraBytesNdrPtr = 0;
2988
0
  UINT32 pbSendBufferNdrPtr = 0;
2989
0
  UINT32 pioRecvPciNdrPtr = 0;
2990
0
  SCardIO_Request ioSendPci;
2991
0
  SCardIO_Request ioRecvPci;
2992
0
  UINT32 index = 0;
2993
0
  UINT32 pbContextNdrPtr = 0;
2994
2995
0
  WINPR_ASSERT(call);
2996
0
  wLog* log = scard_log();
2997
2998
0
  call->pioSendPci = NULL;
2999
0
  call->pioRecvPci = NULL;
3000
0
  call->pbSendBuffer = NULL;
3001
3002
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3003
0
                                                     &pbContextNdrPtr);
3004
0
  if (status != SCARD_S_SUCCESS)
3005
0
    return status;
3006
3007
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
3008
0
  if (status != SCARD_S_SUCCESS)
3009
0
    return status;
3010
3011
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 32))
3012
0
    return STATUS_BUFFER_TOO_SMALL;
3013
3014
0
  Stream_Read_UINT32(s, ioSendPci.dwProtocol);   /* dwProtocol (4 bytes) */
3015
0
  Stream_Read_UINT32(s, ioSendPci.cbExtraBytes); /* cbExtraBytes (4 bytes) */
3016
0
  if (!smartcard_ndr_pointer_read(log, s, &index,
3017
0
                                  &pbExtraBytesNdrPtr)) /* pbExtraBytesNdrPtr (4 bytes) */
3018
0
    return ERROR_INVALID_DATA;
3019
3020
0
  Stream_Read_UINT32(s, call->cbSendLength); /* cbSendLength (4 bytes) */
3021
0
  if (!smartcard_ndr_pointer_read(log, s, &index,
3022
0
                                  &pbSendBufferNdrPtr)) /* pbSendBufferNdrPtr (4 bytes) */
3023
0
    return ERROR_INVALID_DATA;
3024
3025
0
  if (!smartcard_ndr_pointer_read(log, s, &index,
3026
0
                                  &pioRecvPciNdrPtr)) /* pioRecvPciNdrPtr (4 bytes) */
3027
0
    return ERROR_INVALID_DATA;
3028
3029
0
  Stream_Read_INT32(s, call->fpbRecvBufferIsNULL); /* fpbRecvBufferIsNULL (4 bytes) */
3030
0
  Stream_Read_UINT32(s, call->cbRecvLength);       /* cbRecvLength (4 bytes) */
3031
3032
0
  if (ioSendPci.cbExtraBytes > 1024)
3033
0
  {
3034
0
    WLog_Print(log, WLOG_WARN,
3035
0
               "Transmit_Call ioSendPci.cbExtraBytes is out of bounds: %" PRIu32 " (max: 1024)",
3036
0
               ioSendPci.cbExtraBytes);
3037
0
    return STATUS_INVALID_PARAMETER;
3038
0
  }
3039
3040
0
  if (call->cbSendLength > 66560)
3041
0
  {
3042
0
    WLog_Print(log, WLOG_WARN,
3043
0
               "Transmit_Call cbSendLength is out of bounds: %" PRIu32 " (max: 66560)",
3044
0
               ioSendPci.cbExtraBytes);
3045
0
    return STATUS_INVALID_PARAMETER;
3046
0
  }
3047
3048
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3049
0
                                                    &(call->handles.hContext));
3050
0
  if (status != SCARD_S_SUCCESS)
3051
0
    return status;
3052
3053
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
3054
0
  if (status != SCARD_S_SUCCESS)
3055
0
    return status;
3056
3057
0
  if (ioSendPci.cbExtraBytes && !pbExtraBytesNdrPtr)
3058
0
  {
3059
0
    WLog_Print(
3060
0
        log, WLOG_WARN,
3061
0
        "Transmit_Call ioSendPci.cbExtraBytes is non-zero but pbExtraBytesNdrPtr is null");
3062
0
    return STATUS_INVALID_PARAMETER;
3063
0
  }
3064
3065
0
  if (pbExtraBytesNdrPtr)
3066
0
  {
3067
    // TODO: Use unified pointer reading
3068
0
    if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3069
0
      return STATUS_BUFFER_TOO_SMALL;
3070
3071
0
    Stream_Read_UINT32(s, length); /* Length (4 bytes) */
3072
3073
0
    if (!Stream_CheckAndLogRequiredLengthWLog(log, s, ioSendPci.cbExtraBytes))
3074
0
      return STATUS_BUFFER_TOO_SMALL;
3075
3076
0
    ioSendPci.pbExtraBytes = Stream_Pointer(s);
3077
0
    call->pioSendPci =
3078
0
        (LPSCARD_IO_REQUEST)malloc(sizeof(SCARD_IO_REQUEST) + ioSendPci.cbExtraBytes);
3079
3080
0
    if (!call->pioSendPci)
3081
0
    {
3082
0
      WLog_Print(log, WLOG_WARN, "Transmit_Call out of memory error (pioSendPci)");
3083
0
      return STATUS_NO_MEMORY;
3084
0
    }
3085
3086
0
    call->pioSendPci->dwProtocol = ioSendPci.dwProtocol;
3087
0
    call->pioSendPci->cbPciLength = (DWORD)(ioSendPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST));
3088
0
    pbExtraBytes = &((BYTE*)call->pioSendPci)[sizeof(SCARD_IO_REQUEST)];
3089
0
    Stream_Read(s, pbExtraBytes, ioSendPci.cbExtraBytes);
3090
0
    if (smartcard_unpack_read_size_align(s, ioSendPci.cbExtraBytes, 4) < 0)
3091
0
      return STATUS_INVALID_PARAMETER;
3092
0
  }
3093
0
  else
3094
0
  {
3095
0
    call->pioSendPci = (LPSCARD_IO_REQUEST)calloc(1, sizeof(SCARD_IO_REQUEST));
3096
3097
0
    if (!call->pioSendPci)
3098
0
    {
3099
0
      WLog_Print(log, WLOG_WARN, "Transmit_Call out of memory error (pioSendPci)");
3100
0
      return STATUS_NO_MEMORY;
3101
0
    }
3102
3103
0
    call->pioSendPci->dwProtocol = ioSendPci.dwProtocol;
3104
0
    call->pioSendPci->cbPciLength = sizeof(SCARD_IO_REQUEST);
3105
0
  }
3106
3107
0
  if (pbSendBufferNdrPtr)
3108
0
  {
3109
0
    status =
3110
0
        smartcard_ndr_read(log, s, &call->pbSendBuffer, call->cbSendLength, 1, NDR_PTR_SIMPLE);
3111
0
    if (status != SCARD_S_SUCCESS)
3112
0
      return status;
3113
0
  }
3114
3115
0
  if (pioRecvPciNdrPtr)
3116
0
  {
3117
0
    if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 12))
3118
0
      return STATUS_BUFFER_TOO_SMALL;
3119
3120
0
    Stream_Read_UINT32(s, ioRecvPci.dwProtocol);   /* dwProtocol (4 bytes) */
3121
0
    Stream_Read_UINT32(s, ioRecvPci.cbExtraBytes); /* cbExtraBytes (4 bytes) */
3122
0
    if (!smartcard_ndr_pointer_read(log, s, &index,
3123
0
                                    &pbExtraBytesNdrPtr)) /* pbExtraBytesNdrPtr (4 bytes) */
3124
0
      return ERROR_INVALID_DATA;
3125
3126
0
    if (ioRecvPci.cbExtraBytes && !pbExtraBytesNdrPtr)
3127
0
    {
3128
0
      WLog_Print(
3129
0
          log, WLOG_WARN,
3130
0
          "Transmit_Call ioRecvPci.cbExtraBytes is non-zero but pbExtraBytesNdrPtr is null");
3131
0
      return STATUS_INVALID_PARAMETER;
3132
0
    }
3133
3134
0
    if (pbExtraBytesNdrPtr)
3135
0
    {
3136
      // TODO: Unify ndr pointer reading
3137
0
      if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
3138
0
        return STATUS_BUFFER_TOO_SMALL;
3139
3140
0
      Stream_Read_UINT32(s, length); /* Length (4 bytes) */
3141
3142
0
      if (ioRecvPci.cbExtraBytes > 1024)
3143
0
      {
3144
0
        WLog_Print(log, WLOG_WARN,
3145
0
                   "Transmit_Call ioRecvPci.cbExtraBytes is out of bounds: %" PRIu32
3146
0
                   " (max: 1024)",
3147
0
                   ioRecvPci.cbExtraBytes);
3148
0
        return STATUS_INVALID_PARAMETER;
3149
0
      }
3150
3151
0
      if (length != ioRecvPci.cbExtraBytes)
3152
0
      {
3153
0
        WLog_Print(log, WLOG_WARN,
3154
0
                   "Transmit_Call unexpected length: Actual: %" PRIu32
3155
0
                   ", Expected: %" PRIu32 " (ioRecvPci.cbExtraBytes)",
3156
0
                   length, ioRecvPci.cbExtraBytes);
3157
0
        return STATUS_INVALID_PARAMETER;
3158
0
      }
3159
3160
0
      if (!Stream_CheckAndLogRequiredLengthWLog(log, s, ioRecvPci.cbExtraBytes))
3161
0
        return STATUS_BUFFER_TOO_SMALL;
3162
3163
0
      ioRecvPci.pbExtraBytes = Stream_Pointer(s);
3164
0
      call->pioRecvPci =
3165
0
          (LPSCARD_IO_REQUEST)malloc(sizeof(SCARD_IO_REQUEST) + ioRecvPci.cbExtraBytes);
3166
3167
0
      if (!call->pioRecvPci)
3168
0
      {
3169
0
        WLog_Print(log, WLOG_WARN, "Transmit_Call out of memory error (pioRecvPci)");
3170
0
        return STATUS_NO_MEMORY;
3171
0
      }
3172
3173
0
      call->pioRecvPci->dwProtocol = ioRecvPci.dwProtocol;
3174
0
      call->pioRecvPci->cbPciLength =
3175
0
          (DWORD)(ioRecvPci.cbExtraBytes + sizeof(SCARD_IO_REQUEST));
3176
0
      pbExtraBytes = &((BYTE*)call->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
3177
0
      Stream_Read(s, pbExtraBytes, ioRecvPci.cbExtraBytes);
3178
0
      if (smartcard_unpack_read_size_align(s, ioRecvPci.cbExtraBytes, 4) < 0)
3179
0
        return STATUS_INVALID_PARAMETER;
3180
0
    }
3181
0
    else
3182
0
    {
3183
0
      call->pioRecvPci = (LPSCARD_IO_REQUEST)calloc(1, sizeof(SCARD_IO_REQUEST));
3184
3185
0
      if (!call->pioRecvPci)
3186
0
      {
3187
0
        WLog_Print(log, WLOG_WARN, "Transmit_Call out of memory error (pioRecvPci)");
3188
0
        return STATUS_NO_MEMORY;
3189
0
      }
3190
3191
0
      call->pioRecvPci->dwProtocol = ioRecvPci.dwProtocol;
3192
0
      call->pioRecvPci->cbPciLength = sizeof(SCARD_IO_REQUEST);
3193
0
    }
3194
0
  }
3195
3196
0
  smartcard_trace_transmit_call(log, call);
3197
0
  return SCARD_S_SUCCESS;
3198
0
}
3199
3200
LONG smartcard_pack_transmit_return(wStream* s, const Transmit_Return* ret)
3201
0
{
3202
0
  WINPR_ASSERT(ret);
3203
0
  wLog* log = scard_log();
3204
3205
0
  LONG status = 0;
3206
0
  UINT32 index = 0;
3207
0
  LONG error = 0;
3208
0
  UINT32 cbRecvLength = ret->cbRecvLength;
3209
0
  UINT32 cbRecvPci = ret->pioRecvPci ? ret->pioRecvPci->cbPciLength : 0;
3210
3211
0
  smartcard_trace_transmit_return(log, ret);
3212
3213
0
  if (!ret->pbRecvBuffer)
3214
0
    cbRecvLength = 0;
3215
3216
0
  if (!smartcard_ndr_pointer_write(s, &index, cbRecvPci))
3217
0
    return SCARD_E_NO_MEMORY;
3218
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
3219
0
    return SCARD_E_NO_MEMORY;
3220
0
  Stream_Write_UINT32(s, cbRecvLength); /* cbRecvLength (4 bytes) */
3221
0
  if (!smartcard_ndr_pointer_write(s, &index, cbRecvLength))
3222
0
    return SCARD_E_NO_MEMORY;
3223
3224
0
  if (ret->pioRecvPci)
3225
0
  {
3226
0
    UINT32 cbExtraBytes = (UINT32)(ret->pioRecvPci->cbPciLength - sizeof(SCARD_IO_REQUEST));
3227
0
    BYTE* pbExtraBytes = &((BYTE*)ret->pioRecvPci)[sizeof(SCARD_IO_REQUEST)];
3228
3229
0
    if (!Stream_EnsureRemainingCapacity(s, cbExtraBytes + 16))
3230
0
    {
3231
0
      WLog_Print(log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
3232
0
      return SCARD_F_INTERNAL_ERROR;
3233
0
    }
3234
3235
0
    Stream_Write_UINT32(s, ret->pioRecvPci->dwProtocol); /* dwProtocol (4 bytes) */
3236
0
    Stream_Write_UINT32(s, cbExtraBytes);                /* cbExtraBytes (4 bytes) */
3237
0
    if (!smartcard_ndr_pointer_write(s, &index, cbExtraBytes))
3238
0
      return SCARD_E_NO_MEMORY;
3239
0
    error = smartcard_ndr_write(s, pbExtraBytes, cbExtraBytes, 1, NDR_PTR_SIMPLE);
3240
0
    if (error)
3241
0
      return error;
3242
0
  }
3243
3244
0
  status = smartcard_ndr_write(s, ret->pbRecvBuffer, ret->cbRecvLength, 1, NDR_PTR_SIMPLE);
3245
0
  if (status != SCARD_S_SUCCESS)
3246
0
    return status;
3247
0
  return ret->ReturnCode;
3248
0
}
3249
3250
LONG smartcard_unpack_locate_cards_by_atr_a_call(wStream* s, LocateCardsByATRA_Call* call)
3251
0
{
3252
0
  UINT32 rgReaderStatesNdrPtr = 0;
3253
0
  UINT32 rgAtrMasksNdrPtr = 0;
3254
0
  UINT32 index = 0;
3255
0
  UINT32 pbContextNdrPtr = 0;
3256
3257
0
  WINPR_ASSERT(call);
3258
0
  wLog* log = scard_log();
3259
3260
0
  call->rgReaderStates = NULL;
3261
3262
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3263
0
                                                     &pbContextNdrPtr);
3264
0
  if (status != SCARD_S_SUCCESS)
3265
0
    return status;
3266
3267
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3268
0
    return STATUS_BUFFER_TOO_SMALL;
3269
3270
0
  Stream_Read_UINT32(s, call->cAtrs);
3271
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &rgAtrMasksNdrPtr))
3272
0
    return ERROR_INVALID_DATA;
3273
0
  Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */
3274
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &rgReaderStatesNdrPtr))
3275
0
    return ERROR_INVALID_DATA;
3276
3277
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3278
0
                                                    &(call->handles.hContext));
3279
0
  if (status != SCARD_S_SUCCESS)
3280
0
    return status;
3281
3282
0
  if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs))
3283
0
  {
3284
0
    WLog_Print(log, WLOG_WARN,
3285
0
               "LocateCardsByATRA_Call rgAtrMasksNdrPtr (0x%08" PRIX32
3286
0
               ") and cAtrs (0x%08" PRIX32 ") inconsistency",
3287
0
               rgAtrMasksNdrPtr, call->cAtrs);
3288
0
    return STATUS_INVALID_PARAMETER;
3289
0
  }
3290
3291
0
  if (rgAtrMasksNdrPtr)
3292
0
  {
3293
0
    status = smartcard_ndr_read_atrmask(log, s, &call->rgAtrMasks, call->cAtrs, NDR_PTR_SIMPLE);
3294
0
    if (status != SCARD_S_SUCCESS)
3295
0
      return status;
3296
0
  }
3297
3298
0
  if (rgReaderStatesNdrPtr)
3299
0
  {
3300
0
    status =
3301
0
        smartcard_unpack_reader_state_a(log, s, &call->rgReaderStates, call->cReaders, &index);
3302
0
    if (status != SCARD_S_SUCCESS)
3303
0
      return status;
3304
0
  }
3305
3306
0
  smartcard_trace_locate_cards_by_atr_a_call(log, call);
3307
0
  return SCARD_S_SUCCESS;
3308
0
}
3309
3310
LONG smartcard_unpack_context_and_two_strings_a_call(wStream* s, ContextAndTwoStringA_Call* call)
3311
0
{
3312
0
  UINT32 sz1NdrPtr = 0;
3313
0
  UINT32 sz2NdrPtr = 0;
3314
0
  UINT32 index = 0;
3315
0
  UINT32 pbContextNdrPtr = 0;
3316
3317
0
  WINPR_ASSERT(call);
3318
0
  wLog* log = scard_log();
3319
3320
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3321
0
                                                     &pbContextNdrPtr);
3322
0
  if (status != SCARD_S_SUCCESS)
3323
0
    return status;
3324
3325
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &sz1NdrPtr))
3326
0
    return ERROR_INVALID_DATA;
3327
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &sz2NdrPtr))
3328
0
    return ERROR_INVALID_DATA;
3329
3330
0
  status =
3331
0
      smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr, &call->handles.hContext);
3332
0
  if (status != SCARD_S_SUCCESS)
3333
0
    return status;
3334
3335
0
  if (sz1NdrPtr)
3336
0
  {
3337
0
    status = smartcard_ndr_read_a(log, s, &call->sz1, NDR_PTR_FULL);
3338
0
    if (status != SCARD_S_SUCCESS)
3339
0
      return status;
3340
0
  }
3341
0
  if (sz2NdrPtr)
3342
0
  {
3343
0
    status = smartcard_ndr_read_a(log, s, &call->sz2, NDR_PTR_FULL);
3344
0
    if (status != SCARD_S_SUCCESS)
3345
0
      return status;
3346
0
  }
3347
0
  smartcard_trace_context_and_two_strings_a_call(log, call);
3348
0
  return SCARD_S_SUCCESS;
3349
0
}
3350
3351
LONG smartcard_unpack_context_and_two_strings_w_call(wStream* s, ContextAndTwoStringW_Call* call)
3352
0
{
3353
0
  UINT32 sz1NdrPtr = 0;
3354
0
  UINT32 sz2NdrPtr = 0;
3355
0
  UINT32 index = 0;
3356
0
  UINT32 pbContextNdrPtr = 0;
3357
3358
0
  WINPR_ASSERT(call);
3359
0
  wLog* log = scard_log();
3360
3361
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3362
0
                                                     &pbContextNdrPtr);
3363
0
  if (status != SCARD_S_SUCCESS)
3364
0
    return status;
3365
3366
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &sz1NdrPtr))
3367
0
    return ERROR_INVALID_DATA;
3368
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &sz2NdrPtr))
3369
0
    return ERROR_INVALID_DATA;
3370
3371
0
  status =
3372
0
      smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr, &call->handles.hContext);
3373
0
  if (status != SCARD_S_SUCCESS)
3374
0
    return status;
3375
3376
0
  if (sz1NdrPtr)
3377
0
  {
3378
0
    status = smartcard_ndr_read_w(log, s, &call->sz1, NDR_PTR_FULL);
3379
0
    if (status != SCARD_S_SUCCESS)
3380
0
      return status;
3381
0
  }
3382
0
  if (sz2NdrPtr)
3383
0
  {
3384
0
    status = smartcard_ndr_read_w(log, s, &call->sz2, NDR_PTR_FULL);
3385
0
    if (status != SCARD_S_SUCCESS)
3386
0
      return status;
3387
0
  }
3388
0
  smartcard_trace_context_and_two_strings_w_call(log, call);
3389
0
  return SCARD_S_SUCCESS;
3390
0
}
3391
3392
LONG smartcard_unpack_locate_cards_a_call(wStream* s, LocateCardsA_Call* call)
3393
0
{
3394
0
  UINT32 sz1NdrPtr = 0;
3395
0
  UINT32 sz2NdrPtr = 0;
3396
0
  UINT32 index = 0;
3397
0
  UINT32 pbContextNdrPtr = 0;
3398
3399
0
  WINPR_ASSERT(call);
3400
0
  wLog* log = scard_log();
3401
3402
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3403
0
                                                     &pbContextNdrPtr);
3404
0
  if (status != SCARD_S_SUCCESS)
3405
0
    return status;
3406
3407
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3408
0
    return STATUS_BUFFER_TOO_SMALL;
3409
3410
0
  Stream_Read_UINT32(s, call->cBytes);
3411
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &sz1NdrPtr))
3412
0
    return ERROR_INVALID_DATA;
3413
3414
0
  Stream_Read_UINT32(s, call->cReaders);
3415
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &sz2NdrPtr))
3416
0
    return ERROR_INVALID_DATA;
3417
3418
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3419
0
                                                    &(call->handles.hContext));
3420
0
  if (status != SCARD_S_SUCCESS)
3421
0
    return status;
3422
3423
0
  if (sz1NdrPtr)
3424
0
  {
3425
0
    status = smartcard_ndr_read_fixed_string_a(log, s, &call->mszCards, call->cBytes,
3426
0
                                               NDR_PTR_SIMPLE);
3427
0
    if (status != SCARD_S_SUCCESS)
3428
0
      return status;
3429
0
  }
3430
0
  if (sz2NdrPtr)
3431
0
  {
3432
0
    status =
3433
0
        smartcard_unpack_reader_state_a(log, s, &call->rgReaderStates, call->cReaders, &index);
3434
0
    if (status != SCARD_S_SUCCESS)
3435
0
      return status;
3436
0
  }
3437
0
  smartcard_trace_locate_cards_a_call(log, call);
3438
0
  return SCARD_S_SUCCESS;
3439
0
}
3440
3441
LONG smartcard_unpack_locate_cards_w_call(wStream* s, LocateCardsW_Call* call)
3442
0
{
3443
0
  UINT32 sz1NdrPtr = 0;
3444
0
  UINT32 sz2NdrPtr = 0;
3445
0
  UINT32 index = 0;
3446
0
  UINT32 pbContextNdrPtr = 0;
3447
3448
0
  WINPR_ASSERT(call);
3449
0
  wLog* log = scard_log();
3450
3451
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3452
0
                                                     &pbContextNdrPtr);
3453
0
  if (status != SCARD_S_SUCCESS)
3454
0
    return status;
3455
3456
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3457
0
    return STATUS_BUFFER_TOO_SMALL;
3458
3459
0
  Stream_Read_UINT32(s, call->cBytes);
3460
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &sz1NdrPtr))
3461
0
    return ERROR_INVALID_DATA;
3462
3463
0
  Stream_Read_UINT32(s, call->cReaders);
3464
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &sz2NdrPtr))
3465
0
    return ERROR_INVALID_DATA;
3466
3467
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3468
0
                                                    &(call->handles.hContext));
3469
0
  if (status != SCARD_S_SUCCESS)
3470
0
    return status;
3471
3472
0
  if (sz1NdrPtr)
3473
0
  {
3474
0
    status = smartcard_ndr_read_fixed_string_w(log, s, &call->mszCards, call->cBytes,
3475
0
                                               NDR_PTR_SIMPLE);
3476
0
    if (status != SCARD_S_SUCCESS)
3477
0
      return status;
3478
0
  }
3479
0
  if (sz2NdrPtr)
3480
0
  {
3481
0
    status =
3482
0
        smartcard_unpack_reader_state_w(log, s, &call->rgReaderStates, call->cReaders, &index);
3483
0
    if (status != SCARD_S_SUCCESS)
3484
0
      return status;
3485
0
  }
3486
0
  smartcard_trace_locate_cards_w_call(log, call);
3487
0
  return SCARD_S_SUCCESS;
3488
0
}
3489
3490
LONG smartcard_unpack_set_attrib_call(wStream* s, SetAttrib_Call* call)
3491
0
{
3492
0
  UINT32 index = 0;
3493
0
  UINT32 ndrPtr = 0;
3494
0
  UINT32 pbContextNdrPtr = 0;
3495
3496
0
  WINPR_ASSERT(call);
3497
0
  wLog* log = scard_log();
3498
3499
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3500
0
                                                     &pbContextNdrPtr);
3501
0
  if (status != SCARD_S_SUCCESS)
3502
0
    return status;
3503
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
3504
0
  if (status != SCARD_S_SUCCESS)
3505
0
    return status;
3506
3507
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 12))
3508
0
    return STATUS_BUFFER_TOO_SMALL;
3509
0
  Stream_Read_UINT32(s, call->dwAttrId);
3510
0
  Stream_Read_UINT32(s, call->cbAttrLen);
3511
3512
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &ndrPtr))
3513
0
    return ERROR_INVALID_DATA;
3514
3515
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3516
0
                                                    &(call->handles.hContext));
3517
0
  if (status != SCARD_S_SUCCESS)
3518
0
    return status;
3519
3520
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
3521
0
  if (status != SCARD_S_SUCCESS)
3522
0
    return status;
3523
3524
0
  if (ndrPtr)
3525
0
  {
3526
0
    size_t len = 0;
3527
0
    status = smartcard_ndr_read_ex(log, s, &call->pbAttr, 0, 1, NDR_PTR_SIMPLE, &len);
3528
0
    if (status != SCARD_S_SUCCESS)
3529
0
      return status;
3530
0
    if (call->cbAttrLen > len)
3531
0
      call->cbAttrLen = WINPR_ASSERTING_INT_CAST(DWORD, len);
3532
0
  }
3533
0
  else
3534
0
    call->cbAttrLen = 0;
3535
0
  smartcard_trace_set_attrib_call(log, call);
3536
0
  return SCARD_S_SUCCESS;
3537
0
}
3538
3539
LONG smartcard_unpack_locate_cards_by_atr_w_call(wStream* s, LocateCardsByATRW_Call* call)
3540
0
{
3541
0
  UINT32 rgReaderStatesNdrPtr = 0;
3542
0
  UINT32 rgAtrMasksNdrPtr = 0;
3543
0
  UINT32 index = 0;
3544
0
  UINT32 pbContextNdrPtr = 0;
3545
3546
0
  WINPR_ASSERT(call);
3547
0
  wLog* log = scard_log();
3548
3549
0
  call->rgReaderStates = NULL;
3550
3551
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3552
0
                                                     &pbContextNdrPtr);
3553
0
  if (status != SCARD_S_SUCCESS)
3554
0
    return status;
3555
3556
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 16))
3557
0
    return STATUS_BUFFER_TOO_SMALL;
3558
3559
0
  Stream_Read_UINT32(s, call->cAtrs);
3560
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &rgAtrMasksNdrPtr))
3561
0
    return ERROR_INVALID_DATA;
3562
3563
0
  Stream_Read_UINT32(s, call->cReaders); /* cReaders (4 bytes) */
3564
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &rgReaderStatesNdrPtr))
3565
0
    return ERROR_INVALID_DATA;
3566
3567
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3568
0
                                                    &(call->handles.hContext));
3569
0
  if (status != SCARD_S_SUCCESS)
3570
0
    return status;
3571
3572
0
  if ((rgAtrMasksNdrPtr && !call->cAtrs) || (!rgAtrMasksNdrPtr && call->cAtrs))
3573
0
  {
3574
0
    WLog_Print(log, WLOG_WARN,
3575
0
               "LocateCardsByATRW_Call rgAtrMasksNdrPtr (0x%08" PRIX32
3576
0
               ") and cAtrs (0x%08" PRIX32 ") inconsistency",
3577
0
               rgAtrMasksNdrPtr, call->cAtrs);
3578
0
    return STATUS_INVALID_PARAMETER;
3579
0
  }
3580
3581
0
  if (rgAtrMasksNdrPtr)
3582
0
  {
3583
0
    status = smartcard_ndr_read_atrmask(log, s, &call->rgAtrMasks, call->cAtrs, NDR_PTR_SIMPLE);
3584
0
    if (status != SCARD_S_SUCCESS)
3585
0
      return status;
3586
0
  }
3587
3588
0
  if (rgReaderStatesNdrPtr)
3589
0
  {
3590
0
    status =
3591
0
        smartcard_unpack_reader_state_w(log, s, &call->rgReaderStates, call->cReaders, &index);
3592
0
    if (status != SCARD_S_SUCCESS)
3593
0
      return status;
3594
0
  }
3595
3596
0
  smartcard_trace_locate_cards_by_atr_w_call(log, call);
3597
0
  return SCARD_S_SUCCESS;
3598
0
}
3599
3600
LONG smartcard_unpack_read_cache_a_call(wStream* s, ReadCacheA_Call* call)
3601
0
{
3602
0
  UINT32 mszNdrPtr = 0;
3603
0
  UINT32 contextNdrPtr = 0;
3604
0
  UINT32 index = 0;
3605
0
  UINT32 pbContextNdrPtr = 0;
3606
3607
0
  WINPR_ASSERT(call);
3608
0
  wLog* log = scard_log();
3609
3610
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &mszNdrPtr))
3611
0
    return ERROR_INVALID_DATA;
3612
3613
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->Common.handles.hContext),
3614
0
                                                     &index, &pbContextNdrPtr);
3615
0
  if (status != SCARD_S_SUCCESS)
3616
0
    return status;
3617
3618
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &contextNdrPtr))
3619
0
    return ERROR_INVALID_DATA;
3620
3621
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 12))
3622
0
    return STATUS_BUFFER_TOO_SMALL;
3623
0
  Stream_Read_UINT32(s, call->Common.FreshnessCounter);
3624
0
  Stream_Read_INT32(s, call->Common.fPbDataIsNULL);
3625
0
  Stream_Read_UINT32(s, call->Common.cbDataLen);
3626
3627
0
  call->szLookupName = NULL;
3628
0
  if (mszNdrPtr)
3629
0
  {
3630
0
    status = smartcard_ndr_read_a(log, s, &call->szLookupName, NDR_PTR_FULL);
3631
0
    if (status != SCARD_S_SUCCESS)
3632
0
      return status;
3633
0
  }
3634
3635
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3636
0
                                                    &call->Common.handles.hContext);
3637
0
  if (status != SCARD_S_SUCCESS)
3638
0
    return status;
3639
3640
0
  if (contextNdrPtr)
3641
0
  {
3642
0
    status = smartcard_ndr_read_u(log, s, &call->Common.CardIdentifier);
3643
0
    if (status != SCARD_S_SUCCESS)
3644
0
      return status;
3645
0
  }
3646
0
  smartcard_trace_read_cache_a_call(log, call);
3647
0
  return SCARD_S_SUCCESS;
3648
0
}
3649
3650
LONG smartcard_unpack_read_cache_w_call(wStream* s, ReadCacheW_Call* call)
3651
0
{
3652
0
  UINT32 mszNdrPtr = 0;
3653
0
  UINT32 contextNdrPtr = 0;
3654
0
  UINT32 index = 0;
3655
0
  UINT32 pbContextNdrPtr = 0;
3656
3657
0
  WINPR_ASSERT(call);
3658
0
  wLog* log = scard_log();
3659
3660
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &mszNdrPtr))
3661
0
    return ERROR_INVALID_DATA;
3662
3663
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->Common.handles.hContext),
3664
0
                                                     &index, &pbContextNdrPtr);
3665
0
  if (status != SCARD_S_SUCCESS)
3666
0
    return status;
3667
3668
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &contextNdrPtr))
3669
0
    return ERROR_INVALID_DATA;
3670
3671
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 12))
3672
0
    return STATUS_BUFFER_TOO_SMALL;
3673
0
  Stream_Read_UINT32(s, call->Common.FreshnessCounter);
3674
0
  Stream_Read_INT32(s, call->Common.fPbDataIsNULL);
3675
0
  Stream_Read_UINT32(s, call->Common.cbDataLen);
3676
3677
0
  call->szLookupName = NULL;
3678
0
  if (mszNdrPtr)
3679
0
  {
3680
0
    status = smartcard_ndr_read_w(log, s, &call->szLookupName, NDR_PTR_FULL);
3681
0
    if (status != SCARD_S_SUCCESS)
3682
0
      return status;
3683
0
  }
3684
3685
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3686
0
                                                    &call->Common.handles.hContext);
3687
0
  if (status != SCARD_S_SUCCESS)
3688
0
    return status;
3689
3690
0
  if (contextNdrPtr)
3691
0
  {
3692
0
    status = smartcard_ndr_read_u(log, s, &call->Common.CardIdentifier);
3693
0
    if (status != SCARD_S_SUCCESS)
3694
0
      return status;
3695
0
  }
3696
0
  smartcard_trace_read_cache_w_call(log, call);
3697
0
  return SCARD_S_SUCCESS;
3698
0
}
3699
3700
LONG smartcard_unpack_write_cache_a_call(wStream* s, WriteCacheA_Call* call)
3701
0
{
3702
0
  UINT32 mszNdrPtr = 0;
3703
0
  UINT32 contextNdrPtr = 0;
3704
0
  UINT32 pbDataNdrPtr = 0;
3705
0
  UINT32 index = 0;
3706
0
  UINT32 pbContextNdrPtr = 0;
3707
3708
0
  WINPR_ASSERT(call);
3709
0
  wLog* log = scard_log();
3710
3711
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &mszNdrPtr))
3712
0
    return ERROR_INVALID_DATA;
3713
3714
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->Common.handles.hContext),
3715
0
                                                     &index, &pbContextNdrPtr);
3716
0
  if (status != SCARD_S_SUCCESS)
3717
0
    return status;
3718
3719
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &contextNdrPtr))
3720
0
    return ERROR_INVALID_DATA;
3721
3722
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3723
0
    return STATUS_BUFFER_TOO_SMALL;
3724
3725
0
  Stream_Read_UINT32(s, call->Common.FreshnessCounter);
3726
0
  Stream_Read_UINT32(s, call->Common.cbDataLen);
3727
3728
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &pbDataNdrPtr))
3729
0
    return ERROR_INVALID_DATA;
3730
3731
0
  call->szLookupName = NULL;
3732
0
  if (mszNdrPtr)
3733
0
  {
3734
0
    status = smartcard_ndr_read_a(log, s, &call->szLookupName, NDR_PTR_FULL);
3735
0
    if (status != SCARD_S_SUCCESS)
3736
0
      return status;
3737
0
  }
3738
3739
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3740
0
                                                    &call->Common.handles.hContext);
3741
0
  if (status != SCARD_S_SUCCESS)
3742
0
    return status;
3743
3744
0
  call->Common.CardIdentifier = NULL;
3745
0
  if (contextNdrPtr)
3746
0
  {
3747
0
    status = smartcard_ndr_read_u(log, s, &call->Common.CardIdentifier);
3748
0
    if (status != SCARD_S_SUCCESS)
3749
0
      return status;
3750
0
  }
3751
3752
0
  call->Common.pbData = NULL;
3753
0
  if (pbDataNdrPtr)
3754
0
  {
3755
0
    status = smartcard_ndr_read(log, s, &call->Common.pbData, call->Common.cbDataLen, 1,
3756
0
                                NDR_PTR_SIMPLE);
3757
0
    if (status != SCARD_S_SUCCESS)
3758
0
      return status;
3759
0
  }
3760
0
  smartcard_trace_write_cache_a_call(log, call);
3761
0
  return SCARD_S_SUCCESS;
3762
0
}
3763
3764
LONG smartcard_unpack_write_cache_w_call(wStream* s, WriteCacheW_Call* call)
3765
0
{
3766
0
  UINT32 mszNdrPtr = 0;
3767
0
  UINT32 contextNdrPtr = 0;
3768
0
  UINT32 pbDataNdrPtr = 0;
3769
0
  UINT32 index = 0;
3770
0
  UINT32 pbContextNdrPtr = 0;
3771
3772
0
  WINPR_ASSERT(call);
3773
0
  wLog* log = scard_log();
3774
3775
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &mszNdrPtr))
3776
0
    return ERROR_INVALID_DATA;
3777
3778
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->Common.handles.hContext),
3779
0
                                                     &index, &pbContextNdrPtr);
3780
0
  if (status != SCARD_S_SUCCESS)
3781
0
    return status;
3782
3783
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &contextNdrPtr))
3784
0
    return ERROR_INVALID_DATA;
3785
3786
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
3787
0
    return STATUS_BUFFER_TOO_SMALL;
3788
0
  Stream_Read_UINT32(s, call->Common.FreshnessCounter);
3789
0
  Stream_Read_UINT32(s, call->Common.cbDataLen);
3790
3791
0
  if (!smartcard_ndr_pointer_read(log, s, &index, &pbDataNdrPtr))
3792
0
    return ERROR_INVALID_DATA;
3793
3794
0
  call->szLookupName = NULL;
3795
0
  if (mszNdrPtr)
3796
0
  {
3797
0
    status = smartcard_ndr_read_w(log, s, &call->szLookupName, NDR_PTR_FULL);
3798
0
    if (status != SCARD_S_SUCCESS)
3799
0
      return status;
3800
0
  }
3801
3802
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3803
0
                                                    &call->Common.handles.hContext);
3804
0
  if (status != SCARD_S_SUCCESS)
3805
0
    return status;
3806
3807
0
  call->Common.CardIdentifier = NULL;
3808
0
  if (contextNdrPtr)
3809
0
  {
3810
0
    status = smartcard_ndr_read_u(log, s, &call->Common.CardIdentifier);
3811
0
    if (status != SCARD_S_SUCCESS)
3812
0
      return status;
3813
0
  }
3814
3815
0
  call->Common.pbData = NULL;
3816
0
  if (pbDataNdrPtr)
3817
0
  {
3818
0
    status = smartcard_ndr_read(log, s, &call->Common.pbData, call->Common.cbDataLen, 1,
3819
0
                                NDR_PTR_SIMPLE);
3820
0
    if (status != SCARD_S_SUCCESS)
3821
0
      return status;
3822
0
  }
3823
0
  smartcard_trace_write_cache_w_call(log, call);
3824
0
  return status;
3825
0
}
3826
3827
LONG smartcard_unpack_get_transmit_count_call(wStream* s, GetTransmitCount_Call* call)
3828
0
{
3829
0
  WINPR_ASSERT(call);
3830
0
  wLog* log = scard_log();
3831
3832
0
  UINT32 index = 0;
3833
0
  UINT32 pbContextNdrPtr = 0;
3834
3835
0
  LONG status = smartcard_unpack_redir_scard_context(log, s, &(call->handles.hContext), &index,
3836
0
                                                     &pbContextNdrPtr);
3837
0
  if (status != SCARD_S_SUCCESS)
3838
0
    return status;
3839
3840
0
  status = smartcard_unpack_redir_scard_handle(log, s, &(call->handles.hCard), &index);
3841
0
  if (status != SCARD_S_SUCCESS)
3842
0
    return status;
3843
3844
0
  status = smartcard_unpack_redir_scard_context_ref(log, s, pbContextNdrPtr,
3845
0
                                                    &(call->handles.hContext));
3846
0
  if (status != SCARD_S_SUCCESS)
3847
0
  {
3848
0
    WLog_Print(log, WLOG_ERROR,
3849
0
               "smartcard_unpack_redir_scard_context_ref failed with error %" PRId32 "",
3850
0
               status);
3851
0
    return status;
3852
0
  }
3853
3854
0
  status = smartcard_unpack_redir_scard_handle_ref(log, s, &(call->handles.hCard));
3855
0
  if (status != SCARD_S_SUCCESS)
3856
0
    WLog_Print(log, WLOG_ERROR,
3857
0
               "smartcard_unpack_redir_scard_handle_ref failed with error %" PRId32 "", status);
3858
3859
0
  smartcard_trace_get_transmit_count_call(log, call);
3860
0
  return status;
3861
0
}
3862
3863
LONG smartcard_unpack_get_reader_icon_call(wStream* s, GetReaderIcon_Call* call)
3864
0
{
3865
0
  WINPR_ASSERT(call);
3866
0
  wLog* log = scard_log();
3867
0
  return smartcard_unpack_common_context_and_string_w(log, s, &call->handles.hContext,
3868
0
                                                      &call->szReaderName);
3869
0
}
3870
3871
LONG smartcard_unpack_context_and_string_a_call(wStream* s, ContextAndStringA_Call* call)
3872
0
{
3873
0
  WINPR_ASSERT(call);
3874
0
  wLog* log = scard_log();
3875
0
  return smartcard_unpack_common_context_and_string_a(log, s, &call->handles.hContext, &call->sz);
3876
0
}
3877
3878
LONG smartcard_unpack_context_and_string_w_call(wStream* s, ContextAndStringW_Call* call)
3879
0
{
3880
0
  WINPR_ASSERT(call);
3881
0
  wLog* log = scard_log();
3882
0
  return smartcard_unpack_common_context_and_string_w(log, s, &call->handles.hContext, &call->sz);
3883
0
}
3884
3885
LONG smartcard_unpack_get_device_type_id_call(wStream* s, GetDeviceTypeId_Call* call)
3886
0
{
3887
0
  WINPR_ASSERT(call);
3888
0
  wLog* log = scard_log();
3889
0
  return smartcard_unpack_common_context_and_string_w(log, s, &call->handles.hContext,
3890
0
                                                      &call->szReaderName);
3891
0
}
3892
3893
LONG smartcard_pack_device_type_id_return(wStream* s, const GetDeviceTypeId_Return* ret)
3894
0
{
3895
0
  WINPR_ASSERT(ret);
3896
0
  wLog* log = scard_log();
3897
0
  smartcard_trace_device_type_id_return(log, ret);
3898
3899
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
3900
0
  {
3901
0
    WLog_Print(log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
3902
0
    return SCARD_F_INTERNAL_ERROR;
3903
0
  }
3904
3905
0
  Stream_Write_UINT32(s, ret->dwDeviceId); /* cBytes (4 bytes) */
3906
3907
0
  return ret->ReturnCode;
3908
0
}
3909
3910
LONG smartcard_pack_locate_cards_return(wStream* s, const LocateCards_Return* ret)
3911
0
{
3912
0
  WINPR_ASSERT(ret);
3913
0
  wLog* log = scard_log();
3914
3915
0
  LONG status = 0;
3916
0
  DWORD cbDataLen = ret->cReaders;
3917
0
  UINT32 index = 0;
3918
3919
0
  smartcard_trace_locate_cards_return(log, ret);
3920
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
3921
0
    cbDataLen = 0;
3922
0
  if (cbDataLen == SCARD_AUTOALLOCATE)
3923
0
    cbDataLen = 0;
3924
3925
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
3926
0
  {
3927
0
    WLog_Print(log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
3928
0
    return SCARD_F_INTERNAL_ERROR;
3929
0
  }
3930
3931
0
  Stream_Write_UINT32(s, cbDataLen); /* cBytes (4 cbDataLen) */
3932
0
  if (!smartcard_ndr_pointer_write(s, &index, cbDataLen))
3933
0
    return SCARD_E_NO_MEMORY;
3934
3935
0
  status = smartcard_ndr_write_state(s, ret->rgReaderStates, cbDataLen, NDR_PTR_SIMPLE);
3936
0
  if (status != SCARD_S_SUCCESS)
3937
0
    return status;
3938
0
  return ret->ReturnCode;
3939
0
}
3940
3941
LONG smartcard_pack_get_reader_icon_return(wStream* s, const GetReaderIcon_Return* ret)
3942
0
{
3943
0
  WINPR_ASSERT(ret);
3944
0
  wLog* log = scard_log();
3945
3946
0
  LONG status = 0;
3947
0
  UINT32 index = 0;
3948
0
  DWORD cbDataLen = ret->cbDataLen;
3949
0
  smartcard_trace_get_reader_icon_return(log, ret);
3950
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
3951
0
    cbDataLen = 0;
3952
0
  if (cbDataLen == SCARD_AUTOALLOCATE)
3953
0
    cbDataLen = 0;
3954
3955
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
3956
0
  {
3957
0
    WLog_Print(log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
3958
0
    return SCARD_F_INTERNAL_ERROR;
3959
0
  }
3960
3961
0
  Stream_Write_UINT32(s, cbDataLen); /* cBytes (4 cbDataLen) */
3962
0
  if (!smartcard_ndr_pointer_write(s, &index, cbDataLen))
3963
0
    return SCARD_E_NO_MEMORY;
3964
3965
0
  status = smartcard_ndr_write(s, ret->pbData, cbDataLen, 1, NDR_PTR_SIMPLE);
3966
0
  if (status != SCARD_S_SUCCESS)
3967
0
    return status;
3968
0
  return ret->ReturnCode;
3969
0
}
3970
3971
LONG smartcard_pack_get_transmit_count_return(wStream* s, const GetTransmitCount_Return* ret)
3972
0
{
3973
0
  WINPR_ASSERT(ret);
3974
0
  wLog* log = scard_log();
3975
3976
0
  smartcard_trace_get_transmit_count_return(log, ret);
3977
3978
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
3979
0
  {
3980
0
    WLog_Print(log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
3981
0
    return SCARD_F_INTERNAL_ERROR;
3982
0
  }
3983
3984
0
  Stream_Write_UINT32(s, ret->cTransmitCount); /* cBytes (4 cbDataLen) */
3985
3986
0
  return ret->ReturnCode;
3987
0
}
3988
3989
LONG smartcard_pack_read_cache_return(wStream* s, const ReadCache_Return* ret)
3990
0
{
3991
0
  WINPR_ASSERT(ret);
3992
0
  wLog* log = scard_log();
3993
3994
0
  LONG status = 0;
3995
0
  UINT32 index = 0;
3996
0
  DWORD cbDataLen = ret->cbDataLen;
3997
0
  smartcard_trace_read_cache_return(log, ret);
3998
0
  if (ret->ReturnCode != SCARD_S_SUCCESS)
3999
0
    cbDataLen = 0;
4000
4001
0
  if (cbDataLen == SCARD_AUTOALLOCATE)
4002
0
    cbDataLen = 0;
4003
4004
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
4005
0
  {
4006
0
    WLog_Print(log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
4007
0
    return SCARD_F_INTERNAL_ERROR;
4008
0
  }
4009
4010
0
  Stream_Write_UINT32(s, cbDataLen); /* cBytes (4 cbDataLen) */
4011
0
  if (!smartcard_ndr_pointer_write(s, &index, cbDataLen))
4012
0
    return SCARD_E_NO_MEMORY;
4013
4014
0
  status = smartcard_ndr_write(s, ret->pbData, cbDataLen, 1, NDR_PTR_SIMPLE);
4015
0
  if (status != SCARD_S_SUCCESS)
4016
0
    return status;
4017
0
  return ret->ReturnCode;
4018
0
}