pcsc-lite 1.6.4
|
00001 /* 00002 * MUSCLE SmartCard Development ( http://www.linuxnet.com ) 00003 * 00004 * Copyright (C) 1999 00005 * David Corcoran <corcoran@linuxnet.com> 00006 * Copyright (C) 2004-2010 00007 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00008 * 00009 * $Id: testpcsc.c 5096 2010-08-02 14:33:35Z 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 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 case SCARD_PROTOCOL_RAW: 00228 pioSendPci = *SCARD_PCI_RAW; 00229 break; 00230 default: 00231 printf("Unknown protocol\n"); 00232 return -1; 00233 } 00234 00235 /* APDU select file */ 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_DEVICE_FRIENDLY_NAME, (unsigned char *)&pbAttr, 00282 &pcbAttrLen); 00283 #else 00284 rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, NULL, &pcbAttrLen); 00285 test_rv(rv, hContext, DONT_PANIC); 00286 if (rv == SCARD_S_SUCCESS) 00287 { 00288 printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME length: " GREEN "%ld\n" NORMAL, pcbAttrLen); 00289 pbAttr = malloc(pcbAttrLen); 00290 } 00291 00292 printf("Testing SCardGetAttrib\t\t: "); 00293 rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME, pbAttr, &pcbAttrLen); 00294 #endif 00295 test_rv(rv, hContext, DONT_PANIC); 00296 if (rv == SCARD_S_SUCCESS) 00297 printf("SCARD_ATTR_DEVICE_FRIENDLY_NAME: " GREEN "%s\n" NORMAL, pbAttr); 00298 00299 #ifdef USE_AUTOALLOCATE 00300 printf("Testing SCardFreeMemory\t\t: "); 00301 rv = SCardFreeMemory(hContext, pbAttr); 00302 test_rv(rv, hContext, PANIC); 00303 #else 00304 if (pbAttr) 00305 free(pbAttr); 00306 #endif 00307 00308 printf("Testing SCardGetAttrib\t\t: "); 00309 #ifdef USE_AUTOALLOCATE 00310 pcbAttrLen = SCARD_AUTOALLOCATE; 00311 rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (unsigned char *)&pbAttr, 00312 &pcbAttrLen); 00313 #else 00314 rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &pcbAttrLen); 00315 test_rv(rv, hContext, DONT_PANIC); 00316 if (rv == SCARD_S_SUCCESS) 00317 { 00318 printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen); 00319 pbAttr = malloc(pcbAttrLen); 00320 } 00321 00322 printf("Testing SCardGetAttrib\t\t: "); 00323 rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAttr, &pcbAttrLen); 00324 #endif 00325 test_rv(rv, hContext, DONT_PANIC); 00326 if (rv == SCARD_S_SUCCESS) 00327 { 00328 printf("SCARD_ATTR_ATR_STRING length: " GREEN "%ld\n" NORMAL, pcbAttrLen); 00329 printf("SCARD_ATTR_ATR_STRING: " GREEN); 00330 for (i = 0; i < pcbAttrLen; i++) 00331 printf("%02X ", pbAttr[i]); 00332 printf("\n" NORMAL); 00333 } 00334 00335 #ifdef USE_AUTOALLOCATE 00336 printf("Testing SCardFreeMemory\t\t: "); 00337 rv = SCardFreeMemory(hContext, pbAttr); 00338 test_rv(rv, hContext, PANIC); 00339 #else 00340 if (pbAttr) 00341 free(pbAttr); 00342 #endif 00343 00344 printf("Testing SCardGetAttrib\t\t: "); 00345 dwBufLen = sizeof(buf); 00346 rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, buf.as_char, &dwBufLen); 00347 test_rv(rv, hContext, DONT_PANIC); 00348 if (rv == SCARD_S_SUCCESS) 00349 printf("Vendor IFD version\t\t: " GREEN "0x%08lX\n" NORMAL, 00350 buf.as_DWORD); 00351 00352 printf("Testing SCardGetAttrib\t\t: "); 00353 dwBufLen = sizeof(buf); 00354 rv = SCardGetAttrib(hCard, SCARD_ATTR_MAXINPUT, buf.as_char, &dwBufLen); 00355 test_rv(rv, hContext, DONT_PANIC); 00356 if (rv == SCARD_S_SUCCESS) 00357 { 00358 if (dwBufLen == sizeof(uint32_t)) 00359 printf("Max message length\t\t: " GREEN "%d\n" NORMAL, 00360 buf.as_uint32_t); 00361 else 00362 printf(RED "Wrong size" NORMAL); 00363 } 00364 00365 printf("Testing SCardGetAttrib\t\t: "); 00366 dwBufLen = sizeof(buf); 00367 rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_NAME, buf.as_char, &dwBufLen); 00368 test_rv(rv, hContext, DONT_PANIC); 00369 if (rv == SCARD_S_SUCCESS) 00370 printf("Vendor name\t\t\t: " GREEN "%s\n" NORMAL, buf.as_char); 00371 00372 printf("Testing SCardSetAttrib\t\t: "); 00373 rv = SCardSetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPCBYTE)"", 1); 00374 test_rv(rv, hContext, DONT_PANIC); 00375 00376 printf("Testing SCardStatus\t\t: "); 00377 00378 #ifdef USE_AUTOALLOCATE 00379 dwReaderLen = SCARD_AUTOALLOCATE; 00380 dwAtrLen = SCARD_AUTOALLOCATE; 00381 rv = SCardStatus(hCard, (LPSTR)&pcReaders, &dwReaderLen, &dwState, &dwProt, 00382 (LPBYTE)&pbAtr, &dwAtrLen); 00383 #else 00384 dwReaderLen = 100; 00385 pcReaders = malloc(sizeof(char) * 100); 00386 dwAtrLen = MAX_ATR_SIZE; 00387 00388 rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt, 00389 pbAtr, &dwAtrLen); 00390 #endif 00391 test_rv(rv, hContext, PANIC); 00392 00393 printf("Current Reader Name\t\t: " GREEN "%s\n" NORMAL, pcReaders); 00394 printf("Current Reader State\t\t: " GREEN "0x%.4lx\n" NORMAL, dwState); 00395 printf("Current Reader Protocol\t\t: T=" GREEN "%ld\n" NORMAL, dwProt - 1); 00396 printf("Current Reader ATR Size\t\t: " GREEN "%ld" NORMAL " bytes\n", 00397 dwAtrLen); 00398 printf("Current Reader ATR Value\t: " GREEN); 00399 00400 for (i = 0; i < dwAtrLen; i++) 00401 { 00402 printf("%02X ", pbAtr[i]); 00403 } 00404 printf(NORMAL "\n"); 00405 00406 #ifdef USE_AUTOALLOCATE 00407 printf("Testing SCardFreeMemory\t\t: "); 00408 rv = SCardFreeMemory(hContext, pcReaders); 00409 test_rv(rv, hContext, PANIC); 00410 printf("Testing SCardFreeMemory\t\t: "); 00411 rv = SCardFreeMemory(hContext, pbAtr); 00412 test_rv(rv, hContext, PANIC); 00413 #else 00414 if (pcReaders) 00415 free(pcReaders); 00416 #endif 00417 00418 if (rv != SCARD_S_SUCCESS) 00419 { 00420 (void)SCardDisconnect(hCard, SCARD_RESET_CARD); 00421 (void)SCardReleaseContext(hContext); 00422 } 00423 00424 printf("Press enter: "); 00425 (void)getchar(); 00426 printf("Testing SCardReconnect\t\t: "); 00427 rv = SCardReconnect(hCard, SCARD_SHARE_SHARED, 00428 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref); 00429 test_rv(rv, hContext, PANIC); 00430 00431 printf("Testing SCardDisconnect\t\t: "); 00432 rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD); 00433 test_rv(rv, hContext, PANIC); 00434 00435 #ifdef USE_AUTOALLOCATE 00436 printf("Testing SCardFreeMemory\t\t: "); 00437 rv = SCardFreeMemory(hContext, mszReaders); 00438 test_rv(rv, hContext, PANIC); 00439 #else 00440 free(mszReaders); 00441 #endif 00442 00443 printf("Testing SCardReleaseContext\t: "); 00444 rv = SCardReleaseContext(hContext); 00445 test_rv(rv, hContext, PANIC); 00446 00447 printf("\n"); 00448 printf("PC/SC Test Completed Successfully !\n"); 00449 00450 return 0; 00451 }