forked from LudovicRousseau/PCSC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SCardCancel.c
88 lines (68 loc) · 2.11 KB
/
SCardCancel.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#ifdef __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#else
#include <winscard.h>
#endif
#define CHECK(f, rv) printf(f ":[0x%08lX] %s\n", rv, pcsc_stringify_error(rv))
#define GREEN "\33[32m"
#define BRIGHT_RED "\33[01;31m"
#define NORMAL "\33[0m"
static SCARDCONTEXT context;
static void *canceler_thread(void *arg) {
LONG ret;
getchar();
printf("Calling SCardCancel...\n");
ret = SCardCancel(context);
CHECK("SCardCancel", ret);
return NULL;
}
int main(void) {
LONG ret;
int delay = 3;
ret = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &context);
CHECK("SCardEstablishContext", ret);
// Spawn a thread which waits for a key-press then cancels the operation.
pthread_t thread;
ret = pthread_create(&thread, NULL, canceler_thread, NULL);
printf(GREEN "Press Enter to cancel within %d seconds\n" NORMAL, delay);
// Set up the blocking call, and wait for cancel or timeout.
printf("Entering blocking call\n");
SCARD_READERSTATE reader_states[] = {
{
.szReader = "\\\\?PnP?\\Notification",
.pvUserData = NULL,
.dwCurrentState = SCARD_STATE_UNAWARE,
.dwEventState = SCARD_STATE_UNAWARE,
},
};
ret = SCardGetStatusChange(context, delay * 1000, reader_states, 1);
CHECK("SCardGetStatusChange", ret);
switch (ret) {
case SCARD_S_SUCCESS:
printf("Blocking call exited normally\n");
break;
case SCARD_E_CANCELLED:
/* this should be the correct returned value */
printf("Blocking call canceled\n");
break;
case SCARD_E_TIMEOUT:
printf("Blocking call timed out\n");
break;
default:
fprintf(stderr, "Failed to get status changes: %ld", ret);
break;
}
if (SCARD_E_CANCELLED != ret)
printf(BRIGHT_RED "ERROR: Something wrong happened!\n" NORMAL);
else
printf(GREEN "Good\n" NORMAL);
ret = SCardReleaseContext(context);
CHECK("SCardReleaseContext", ret);
printf("Waiting thread...\n");
pthread_join(thread, NULL);
return 0;
}