#include <winscard.h>   /* PC/SC Prototypen */
#include <stdio.h>

int main(void)
{
   SCARDCONTEXT Context;                /* Kontext zum Ressource Manager */
   SCARDHANDLE  CardHandle;             /* Handle auf die Chipkarte */
   DWORD        Protocol;               /* verwendetes Übertragungsprotokoll */
   LONG         result;                 /* Variable für Return-Codes */
   DWORD        dwReaders;              /* Anzahl der verfügbaren Terminals */
   LPSTR        mszReaders;             /* String-Liste der verfügbaren Terminals */
   int          i,p,iList[20],reader;   /* Hilfsvariablen */
   SCARD_READERSTATE_A readerState[1];  /* Status des Terminals */
   DWORD responseLength;                /* Antwortlänge */
   unsigned char response[100];         /* Puffer für Antwort-APDU */
   unsigned short int trailer;          /* Antwort Trailer */

                        /* CLA  INS   P1   P2   Lc     Data */
   unsigned char APDU[] = {0xA0,0xA4,0x00,0x00,0x02,0x7F,0x10}; /* GSM-Kommando SELECT 7F10 */

   /* Verbindung zum PC/SC Ressource Manager aufbauen */
   result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &Context);

   if (result==SCARD_S_SUCCESS)
   {
           printf("Verbindung zum Ressource Manager konnte erfolgreich aufgebaut werden.\n");

           /* Liste aller über den Ressource Manager ereichbaren Terminals ermitteln */
           SCardListReaders(Context, NULL, NULL, &dwReaders);
           mszReaders = (LPSTR)malloc(sizeof(char)*dwReaders);
           SCardListReaders(Context, NULL, mszReaders, &dwReaders);

           p = 0;
           for (i=0;i<dwReaders-1;i++)
           {
                   p++;
                   iList[p] = i;
                   printf("Terminal %d: %s\n",p, &mszReaders[i]);
                   while (mszReaders[++i] != 0);
           }

           do
           {
               printf("Geben Sie bitte die gewünschte Terminal-Nummer ein: ");
               scanf("%d",&reader);
           }
           while ((reader>p) || (reader <=0));

           readerState[0].szReader = &mszReaders[iList[reader]];
           readerState[0].dwCurrentState = SCARD_STATE_EMPTY;

           /* wartet solange bis Karte eingelegt wird */
           printf("Chipkarte einlegen ... \n");
           SCardGetStatusChange(Context, INFINITE, readerState, 1);

           /* mit dem gewünschten Terminal verbinden */
           result = SCardConnect(Context,
                                 &mszReaders[iList[reader]],
                                 SCARD_SHARE_SHARED,
                                 SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
                                 &CardHandle,
                                 &Protocol);

           if (result == SCARD_S_SUCCESS)
           {
               printf("Karten-Verbindung steht ... \n");

               /* APDU an die Karte schicken */
               responseLength = sizeof(response);
               result = SCardTransmit(CardHandle, SCARD_PCI_T0, APDU, sizeof(APDU), NULL, response, &responseLength);

               if (result==SCARD_S_SUCCESS)
               {
                  printf("Antwort Trailer SW1=%.2xh SW2=%.2xh\n",response[0], response[1]);

                  if ( (response[0]==0x90) || (response[0]==0x97))
                  {
                     /* APDU konnte ausgeführt werden - Auswerten der Antwort-APDU
                           .....
                     */
                  }

                  SCardDisconnect(CardHandle, SCARD_EJECT_CARD);  /* Verbindung trennen */
               }
               else
                   printf("Transmit der APDU fehlgeschlagen\n");
           }
           else
               printf("Verbindung fehlgeschlagen\n");

           SCardReleaseContext(Context);       /* Kontext zum Ressource Manager wieder freigeben */
   }
   else
           printf("Verbindungsaufbau zum Ressource Manager fehlgeschlagen\n" \
                  "!!! möglicherweise /usr/local/pcscd nicht gestartet !!!\n");
}