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

Generated on Thu Aug 28 20:14:32 2008 for pcsc-lite by  doxygen 1.5.6