1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <pthread.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <sys/un.h>
12 #include <sys/stat.h>
13 
14 #include "string_calls.h"
15 
16 #define PCSC_API
17 
18 typedef unsigned char BYTE;
19 typedef BYTE *LPBYTE;
20 #ifdef __APPLE__
21 typedef int LONG;
22 typedef unsigned int DWORD;
23 #else
24 typedef long LONG;
25 typedef unsigned long DWORD;
26 #endif
27 typedef DWORD *LPDWORD;
28 typedef const void *LPCVOID;
29 typedef const char *LPCSTR;
30 typedef char *LPSTR;
31 typedef void *LPVOID;
32 typedef const BYTE *LPCBYTE;
33 
34 typedef LONG SCARDCONTEXT;
35 typedef SCARDCONTEXT *LPSCARDCONTEXT;
36 
37 typedef LONG SCARDHANDLE;
38 typedef SCARDHANDLE *LPSCARDHANDLE;
39 
40 #define MAX_ATR_SIZE 33
41 
42 typedef struct _SCARD_READERSTATE
43 {
44     const char *szReader;
45     void *pvUserData;
46     DWORD dwCurrentState;
47     DWORD dwEventState;
48     DWORD cbAtr;
49     unsigned char rgbAtr[MAX_ATR_SIZE];
50 } SCARD_READERSTATE, *LPSCARD_READERSTATE;
51 
52 typedef struct _SCARD_IO_REQUEST
53 {
54     unsigned long dwProtocol;
55     unsigned long cbPciLength;
56 } SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
57 
58 #define SCARD_PROTOCOL_T0       0x0001 /**< T=0 active protocol. */
59 #define SCARD_PROTOCOL_T1       0x0002 /**< T=1 active protocol. */
60 #define SCARD_PROTOCOL_RAW      0x0004 /**< Raw active protocol. */
61 
62 PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci  = { SCARD_PROTOCOL_T0,  8 };
63 PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci  = { SCARD_PROTOCOL_T1,  8 };
64 PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
65 
66 #define LLOG_LEVEL 5
67 #define LLOGLN(_level, _args) \
68     do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
69 #define LHEXDUMP(_level, _args) \
70     do { if  (_level < LLOG_LEVEL) { lhexdump _args ; } } while (0)
71 
72 #define SCARD_ESTABLISH_CONTEXT  0x01
73 #define SCARD_RELEASE_CONTEXT    0x02
74 #define SCARD_LIST_READERS       0x03
75 #define SCARD_CONNECT            0x04
76 #define SCARD_RECONNECT          0x05
77 #define SCARD_DISCONNECT         0x06
78 #define SCARD_BEGIN_TRANSACTION  0x07
79 #define SCARD_END_TRANSACTION    0x08
80 #define SCARD_TRANSMIT           0x09
81 #define SCARD_CONTROL            0x0A
82 #define SCARD_STATUS             0x0B
83 #define SCARD_GET_STATUS_CHANGE  0x0C
84 #define SCARD_CANCEL             0x0D
85 #define SCARD_CANCEL_TRANSACTION 0x0E
86 #define SCARD_GET_ATTRIB         0x0F
87 #define SCARD_SET_ATTRIB         0x10
88 
89 #define SCARD_S_SUCCESS 0x00000000
90 #define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001)
91 
92 #define SET_UINT32(_data, _offset, _val) do { \
93         (((BYTE*)(_data)) + (_offset))[0] = ((_val) >> 0)  & 0xff; \
94         (((BYTE*)(_data)) + (_offset))[1] = ((_val) >> 8)  & 0xff; \
95         (((BYTE*)(_data)) + (_offset))[2] = ((_val) >> 16) & 0xff; \
96         (((BYTE*)(_data)) + (_offset))[3] = ((_val) >> 24) & 0xff; } while (0)
97 
98 #define GET_UINT32(_data, _offset) \
99     ((((BYTE*)(_data)) + (_offset))[0] << 0)  | \
100     ((((BYTE*)(_data)) + (_offset))[1] << 8)  | \
101     ((((BYTE*)(_data)) + (_offset))[2] << 16) | \
102     ((((BYTE*)(_data)) + (_offset))[3] << 24)
103 
104 #define LMIN(_val1, _val2) (_val1) < (_val2) ? (_val1) : (_val2)
105 #define LMAX(_val1, _val2) (_val1) > (_val2) ? (_val1) : (_val2)
106 
107 static int g_sck = -1; /* unix domain socket */
108 
109 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
110 
111 /* for pcsc_stringify_error */
112 static char g_error_str[512];
113 
114 /*****************************************************************************/
115 /* produce a hex dump */
116 static void
lhexdump(void * p,int len)117 lhexdump(void *p, int len)
118 {
119     unsigned char *line;
120     int i;
121     int thisline;
122     int offset;
123 
124     line = (unsigned char *)p;
125     offset = 0;
126 
127     while (offset < len)
128     {
129         printf("%04x ", offset);
130         thisline = len - offset;
131 
132         if (thisline > 16)
133         {
134             thisline = 16;
135         }
136 
137         for (i = 0; i < thisline; i++)
138         {
139             printf("%02x ", line[i]);
140         }
141 
142         for (; i < 16; i++)
143         {
144             printf("   ");
145         }
146 
147         for (i = 0; i < thisline; i++)
148         {
149             printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
150         }
151 
152         printf("\n");
153         offset += thisline;
154         line += thisline;
155     }
156 }
157 
158 /*****************************************************************************/
159 static int
connect_to_chansrv(void)160 connect_to_chansrv(void)
161 {
162     int bytes;
163     int dis;
164     int error;
165     char *xrdp_session;
166     char *xrdp_display;
167     char *home_str;
168     struct sockaddr_un saddr;
169     struct sockaddr *psaddr;
170 
171     if (g_sck != -1)
172     {
173         /* already connected */
174         return 0;
175     }
176     xrdp_session = getenv("XRDP_SESSION");
177     if (xrdp_session == NULL)
178     {
179         /* XRDP_SESSION must be set */
180         LLOGLN(0, ("connect_to_chansrv: error, not xrdp session"));
181         return 1;
182     }
183     xrdp_display = getenv("DISPLAY");
184     if (xrdp_display == NULL)
185     {
186         /* DISPLAY must be set */
187         LLOGLN(0, ("connect_to_chansrv: error, display not set"));
188         return 1;
189     }
190     home_str = getenv("HOME");
191     if (home_str == NULL)
192     {
193         /* HOME must be set */
194         LLOGLN(0, ("connect_to_chansrv: error, home not set"));
195         return 1;
196     }
197     dis = g_get_display_num_from_display(xrdp_display);
198     if (dis < 0)
199     {
200         LLOGLN(0, ("connect_to_chansrv: error, don't understand DISPLAY='%s'",
201                xrdp_display));
202         return 1;
203     }
204     g_sck = socket(PF_LOCAL, SOCK_STREAM, 0);
205     if (g_sck == -1)
206     {
207         LLOGLN(0, ("connect_to_chansrv: error, socket failed"));
208         return 1;
209     }
210     memset(&saddr, 0, sizeof(struct sockaddr_un));
211     saddr.sun_family = AF_UNIX;
212     bytes = sizeof(saddr.sun_path);
213     snprintf(saddr.sun_path, bytes, "%s/.pcsc%d/pcscd.comm", home_str, dis);
214     saddr.sun_path[bytes - 1] = 0;
215     LLOGLN(10, ("connect_to_chansrv: connecting to %s", saddr.sun_path));
216     psaddr = (struct sockaddr *) &saddr;
217     bytes = sizeof(struct sockaddr_un);
218     error = connect(g_sck, psaddr, bytes);
219     if (error == 0)
220     {
221     }
222     else
223     {
224         perror("connect_to_chansrv");
225         close(g_sck);
226         g_sck = -1;
227         LLOGLN(0, ("connect_to_chansrv: error, open %s", saddr.sun_path));
228         return 1;
229     }
230     return 0;
231 }
232 
233 /*****************************************************************************/
234 static int
send_message(int code,char * data,int bytes)235 send_message(int code, char *data, int bytes)
236 {
237     char header[8];
238 
239     pthread_mutex_lock(&g_mutex);
240     SET_UINT32(header, 0, bytes);
241     SET_UINT32(header, 4, code);
242     if (send(g_sck, header, 8, 0) != 8)
243     {
244         pthread_mutex_unlock(&g_mutex);
245         return 1;
246     }
247     if (send(g_sck, data, bytes, 0) != bytes)
248     {
249         pthread_mutex_unlock(&g_mutex);
250         return 1;
251     }
252     LLOGLN(10, ("send_message:"));
253     LHEXDUMP(10, (data, bytes));
254     pthread_mutex_unlock(&g_mutex);
255     return 0;
256 }
257 
258 /*****************************************************************************/
259 static int
get_message(int * code,char * data,int * bytes)260 get_message(int *code, char *data, int *bytes)
261 {
262     char header[8];
263     int max_bytes;
264     int error;
265     int recv_rv;
266     int max;
267     int lcode;
268     struct timeval time;
269     fd_set rd_set;
270 
271     LLOGLN(10, ("get_message:"));
272     max = g_sck + 1;
273     while (1)
274     {
275         LLOGLN(10, ("get_message: loop"));
276         time.tv_sec = 1;
277         time.tv_usec = 0;
278         FD_ZERO(&rd_set);
279         FD_SET(((unsigned int)g_sck), &rd_set);
280         error = select(max, &rd_set, 0, 0, &time);
281         if (error == 1)
282         {
283             pthread_mutex_lock(&g_mutex);
284             time.tv_sec = 0;
285             time.tv_usec = 0;
286             FD_ZERO(&rd_set);
287             FD_SET(((unsigned int)g_sck), &rd_set);
288             error = select(max, &rd_set, 0, 0, &time);
289             if (error == 1)
290             {
291                 /* just take a look at the next message */
292                 recv_rv = recv(g_sck, header, 8, MSG_PEEK);
293                 if (recv_rv == 8)
294                 {
295                     lcode = GET_UINT32(header, 4);
296                     if (lcode == *code)
297                     {
298                         /* still have mutex lock */
299                         break;
300                     }
301                     else
302                     {
303                         LLOGLN(10, ("get_message: lcode %d *code %d",
304                                     lcode, *code));
305                     }
306                 }
307                 else if (recv_rv == 0)
308                 {
309                     pthread_mutex_unlock(&g_mutex);
310                     LLOGLN(0, ("get_message: recv_rv 0, disconnect"));
311                     return 1;
312                 }
313                 else
314                 {
315                     LLOGLN(10, ("get_message: recv_rv %d", recv_rv));
316                 }
317             }
318             else
319             {
320                 LLOGLN(10, ("get_message: select return %d", error));
321             }
322             pthread_mutex_unlock(&g_mutex);
323             usleep(1000);
324         }
325     }
326 
327     if (recv(g_sck, header, 8, 0) != 8)
328     {
329         pthread_mutex_unlock(&g_mutex);
330         return 1;
331     }
332     max_bytes = *bytes;
333     *bytes = GET_UINT32(header, 0);
334     *code = GET_UINT32(header, 4);
335     if (*bytes > max_bytes)
336     {
337         pthread_mutex_unlock(&g_mutex);
338         return 1;
339     }
340     if (recv(g_sck, data, *bytes, 0) != *bytes)
341     {
342         pthread_mutex_unlock(&g_mutex);
343         return 1;
344     }
345     pthread_mutex_unlock(&g_mutex);
346     return 0;
347 }
348 
349 /*****************************************************************************/
350 PCSC_API LONG
SCardEstablishContext(DWORD dwScope,LPCVOID pvReserved1,LPCVOID pvReserved2,LPSCARDCONTEXT phContext)351 SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2,
352                       LPSCARDCONTEXT phContext)
353 {
354     char msg[256];
355     DWORD context;
356     int code;
357     int bytes;
358     int status;
359 
360     LLOGLN(10, ("SCardEstablishContext:"));
361     if (g_sck == -1)
362     {
363         if (connect_to_chansrv() != 0)
364         {
365             LLOGLN(0, ("SCardEstablishContext: error, can not connect "
366                        "to chansrv"));
367             return SCARD_F_INTERNAL_ERROR;
368         }
369     }
370     SET_UINT32(msg, 0, dwScope);
371     if (send_message(SCARD_ESTABLISH_CONTEXT, msg, 4) != 0)
372     {
373         LLOGLN(0, ("SCardEstablishContext: error, send_message"));
374         return SCARD_F_INTERNAL_ERROR;
375     }
376     bytes = 256;
377     code = SCARD_ESTABLISH_CONTEXT;
378     if (get_message(&code, msg, &bytes) != 0)
379     {
380         LLOGLN(0, ("SCardEstablishContext: error, get_message"));
381         return SCARD_F_INTERNAL_ERROR;
382     }
383     if ((code != SCARD_ESTABLISH_CONTEXT) || (bytes != 8))
384     {
385         LLOGLN(0, ("SCardEstablishContext: error, bad code"));
386         return SCARD_F_INTERNAL_ERROR;
387     }
388     context = GET_UINT32(msg, 0);
389     status = GET_UINT32(msg, 4);
390     LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", (int)context));
391     *phContext = context;
392     return status;
393 }
394 
395 /*****************************************************************************/
396 PCSC_API LONG
SCardReleaseContext(SCARDCONTEXT hContext)397 SCardReleaseContext(SCARDCONTEXT hContext)
398 {
399     char msg[256];
400     int code;
401     int bytes;
402     int status;
403 
404     LLOGLN(10, ("SCardReleaseContext:"));
405     if (g_sck == -1)
406     {
407         LLOGLN(0, ("SCardReleaseContext: error, not connected"));
408         return SCARD_F_INTERNAL_ERROR;
409     }
410     SET_UINT32(msg, 0, hContext);
411     if (send_message(SCARD_RELEASE_CONTEXT, msg, 4) != 0)
412     {
413         LLOGLN(0, ("SCardReleaseContext: error, send_message"));
414         return SCARD_F_INTERNAL_ERROR;
415     }
416     bytes = 256;
417     code = SCARD_RELEASE_CONTEXT;
418     if (get_message(&code, msg, &bytes) != 0)
419     {
420         LLOGLN(0, ("SCardReleaseContext: error, get_message"));
421         return SCARD_F_INTERNAL_ERROR;
422     }
423     if ((code != SCARD_RELEASE_CONTEXT) || (bytes != 4))
424     {
425         LLOGLN(0, ("SCardReleaseContext: error, bad code"));
426         return SCARD_F_INTERNAL_ERROR;
427     }
428     status = GET_UINT32(msg, 0);
429     LLOGLN(10, ("SCardReleaseContext: got status 0x%8.8x", status));
430     return status;
431 }
432 
433 /*****************************************************************************/
434 PCSC_API LONG
SCardIsValidContext(SCARDCONTEXT hContext)435 SCardIsValidContext(SCARDCONTEXT hContext)
436 {
437     LLOGLN(10, ("SCardIsValidContext:"));
438     if (g_sck == -1)
439     {
440         LLOGLN(0, ("SCardIsValidContext: error, not connected"));
441         return SCARD_F_INTERNAL_ERROR;
442     }
443     return SCARD_S_SUCCESS;
444 }
445 
446 /*****************************************************************************/
447 PCSC_API LONG
SCardConnect(SCARDCONTEXT hContext,LPCSTR szReader,DWORD dwShareMode,DWORD dwPreferredProtocols,LPSCARDHANDLE phCard,LPDWORD pdwActiveProtocol)448 SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
449              DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
450              LPDWORD pdwActiveProtocol)
451 {
452     char msg[256];
453     int code;
454     int bytes;
455     int status;
456     int offset;
457 
458     LLOGLN(10, ("SCardConnect:"));
459     LLOGLN(10, ("SCardConnect: hContext 0x%8.8x szReader %s dwShareMode %d "
460                 "dwPreferredProtocols %d",
461                 (int)hContext, szReader, (int)dwShareMode, (int)dwPreferredProtocols));
462     if (g_sck == -1)
463     {
464         LLOGLN(0, ("SCardConnect: error, not connected"));
465         return SCARD_F_INTERNAL_ERROR;
466     }
467     offset = 0;
468     SET_UINT32(msg, offset, hContext);
469     offset += 4;
470     bytes = strlen(szReader);
471     if (bytes > 99)
472     {
473         LLOGLN(0, ("SCardConnect: error, name too long"));
474         return SCARD_F_INTERNAL_ERROR;
475     }
476     memcpy(msg + offset, szReader, bytes);
477     memset(msg + offset + bytes, 0, 100 - bytes);
478     offset += 100;
479     SET_UINT32(msg, offset, dwShareMode);
480     offset += 4;
481     SET_UINT32(msg, offset, dwPreferredProtocols);
482     offset += 4;
483     if (send_message(SCARD_CONNECT, msg, offset) != 0)
484     {
485         LLOGLN(0, ("SCardConnect: error, send_message"));
486         return SCARD_F_INTERNAL_ERROR;
487     }
488     bytes = 256;
489     code = SCARD_CONNECT;
490     if (get_message(&code, msg, &bytes) != 0)
491     {
492         LLOGLN(0, ("SCardConnect: error, get_message"));
493         return SCARD_F_INTERNAL_ERROR;
494     }
495     if (code != SCARD_CONNECT)
496     {
497         LLOGLN(0, ("SCardConnect: error, bad code"));
498         return SCARD_F_INTERNAL_ERROR;
499     }
500     *phCard = GET_UINT32(msg, 0);
501     *pdwActiveProtocol = GET_UINT32(msg, 4);
502     status = GET_UINT32(msg, 8);
503     LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard 0x%8.8x "
504                 "dwActiveProtocol %d",
505                 status, (int)*phCard, (int)*pdwActiveProtocol));
506     return status;
507 }
508 
509 /*****************************************************************************/
510 PCSC_API LONG
SCardReconnect(SCARDHANDLE hCard,DWORD dwShareMode,DWORD dwPreferredProtocols,DWORD dwInitialization,LPDWORD pdwActiveProtocol)511 SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
512                DWORD dwPreferredProtocols, DWORD dwInitialization,
513                LPDWORD pdwActiveProtocol)
514 {
515     LLOGLN(0, ("SCardReconnect:"));
516     if (g_sck == -1)
517     {
518         LLOGLN(0, ("SCardReconnect: error, not connected"));
519         return SCARD_F_INTERNAL_ERROR;
520     }
521     return SCARD_S_SUCCESS;
522 }
523 
524 /*****************************************************************************/
525 PCSC_API LONG
SCardDisconnect(SCARDHANDLE hCard,DWORD dwDisposition)526 SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
527 {
528     char msg[256];
529     int code;
530     int bytes;
531     int status;
532 
533     LLOGLN(10, ("SCardDisconnect: hCard 0x%8.8x dwDisposition %d",
534                 (int)hCard, (int)dwDisposition));
535     if (g_sck == -1)
536     {
537         LLOGLN(0, ("SCardDisconnect: error, not connected"));
538         return SCARD_F_INTERNAL_ERROR;
539     }
540     SET_UINT32(msg, 0, hCard);
541     SET_UINT32(msg, 4, dwDisposition);
542     if (send_message(SCARD_DISCONNECT, msg, 8) != 0)
543     {
544         LLOGLN(0, ("SCardDisconnect: error, send_message"));
545         return SCARD_F_INTERNAL_ERROR;
546     }
547     bytes = 256;
548     code = SCARD_DISCONNECT;
549     if (get_message(&code, msg, &bytes) != 0)
550     {
551         LLOGLN(0, ("SCardDisconnect: error, get_message"));
552         return SCARD_F_INTERNAL_ERROR;
553     }
554     if ((code != SCARD_DISCONNECT) || (bytes != 4))
555     {
556         LLOGLN(0, ("SCardDisconnect: error, bad code"));
557         return SCARD_F_INTERNAL_ERROR;
558     }
559     status = GET_UINT32(msg, 0);
560     LLOGLN(10, ("SCardDisconnect: got status 0x%8.8x", status));
561     return status;
562 }
563 
564 /*****************************************************************************/
565 PCSC_API LONG
SCardBeginTransaction(SCARDHANDLE hCard)566 SCardBeginTransaction(SCARDHANDLE hCard)
567 {
568     char msg[256];
569     int code;
570     int bytes;
571     int status;
572 
573     LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", (int)hCard));
574     if (hCard == 0)
575     {
576         LLOGLN(0, ("SCardBeginTransaction: error, bad hCard"));
577         return SCARD_F_INTERNAL_ERROR;
578     }
579     if (g_sck == -1)
580     {
581         LLOGLN(0, ("SCardBeginTransaction: error, not connected"));
582         return SCARD_F_INTERNAL_ERROR;
583     }
584     SET_UINT32(msg, 0, hCard);
585     if (send_message(SCARD_BEGIN_TRANSACTION, msg, 4) != 0)
586     {
587         LLOGLN(0, ("SCardBeginTransaction: error, send_message"));
588         return SCARD_F_INTERNAL_ERROR;
589     }
590     bytes = 256;
591     code = SCARD_BEGIN_TRANSACTION;
592     if (get_message(&code, msg, &bytes) != 0)
593     {
594         LLOGLN(0, ("SCardBeginTransaction: error, get_message"));
595         return SCARD_F_INTERNAL_ERROR;
596     }
597     if ((code != SCARD_BEGIN_TRANSACTION) || (bytes != 4))
598     {
599         LLOGLN(0, ("SCardBeginTransaction: error, bad code"));
600         return SCARD_F_INTERNAL_ERROR;
601     }
602     status = GET_UINT32(msg, 0);
603     LLOGLN(10, ("SCardBeginTransaction: got status 0x%8.8x", status));
604     return status;
605 }
606 
607 /*****************************************************************************/
608 PCSC_API LONG
SCardEndTransaction(SCARDHANDLE hCard,DWORD dwDisposition)609 SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
610 {
611     char msg[256];
612     int code;
613     int bytes;
614     int status;
615 
616     LLOGLN(10, ("SCardEndTransaction:"));
617     if (g_sck == -1)
618     {
619         LLOGLN(0, ("SCardEndTransaction: error, not connected"));
620         return SCARD_F_INTERNAL_ERROR;
621     }
622     SET_UINT32(msg, 0, hCard);
623     SET_UINT32(msg, 4, dwDisposition);
624     if (send_message(SCARD_END_TRANSACTION, msg, 8) != 0)
625     {
626         LLOGLN(0, ("SCardEndTransaction: error, send_message"));
627         return SCARD_F_INTERNAL_ERROR;
628     }
629     bytes = 256;
630     code = SCARD_END_TRANSACTION;
631     if (get_message(&code, msg, &bytes) != 0)
632     {
633         LLOGLN(0, ("SCardEndTransaction: error, get_message"));
634         return SCARD_F_INTERNAL_ERROR;
635     }
636     if ((code != SCARD_END_TRANSACTION) || (bytes != 4))
637     {
638         LLOGLN(0, ("SCardEndTransaction: error, bad code"));
639         return SCARD_F_INTERNAL_ERROR;
640     }
641     status = GET_UINT32(msg, 0);
642     LLOGLN(10, ("SCardEndTransaction: got status 0x%8.8x", status));
643     return status;
644 }
645 
646 /*****************************************************************************/
647 PCSC_API LONG
SCardStatus(SCARDHANDLE hCard,LPSTR mszReaderName,LPDWORD pcchReaderLen,LPDWORD pdwState,LPDWORD pdwProtocol,LPBYTE pbAtr,LPDWORD pcbAtrLen)648 SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
649             LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
650             LPDWORD pcbAtrLen)
651 {
652     char *msg;
653     int code;
654     int bytes;
655     int status;
656     int offset;
657     int cchReaderLen;
658     int to_copy;
659 
660     LLOGLN(10, ("SCardStatus:"));
661     if (hCard == 0)
662     {
663         LLOGLN(10, ("SCardStatus: error, bad hCard"));
664         return SCARD_F_INTERNAL_ERROR;
665     }
666     if (g_sck == -1)
667     {
668         LLOGLN(0, ("SCardStatus: error, not connected"));
669         return SCARD_F_INTERNAL_ERROR;
670     }
671     LLOGLN(10, ("  hCard 0x%8.8x", (int)hCard));
672     LLOGLN(10, ("  cchReaderLen %d", (int)*pcchReaderLen));
673     LLOGLN(10, ("  cbAtrLen %d", (int)*pcbAtrLen));
674 
675     cchReaderLen = *pcchReaderLen;
676     msg = (char *) malloc(8192);
677     SET_UINT32(msg, 0, hCard);
678     SET_UINT32(msg, 4, cchReaderLen);
679     SET_UINT32(msg, 8, *pcbAtrLen);
680     if (send_message(SCARD_STATUS, msg, 12) != 0)
681     {
682         LLOGLN(0, ("SCardStatus: error, send_message"));
683         free(msg);
684         return SCARD_F_INTERNAL_ERROR;
685     }
686     bytes = 8192;
687     code = SCARD_STATUS;
688     if (get_message(&code, msg, &bytes) != 0)
689     {
690         LLOGLN(0, ("SCardStatus: error, get_message"));
691         free(msg);
692         return SCARD_F_INTERNAL_ERROR;
693     }
694     if (code != SCARD_STATUS)
695     {
696         LLOGLN(0, ("SCardStatus: error, bad code"));
697         free(msg);
698         return SCARD_F_INTERNAL_ERROR;
699     }
700 
701     LLOGLN(10, ("SCardStatus: cchReaderLen in %d", (int)*pcchReaderLen));
702     offset = 0;
703     *pcchReaderLen = GET_UINT32(msg, offset);
704     LLOGLN(10, ("SCardStatus: cchReaderLen out %d", (int)*pcchReaderLen));
705     offset += 4;
706     if (cchReaderLen > 0)
707     {
708         to_copy = cchReaderLen - 1;
709         if (*pcchReaderLen < to_copy)
710         {
711             to_copy = *pcchReaderLen;
712         }
713         memcpy(mszReaderName, msg + offset, to_copy);
714         mszReaderName[to_copy] = 0;
715     }
716     LLOGLN(10, ("SCardStatus: mszReaderName out %s", mszReaderName));
717     offset += *pcchReaderLen;
718     *pdwState = GET_UINT32(msg, offset);
719     if (*pdwState == 1)
720     {
721         *pdwState = 0x34;
722     }
723     LLOGLN(10, ("SCardStatus: dwState %d", (int)*pdwState));
724     offset += 4;
725     *pdwProtocol = GET_UINT32(msg, offset);
726     LLOGLN(10, ("SCardStatus: dwProtocol %d", (int)*pdwProtocol));
727     offset += 4;
728     *pcbAtrLen = GET_UINT32(msg, offset);
729     offset += 4;
730     LLOGLN(10, ("SCardStatus: cbAtrLen %d", (int)*pcbAtrLen));
731     memcpy(pbAtr, msg + offset, *pcbAtrLen);
732     offset += *pcbAtrLen;
733     status = GET_UINT32(msg, offset);
734     LLOGLN(10, ("SCardStatus: status %d", status));
735     offset += 4;
736     free(msg);
737     return status;
738 }
739 
740 /*****************************************************************************/
741 PCSC_API LONG
SCardGetStatusChange(SCARDCONTEXT hContext,DWORD dwTimeout,LPSCARD_READERSTATE rgReaderStates,DWORD cReaders)742 SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
743                      LPSCARD_READERSTATE rgReaderStates, DWORD cReaders)
744 {
745     char *msg;
746     const char *rname;
747     int bytes;
748     int code;
749     int index;
750     int offset;
751     int str_len;
752     int status;
753     int dwCurrentState;
754     int dwEventState;
755     int cbAtr;
756     char atr[36];
757 
758     LLOGLN(10, ("SCardGetStatusChange:"));
759     LLOGLN(10, ("  dwTimeout %d cReaders %d", (int)dwTimeout, (int)cReaders));
760     if (g_sck == -1)
761     {
762         LLOGLN(0, ("SCardGetStatusChange: error, not connected"));
763         return SCARD_F_INTERNAL_ERROR;
764     }
765     msg = (char *) malloc(8192);
766     SET_UINT32(msg, 0, hContext);
767     SET_UINT32(msg, 4, dwTimeout);
768     SET_UINT32(msg, 8, cReaders);
769     offset = 12;
770     for (index = 0; index < cReaders; index++)
771     {
772         rgReaderStates[index].dwCurrentState &= ~2;
773         rgReaderStates[index].dwEventState &= ~2;
774         rname = rgReaderStates[index].szReader;
775         if (strcmp(rname, "\\\\?PnP?\\Notification") == 0)
776         {
777             LLOGLN(10, ("  \\\\?PnP?\\Notification present"));
778             dwCurrentState = 0;
779             dwEventState = 0;
780             cbAtr = 0;
781             memset(atr, 0, 36);
782         }
783         else
784         {
785             dwCurrentState = rgReaderStates[index].dwCurrentState;
786             dwEventState = rgReaderStates[index].dwEventState;
787             cbAtr = rgReaderStates[index].cbAtr;
788             memset(atr, 0, 36);
789             memcpy(atr, rgReaderStates[index].rgbAtr, 33);
790         }
791         str_len = strlen(rname);
792         str_len = LMIN(str_len, 99);
793         memset(msg + offset, 0, 100);
794         memcpy(msg + offset, rname, str_len);
795         LLOGLN(10, ("  in szReader       %s", rname));
796         offset += 100;
797         LLOGLN(10, ("  in dwCurrentState 0x%8.8x", dwCurrentState));
798         SET_UINT32(msg, offset, dwCurrentState);
799         offset += 4;
800         LLOGLN(10, ("  in dwEventState   0x%8.8x", dwEventState));
801         SET_UINT32(msg, offset, dwEventState);
802         offset += 4;
803         LLOGLN(10, ("  in cbAtr          %d", cbAtr));
804         SET_UINT32(msg, offset, cbAtr);
805         offset += 4;
806         memcpy(msg + offset, atr, 36);
807         offset += 36;
808     }
809     if (send_message(SCARD_GET_STATUS_CHANGE, msg, offset) != 0)
810     {
811         LLOGLN(0, ("SCardGetStatusChange: error, send_message"));
812         free(msg);
813         return SCARD_F_INTERNAL_ERROR;
814     }
815     bytes = 8192;
816     code = SCARD_GET_STATUS_CHANGE;
817     if (get_message(&code, msg, &bytes) != 0)
818     {
819         LLOGLN(0, ("SCardGetStatusChange: error, get_message"));
820         free(msg);
821         return SCARD_F_INTERNAL_ERROR;
822     }
823     if (code != SCARD_GET_STATUS_CHANGE)
824     {
825         LLOGLN(0, ("SCardGetStatusChange: error, bad code"));
826         free(msg);
827         return SCARD_F_INTERNAL_ERROR;
828     }
829     cReaders = GET_UINT32(msg, 0);
830     offset = 4;
831     LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", (int)cReaders));
832     for (index = 0; index < cReaders; index++)
833     {
834         rname = rgReaderStates[index].szReader;
835 #if 1
836         if (strcmp(rname, "\\\\?PnP?\\Notification") == 0)
837         {
838             LLOGLN(10, ("  out szReader       %s", rgReaderStates[index].szReader));
839             dwCurrentState = GET_UINT32(msg, offset);
840             rgReaderStates[index].dwCurrentState = dwCurrentState;
841             offset += 4;
842             LLOGLN(10, ("  out dwCurrentState 0x%8.8x", dwCurrentState));
843             // disable PnP for now
844             dwEventState = 4; // GET_UINT32(msg, offset);
845             rgReaderStates[index].dwEventState = dwEventState;
846             offset += 4;
847             LLOGLN(10, ("  out dwEventState   0x%8.8x", dwEventState));
848             cbAtr = GET_UINT32(msg, offset);
849             rgReaderStates[index].cbAtr = cbAtr;
850             offset += 4;
851             LLOGLN(10, ("  out cbAtr          %d", cbAtr));
852             memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33);
853             offset += 36;
854         }
855         else
856 #endif
857         {
858             LLOGLN(10, ("  out szReader       %s", rgReaderStates[index].szReader));
859             dwCurrentState = GET_UINT32(msg, offset);
860             rgReaderStates[index].dwCurrentState = dwCurrentState;
861             offset += 4;
862             LLOGLN(10, ("  out dwCurrentState 0x%8.8x", dwCurrentState));
863             dwEventState = GET_UINT32(msg, offset);
864             rgReaderStates[index].dwEventState = dwEventState;
865             offset += 4;
866             LLOGLN(10, ("  out dwEventState   0x%8.8x", dwEventState));
867             cbAtr = GET_UINT32(msg, offset);
868             rgReaderStates[index].cbAtr = cbAtr;
869             offset += 4;
870             LLOGLN(10, ("  out cbAtr          %d", cbAtr));
871             memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33);
872             offset += 36;
873         }
874     }
875     status = GET_UINT32(msg, offset);
876     offset += 4;
877     free(msg);
878     return status;
879 }
880 
881 /*****************************************************************************/
882 PCSC_API LONG
SCardControl(SCARDHANDLE hCard,DWORD dwControlCode,LPCVOID pbSendBuffer,DWORD cbSendLength,LPVOID pbRecvBuffer,DWORD cbRecvLength,LPDWORD lpBytesReturned)883 SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
884              DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
885              LPDWORD lpBytesReturned)
886 {
887     char *msg;
888     int bytes;
889     int code;
890     int offset;
891     int status = 0;
892 
893     LLOGLN(10, ("SCardControl:"));
894     if (g_sck == -1)
895     {
896         LLOGLN(0, ("SCardControl: error, not connected"));
897         return SCARD_F_INTERNAL_ERROR;
898     }
899     LLOGLN(10, ("  hCard 0x%8.8x", (int)hCard));
900     LLOGLN(10, ("  dwControlCode 0x%8.8x", (int)dwControlCode));
901     LLOGLN(10, ("  cbSendLength %d", (int)cbSendLength));
902     LLOGLN(10, ("  cbRecvLength %d", (int)cbRecvLength));
903 
904     /* #define SCARD_CTL_CODE(code) (0x42000000 + (code))
905        control_code = (control_code & 0x3ffc) >> 2;
906        control_code = SCARD_CTL_CODE(control_code); */
907 
908     /* PCSC to Windows control code conversion */
909     dwControlCode = dwControlCode - 0x42000000;
910     dwControlCode = dwControlCode << 2;
911     dwControlCode = dwControlCode | (49 << 16);
912     LLOGLN(10, ("  MS dwControlCode 0x%8.8d", (int)dwControlCode));
913 
914     msg = (char *) malloc(8192);
915     offset = 0;
916     SET_UINT32(msg, offset, hCard);
917     offset += 4;
918     SET_UINT32(msg, offset, dwControlCode);
919     offset += 4;
920     SET_UINT32(msg, offset, cbSendLength);
921     offset += 4;
922     memcpy(msg + offset, pbSendBuffer, cbSendLength);
923     offset += cbSendLength;
924     SET_UINT32(msg, offset, cbRecvLength);
925     offset += 4;
926     if (send_message(SCARD_CONTROL, msg, offset) != 0)
927     {
928         LLOGLN(0, ("SCardControl: error, send_message"));
929         free(msg);
930         return SCARD_F_INTERNAL_ERROR;
931     }
932     bytes = 8192;
933     code = SCARD_CONTROL;
934     if (get_message(&code, msg, &bytes) != 0)
935     {
936         LLOGLN(0, ("SCardControl: error, get_message"));
937         free(msg);
938         return SCARD_F_INTERNAL_ERROR;
939     }
940     if (code != SCARD_CONTROL)
941     {
942         LLOGLN(0, ("SCardControl: error, bad code"));
943         free(msg);
944         return SCARD_F_INTERNAL_ERROR;
945     }
946     offset = 0;
947     *lpBytesReturned = GET_UINT32(msg, offset);
948     LLOGLN(10, ("  cbRecvLength %d", (int)*lpBytesReturned));
949     offset += 4;
950     memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned);
951     offset += *lpBytesReturned;
952     status = GET_UINT32(msg, offset);
953     free(msg);
954     return status;
955 }
956 
957 /*****************************************************************************/
958 PCSC_API LONG
SCardTransmit(SCARDHANDLE hCard,const SCARD_IO_REQUEST * pioSendPci,LPCBYTE pbSendBuffer,DWORD cbSendLength,SCARD_IO_REQUEST * pioRecvPci,LPBYTE pbRecvBuffer,LPDWORD pcbRecvLength)959 SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
960               LPCBYTE pbSendBuffer, DWORD cbSendLength,
961               SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,
962               LPDWORD pcbRecvLength)
963 {
964     char *msg;
965     int bytes;
966     int code;
967     int offset;
968     int status;
969     int extra_len;
970     int got_recv_pci;
971 
972     LLOGLN(10, ("SCardTransmit:"));
973     if (g_sck == -1)
974     {
975         LLOGLN(0, ("SCardTransmit: error, not connected"));
976         return SCARD_F_INTERNAL_ERROR;
977     }
978 
979     LLOGLN(10, ("  hCard 0x%8.8x", (int)hCard));
980     LLOGLN(10, ("  cbSendLength %d", (int)cbSendLength));
981     LLOGLN(10, ("  cbRecvLength %d", (int)*pcbRecvLength));
982     LLOGLN(10, ("  pioSendPci->dwProtocol %d", (int)(pioSendPci->dwProtocol)));
983     LLOGLN(10, ("  pioSendPci->cbPciLength %d", (int)(pioSendPci->cbPciLength)));
984     LLOGLN(10, ("  pioRecvPci %p", pioRecvPci));
985     if (pioRecvPci != 0)
986     {
987         LLOGLN(10, ("    pioRecvPci->dwProtocol %d", (int)(pioRecvPci->dwProtocol)));
988         LLOGLN(10, ("    pioRecvPci->cbPciLength %d", (int)(pioRecvPci->cbPciLength)));
989     }
990     msg = (char *) malloc(8192);
991     offset = 0;
992     SET_UINT32(msg, offset, hCard);
993     offset += 4;
994     SET_UINT32(msg, offset, pioSendPci->dwProtocol);
995     offset += 4;
996     /*  SET_UINT32(msg, offset, pioSendPci->cbPciLength); */
997     SET_UINT32(msg, offset, 8);
998     offset += 4;
999     /*  extra_len = pioSendPci->cbPciLength - 8;  */
1000     extra_len = 0;
1001     SET_UINT32(msg, offset, extra_len);
1002     offset += 4;
1003     memcpy(msg + offset, pioSendPci + 1, extra_len);
1004     offset += extra_len;
1005     SET_UINT32(msg, offset, cbSendLength);
1006     offset += 4;
1007     memcpy(msg + offset, pbSendBuffer, cbSendLength);
1008     offset += cbSendLength;
1009     got_recv_pci = (pioRecvPci != NULL) && (pioRecvPci->cbPciLength >= 8);
1010     // TODO figure out why recv pci does not work
1011     got_recv_pci = 0;
1012     if (got_recv_pci == 0)
1013     {
1014         SET_UINT32(msg, offset, 0); /* dwProtocol */
1015         offset += 4;
1016         SET_UINT32(msg, offset, 0); /* cbPciLength */
1017         offset += 4;
1018         SET_UINT32(msg, offset, 0); /* extra_len */
1019         offset += 4;
1020     }
1021     else
1022     {
1023         SET_UINT32(msg, offset, pioRecvPci->dwProtocol);
1024         offset += 4;
1025         SET_UINT32(msg, offset, pioRecvPci->cbPciLength);
1026         offset += 4;
1027         extra_len = pioRecvPci->cbPciLength - 8;
1028         SET_UINT32(msg, offset, extra_len);
1029         offset += 4;
1030         memcpy(msg + offset, pioRecvPci + 1, extra_len);
1031         offset += extra_len;
1032     }
1033     SET_UINT32(msg, offset, *pcbRecvLength);
1034     offset += 4;
1035     if (send_message(SCARD_TRANSMIT, msg, offset) != 0)
1036     {
1037         LLOGLN(0, ("SCardTransmit: error, send_message"));
1038         free(msg);
1039         return SCARD_F_INTERNAL_ERROR;
1040     }
1041     bytes = 8192;
1042     code = SCARD_TRANSMIT;
1043     if (get_message(&code, msg, &bytes) != 0)
1044     {
1045         LLOGLN(0, ("SCardTransmit: error, get_message"));
1046         free(msg);
1047         return SCARD_F_INTERNAL_ERROR;
1048     }
1049     if (code != SCARD_TRANSMIT)
1050     {
1051         LLOGLN(0, ("SCardTransmit: error, bad code"));
1052         free(msg);
1053         return SCARD_F_INTERNAL_ERROR;
1054     }
1055     offset = 0;
1056     if (got_recv_pci == 0)
1057     {
1058         offset += 8;
1059         extra_len = GET_UINT32(msg, offset);
1060         offset += 4;
1061         offset += extra_len;
1062     }
1063     else
1064     {
1065         pioRecvPci->dwProtocol = GET_UINT32(msg, offset);
1066         offset += 4;
1067         pioRecvPci->cbPciLength = GET_UINT32(msg, offset);
1068         offset += 4;
1069         extra_len = GET_UINT32(msg, offset);
1070         offset += 4;
1071         offset += extra_len;
1072     }
1073     *pcbRecvLength = GET_UINT32(msg, offset);
1074     offset += 4;
1075     LLOGLN(10, ("  cbRecvLength %d", (int)*pcbRecvLength));
1076     memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength);
1077     LHEXDUMP(10, (pbRecvBuffer, *pcbRecvLength));
1078     offset += *pcbRecvLength;
1079     status = GET_UINT32(msg, offset);
1080     free(msg);
1081     return status;
1082 }
1083 
1084 /*****************************************************************************/
1085 PCSC_API LONG
SCardListReaderGroups(SCARDCONTEXT hContext,LPSTR mszGroups,LPDWORD pcchGroups)1086 SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
1087                       LPDWORD pcchGroups)
1088 {
1089     LLOGLN(10, ("SCardListReaderGroups:"));
1090     if (g_sck == -1)
1091     {
1092         LLOGLN(0, ("SCardListReaderGroups: error, not connected"));
1093         return SCARD_F_INTERNAL_ERROR;
1094     }
1095     return SCARD_S_SUCCESS;
1096 }
1097 
1098 /*****************************************************************************/
1099 PCSC_API LONG
SCardListReaders(SCARDCONTEXT hContext,LPCSTR mszGroups,LPSTR mszReaders,LPDWORD pcchReaders)1100 SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
1101                  LPDWORD pcchReaders)
1102 {
1103     char *msg;
1104     char *reader_names;
1105     int reader_names_index;
1106     int code;
1107     int bytes;
1108     int num_readers;
1109     int status;
1110     int offset;
1111     int index;
1112     int val;
1113     int llen;
1114     char reader[100];
1115 
1116     LLOGLN(10, ("SCardListReaders:"));
1117     LLOGLN(10, ("SCardListReaders: mszGroups %s", mszGroups));
1118     LLOGLN(10, ("SCardListReaders: *pcchReaders %d", (int)*pcchReaders));
1119     if (g_sck == -1)
1120     {
1121         LLOGLN(0, ("SCardListReaders: error, not connected"));
1122         return SCARD_F_INTERNAL_ERROR;
1123     }
1124     if ((mszGroups == NULL) && (mszReaders == NULL))
1125     {
1126         *pcchReaders = 0;
1127     }
1128     msg = (char *) malloc(8192);
1129     offset = 0;
1130     SET_UINT32(msg, offset, hContext);
1131     offset += 4;
1132     if (mszGroups != 0)
1133     {
1134         unsigned int bytes_groups = strlen(mszGroups);
1135         SET_UINT32(msg, offset, bytes_groups);
1136         offset += 4;
1137         memcpy(msg + offset, mszGroups, bytes_groups);
1138         offset += bytes_groups;
1139     }
1140     else
1141     {
1142         SET_UINT32(msg, offset, 0);
1143         offset += 4;
1144     }
1145     val = *pcchReaders;
1146     SET_UINT32(msg, offset, val);
1147     offset += 4;
1148     if (send_message(SCARD_LIST_READERS, msg, offset) != 0)
1149     {
1150         LLOGLN(0, ("SCardListReaders: error, send_message"));
1151         free(msg);
1152         return SCARD_F_INTERNAL_ERROR;
1153     }
1154     bytes = 8192;
1155     code = SCARD_LIST_READERS;
1156     if (get_message(&code, msg, &bytes) != 0)
1157     {
1158         LLOGLN(0, ("SCardListReaders: error, get_message"));
1159         free(msg);
1160         return SCARD_F_INTERNAL_ERROR;
1161     }
1162     if (code != SCARD_LIST_READERS)
1163     {
1164         LLOGLN(0, ("SCardListReaders: error, bad code"));
1165         free(msg);
1166         return SCARD_F_INTERNAL_ERROR;
1167     }
1168     offset = 0;
1169     llen = GET_UINT32(msg, offset);
1170     offset += 4;
1171     num_readers = GET_UINT32(msg, offset);
1172     offset += 4;
1173     LLOGLN(10, ("SCardListReaders: mszReaders %p pcchReaders %p num_readers %d",
1174                 mszReaders, pcchReaders, num_readers));
1175     reader_names = (char *) malloc(8192);
1176     reader_names_index = 0;
1177     for (index = 0; index < num_readers; index++)
1178     {
1179         memcpy(reader, msg + offset, 100);
1180         bytes = strlen(reader);
1181         memcpy(reader_names + reader_names_index, reader, bytes);
1182         reader_names_index += bytes;
1183         reader_names[reader_names_index] = 0;
1184         reader_names_index++;
1185         offset += 100;
1186         LLOGLN(10, ("SCardListReaders: readername %s", reader));
1187     }
1188     reader_names[reader_names_index] = 0;
1189     reader_names_index++;
1190     status = GET_UINT32(msg, offset);
1191     LLOGLN(10, ("SCardListReaders: status 0x%8.8x", status));
1192     offset += 4;
1193     if (mszReaders == 0)
1194     {
1195         reader_names_index = llen / 2;
1196     }
1197     if (pcchReaders != 0)
1198     {
1199         *pcchReaders = reader_names_index;
1200     }
1201     if (mszReaders != 0)
1202     {
1203         memcpy(mszReaders, reader_names, reader_names_index);
1204     }
1205     free(msg);
1206     free(reader_names);
1207     return status;
1208 }
1209 
1210 /*****************************************************************************/
1211 PCSC_API LONG
SCardFreeMemory(SCARDCONTEXT hContext,LPCVOID pvMem)1212 SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
1213 {
1214     LLOGLN(0, ("SCardFreeMemory:"));
1215     if (g_sck == -1)
1216     {
1217         LLOGLN(0, ("SCardFreeMemory: error, not connected"));
1218         return SCARD_F_INTERNAL_ERROR;
1219     }
1220     return SCARD_S_SUCCESS;
1221 }
1222 
1223 /*****************************************************************************/
1224 PCSC_API LONG
SCardCancel(SCARDCONTEXT hContext)1225 SCardCancel(SCARDCONTEXT hContext)
1226 {
1227     char msg[256];
1228     int code;
1229     int bytes;
1230     int status;
1231 
1232     LLOGLN(10, ("SCardCancel:"));
1233     if (g_sck == -1)
1234     {
1235         LLOGLN(0, ("SCardCancel: error, not connected"));
1236         return SCARD_F_INTERNAL_ERROR;
1237     }
1238     SET_UINT32(msg, 0, hContext);
1239     if (send_message(SCARD_CANCEL, msg, 4) != 0)
1240     {
1241         LLOGLN(0, ("SCardCancel: error, send_message"));
1242         return SCARD_F_INTERNAL_ERROR;
1243     }
1244     bytes = 256;
1245     code = SCARD_CANCEL;
1246     if (get_message(&code, msg, &bytes) != 0)
1247     {
1248         LLOGLN(0, ("SCardCancel: error, get_message"));
1249         return SCARD_F_INTERNAL_ERROR;
1250     }
1251     if ((code != SCARD_RELEASE_CONTEXT) || (bytes != 4))
1252     {
1253         LLOGLN(0, ("SCardCancel: error, bad code"));
1254         return SCARD_F_INTERNAL_ERROR;
1255     }
1256     status = GET_UINT32(msg, 0);
1257     LLOGLN(10, ("SCardCancel: got status 0x%8.8x", status));
1258     return status;
1259 }
1260 
1261 /*****************************************************************************/
1262 PCSC_API LONG
SCardGetAttrib(SCARDHANDLE hCard,DWORD dwAttrId,LPBYTE pbAttr,LPDWORD pcbAttrLen)1263 SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
1264                LPDWORD pcbAttrLen)
1265 {
1266     LLOGLN(0, ("SCardGetAttrib:"));
1267     if (g_sck == -1)
1268     {
1269         LLOGLN(0, ("SCardGetAttrib: error, not connected"));
1270         return SCARD_F_INTERNAL_ERROR;
1271     }
1272     return SCARD_S_SUCCESS;
1273 }
1274 
1275 /*****************************************************************************/
1276 PCSC_API LONG
SCardSetAttrib(SCARDHANDLE hCard,DWORD dwAttrId,LPCBYTE pbAttr,DWORD cbAttrLen)1277 SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
1278                DWORD cbAttrLen)
1279 {
1280     LLOGLN(0, ("SCardSetAttrib:"));
1281     if (g_sck == -1)
1282     {
1283         LLOGLN(0, ("SCardSetAttrib: error, not connected"));
1284         return SCARD_F_INTERNAL_ERROR;
1285     }
1286     return SCARD_S_SUCCESS;
1287 }
1288 
1289 /*****************************************************************************/
1290 PCSC_API char *
pcsc_stringify_error(const long code)1291 pcsc_stringify_error(const long code)
1292 {
1293     LLOGLN(10, ("pcsc_stringify_error: 0x%8.8x", (int)code));
1294     switch (code)
1295     {
1296         case SCARD_S_SUCCESS:
1297             snprintf(g_error_str, 511, "Command successful.");
1298             break;
1299         case SCARD_F_INTERNAL_ERROR:
1300             snprintf(g_error_str, 511, "Internal error.");
1301             break;
1302         default:
1303             snprintf(g_error_str, 511, "error 0x%8.8x", (int)code);
1304             break;
1305     }
1306     g_error_str[511] = 0;
1307     return g_error_str;
1308 }
1309