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 case SCARD_PROTOCOL_RAW:
00228 pioSendPci = *SCARD_PCI_RAW;
00229 break;
00230 default:
00231 printf("Unknown protocol\n");
00232 return -1;
00233 }
00234
00235
00236 printf("Select file:");
00237 send_length = 7;
00238 memcpy(bSendBuffer, "\x00\xA4\x00\x00\x02\x3F\x00", send_length);
00239 for (i=0; i<send_length; i++)
00240 printf(" %02X", bSendBuffer[i]);
00241 printf("\n");
00242 length = sizeof(bRecvBuffer);
00243
00244 printf("Testing SCardTransmit\t\t: ");
00245 rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
00246 &pioRecvPci, bRecvBuffer, &length);
00247 test_rv(rv, hContext, PANIC);
00248 printf(" card response:" GREEN);
00249 for (i=0; i<length; i++)
00250 printf(" %02X", bRecvBuffer[i]);
00251 printf("\n" NORMAL);
00252
00253 printf("Testing SCardControl\t\t: ");
00254 #ifdef PCSC_PRE_120
00255 {
00256 char buffer[1024] = "Foobar";
00257 DWORD cbRecvLength = sizeof(buffer);
00258
00259 rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength);
00260 }
00261 #else
00262 {
00263 char buffer[1024] = { 0x02 };
00264 DWORD cbRecvLength = sizeof(buffer);
00265
00266 rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer,
00267 sizeof(buffer), &cbRecvLength);
00268 if (cbRecvLength && (SCARD_S_SUCCESS == rv))
00269 {
00270 for (i=0; i<cbRecvLength; i++)
00271 printf("%c", buffer[i]);
00272 printf(" ");
00273 }
00274 }
00275 #endif
00276 test_rv(rv, hContext, DONT_PANIC);
00277
00278 printf("Testing SCardGetAttrib\t\t: ");
00279 #ifdef USE_AUTOALLOCATE
00280 pcbAttrLen = SCARD_AUTOALLOCATE;
00281 rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (unsigned char *)&pbAttr,
00282 &pcbAttrLen);
00283 #else
00284 rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &pcbAttrLen);
00285 test_rv(rv, hContext, DONT_PANIC);
00286 if (rv == SCARD_S_SUCCESS)
00287 {
00288 printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
00289 pbAttr = malloc(pcbAttrLen);
00290 }
00291
00292 printf("Testing SCardGetAttrib\t\t: ");
00293 rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAttr, &pcbAttrLen);
00294 #endif
00295 test_rv(rv, hContext, DONT_PANIC);
00296 if (rv == SCARD_S_SUCCESS)
00297 {
00298 printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen);
00299 printf("SCARD_ATTR_ATR_STRING: " GREEN);
00300 for (i = 0; i < pcbAttrLen; i++)
00301 printf("%02X ", pbAttr[i]);
00302 printf("\n" NORMAL);
00303 }
00304
00305 #ifdef USE_AUTOALLOCATE
00306 printf("Testing SCardFreeMemory\t\t: ");
00307 rv = SCardFreeMemory(hContext, pbAttr);
00308 test_rv(rv, hContext, PANIC);
00309 #else
00310 if (pbAttr)
00311 free(pbAttr);
00312 #endif
00313
00314 printf("Testing SCardGetAttrib\t\t: ");
00315 dwBufLen = sizeof(buf);
00316 rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, buf.as_char, &dwBufLen);
00317 test_rv(rv, hContext, DONT_PANIC);
00318 if (rv == SCARD_S_SUCCESS)
00319 printf("Vendor IFD version\t\t: " GREEN "0x%08lX\n" NORMAL,
00320 buf.as_DWORD);
00321
00322 printf("Testing SCardGetAttrib\t\t: ");
00323 dwBufLen = sizeof(buf);
00324 rv = SCardGetAttrib(hCard, SCARD_ATTR_MAXINPUT, buf.as_char, &dwBufLen);
00325 test_rv(rv, hContext, DONT_PANIC);
00326 if (rv == SCARD_S_SUCCESS)
00327 {
00328 if (dwBufLen == sizeof(uint32_t))
00329 printf("Max message length\t\t: " GREEN "%d\n" NORMAL,
00330 buf.as_uint32_t);
00331 else
00332 printf(RED "Wrong size" NORMAL);
00333 }
00334
00335 printf("Testing SCardGetAttrib\t\t: ");
00336 dwBufLen = sizeof(buf);
00337 rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_NAME, buf.as_char, &dwBufLen);
00338 test_rv(rv, hContext, DONT_PANIC);
00339 if (rv == SCARD_S_SUCCESS)
00340 printf("Vendor name\t\t\t: " GREEN "%s\n" NORMAL, buf.as_char);
00341
00342 printf("Testing SCardSetAttrib\t\t: ");
00343 rv = SCardSetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPCBYTE)"", 1);
00344 test_rv(rv, hContext, DONT_PANIC);
00345
00346 printf("Testing SCardStatus\t\t: ");
00347
00348 #ifdef USE_AUTOALLOCATE
00349 dwReaderLen = SCARD_AUTOALLOCATE;
00350 dwAtrLen = SCARD_AUTOALLOCATE;
00351 rv = SCardStatus(hCard, (LPSTR)&pcReaders, &dwReaderLen, &dwState, &dwProt,
00352 (LPBYTE)&pbAtr, &dwAtrLen);
00353 #else
00354 dwReaderLen = 100;
00355 pcReaders = malloc(sizeof(char) * 100);
00356 dwAtrLen = MAX_ATR_SIZE;
00357
00358 rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt,
00359 pbAtr, &dwAtrLen);
00360 #endif
00361 test_rv(rv, hContext, PANIC);
00362
00363 printf("Current Reader Name\t\t: " GREEN "%s\n" NORMAL, pcReaders);
00364 printf("Current Reader State\t\t: " GREEN "0x%.4lx\n" NORMAL, dwState);
00365 printf("Current Reader Protocol\t\t: T=" GREEN "%ld\n" NORMAL, dwProt - 1);
00366 printf("Current Reader ATR Size\t\t: " GREEN "%ld" NORMAL " bytes\n",
00367 dwAtrLen);
00368 printf("Current Reader ATR Value\t: " GREEN);
00369
00370 for (i = 0; i < dwAtrLen; i++)
00371 {
00372 printf("%02X ", pbAtr[i]);
00373 }
00374 printf(NORMAL "\n");
00375
00376 #ifdef USE_AUTOALLOCATE
00377 printf("Testing SCardFreeMemory\t\t: ");
00378 rv = SCardFreeMemory(hContext, pcReaders);
00379 test_rv(rv, hContext, PANIC);
00380 printf("Testing SCardFreeMemory\t\t: ");
00381 rv = SCardFreeMemory(hContext, pbAtr);
00382 test_rv(rv, hContext, PANIC);
00383 #else
00384 if (pcReaders)
00385 free(pcReaders);
00386 #endif
00387
00388 if (rv != SCARD_S_SUCCESS)
00389 {
00390 (void)SCardDisconnect(hCard, SCARD_RESET_CARD);
00391 (void)SCardReleaseContext(hContext);
00392 }
00393
00394 printf("Press enter: ");
00395 (void)getchar();
00396 printf("Testing SCardReconnect\t\t: ");
00397 rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
00398 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref);
00399 test_rv(rv, hContext, PANIC);
00400
00401 printf("Testing SCardDisconnect\t\t: ");
00402 rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
00403 test_rv(rv, hContext, PANIC);
00404
00405 #ifdef USE_AUTOALLOCATE
00406 printf("Testing SCardFreeMemory\t\t: ");
00407 rv = SCardFreeMemory(hContext, mszReaders);
00408 test_rv(rv, hContext, PANIC);
00409 #else
00410 free(mszReaders);
00411 #endif
00412
00413 printf("Testing SCardReleaseContext\t: ");
00414 rv = SCardReleaseContext(hContext);
00415 test_rv(rv, hContext, PANIC);
00416
00417 printf("\n");
00418 printf("PC/SC Test Completed Successfully !\n");
00419
00420 return 0;
00421 }