/[pcsclite]/tags/ccid/ccid-1.3.8/examples/scardcontrol.c
ViewVC logotype

Contents of /tags/ccid/ccid-1.3.8/examples/scardcontrol.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2592 - (hide annotations) (download)
Mon Jul 2 13:06:10 2007 UTC (5 years, 10 months ago) by rousseau
Original Path: trunk/Drivers/ccid/examples/scardcontrol.c
File MIME type: text/plain
File size: 16434 byte(s)
remove compilation warnings
1 rousseau 889 /*
2     scardcontrol.c: sample code to use/test SCardControl() API
3 rousseau 1751 Copyright (C) 2004-2005 Ludovic Rousseau
4 rousseau 889
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18     */
19    
20     /*
21     * $Id$
22     */
23    
24     #include <stdio.h>
25     #include <stdlib.h>
26 rousseau 1346 #include <sys/time.h>
27 rousseau 889 #include <unistd.h>
28     #include <string.h>
29 rousseau 2116 #include <arpa/inet.h>
30 rousseau 1771 #include <winscard.h>
31     #include <reader.h>
32 rousseau 889
33 rousseau 2407 #undef VERIFY_PIN
34     #define MODIFY_PIN
35 rousseau 1676
36 rousseau 889 #ifndef TRUE
37     #define TRUE 1
38     #define FALSE 0
39     #endif
40    
41     #define IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE SCARD_CTL_CODE(1)
42    
43     /* PCSC error message pretty print */
44     #define PCSC_ERROR_EXIT(rv, text) \
45     if (rv != SCARD_S_SUCCESS) \
46     { \
47     printf(text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \
48     goto end; \
49     } \
50     else \
51     printf(text ": OK\n\n");
52    
53     #define PCSC_ERROR_CONT(rv, text) \
54     if (rv != SCARD_S_SUCCESS) \
55     printf(text ": %s (0x%lX)\n", pcsc_stringify_error(rv), rv); \
56     else \
57     printf(text ": OK\n\n");
58    
59     int main(int argc, char *argv[])
60     {
61     LONG rv;
62     SCARDCONTEXT hContext;
63     DWORD dwReaders;
64 rousseau 2591 LPSTR mszReaders = NULL;
65 rousseau 889 char *ptr, **readers = NULL;
66     int nbReaders;
67     SCARDHANDLE hCard;
68     DWORD dwActiveProtocol, dwReaderLen, dwState, dwProt, dwAtrLen;
69     BYTE pbAtr[MAX_ATR_SIZE] = "";
70 rousseau 892 char pbReader[MAX_READERNAME] = "";
71 rousseau 889 int reader_nb;
72 rousseau 2592 unsigned int i;
73 rousseau 889 unsigned char bSendBuffer[MAX_BUFFER_SIZE];
74     unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
75 rousseau 1676 DWORD send_length, length;
76 rousseau 1631 DWORD verify_ioctl = 0;
77     DWORD modify_ioctl = 0;
78 rousseau 972 SCARD_IO_REQUEST pioRecvPci;
79 rousseau 1635 SCARD_IO_REQUEST pioSendPci;
80 rousseau 1631 PCSC_TLV_STRUCTURE *pcsc_tlv;
81 rousseau 1691 #if defined(VERIFY_PIN) | defined(MODIFY_PIN)
82     int offset;
83     #endif
84     #ifdef VERIFY_PIN
85 rousseau 1631 PIN_VERIFY_STRUCTURE *pin_verify;
86 rousseau 1691 #endif
87     #ifdef MODIFY_PIN
88 rousseau 1631 PIN_MODIFY_STRUCTURE *pin_modify;
89 rousseau 1691 #endif
90 rousseau 889
91     printf("SCardControl sample code\n");
92 rousseau 1676 printf("V 1.1 2004-2005, Ludovic Rousseau <ludovic.rousseau@free.fr>\n");
93 rousseau 889
94 rousseau 1263 printf("\nTHIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL!\n");
95     printf("Do NOT use it unless you really know what you do.\n\n");
96    
97 rousseau 889 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
98     if (rv != SCARD_S_SUCCESS)
99     {
100     printf("SCardEstablishContext: Cannot Connect to Resource Manager %lX\n", rv);
101     return 1;
102     }
103    
104     /* Retrieve the available readers list */
105     rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
106 rousseau 2590 PCSC_ERROR_EXIT(rv, "SCardListReaders")
107 rousseau 889
108     mszReaders = malloc(sizeof(char)*dwReaders);
109     if (mszReaders == NULL)
110     {
111     printf("malloc: not enough memory\n");
112     goto end;
113     }
114    
115     rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
116     if (rv != SCARD_S_SUCCESS)
117     printf("SCardListReader: %lX\n", rv);
118    
119     /* Extract readers from the null separated string and get the total
120     * number of readers */
121     nbReaders = 0;
122     ptr = mszReaders;
123     while (*ptr != '\0')
124     {
125     ptr += strlen(ptr)+1;
126     nbReaders++;
127     }
128    
129     if (nbReaders == 0)
130     {
131     printf("No reader found\n");
132     goto end;
133     }
134    
135     /* allocate the readers table */
136     readers = calloc(nbReaders, sizeof(char *));
137     if (NULL == readers)
138     {
139     printf("Not enough memory for readers[]\n");
140     goto end;
141     }
142    
143     /* fill the readers table */
144     nbReaders = 0;
145     ptr = mszReaders;
146     while (*ptr != '\0')
147     {
148     printf("%d: %s\n", nbReaders, ptr);
149     readers[nbReaders] = ptr;
150     ptr += strlen(ptr)+1;
151     nbReaders++;
152     }
153    
154     if (argc > 1)
155     {
156     reader_nb = atoi(argv[1]);
157     if (reader_nb < 0 || reader_nb >= nbReaders)
158     {
159     printf("Wrong reader index: %d\n", reader_nb);
160     goto end;
161     }
162     }
163     else
164     reader_nb = 0;
165    
166 rousseau 900 /* connect to a reader (even without a card) */
167 rousseau 889 dwActiveProtocol = -1;
168     rv = SCardConnect(hContext, readers[reader_nb], SCARD_SHARE_DIRECT,
169 rousseau 940 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
170 rousseau 889 printf(" Protocol: %ld\n", dwActiveProtocol);
171     PCSC_ERROR_EXIT(rv, "SCardConnect")
172    
173 rousseau 972 /* get GemPC firmware */
174     printf(" Get GemPC Firmware\n");
175 rousseau 889
176     /* this is specific to Gemplus readers */
177     bSendBuffer[0] = 0x02;
178     rv = SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, bSendBuffer,
179     1, bRecvBuffer, sizeof(bRecvBuffer), &length);
180    
181     printf(" Firmware: ");
182     for (i=0; i<length; i++)
183     printf("%02X ", bRecvBuffer[i]);
184     printf("\n");
185    
186     bRecvBuffer[length] = '\0';
187     printf(" Firmware: %s (length %ld bytes)\n", bRecvBuffer, length);
188    
189     PCSC_ERROR_CONT(rv, "SCardControl")
190    
191     /* get card status */
192     dwAtrLen = sizeof(pbAtr);
193     dwReaderLen = sizeof(pbReader);
194     rv = SCardStatus(hCard, pbReader, &dwReaderLen, &dwState, &dwProt,
195     pbAtr, &dwAtrLen);
196     printf(" Reader: %s (length %ld bytes)\n", pbReader, dwReaderLen);
197     printf(" State: 0x%lX\n", dwState);
198     printf(" Prot: %ld\n", dwProt);
199     printf(" ATR (length %ld bytes):", dwAtrLen);
200     for (i=0; i<dwAtrLen; i++)
201     printf(" %02X", pbAtr[i]);
202     printf("\n");
203     PCSC_ERROR_CONT(rv, "SCardStatus")
204    
205 rousseau 900 /* does the reader support PIN verification? */
206 rousseau 1631 rv = SCardControl(hCard, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0,
207     bRecvBuffer, sizeof(bRecvBuffer), &length);
208    
209     printf(" TLV (%ld): ", length);
210     for (i=0; i<length; i++)
211     printf("%02X ", bRecvBuffer[i]);
212     printf("\n");
213    
214     PCSC_ERROR_CONT(rv, "SCardControl(CM_IOCTL_GET_FEATURE_REQUEST)")
215    
216     if (length % sizeof(PCSC_TLV_STRUCTURE))
217 rousseau 900 {
218 rousseau 1631 printf("Inconsistent result! Bad TLV values!\n");
219     goto end;
220     }
221    
222     /* get the number of elements instead of the complete size */
223     length /= sizeof(PCSC_TLV_STRUCTURE);
224    
225     pcsc_tlv = (PCSC_TLV_STRUCTURE *)bRecvBuffer;
226     for (i = 0; i < length; i++)
227     {
228     if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_DIRECT)
229 rousseau 2116 verify_ioctl = ntohl(pcsc_tlv[i].value);
230 rousseau 1631 if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_DIRECT)
231 rousseau 2116 modify_ioctl = ntohl(pcsc_tlv[i].value);
232 rousseau 1631 }
233    
234     if (0 == verify_ioctl)
235     {
236 rousseau 900 printf("Reader %s does not support PIN verification\n",
237     readers[reader_nb]);
238     goto end;
239     }
240    
241 rousseau 972 /* connect to a reader (even without a card) */
242     dwActiveProtocol = -1;
243     rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
244 rousseau 1635 SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD,
245     &dwActiveProtocol);
246 rousseau 972 printf(" Protocol: %ld\n", dwActiveProtocol);
247     PCSC_ERROR_EXIT(rv, "SCardReconnect")
248    
249 rousseau 1635 switch(dwActiveProtocol)
250     {
251     case SCARD_PROTOCOL_T0:
252     pioSendPci = *SCARD_PCI_T0;
253     break;
254     case SCARD_PROTOCOL_T1:
255     pioSendPci = *SCARD_PCI_T1;
256     break;
257     default:
258 rousseau 2585 printf("Unknown protocol. No card present?\n");
259 rousseau 1635 return -1;
260     }
261    
262 rousseau 1676 /* APDU select applet */
263     printf("Select applet: ");
264     send_length = 11;
265     memcpy(bSendBuffer, "\x00\xA4\x04\x00\x06\xA0\x00\x00\x00\x18\xFF",
266     send_length);
267     for (i=0; i<send_length; i++)
268     printf(" %02X", bSendBuffer[i]);
269 rousseau 972 printf("\n");
270     length = sizeof(bRecvBuffer);
271 rousseau 1676 rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
272 rousseau 972 &pioRecvPci, bRecvBuffer, &length);
273     printf(" card response:");
274     for (i=0; i<length; i++)
275     printf(" %02X", bRecvBuffer[i]);
276     printf("\n");
277     PCSC_ERROR_EXIT(rv, "SCardTransmit")
278 rousseau 1743 if ((bRecvBuffer[0] != 0x90) || (bRecvBuffer[1] != 0x00))
279 rousseau 1742 {
280     printf("Error: test applet not found!\n");
281     goto end;
282     }
283 rousseau 972
284 rousseau 1676 #ifdef VERIFY_PIN
285 rousseau 889 /* verify PIN */
286     printf(" Secure verify PIN\n");
287 rousseau 1631 pin_verify = (PIN_VERIFY_STRUCTURE *)bSendBuffer;
288    
289     /* PC/SC v2.0.2 Part 10 PIN verification data structure */
290     pin_verify -> bTimerOut = 0x00;
291     pin_verify -> bTimerOut2 = 0x00;
292     pin_verify -> bmFormatString = 0x82;
293     pin_verify -> bmPINBlockString = 0x04;
294     pin_verify -> bmPINLengthFormat = 0x00;
295 rousseau 1669 pin_verify -> wPINMaxExtraDigit = HOST_TO_CCID_16(0x0408); /* Min Max */
296 rousseau 1711 pin_verify -> bEntryValidationCondition = 0x02; /* validation key pressed */
297 rousseau 1712 pin_verify -> bNumberMessage = 0x01;
298 rousseau 1669 pin_verify -> wLangId = HOST_TO_CCID_16(0x0904);
299 rousseau 1631 pin_verify -> bMsgIndex = 0x00;
300     pin_verify -> bTeoPrologue[0] = 0x00;
301     pin_verify -> bTeoPrologue[1] = 0x00;
302     pin_verify -> bTeoPrologue[2] = 0x00;
303     /* pin_verify -> ulDataLength = 0x00; we don't know the size yet */
304    
305     /* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
306 rousseau 889 offset = 0;
307 rousseau 1631 pin_verify -> abData[offset++] = 0x00; /* CLA */
308     pin_verify -> abData[offset++] = 0x20; /* INS: VERIFY */
309     pin_verify -> abData[offset++] = 0x00; /* P1 */
310     pin_verify -> abData[offset++] = 0x00; /* P2 */
311     pin_verify -> abData[offset++] = 0x08; /* Lc: 8 data bytes */
312     pin_verify -> abData[offset++] = 0x30; /* '0' */
313     pin_verify -> abData[offset++] = 0x30; /* '0' */
314     pin_verify -> abData[offset++] = 0x30; /* '0' */
315     pin_verify -> abData[offset++] = 0x30; /* '0' */
316     pin_verify -> abData[offset++] = 0x00; /* '\0' */
317     pin_verify -> abData[offset++] = 0x00; /* '\0' */
318     pin_verify -> abData[offset++] = 0x00; /* '\0' */
319     pin_verify -> abData[offset++] = 0x00; /* '\0' */
320 rousseau 1669 pin_verify -> ulDataLength = HOST_TO_CCID_32(offset); /* APDU size */
321 rousseau 889
322 rousseau 1631 length = sizeof(PIN_VERIFY_STRUCTURE) + offset -1; /* -1 because PIN_VERIFY_STRUCTURE contains the first byte of abData[] */
323 rousseau 889
324 rousseau 1631 printf(" command:");
325     for (i=0; i<length; i++)
326     printf(" %02X", bSendBuffer[i]);
327     printf("\n");
328     printf("Enter your PIN: ");
329     fflush(stdout);
330     rv = SCardControl(hCard, verify_ioctl, bSendBuffer,
331     length, bRecvBuffer, sizeof(bRecvBuffer), &length);
332    
333     {
334     #ifndef S_SPLINT_S
335     fd_set fd;
336     #endif
337     struct timeval timeout;
338    
339     FD_ZERO(&fd);
340     FD_SET(STDIN_FILENO, &fd); /* stdin */
341 rousseau 2039 timeout.tv_sec = 0; /* timeout = 0.1s */
342     timeout.tv_usec = 100000;
343 rousseau 1631
344     /* we only try to read stdin if the pinpad is on a keyboard
345     * we do not read stdin for a SPR 532 for example */
346     if (select(1, &fd, NULL, NULL, &timeout) > 0)
347     {
348     /* read the fake digits */
349 rousseau 1749 char in[40]; /* 4 digits + \n + \0 */
350 rousseau 1631 (void)fgets(in, sizeof(in), stdin);
351    
352     printf("keyboard sent: %s", in);
353     }
354 rousseau 1676 else
355     /* if it is not a keyboard */
356     printf("\n");
357 rousseau 1631 }
358    
359 rousseau 1676 printf(" card response:");
360     for (i=0; i<length; i++)
361     printf(" %02X", bRecvBuffer[i]);
362     printf("\n");
363     PCSC_ERROR_CONT(rv, "SCardControl")
364    
365     /* verify PIN dump */
366     printf("\nverify PIN dump: ");
367     send_length = 5;
368     memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
369     send_length);
370     for (i=0; i<send_length; i++)
371     printf(" %02X", bSendBuffer[i]);
372     printf("\n");
373     length = sizeof(bRecvBuffer);
374     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
375     &pioRecvPci, bRecvBuffer, &length);
376     printf(" card response:");
377     for (i=0; i<length; i++)
378     printf(" %02X", bRecvBuffer[i]);
379     printf("\n");
380     PCSC_ERROR_EXIT(rv, "SCardTransmit")
381    
382     if ((2 == length) && (0x6C == bRecvBuffer[0]))
383     {
384     printf("\nverify PIN dump: ");
385     send_length = 5;
386     memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
387     send_length);
388     bSendBuffer[4] = bRecvBuffer[1];
389     for (i=0; i<send_length; i++)
390     printf(" %02X", bSendBuffer[i]);
391     printf("\n");
392     length = sizeof(bRecvBuffer);
393     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
394     &pioRecvPci, bRecvBuffer, &length);
395     printf(" card response:");
396     for (i=0; i<length; i++)
397     printf(" %02X", bRecvBuffer[i]);
398     printf("\n");
399     PCSC_ERROR_EXIT(rv, "SCardTransmit")
400     }
401     #endif
402    
403     /* check if the reader supports Modify PIN */
404 rousseau 1631 if (0 == modify_ioctl)
405     {
406     printf("Reader %s does not support PIN modification\n",
407     readers[reader_nb]);
408     goto end;
409     }
410    
411 rousseau 1676 #ifdef MODIFY_PIN
412 rousseau 1631 /* Modify PIN */
413     printf(" Secure modify PIN\n");
414     pin_modify = (PIN_MODIFY_STRUCTURE *)bSendBuffer;
415    
416 rousseau 2407 /* Table for bConfirmPIN and bNumberMessage
417     * bConfirmPIN = 3, bNumberMessage = 3: "Enter Pin" "New Pin" "Confirm Pin"
418     * bConfirmPIN = 2, bNumberMessage = 2: "Enter Pin" "New Pin"
419     * bConfirmPIN = 1, bNumberMessage = 2: "New Pin" "Confirm Pin"
420     * bConfirmPIN = 0, bNumberMessage = 1: "New Pin"
421     */
422 rousseau 1631 /* PC/SC v2.0.2 Part 10 PIN verification data structure */
423     pin_modify -> bTimerOut = 0x00;
424     pin_modify -> bTimerOut2 = 0x00;
425     pin_modify -> bmFormatString = 0x82;
426     pin_modify -> bmPINBlockString = 0x04;
427     pin_modify -> bmPINLengthFormat = 0x00;
428 rousseau 1716 pin_modify -> bInsertionOffsetOld = 0x00; /* offset from APDU start */
429 rousseau 1717 pin_modify -> bInsertionOffsetNew = 0x04; /* offset from APDU start */
430 rousseau 2405 pin_modify -> wPINMaxExtraDigit = HOST_TO_CCID_16(0x0408); /* Min Max */
431 rousseau 1634 pin_modify -> bConfirmPIN = 0x03; /* b0 set = confirmation requested */
432     /* b1 set = current PIN entry requested */
433     pin_modify -> bEntryValidationCondition = 0x02; /* validation key pressed */
434 rousseau 2407 pin_modify -> bNumberMessage = 0x03; /* see table above */
435 rousseau 1669 pin_modify -> wLangId = HOST_TO_CCID_16(0x0904);
436 rousseau 1631 pin_modify -> bMsgIndex1 = 0x00;
437     pin_modify -> bMsgIndex2 = 0x00;
438     pin_modify -> bMsgIndex3 = 0x00;
439     pin_modify -> bTeoPrologue[0] = 0x00;
440     pin_modify -> bTeoPrologue[1] = 0x00;
441     pin_modify -> bTeoPrologue[2] = 0x00;
442 rousseau 1634 /* pin_modify -> ulDataLength = 0x00; we don't know the size yet */
443 rousseau 1631
444 rousseau 1300 /* APDU: 00 20 00 00 08 30 30 30 30 00 00 00 00 */
445 rousseau 1631 offset = 0;
446     pin_modify -> abData[offset++] = 0x00; /* CLA */
447 rousseau 1634 pin_modify -> abData[offset++] = 0x24; /* INS: CHANGE/UNBLOCK */
448 rousseau 1631 pin_modify -> abData[offset++] = 0x00; /* P1 */
449     pin_modify -> abData[offset++] = 0x00; /* P2 */
450 rousseau 1717 pin_modify -> abData[offset++] = 0x08; /* Lc: 2x8 data bytes */
451 rousseau 1634 pin_modify -> abData[offset++] = 0x30; /* '0' old PIN */
452 rousseau 1631 pin_modify -> abData[offset++] = 0x30; /* '0' */
453     pin_modify -> abData[offset++] = 0x30; /* '0' */
454     pin_modify -> abData[offset++] = 0x30; /* '0' */
455 rousseau 1634 pin_modify -> abData[offset++] = 0x30; /* '0' new PIN */
456 rousseau 1631 pin_modify -> abData[offset++] = 0x30; /* '0' */
457 rousseau 1634 pin_modify -> abData[offset++] = 0x30; /* '0' */
458     pin_modify -> abData[offset++] = 0x30; /* '0' */
459 rousseau 1669 pin_modify -> ulDataLength = HOST_TO_CCID_32(offset); /* APDU size */
460 rousseau 1300
461 rousseau 1634 length = sizeof(PIN_MODIFY_STRUCTURE) + offset -1; /* -1 because PIN_MODIFY_STRUCTURE contains the first byte of abData[] */
462    
463 rousseau 889 printf(" command:");
464 rousseau 1631 for (i=0; i<length; i++)
465 rousseau 889 printf(" %02X", bSendBuffer[i]);
466     printf("\n");
467 rousseau 972 printf("Enter your PIN: ");
468 rousseau 900 fflush(stdout);
469 rousseau 1634 rv = SCardControl(hCard, modify_ioctl, bSendBuffer,
470 rousseau 1631 length, bRecvBuffer, sizeof(bRecvBuffer), &length);
471 rousseau 889
472     printf(" card response:");
473     for (i=0; i<length; i++)
474     printf(" %02X", bRecvBuffer[i]);
475     printf("\n");
476     PCSC_ERROR_CONT(rv, "SCardControl")
477    
478 rousseau 972 {
479 rousseau 1067 #ifndef S_SPLINT_S
480 rousseau 972 fd_set fd;
481 rousseau 1067 #endif
482 rousseau 972 struct timeval timeout;
483    
484 rousseau 1985 /* old PIN, new PIN, confirmation PIN */
485     /* if the command is aborted we will not read every "PIN" */
486     for (i=0; i<3; i++)
487 rousseau 972 {
488 rousseau 1985 FD_ZERO(&fd);
489     FD_SET(STDIN_FILENO, &fd); /* stdin */
490 rousseau 2039 timeout.tv_sec = 0; /* timeout = 0.1s */
491     timeout.tv_usec = 100000;
492 rousseau 1750
493 rousseau 1985 /* we only try to read stdin if the pinpad is on a keyboard
494     * we do not read stdin for a SPR 532 for example */
495     if (select(1, &fd, NULL, NULL, &timeout) > 0)
496     {
497     /* read the fake digits */
498     char in[40]; /* 4 digits + \n + \0 */
499 rousseau 972
500 rousseau 1985 (void)fgets(in, sizeof(in), stdin);
501     printf("keyboard sent: %s", in);
502     }
503 rousseau 972 }
504     }
505 rousseau 1715
506     /* modify PIN dump */
507     printf("\nmodify PIN dump: ");
508     send_length = 5;
509     memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
510     send_length);
511     for (i=0; i<send_length; i++)
512     printf(" %02X", bSendBuffer[i]);
513     printf("\n");
514     length = sizeof(bRecvBuffer);
515     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
516     &pioRecvPci, bRecvBuffer, &length);
517     printf(" card response:");
518     for (i=0; i<length; i++)
519     printf(" %02X", bRecvBuffer[i]);
520     printf("\n");
521     PCSC_ERROR_EXIT(rv, "SCardTransmit")
522    
523     if ((2 == length) && (0x6C == bRecvBuffer[0]))
524     {
525     printf("\nverify PIN dump: ");
526     send_length = 5;
527     memcpy(bSendBuffer, "\x00\x40\x00\x00\xFF",
528     send_length);
529     bSendBuffer[4] = bRecvBuffer[1];
530     for (i=0; i<send_length; i++)
531     printf(" %02X", bSendBuffer[i]);
532     printf("\n");
533     length = sizeof(bRecvBuffer);
534     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
535     &pioRecvPci, bRecvBuffer, &length);
536     printf(" card response:");
537     for (i=0; i<length; i++)
538     printf(" %02X", bRecvBuffer[i]);
539     printf("\n");
540     PCSC_ERROR_EXIT(rv, "SCardTransmit")
541     }
542 rousseau 1676 #endif
543 rousseau 972
544 rousseau 889 /* card disconnect */
545     rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
546     PCSC_ERROR_CONT(rv, "SCardDisconnect")
547    
548     end:
549     /* We try to leave things as clean as possible */
550     rv = SCardReleaseContext(hContext);
551     if (rv != SCARD_S_SUCCESS)
552     printf("SCardReleaseContext: %s (0x%lX)\n", pcsc_stringify_error(rv),
553     rv);
554    
555     /* free allocated memory */
556 rousseau 2591 if (mszReaders)
557     free(mszReaders);
558     if (readers)
559     free(readers);
560 rousseau 889
561     return 0;
562     } /* main */
563    

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5