Coverage Report

Created: 2024-05-20 06:11

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