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