testpcsc.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 1999
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  * Copyright (C) 2004-2006
00007  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00008  *
00009  * $Id: testpcsc.c 2541 2007-05-23 07:34:42Z rousseau $
00010  */
00011 
00017 #include "config.h"
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 
00022 #include "pcsclite.h"
00023 #include "winscard.h"
00024 #include "reader.h"
00025 
00026 #define PANIC 0
00027 #define DONT_PANIC 1
00028 #define RED_PRINTF_FORMAT "\33[01;31m%s\33[0m\n"
00029 
00030 void test_rv(int rv, SCARDCONTEXT hContext, int dont_panic);
00031 void test_rv(int rv, SCARDCONTEXT hContext, int dont_panic)
00032 {
00033     if (rv != SCARD_S_SUCCESS)
00034     {
00035         if (dont_panic)
00036             printf("\33[34m%s (don't panic)\33[0m\n", pcsc_stringify_error(rv));
00037         else
00038         {
00039             printf(RED_PRINTF_FORMAT, pcsc_stringify_error(rv));
00040             SCardReleaseContext(hContext);
00041             exit(-1);
00042         }
00043     }
00044     else
00045         puts(pcsc_stringify_error(rv));
00046 }
00047 
00048 int main(int argc, char **argv)
00049 {
00050     SCARDHANDLE hCard;
00051     SCARDCONTEXT hContext;
00052     SCARD_READERSTATE_A rgReaderStates[1];
00053     DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
00054     DWORD dwPref, dwReaders;
00055     char *pcReaders, *mszReaders;
00056     unsigned char pbAtr[MAX_ATR_SIZE];
00057     char *mszGroups;
00058     DWORD dwGroups;
00059     long rv;
00060     DWORD i;
00061     int p, iReader;
00062     int iList[16];
00063     SCARD_IO_REQUEST pioRecvPci;
00064     SCARD_IO_REQUEST pioSendPci;
00065     unsigned char bSendBuffer[MAX_BUFFER_SIZE];
00066     unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
00067     DWORD send_length, length;
00068 
00069     printf("\nMUSCLE PC/SC Lite unitary test Program\n\n");
00070 
00071     printf("\33[35mTHIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n");
00072     printf("Do NOT use it unless you really know what you do.\33[0m\n\n");
00073 
00074     printf("Testing SCardEstablishContext\t: ");
00075     rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
00076     test_rv(rv, hContext, PANIC);
00077 
00078     printf("Testing SCardIsValidContext\t: ");
00079     rv = SCardIsValidContext(hContext);
00080     test_rv(rv, hContext, PANIC);
00081 
00082     printf("Testing SCardIsValidContext\t: ");
00083     rv = SCardIsValidContext(hContext+1);
00084     test_rv(rv, hContext, DONT_PANIC);
00085 
00086     printf("Testing SCardGetStatusChange \n");
00087     printf("Please insert a working reader\t: ");
00088     fflush(stdout);
00089     rv = SCardGetStatusChange(hContext, INFINITE, 0, 0);
00090     test_rv(rv, hContext, PANIC);
00091 
00092     printf("Testing SCardListReaderGroups\t: ");
00093     rv = SCardListReaderGroups(hContext, 0, &dwGroups);
00094     test_rv(rv, hContext, PANIC);
00095 
00096     mszGroups = malloc(sizeof(char) * dwGroups);
00097     rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups);
00098     test_rv(rv, hContext, PANIC);
00099 
00100     /*
00101      * Have to understand the multi-string here
00102      */
00103     p = 0;
00104     for (i = 0; i < dwGroups - 1; i++)
00105     {
00106         ++p;
00107         printf("Group %02d: %s\n", p, &mszGroups[i]);
00108         iList[p] = i;
00109         while (mszGroups[++i] != 0) ;
00110     }
00111 
00112 wait_for_card_again:
00113     printf("Testing SCardListReaders\t: ");
00114 
00115     mszGroups = 0;
00116     rv = SCardListReaders(hContext, mszGroups, 0, &dwReaders);
00117     test_rv(rv, hContext, PANIC);
00118 
00119     mszReaders = malloc(sizeof(char) * dwReaders);
00120     rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders);
00121     test_rv(rv, hContext, PANIC);
00122 
00123     /*
00124      * Have to understand the multi-string here
00125      */
00126     p = 0;
00127     for (i = 0; i < dwReaders - 1; i++)
00128     {
00129         ++p;
00130         printf("Reader %02d: %s\n", p, &mszReaders[i]);
00131         iList[p] = i;
00132         while (mszReaders[++i] != 0) ;
00133     }
00134 
00135     if (p > 1)
00136         do
00137         {
00138             char input[80];
00139 
00140             printf("Enter the reader number\t\t: ");
00141             fgets(input, sizeof(input), stdin);
00142             sscanf(input, "%d", &iReader);
00143 
00144             if (iReader > p || iReader <= 0)
00145                 printf("Invalid Value - try again\n");
00146         }
00147         while (iReader > p || iReader <= 0);
00148     else
00149         iReader = 1;
00150 
00151     rgReaderStates[0].szReader = &mszReaders[iList[iReader]];
00152     rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;
00153 
00154     printf("Waiting for card insertion\t: ");
00155     fflush(stdout);
00156     rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
00157     test_rv(rv, hContext, PANIC);
00158     if (SCARD_STATE_EMPTY == rgReaderStates[0].dwEventState)
00159     {
00160         printf("\nA reader has been connected/disconnected\n");
00161         goto wait_for_card_again;
00162     }
00163 
00164     printf("Testing SCardConnect\t\t: ");
00165     rv = SCardConnect(hContext, &mszReaders[iList[iReader]],
00166         SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
00167         &hCard, &dwPref);
00168     test_rv(rv, hContext, PANIC);
00169 
00170     switch(dwPref)
00171     {
00172         case SCARD_PROTOCOL_T0:
00173             pioSendPci = *SCARD_PCI_T0;
00174             break;
00175         case SCARD_PROTOCOL_T1:
00176             pioSendPci = *SCARD_PCI_T1;
00177             break;
00178         default:
00179             printf("Unknown protocol\n");
00180             return -1;
00181     }
00182 
00183     /* APDU select file */
00184     printf("Select file: ");
00185     send_length = 7;
00186     memcpy(bSendBuffer, "\x00\xA4\x00\x00\x02\x3F\x00", send_length);
00187     for (i=0; i<send_length; i++)
00188         printf(" %02X", bSendBuffer[i]);
00189     printf("\n");
00190     length = sizeof(bRecvBuffer);
00191 
00192     printf("Testing SCardTransmit\t\t: ");
00193     rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
00194         &pioRecvPci, bRecvBuffer, &length);
00195     printf("%s\n", pcsc_stringify_error(rv));
00196     printf(" card response:");
00197     for (i=0; i<length; i++)
00198         printf(" %02X", bRecvBuffer[i]);
00199     printf("\n");
00200 
00201     printf("Testing SCardControl\t\t: ");
00202 #ifdef PCSC_PRE_120
00203     {
00204         char buffer[1024] = "Foobar";
00205         DWORD cbRecvLength = sizeof(buffer);
00206 
00207         rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength);
00208     }
00209 #else
00210     {
00211         char buffer[1024] = { 0x02 };
00212         DWORD cbRecvLength = sizeof(buffer);
00213 
00214         rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer,
00215             sizeof(buffer), &cbRecvLength);
00216         if (cbRecvLength)
00217         {
00218             for (i=0; i<cbRecvLength; i++)
00219                 printf("%c", buffer[i]);
00220             printf(" ");
00221         }
00222     }
00223 #endif
00224     test_rv(rv, hContext, DONT_PANIC);
00225 
00226     printf("Testing SCardGetAttrib\t\t: ");
00227     rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &dwAtrLen);
00228     test_rv(rv, hContext, DONT_PANIC);
00229     if (rv == SCARD_S_SUCCESS)
00230         printf("ATR length: %ld\n", dwAtrLen);
00231 
00232     printf("Testing SCardGetAttrib\t\t: ");
00233     dwAtrLen = sizeof(pbAtr);
00234     rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAtr, &dwAtrLen);
00235     test_rv(rv, hContext, DONT_PANIC);
00236     if (rv == SCARD_S_SUCCESS)
00237     {
00238         for (i = 0; i < dwAtrLen; i++)
00239             printf("%02X ", pbAtr[i]);
00240         printf("\n");
00241     }
00242 
00243     printf("Testing SCardGetAttrib\t\t: ");
00244     dwAtrLen = sizeof(pbAtr);
00245     rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, pbAtr, &dwAtrLen);
00246     test_rv(rv, hContext, DONT_PANIC);
00247     if (rv == SCARD_S_SUCCESS)
00248         printf("Vendor IFD version\t\t: 0x%08lX\n", ((DWORD *)pbAtr)[0]);
00249 
00250     printf("Testing SCardGetAttrib\t\t: ");
00251     dwAtrLen = sizeof(pbAtr);
00252     rv = SCardGetAttrib(hCard, SCARD_ATTR_MAXINPUT, pbAtr, &dwAtrLen);
00253     test_rv(rv, hContext, DONT_PANIC);
00254     if (rv == SCARD_S_SUCCESS)
00255     {
00256         if (dwAtrLen == sizeof(uint32_t))
00257             printf("Max message length\t\t: %d\n", *(uint32_t *)pbAtr);
00258         else
00259             printf(RED_PRINTF_FORMAT, "Wrong size");
00260     }
00261 
00262     printf("Testing SCardGetAttrib\t\t: ");
00263     dwAtrLen = sizeof(pbAtr);
00264     rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_NAME, pbAtr, &dwAtrLen);
00265     test_rv(rv, hContext, DONT_PANIC);
00266     if (rv == SCARD_S_SUCCESS)
00267         printf("Vendor name\t\t\t: %s\n", pbAtr);
00268 
00269     printf("Testing SCardSetAttrib\t\t: ");
00270     rv = SCardSetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPCBYTE)"", 1);
00271     test_rv(rv, hContext, DONT_PANIC);
00272 
00273     printf("Testing SCardStatus\t\t: ");
00274 
00275     dwReaderLen = 50;
00276     pcReaders   = malloc(sizeof(char) * 50);
00277     dwAtrLen    = MAX_ATR_SIZE;
00278 
00279     rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt,
00280         pbAtr, &dwAtrLen);
00281     test_rv(rv, hContext, PANIC);
00282 
00283     printf("Current Reader Name\t\t: %s\n", pcReaders);
00284     printf("Current Reader State\t\t: 0x%.4lx\n", dwState);
00285     printf("Current Reader Protocol\t\t: T=%ld\n", dwProt - 1);
00286     printf("Current Reader ATR Size\t\t: %ld bytes\n", dwAtrLen);
00287     printf("Current Reader ATR Value\t: ");
00288 
00289     for (i = 0; i < dwAtrLen; i++)
00290     {
00291         printf("%02X ", pbAtr[i]);
00292     }
00293     printf("\n");
00294 
00295     if (rv != SCARD_S_SUCCESS)
00296     {
00297         SCardDisconnect(hCard, SCARD_RESET_CARD);
00298         SCardReleaseContext(hContext);
00299     }
00300 
00301     printf("Press enter: ");
00302     getchar();
00303     printf("Testing SCardReconnect\t\t: ");
00304     rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
00305         SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref);
00306     test_rv(rv, hContext, PANIC);
00307 
00308     printf("Testing SCardDisconnect\t\t: ");
00309     rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
00310     test_rv(rv, hContext, PANIC);
00311 
00312     printf("Testing SCardReleaseContext\t: ");
00313     rv = SCardReleaseContext(hContext);
00314     test_rv(rv, hContext, PANIC);
00315 
00316     printf("\n");
00317     printf("PC/SC Test Completed Successfully !\n");
00318 
00319     return 0;
00320 }

Generated on Wed Mar 31 14:21:31 2010 for pcsc-lite by  doxygen 1.4.7