/* * MUSCLE SmartCard Development ( http://www.linuxnet.com ) * * Copyright (C) 1999 * David Corcoran * Copyright (C) 2004-2006 * Ludovic Rousseau * * $Id: testpcsc.c 2541 2007-05-23 07:34:42Z rousseau $ */ /** * @file * @brief This is a test program for pcsc-lite. */ #include "config.h" #include #include #include #include "pcsclite.h" #include "winscard.h" #include "reader.h" #define PANIC 0 #define DONT_PANIC 1 #define RED_PRINTF_FORMAT "\33[01;31m%s\33[0m\n" void test_rv(int rv, SCARDCONTEXT hContext, int dont_panic); void test_rv(int rv, SCARDCONTEXT hContext, int dont_panic) { if (rv != SCARD_S_SUCCESS) { if (dont_panic) printf("\33[34m%s (don't panic)\33[0m\n", pcsc_stringify_error(rv)); else { printf(RED_PRINTF_FORMAT, pcsc_stringify_error(rv)); SCardReleaseContext(hContext); exit(-1); } } else puts(pcsc_stringify_error(rv)); } int main(int argc, char **argv) { SCARDHANDLE hCard; SCARDCONTEXT hContext; SCARD_READERSTATE_A rgReaderStates[1]; DWORD dwReaderLen, dwState, dwProt, dwAtrLen; DWORD dwPref, dwReaders; char *pcReaders, *mszReaders; unsigned char pbAtr[MAX_ATR_SIZE]; char *mszGroups; DWORD dwGroups; long rv; DWORD i; int p, iReader; int iList[16]; SCARD_IO_REQUEST pioRecvPci; SCARD_IO_REQUEST pioSendPci; unsigned char bSendBuffer[MAX_BUFFER_SIZE]; unsigned char bRecvBuffer[MAX_BUFFER_SIZE]; DWORD send_length, length; printf("\nMUSCLE PC/SC Lite unitary test Program\n\n"); printf("\33[35mTHIS PROGRAM IS NOT DESIGNED AS A TESTING TOOL FOR END USERS!\n"); printf("Do NOT use it unless you really know what you do.\33[0m\n\n"); printf("Testing SCardEstablishContext\t: "); rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); test_rv(rv, hContext, PANIC); printf("Testing SCardIsValidContext\t: "); rv = SCardIsValidContext(hContext); test_rv(rv, hContext, PANIC); printf("Testing SCardIsValidContext\t: "); rv = SCardIsValidContext(hContext+1); test_rv(rv, hContext, DONT_PANIC); printf("Testing SCardGetStatusChange \n"); printf("Please insert a working reader\t: "); fflush(stdout); rv = SCardGetStatusChange(hContext, INFINITE, 0, 0); test_rv(rv, hContext, PANIC); printf("Testing SCardListReaderGroups\t: "); rv = SCardListReaderGroups(hContext, 0, &dwGroups); test_rv(rv, hContext, PANIC); mszGroups = malloc(sizeof(char) * dwGroups); rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups); test_rv(rv, hContext, PANIC); /* * Have to understand the multi-string here */ p = 0; for (i = 0; i < dwGroups - 1; i++) { ++p; printf("Group %02d: %s\n", p, &mszGroups[i]); iList[p] = i; while (mszGroups[++i] != 0) ; } wait_for_card_again: printf("Testing SCardListReaders\t: "); mszGroups = 0; rv = SCardListReaders(hContext, mszGroups, 0, &dwReaders); test_rv(rv, hContext, PANIC); mszReaders = malloc(sizeof(char) * dwReaders); rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders); test_rv(rv, hContext, PANIC); /* * Have to understand the multi-string here */ p = 0; for (i = 0; i < dwReaders - 1; i++) { ++p; printf("Reader %02d: %s\n", p, &mszReaders[i]); iList[p] = i; while (mszReaders[++i] != 0) ; } if (p > 1) do { char input[80]; printf("Enter the reader number\t\t: "); fgets(input, sizeof(input), stdin); sscanf(input, "%d", &iReader); if (iReader > p || iReader <= 0) printf("Invalid Value - try again\n"); } while (iReader > p || iReader <= 0); else iReader = 1; rgReaderStates[0].szReader = &mszReaders[iList[iReader]]; rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY; printf("Waiting for card insertion\t: "); fflush(stdout); rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1); test_rv(rv, hContext, PANIC); if (SCARD_STATE_EMPTY == rgReaderStates[0].dwEventState) { printf("\nA reader has been connected/disconnected\n"); goto wait_for_card_again; } printf("Testing SCardConnect\t\t: "); rv = SCardConnect(hContext, &mszReaders[iList[iReader]], SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwPref); test_rv(rv, hContext, PANIC); switch(dwPref) { case SCARD_PROTOCOL_T0: pioSendPci = *SCARD_PCI_T0; break; case SCARD_PROTOCOL_T1: pioSendPci = *SCARD_PCI_T1; break; default: printf("Unknown protocol\n"); return -1; } /* APDU select file */ printf("Select file: "); send_length = 7; memcpy(bSendBuffer, "\x00\xA4\x00\x00\x02\x3F\x00", send_length); for (i=0; i