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 #define RED_PRINTF_FORMAT "\33[01;31m%s\33[0m\n"
00029
00030 void test_rv(int rv, SCARDCONTEXT hContext, int dont_panic);
00031 void test_rv(int rv, SCARDCONTEXT hContext, int dont_panic)
00032 {
00033 if (rv != SCARD_S_SUCCESS)
00034 {
00035 if (dont_panic)
00036 printf("\33[34m%s (don't panic)\33[0m\n", pcsc_stringify_error(rv));
00037 else
00038 {
00039 printf(RED_PRINTF_FORMAT, pcsc_stringify_error(rv));
00040 SCardReleaseContext(hContext);
00041 exit(-1);
00042 }
00043 }
00044 else
00045 puts(pcsc_stringify_error(rv));
00046 }
00047
00048 int main(int argc, char **argv)
00049 {
00050 SCARDHANDLE hCard;
00051 SCARDCONTEXT hContext;
00052 SCARD_READERSTATE_A rgReaderStates[1];
00053 DWORD dwReaderLen, dwState, dwProt, dwAtrLen;
00054 DWORD dwPref, dwReaders;
00055 char *pcReaders, *mszReaders;
00056 unsigned char pbAtr[MAX_ATR_SIZE];
00057 char *mszGroups;
00058 DWORD dwGroups;
00059 long rv;
00060 DWORD i;
00061 int p, iReader;
00062 int iList[16];
00063 SCARD_IO_REQUEST pioRecvPci;
00064 SCARD_IO_REQUEST pioSendPci;
00065 unsigned char bSendBuffer[MAX_BUFFER_SIZE];
00066 unsigned char bRecvBuffer[MAX_BUFFER_SIZE];
00067 DWORD send_length, length;
00068
00069 printf("\nMUSCLE PC/SC Lite unitary test Program\n\n");
00070
00071 printf("\33[35mTHIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n");
00072 printf("Do NOT use it unless you really know what you do.\33[0m\n\n");
00073
00074 printf("Testing SCardEstablishContext\t: ");
00075 rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
00076 test_rv(rv, hContext, PANIC);
00077
00078 printf("Testing SCardIsValidContext\t: ");
00079 rv = SCardIsValidContext(hContext);
00080 test_rv(rv, hContext, PANIC);
00081
00082 printf("Testing SCardIsValidContext\t: ");
00083 rv = SCardIsValidContext(hContext+1);
00084 test_rv(rv, hContext, DONT_PANIC);
00085
00086 printf("Testing SCardGetStatusChange \n");
00087 printf("Please insert a working reader\t: ");
00088 fflush(stdout);
00089 rv = SCardGetStatusChange(hContext, INFINITE, 0, 0);
00090 test_rv(rv, hContext, PANIC);
00091
00092 printf("Testing SCardListReaderGroups\t: ");
00093 rv = SCardListReaderGroups(hContext, 0, &dwGroups);
00094 test_rv(rv, hContext, PANIC);
00095
00096 mszGroups = malloc(sizeof(char) * dwGroups);
00097 rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups);
00098 test_rv(rv, hContext, PANIC);
00099
00100
00101
00102
00103 p = 0;
00104 for (i = 0; i < dwGroups - 1; i++)
00105 {
00106 ++p;
00107 printf("Group %02d: %s\n", p, &mszGroups[i]);
00108 iList[p] = i;
00109 while (mszGroups[++i] != 0) ;
00110 }
00111
00112 wait_for_card_again:
00113 printf("Testing SCardListReaders\t: ");
00114
00115 mszGroups = 0;
00116 rv = SCardListReaders(hContext, mszGroups, 0, &dwReaders);
00117 test_rv(rv, hContext, PANIC);
00118
00119 mszReaders = malloc(sizeof(char) * dwReaders);
00120 rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders);
00121 test_rv(rv, hContext, PANIC);
00122
00123
00124
00125
00126 p = 0;
00127 for (i = 0; i < dwReaders - 1; i++)
00128 {
00129 ++p;
00130 printf("Reader %02d: %s\n", p, &mszReaders[i]);
00131 iList[p] = i;
00132 while (mszReaders[++i] != 0) ;
00133 }
00134
00135 if (p > 1)
00136 do
00137 {
00138 char input[80];
00139
00140 printf("Enter the reader number\t\t: ");
00141 fgets(input, sizeof(input), stdin);
00142 sscanf(input, "%d", &iReader);
00143
00144 if (iReader > p || iReader <= 0)
00145 printf("Invalid Value - try again\n");
00146 }
00147 while (iReader > p || iReader <= 0);
00148 else
00149 iReader = 1;
00150
00151 rgReaderStates[0].szReader = &mszReaders[iList[iReader]];
00152 rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;
00153
00154 printf("Waiting for card insertion\t: ");
00155 fflush(stdout);
00156 rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
00157 test_rv(rv, hContext, PANIC);
00158 if (SCARD_STATE_EMPTY == rgReaderStates[0].dwEventState)
00159 {
00160 printf("\nA reader has been connected/disconnected\n");
00161 goto wait_for_card_again;
00162 }
00163
00164 printf("Testing SCardConnect\t\t: ");
00165 rv = SCardConnect(hContext, &mszReaders[iList[iReader]],
00166 SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
00167 &hCard, &dwPref);
00168 test_rv(rv, hContext, PANIC);
00169
00170 switch(dwPref)
00171 {
00172 case SCARD_PROTOCOL_T0:
00173 pioSendPci = *SCARD_PCI_T0;
00174 break;
00175 case SCARD_PROTOCOL_T1:
00176 pioSendPci = *SCARD_PCI_T1;
00177 break;
00178 default:
00179 printf("Unknown protocol\n");
00180 return -1;
00181 }
00182
00183
00184 printf("Select file: ");
00185 send_length = 7;
00186 memcpy(bSendBuffer, "\x00\xA4\x00\x00\x02\x3F\x00", send_length);
00187 for (i=0; i<send_length; i++)
00188 printf(" %02X", bSendBuffer[i]);
00189 printf("\n");
00190 length = sizeof(bRecvBuffer);
00191
00192 printf("Testing SCardTransmit\t\t: ");
00193 rv = SCardTransmit(hCard, &pioSendPci, bSendBuffer, send_length,
00194 &pioRecvPci, bRecvBuffer, &length);
00195 printf("%s\n", pcsc_stringify_error(rv));
00196 printf(" card response:");
00197 for (i=0; i<length; i++)
00198 printf(" %02X", bRecvBuffer[i]);
00199 printf("\n");
00200
00201 printf("Testing SCardControl\t\t: ");
00202 #ifdef PCSC_PRE_120
00203 {
00204 char buffer[1024] = "Foobar";
00205 DWORD cbRecvLength = sizeof(buffer);
00206
00207 rv = SCardControl(hCard, buffer, 7, buffer, &cbRecvLength);
00208 }
00209 #else
00210 {
00211 char buffer[1024] = { 0x02 };
00212 DWORD cbRecvLength = sizeof(buffer);
00213
00214 rv = SCardControl(hCard, SCARD_CTL_CODE(1), buffer, 1, buffer,
00215 sizeof(buffer), &cbRecvLength);
00216 if (cbRecvLength)
00217 {
00218 for (i=0; i<cbRecvLength; i++)
00219 printf("%c", buffer[i]);
00220 printf(" ");
00221 }
00222 }
00223 #endif
00224 test_rv(rv, hContext, DONT_PANIC);
00225
00226 printf("Testing SCardGetAttrib\t\t: ");
00227 rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, NULL, &dwAtrLen);
00228 test_rv(rv, hContext, DONT_PANIC);
00229 if (rv == SCARD_S_SUCCESS)
00230 printf("ATR length: %ld\n", dwAtrLen);
00231
00232 printf("Testing SCardGetAttrib\t\t: ");
00233 dwAtrLen = sizeof(pbAtr);
00234 rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAtr, &dwAtrLen);
00235 test_rv(rv, hContext, DONT_PANIC);
00236 if (rv == SCARD_S_SUCCESS)
00237 {
00238 for (i = 0; i < dwAtrLen; i++)
00239 printf("%02X ", pbAtr[i]);
00240 printf("\n");
00241 }
00242
00243 printf("Testing SCardGetAttrib\t\t: ");
00244 dwAtrLen = sizeof(pbAtr);
00245 rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_IFD_VERSION, pbAtr, &dwAtrLen);
00246 test_rv(rv, hContext, DONT_PANIC);
00247 if (rv == SCARD_S_SUCCESS)
00248 printf("Vendor IFD version\t\t: 0x%08lX\n", ((DWORD *)pbAtr)[0]);
00249
00250 printf("Testing SCardGetAttrib\t\t: ");
00251 dwAtrLen = sizeof(pbAtr);
00252 rv = SCardGetAttrib(hCard, SCARD_ATTR_MAXINPUT, pbAtr, &dwAtrLen);
00253 test_rv(rv, hContext, DONT_PANIC);
00254 if (rv == SCARD_S_SUCCESS)
00255 {
00256 if (dwAtrLen == sizeof(uint32_t))
00257 printf("Max message length\t\t: %d\n", *(uint32_t *)pbAtr);
00258 else
00259 printf(RED_PRINTF_FORMAT, "Wrong size");
00260 }
00261
00262 printf("Testing SCardGetAttrib\t\t: ");
00263 dwAtrLen = sizeof(pbAtr);
00264 rv = SCardGetAttrib(hCard, SCARD_ATTR_VENDOR_NAME, pbAtr, &dwAtrLen);
00265 test_rv(rv, hContext, DONT_PANIC);
00266 if (rv == SCARD_S_SUCCESS)
00267 printf("Vendor name\t\t\t: %s\n", pbAtr);
00268
00269 printf("Testing SCardSetAttrib\t\t: ");
00270 rv = SCardSetAttrib(hCard, SCARD_ATTR_ATR_STRING, (LPCBYTE)"", 1);
00271 test_rv(rv, hContext, DONT_PANIC);
00272
00273 printf("Testing SCardStatus\t\t: ");
00274
00275 dwReaderLen = 50;
00276 pcReaders = malloc(sizeof(char) * 50);
00277 dwAtrLen = MAX_ATR_SIZE;
00278
00279 rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt,
00280 pbAtr, &dwAtrLen);
00281 test_rv(rv, hContext, PANIC);
00282
00283 printf("Current Reader Name\t\t: %s\n", pcReaders);
00284 printf("Current Reader State\t\t: 0x%.4lx\n", dwState);
00285 printf("Current Reader Protocol\t\t: T=%ld\n", dwProt - 1);
00286 printf("Current Reader ATR Size\t\t: %ld bytes\n", dwAtrLen);
00287 printf("Current Reader ATR Value\t: ");
00288
00289 for (i = 0; i < dwAtrLen; i++)
00290 {
00291 printf("%02X ", pbAtr[i]);
00292 }
00293 printf("\n");
00294
00295 if (rv != SCARD_S_SUCCESS)
00296 {
00297 SCardDisconnect(hCard, SCARD_RESET_CARD);
00298 SCardReleaseContext(hContext);
00299 }
00300
00301 printf("Press enter: ");
00302 getchar();
00303 printf("Testing SCardReconnect\t\t: ");
00304 rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,
00305 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_UNPOWER_CARD, &dwPref);
00306 test_rv(rv, hContext, PANIC);
00307
00308 printf("Testing SCardDisconnect\t\t: ");
00309 rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
00310 test_rv(rv, hContext, PANIC);
00311
00312 printf("Testing SCardReleaseContext\t: ");
00313 rv = SCardReleaseContext(hContext);
00314 test_rv(rv, hContext, PANIC);
00315
00316 printf("\n");
00317 printf("PC/SC Test Completed Successfully !\n");
00318
00319 return 0;
00320 }