FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
test-scard.cpp
1
27#include <iostream>
28#include <string>
29#include <sstream>
30#include <locale>
31#include <codecvt>
32
33#include <comdef.h>
34#include <winscard.h>
35
36static const WCHAR* listW[] = { nullptr, L"SCard$AllReaders\000", L"SCard$DefaultReaders\000",
37 L"SCard$LocalReaders\000", L"SCard$SystemReaders\000" };
38static const char* listA[] = { nullptr, "SCard$AllReaders\000", "SCard$DefaultReaders\000",
39 "SCard$LocalReaders\000", "SCard$SystemReaders\000" };
40
41static std::string scope2str(DWORD scope)
42{
43 switch (scope)
44 {
45 case SCARD_SCOPE_USER:
46 return "SCARD_SCOPE_USER";
47 case SCARD_SCOPE_TERMINAL:
48 return "SCARD_SCOPE_TERMINAL";
49 case SCARD_SCOPE_SYSTEM:
50 return "SCARD_SCOPE_SYSTEM";
51 default:
52 return "UNKNOWN";
53 }
54}
55
56static std::string err2str(LONG code)
57{
58 switch (code)
59 {
60 case ERROR_BROKEN_PIPE:
61 return "ERROR_BROKEN_PIPE";
62 case SCARD_E_BAD_SEEK:
63 return "SCARD_E_BAD_SEEK";
64 case SCARD_E_CANCELLED:
65 return "SCARD_E_CANCELLED";
66 case SCARD_E_CANT_DISPOSE:
67 return "SCARD_E_CANT_DISPOSE";
68 case SCARD_E_CARD_UNSUPPORTED:
69 return "SCARD_E_CARD_UNSUPPORTED";
70 case SCARD_E_CERTIFICATE_UNAVAILABLE:
71 return "SCARD_E_CERTIFICATE_UNAVAILABLE";
72 case SCARD_E_COMM_DATA_LOST:
73 return "SCARD_E_COMM_DATA_LOST";
74 case SCARD_E_DIR_NOT_FOUND:
75 return "SCARD_E_DIR_NOT_FOUND";
76 case SCARD_E_DUPLICATE_READER:
77 return "SCARD_E_DUPLICATE_READER";
78 case SCARD_E_FILE_NOT_FOUND:
79 return "SCARD_E_FILE_NOT_FOUND";
80 case SCARD_E_ICC_CREATEORDER:
81 return "SCARD_E_ICC_CREATEORDER";
82 case SCARD_E_ICC_INSTALLATION:
83 return "SCARD_E_ICC_INSTALLATION";
84 case SCARD_E_INSUFFICIENT_BUFFER:
85 return "SCARD_E_INSUFFICIENT_BUFFER";
86 case SCARD_E_INVALID_ATR:
87 return "SCARD_E_INVALID_ATR";
88 case SCARD_E_INVALID_CHV:
89 return "SCARD_E_INVALID_CHV";
90 case SCARD_E_INVALID_HANDLE:
91 return "SCARD_E_INVALID_HANDLE";
92 case SCARD_E_INVALID_PARAMETER:
93 return "SCARD_E_INVALID_PARAMETER";
94 case SCARD_E_INVALID_TARGET:
95 return "SCARD_E_INVALID_TARGET";
96 case SCARD_E_INVALID_VALUE:
97 return "SCARD_E_INVALID_VALUE";
98 case SCARD_E_NO_ACCESS:
99 return "SCARD_E_NO_ACCESS";
100 case SCARD_E_NO_DIR:
101 return "SCARD_E_NO_DIR";
102 case SCARD_E_NO_FILE:
103 return "SCARD_E_NO_FILE";
104 case SCARD_E_NO_KEY_CONTAINER:
105 return "SCARD_E_NO_KEY_CONTAINER";
106 case SCARD_E_NO_MEMORY:
107 return "SCARD_E_NO_MEMORY";
108 case SCARD_E_NO_PIN_CACHE:
109 return "SCARD_E_NO_PIN_CACHE";
110 case SCARD_E_NO_READERS_AVAILABLE:
111 return "SCARD_E_NO_READERS_AVAILABLE";
112 case SCARD_E_NO_SERVICE:
113 return "SCARD_E_NO_SERVICE";
114 case SCARD_E_NO_SMARTCARD:
115 return "SCARD_E_NO_SMARTCARD";
116 case SCARD_E_NO_SUCH_CERTIFICATE:
117 return "SCARD_E_NO_SUCH_CERTIFICATE";
118 case SCARD_E_NOT_READY:
119 return "SCARD_E_NOT_READY";
120 case SCARD_E_NOT_TRANSACTED:
121 return "SCARD_E_NOT_TRANSACTED";
122 case SCARD_E_PCI_TOO_SMALL:
123 return "SCARD_E_PCI_TOO_SMALL";
124 case SCARD_E_PIN_CACHE_EXPIRED:
125 return "SCARD_E_PIN_CACHE_EXPIRED";
126 case SCARD_E_PROTO_MISMATCH:
127 return "SCARD_E_PROTO_MISMATCH";
128 case SCARD_E_READ_ONLY_CARD:
129 return "SCARD_E_READ_ONLY_CARD";
130 case SCARD_E_READER_UNAVAILABLE:
131 return "SCARD_E_READER_UNAVAILABLE";
132 case SCARD_E_READER_UNSUPPORTED:
133 return "SCARD_E_READER_UNSUPPORTED";
134 case SCARD_E_SERVER_TOO_BUSY:
135 return "SCARD_E_SERVER_TOO_BUSY";
136 case SCARD_E_SERVICE_STOPPED:
137 return "SCARD_E_SERVICE_STOPPED";
138 case SCARD_E_SHARING_VIOLATION:
139 return "SCARD_E_SHARING_VIOLATION";
140 case SCARD_E_SYSTEM_CANCELLED:
141 return "SCARD_E_SYSTEM_CANCELLED";
142 case SCARD_E_TIMEOUT:
143 return "SCARD_E_TIMEOUT";
144 case SCARD_E_UNEXPECTED:
145 return "SCARD_E_UNEXPECTED";
146 case SCARD_E_UNKNOWN_CARD:
147 return "SCARD_E_UNKNOWN_CARD";
148 case SCARD_E_UNKNOWN_READER:
149 return "SCARD_E_UNKNOWN_READER";
150 case SCARD_E_UNKNOWN_RES_MNG:
151 return "SCARD_E_UNKNOWN_RES_MNG";
152 case SCARD_E_UNSUPPORTED_FEATURE:
153 return "SCARD_E_UNSUPPORTED_FEATURE";
154 case SCARD_E_WRITE_TOO_MANY:
155 return "SCARD_E_WRITE_TOO_MANY";
156 case SCARD_F_COMM_ERROR:
157 return "SCARD_F_COMM_ERROR";
158 case SCARD_F_INTERNAL_ERROR:
159 return "SCARD_F_INTERNAL_ERROR";
160 case SCARD_F_UNKNOWN_ERROR:
161 return "SCARD_F_UNKNOWN_ERROR";
162 case SCARD_F_WAITED_TOO_LONG:
163 return "SCARD_F_WAITED_TOO_LONG";
164 case SCARD_P_SHUTDOWN:
165 return "SCARD_P_SHUTDOWN";
166 case SCARD_S_SUCCESS:
167 return "SCARD_S_SUCCESS";
168 case SCARD_W_CANCELLED_BY_USER:
169 return "SCARD_W_CANCELLED_BY_USER";
170 case SCARD_W_CACHE_ITEM_NOT_FOUND:
171 return "SCARD_W_CACHE_ITEM_NOT_FOUND";
172 case SCARD_W_CACHE_ITEM_STALE:
173 return "SCARD_W_CACHE_ITEM_STALE";
174 case SCARD_W_CACHE_ITEM_TOO_BIG:
175 return "SCARD_W_CACHE_ITEM_TOO_BIG";
176 case SCARD_W_CARD_NOT_AUTHENTICATED:
177 return "SCARD_W_CARD_NOT_AUTHENTICATED";
178 case SCARD_W_CHV_BLOCKED:
179 return "SCARD_W_CHV_BLOCKED";
180 case SCARD_W_EOF:
181 return "SCARD_W_EOF";
182 case SCARD_W_REMOVED_CARD:
183 return "SCARD_W_REMOVED_CARD";
184 case SCARD_W_RESET_CARD:
185 return "SCARD_W_RESET_CARD";
186 case SCARD_W_SECURITY_VIOLATION:
187 return "SCARD_W_SECURITY_VIOLATION";
188 case SCARD_W_UNPOWERED_CARD:
189 return "SCARD_W_UNPOWERED_CARD";
190 case SCARD_W_UNRESPONSIVE_CARD:
191 return "SCARD_W_UNRESPONSIVE_CARD";
192 case SCARD_W_UNSUPPORTED_CARD:
193 return "SCARD_W_UNSUPPORTED_CARD";
194 case SCARD_W_WRONG_CHV:
195 return "SCARD_W_WRONG_CHV";
196 default:
197 return "UNKNOWN";
198 }
199}
200
201static std::wstring err2wstr(LONG code)
202{
203 auto str = err2str(code);
204 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
205 return converter.from_bytes(str);
206}
207
208static bool test_valid(SCARDCONTEXT context)
209{
210 auto rc = SCardIsValidContext(context);
211 if (rc)
212 std::cerr << "SCardIsValidContext failed with " << err2str(rc) << std::endl;
213 return true;
214}
215
216static bool test_list_readers_a(SCARDCONTEXT context)
217{
218 for (auto cur : listA)
219 {
220 LPSTR mszReaders = nullptr;
221 DWORD chReaders = SCARD_AUTOALLOCATE;
222 auto rc = SCardListReadersA(context, cur, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
223 if (!cur)
224 {
225 cur = "NULL";
226 }
227 if (rc != SCARD_S_SUCCESS)
228 {
229 std::cerr << "SCardListReadersA [" << cur << "] failed with " << err2str(rc)
230 << std::endl;
231 }
232 else
233 {
234 auto start = mszReaders;
235 auto end = &mszReaders[chReaders];
236
237 std::cout << "SCardListReadersA [" << cur << "] " << chReaders << " [";
238 while (start < end)
239 {
240 std::cout << start << ", ";
241 start += strnlen(start, chReaders) + 2;
242 }
243 std::cout << "]" << std::endl;
244 }
245 SCardFreeMemory(context, mszReaders);
246 }
247
248 return true;
249}
250
251static bool test_list_readers_w(SCARDCONTEXT context)
252{
253 for (auto cur : listW)
254 {
255 LPWSTR mszReaders = nullptr;
256 DWORD chReaders = SCARD_AUTOALLOCATE;
257 auto rc =
258 SCardListReadersW(context, cur, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
259 if (!cur)
260 {
261 cur = L"NULL";
262 }
263 if (rc != SCARD_S_SUCCESS)
264 {
265 std::wcerr << L"SCardListReadersW [" << cur << L"] failed with " << err2wstr(rc)
266 << std::endl;
267 }
268 else
269 {
270 auto start = mszReaders;
271 auto end = &mszReaders[chReaders];
272
273 std::wcout << L"SCardListReadersW [" << cur << L"] " << chReaders << L" [";
274 while (start < end)
275 {
276 std::wcout << start << L", ";
277 start += wcsnlen(start, chReaders) + 2;
278 }
279 std::wcout << L"]" << std::endl;
280 }
281 SCardFreeMemory(context, mszReaders);
282 }
283
284 return true;
285}
286
287static bool test_list_reader_groups_a(SCARDCONTEXT context)
288{
289 LPSTR mszReaders = nullptr;
290 DWORD chReaders = SCARD_AUTOALLOCATE;
291 auto rc = SCardListReaderGroupsA(context, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
292 if (rc != SCARD_S_SUCCESS)
293 {
294 std::cerr << "SCardListReaderGroupsA failed with " << err2str(rc) << std::endl;
295 }
296 else
297 {
298 auto start = mszReaders;
299 auto end = &mszReaders[chReaders];
300
301 std::cout << "SCardListReaderGroupsA " << chReaders << " [";
302 while (start < end)
303 {
304 std::cout << start << ", ";
305 start += strnlen(start, chReaders) + 2;
306 }
307 std::cout << "]" << std::endl;
308 }
309 SCardFreeMemory(context, mszReaders);
310
311 return true;
312}
313
314static bool test_list_reader_groups_w(SCARDCONTEXT context)
315{
316 LPWSTR mszReaders = nullptr;
317 DWORD chReaders = SCARD_AUTOALLOCATE;
318 auto rc = SCardListReaderGroupsW(context, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
319 if (rc != SCARD_S_SUCCESS)
320 {
321 std::wcerr << L"SCardListReaderGroupsW failed with " << err2wstr(rc) << std::endl;
322 }
323 else
324 {
325 auto start = mszReaders;
326 auto end = &mszReaders[chReaders];
327
328 std::wcout << L"SCardListReaderGroupsW " << chReaders << L" [";
329 while (start < end)
330 {
331 std::wcout << start << L", ";
332 start += wcsnlen(start, chReaders) + 2;
333 }
334 std::wcout << L"]" << std::endl;
335 }
336 SCardFreeMemory(context, mszReaders);
337
338 return true;
339}
340
341static bool test_introduce_forget_reader_groups_a(SCARDCONTEXT context)
342{
343 LPSTR group = "somefancygroup";
344
345 auto rc = SCardIntroduceReaderGroupA(context, group);
346 if (rc != SCARD_S_SUCCESS)
347 {
348 std::cerr << "SCardIntroduceReaderGroupA failed with " << err2str(rc) << std::endl;
349 return false;
350 }
351 else
352 {
353 rc = SCardForgetReaderGroupA(context, group);
354 if (rc != SCARD_S_SUCCESS)
355 {
356 std::cerr << "SCardForgetReaderGroupA failed with " << err2str(rc) << std::endl;
357 return false;
358 }
359 return true;
360 }
361}
362
363static bool test_introduce_forget_reader_groups_w(SCARDCONTEXT context)
364{
365 LPWSTR group = L"somefancygroup";
366
367 auto rc = SCardIntroduceReaderGroupW(context, group);
368 if (rc != SCARD_S_SUCCESS)
369 {
370 std::cerr << "SCardIntroduceReaderGroupW failed with " << err2str(rc) << std::endl;
371 return false;
372 }
373 else
374 {
375 rc = SCardForgetReaderGroupW(context, group);
376 if (rc != SCARD_S_SUCCESS)
377 {
378 std::cerr << "SCardForgetReaderGroupW failed with " << err2str(rc) << std::endl;
379 return false;
380 }
381 return true;
382 }
383}
384
385static bool test_introduce_forget_reader_a(SCARDCONTEXT context)
386{
387 LPSTR reader = "somefancygroup";
388 LPSTR device = "otherfancy";
389
390 auto rc = SCardIntroduceReaderA(context, reader, device);
391 if (rc != SCARD_S_SUCCESS)
392 {
393 std::cerr << "SCardIntroduceReaderA failed with " << err2str(rc) << std::endl;
394 return false;
395 }
396 else
397 {
398 rc = SCardForgetReaderA(context, reader);
399 if (rc != SCARD_S_SUCCESS)
400 {
401 std::cerr << "SCardForgetReaderA failed with " << err2str(rc) << std::endl;
402 return false;
403 }
404 return true;
405 }
406}
407
408static bool test_introduce_forget_reader_w(SCARDCONTEXT context)
409{
410 LPWSTR reader = L"somefancygroup";
411 LPWSTR device = L"otherfancy";
412
413 auto rc = SCardIntroduceReaderW(context, reader, device);
414 if (rc != SCARD_S_SUCCESS)
415 {
416 std::cerr << "SCardIntroduceReaderW failed with " << err2str(rc) << std::endl;
417 return false;
418 }
419 else
420 {
421 rc = SCardForgetReaderW(context, reader);
422 if (rc != SCARD_S_SUCCESS)
423 {
424 std::cerr << "SCardForgetReaderW failed with " << err2str(rc) << std::endl;
425 return false;
426 }
427 return true;
428 }
429}
430
431static bool test_list_cards_a(SCARDCONTEXT context)
432{
433 DWORD chCards = SCARD_AUTOALLOCATE;
434 LPSTR mszCards = nullptr;
435 auto rc =
436 SCardListCardsA(context, nullptr, nullptr, 0, reinterpret_cast<LPSTR>(&mszCards), &chCards);
437 if (rc != SCARD_S_SUCCESS)
438 {
439 std::cerr << "SCardListCardsA failed with " << err2str(rc) << std::endl;
440 }
441 else
442 {
443 auto start = mszCards;
444 auto end = &mszCards[chCards];
445 std::cout << "SCardListCardsA " << chCards << " [";
446 while (start < end)
447 {
448 std::cout << start << ", ";
449 start += strnlen(start, chCards) + 2;
450 }
451 std::cout << "]" << std::endl;
452 }
453 return true;
454}
455
456static bool test_list_cards_w(SCARDCONTEXT context)
457{
458 DWORD chCards = SCARD_AUTOALLOCATE;
459 LPWSTR mszCards = nullptr;
460 auto rc = SCardListCardsW(context, nullptr, nullptr, 0, reinterpret_cast<LPWSTR>(&mszCards),
461 &chCards);
462 if (rc != SCARD_S_SUCCESS)
463 {
464 std::cerr << "SCardListCardsW failed with " << err2str(rc) << std::endl;
465 }
466 else
467 {
468 auto start = mszCards;
469 auto end = &mszCards[chCards];
470 std::cout << "SCardListCardsW " << chCards << " [";
471 while (start < end)
472 {
473 std::wcout << start << L", ";
474 start += wcsnlen(start, chCards) + 2;
475 }
476 std::cout << "]" << std::endl;
477 }
478 return true;
479}
480
481static bool test_cache_a(SCARDCONTEXT context)
482{
483 BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
484 const DWORD wdatalen = sizeof(wdata);
485 BYTE data[32] = {};
486 DWORD datalen = sizeof(data);
487 LPSTR name = "testdata";
488 UUID id = {};
489
490 auto rc = SCardWriteCacheA(context, &id, 0, name, wdata, wdatalen);
491 if (rc != SCARD_S_SUCCESS)
492 {
493 std::cerr << "SCardWriteCacheA failed with " << err2str(rc) << std::endl;
494 return false;
495 }
496
497 rc = SCardReadCacheA(context, &id, 0, name, data, &datalen);
498 if (rc != SCARD_S_SUCCESS)
499 {
500 std::cerr << "SCardReadCacheA failed with " << err2str(rc) << std::endl;
501 return false;
502 }
503
504 if (wdatalen != datalen)
505 {
506 std::cerr << "SCardWriteCacheA wrote " << wdatalen << "bytes, SCardReadCacheA read "
507 << datalen << "bytes" << std::endl;
508 return false;
509 }
510
511 if (memcmp(wdata, data, wdatalen) != 0)
512 {
513 std::cerr << "SCardWriteCacheA / SCardReadCacheA data corruption detected" << std::endl;
514 return false;
515 }
516
517 return true;
518}
519
520static bool test_cache_w(SCARDCONTEXT context)
521{
522 BYTE wdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
523 const DWORD wdatalen = sizeof(wdata);
524 BYTE data[32] = {};
525 DWORD datalen = sizeof(data);
526 LPWSTR name = L"testdata";
527 UUID id = {};
528
529 auto rc = SCardWriteCacheW(context, &id, 0, name, wdata, wdatalen);
530 if (rc != SCARD_S_SUCCESS)
531 {
532 std::cerr << "SCardWriteCacheW failed with " << err2str(rc) << std::endl;
533 return false;
534 }
535
536 rc = SCardReadCacheW(context, &id, 0, name, data, &datalen);
537 if (rc != SCARD_S_SUCCESS)
538 {
539 std::cerr << "SCardReadCacheW failed with " << err2str(rc) << std::endl;
540 return false;
541 }
542
543 if (wdatalen != datalen)
544 {
545 std::cerr << "SCardReadCacheW wrote " << wdatalen << "bytes, SCardReadCacheW read "
546 << datalen << "bytes" << std::endl;
547 return false;
548 }
549
550 if (memcmp(wdata, data, wdatalen) != 0)
551 {
552 std::cerr << "SCardReadCacheW / SCardReadCacheW data corruption detected" << std::endl;
553 return false;
554 }
555
556 return true;
557}
558
559static bool test_reader_icon_a(SCARDCONTEXT context)
560{
561 LPSTR name = "Gemalto PC Twin Reader 00 00\0\0";
562 LPBYTE pbIcon = nullptr;
563 DWORD cbIcon = SCARD_AUTOALLOCATE;
564
565 auto rc = SCardGetReaderIconA(context, name, reinterpret_cast<LPBYTE>(&pbIcon), &cbIcon);
566 SCardFreeMemory(context, pbIcon);
567 if (rc != SCARD_S_SUCCESS)
568 {
569 std::cerr << "SCardGetReaderIconA failed with " << err2str(rc) << std::endl;
570 return false;
571 }
572
573 return true;
574}
575
576static bool test_reader_icon_w(SCARDCONTEXT context)
577{
578 LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0";
579 LPBYTE pbIcon = nullptr;
580 DWORD cbIcon = SCARD_AUTOALLOCATE;
581
582 auto rc = SCardGetReaderIconW(context, name, reinterpret_cast<LPBYTE>(&pbIcon), &cbIcon);
583 SCardFreeMemory(context, pbIcon);
584 if (rc != SCARD_S_SUCCESS)
585 {
586 std::cerr << "SCardGetReaderIconW failed with " << err2str(rc) << std::endl;
587 return false;
588 }
589
590 return true;
591}
592
593static bool test_locate_cards_a(SCARDCONTEXT context)
594{
595 LPSTR name = "Gemalto PC Twin Reader 00 00\0\0";
596 SCARD_READERSTATEA rgReaderStates[16] = {};
597
598 auto rc = SCardLocateCardsA(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates));
599 if (rc != SCARD_S_SUCCESS)
600 {
601 std::cerr << "SCardLocateCardsA failed with " << err2str(rc) << std::endl;
602 return false;
603 }
604
605 return true;
606}
607
608static bool test_locate_cards_w(SCARDCONTEXT context)
609{
610 LPWSTR name = L"Gemalto PC Twin Reader 00 00\0\0";
611 SCARD_READERSTATEW rgReaderStates[16] = {};
612
613 auto rc = SCardLocateCardsW(context, name, rgReaderStates, ARRAYSIZE(rgReaderStates));
614 if (rc != SCARD_S_SUCCESS)
615 {
616 std::cerr << "SCardLocateCardsW failed with " << err2str(rc) << std::endl;
617 return false;
618 }
619
620 return true;
621}
622
623static bool test_locate_cards_by_atr_a(SCARDCONTEXT context)
624{
625 SCARD_READERSTATEA rgReaderStates[16] = {};
626 SCARD_ATRMASK rgAtrMasks[16] = {};
627
628 auto rc = SCardLocateCardsByATRA(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates,
629 ARRAYSIZE(rgReaderStates));
630 if (rc != SCARD_S_SUCCESS)
631 {
632 std::cerr << "SCardLocateCardsByATRA failed with " << err2str(rc) << std::endl;
633 return false;
634 }
635
636 return true;
637}
638
639static bool test_locate_cards_by_atr_w(SCARDCONTEXT context)
640{
641 SCARD_READERSTATEW rgReaderStates[16] = {};
642 SCARD_ATRMASK rgAtrMasks[16] = {};
643
644 auto rc = SCardLocateCardsByATRW(context, rgAtrMasks, ARRAYSIZE(rgAtrMasks), rgReaderStates,
645 ARRAYSIZE(rgReaderStates));
646 if (rc != SCARD_S_SUCCESS)
647 {
648 std::cerr << "SCardLocateCardsByATRW failed with " << err2str(rc) << std::endl;
649 return false;
650 }
651
652 return true;
653}
654
655static bool test_devicetype_id_a(SCARDCONTEXT context)
656{
657 BYTE data[32] = {};
658 LPSTR name = "testdata";
659 DWORD type;
660
661 auto rc = SCardGetDeviceTypeIdA(context, name, &type);
662 if (rc != SCARD_S_SUCCESS)
663 {
664 std::cerr << "SCardGetDeviceTypeIdA failed with " << err2str(rc) << std::endl;
665 return false;
666 }
667
668 return true;
669}
670
671static bool test_devicetype_id_w(SCARDCONTEXT context)
672{
673 BYTE data[32] = {};
674 LPWSTR name = L"testdata";
675 DWORD type;
676
677 auto rc = SCardGetDeviceTypeIdW(context, name, &type);
678 if (rc != SCARD_S_SUCCESS)
679 {
680 std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
681 return false;
682 }
683
684 return true;
685}
686
687static bool test_transmitcount(SCARDHANDLE handle)
688{
689 BYTE data[32] = {};
690 LPWSTR name = L"testdata";
691 DWORD count;
692
693 auto rc = SCardGetTransmitCount(handle, &count);
694 if (rc != SCARD_S_SUCCESS)
695 {
696 std::cerr << "SCardGetTransmitCount failed with " << err2str(rc) << std::endl;
697 return false;
698 }
699 std::cout << "SCardGetTransmitCount() " << count << std::endl;
700 return true;
701}
702
703static bool test_status_a(SCARDHANDLE handle)
704{
705 BYTE data[32] = {};
706 LPWSTR name = L"testdata";
707 DWORD count;
708 /*
709 auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen);
710 if (rc != SCARD_S_SUCCESS) {
711 std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
712 return false;
713 }
714 */
715 return true;
716}
717
718static bool test_status_w(SCARDHANDLE handle)
719{
720 BYTE data[32] = {};
721 LPWSTR name = L"testdata";
722 DWORD count;
723 /*
724 auto rc = SCardStatusA(handle, names, len, &state, &protocol, attr, &attrlen);
725 if (rc != SCARD_S_SUCCESS) {
726 std::cerr << "SCardGetDeviceTypeIdW failed with " << err2str(rc) << std::endl;
727 return false;
728 }
729*/
730 return true;
731}
732
733static bool test_get_attrib(SCARDCONTEXT context, SCARDHANDLE handle)
734{
735 DWORD attrlen = SCARD_AUTOALLOCATE;
736 LPBYTE attr = nullptr;
737
738 auto rc =
739 SCardGetAttrib(handle, SCARD_ATTR_ATR_STRING, reinterpret_cast<LPBYTE>(&attr), &attrlen);
740 if (rc != SCARD_S_SUCCESS)
741 {
742 std::cerr << "SCardGetAttrib failed with " << err2str(rc) << std::endl;
743 return false;
744 }
745 std::cout << "SCardGetAttrib [" << attrlen << "]: " << (char*)attr << std::endl;
746 SCardFreeMemory(context, attr);
747
748 return true;
749}
750
751static bool test_set_attrib(SCARDCONTEXT context, SCARDHANDLE handle)
752{
753 DWORD attrlen = SCARD_AUTOALLOCATE;
754 BYTE attr[] = "0123456789";
755
756 auto rc = SCardSetAttrib(handle, SCARD_ATTR_SUPRESS_T1_IFS_REQUEST, attr, ARRAYSIZE(attr));
757 if (rc != SCARD_S_SUCCESS)
758 {
759 std::cerr << "SCardSetAttrib failed with " << err2str(rc) << std::endl;
760 return false;
761 }
762 std::cout << "SCardSetAttrib [" << attrlen << "]: " << (char*)attr << std::endl;
763 SCardFreeMemory(context, attr);
764
765 return true;
766}
767
768int main()
769{
770 std::cout << "Hello World!" << std::endl;
771 try
772 {
773 auto scopes = { SCARD_SCOPE_USER, SCARD_SCOPE_SYSTEM };
774 for (auto scope : scopes)
775 {
776 SCARDCONTEXT context;
777 auto rc = SCardEstablishContext(scope, nullptr, nullptr, &context);
778 if (rc != SCARD_S_SUCCESS)
779 {
780 std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] failed with "
781 << err2str(rc) << std::endl;
782 }
783 else
784 {
785 std::cerr << "SCardEstablishContext [" << scope2str(scope) << "] success"
786 << std::endl;
787
788 test_valid(context);
789
790 test_list_reader_groups_a(context);
791 test_list_reader_groups_w(context);
792
793 test_list_readers_a(context);
794 test_list_readers_w(context);
795
796 test_list_cards_a(context);
797 test_list_cards_w(context);
798
799 test_introduce_forget_reader_groups_a(context);
800 test_introduce_forget_reader_groups_w(context);
801
802 test_introduce_forget_reader_a(context);
803 test_introduce_forget_reader_w(context);
804
805 // TODO: Introduce/Remove reader to group
806 test_locate_cards_a(context);
807 test_locate_cards_w(context);
808
809 test_locate_cards_by_atr_a(context);
810 test_locate_cards_by_atr_w(context);
811
812 test_cache_a(context);
813 test_cache_w(context);
814
815 test_reader_icon_a(context);
816 test_reader_icon_w(context);
817
818 test_devicetype_id_a(context);
819 test_devicetype_id_w(context);
820
821 // TODO: statuschange
822 // TODO: begin/end transaction
823 // TODO: state
824 // TODO: transmit
825 // TODO: control
826
827 {
828 DWORD protocol;
829 SCARDHANDLE handle = 0;
830 LPSTR mszReaders;
831 DWORD chReaders = SCARD_AUTOALLOCATE;
832
833 LONG status = SCardListReadersA(
834 context, nullptr, reinterpret_cast<LPSTR>(&mszReaders), &chReaders);
835 if (status == SCARD_S_SUCCESS)
836 status = SCardConnectA(context, mszReaders, SCARD_SHARE_SHARED,
837 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 |
838 SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW,
839 &handle, &protocol);
840 SCardFreeMemory(context, mszReaders);
841 if (status != SCARD_S_SUCCESS)
842 {
843 std::cerr << "SCardConnectA ["
844 << "] failed with " << err2str(status) << std::endl;
845 }
846 else
847 {
848 test_status_a(handle);
849 test_status_w(handle);
850 test_get_attrib(context, handle);
851 test_set_attrib(context, handle);
852 test_transmitcount(handle);
853
854 status = SCardDisconnect(handle, 0);
855 if (status)
856 {
857 std::cerr << "SCardDisconnect ["
858 << "] failed with " << err2str(status) << std::endl;
859 }
860 }
861 }
862 {
863 DWORD protocol;
864 SCARDHANDLE handle = 0;
865 LPWSTR mszReaders;
866 DWORD chReaders = SCARD_AUTOALLOCATE;
867
868 LONG status = SCardListReadersW(
869 context, nullptr, reinterpret_cast<LPWSTR>(&mszReaders), &chReaders);
870 if (status == SCARD_S_SUCCESS)
871 status = SCardConnectW(context, mszReaders, SCARD_SHARE_SHARED,
872 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 |
873 SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW,
874 &handle, &protocol);
875 SCardFreeMemory(context, mszReaders);
876
877 if (status != SCARD_S_SUCCESS)
878 {
879 std::cerr << "SCardConnectW ["
880 << "] failed with " << err2str(status) << std::endl;
881 }
882 else
883 {
884 test_status_a(handle);
885 test_status_w(handle);
886 test_get_attrib(context, handle);
887 test_set_attrib(context, handle);
888 test_transmitcount(handle);
889
890 status = SCardDisconnect(handle, 0);
891 if (status)
892 {
893 std::cerr << "SCardDisconnect ["
894 << "] failed with " << err2str(status) << std::endl;
895 }
896 }
897 }
898
899 rc = SCardReleaseContext(context);
900 if (rc != SCARD_S_SUCCESS)
901 {
902 std::cerr << "SCardReleaseContext [" << scope2str(scope) << "] failed with "
903 << err2str(rc) << std::endl;
904 }
905 }
906 }
907 }
908 catch (...)
909 {
910 std::cerr << "exception!!!!" << std::endl;
911 }
912
913 return 0;
914}
Definition wtypes.h:252