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

Generated on Wed Apr 30 17:11:41 2008 for pcsc-lite by  doxygen 1.5.5