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

Generated on Wed Jul 22 23:13:21 2009 for pcsc-lite by  doxygen 1.5.8