00001
00002
00003
00004
00005
00006
00007
00008
00009
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( int argc, 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
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
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
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 }