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

Generated on Mon Aug 17 01:00:11 2009 for pcsc-lite by  doxygen 1.5.9