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 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
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
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
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 }