/[winpt]/trunk/Src/wptCardPCSC.c
ViewVC logotype

Diff of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 261 by twoaday, Sat Apr 1 12:36:35 2006 UTC revision 262 by twoaday, Sat Sep 30 10:24:34 2006 UTC
# Line 1  Line 1 
1  /* wptCardPCSC.cpp - PC/SC card API interface  /* wptCardPCSC.cpp - PC/SC card API interface
2   *      Copyright (C) 2003 Timo Schulz   *      Copyright (C) 2003, 2006 Timo Schulz
  *      Copyright (C) 2003, 2004 Free Software Foundation, Inc.  
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
# Line 22  Line 21 
21  #include <config.h>  #include <config.h>
22  #endif  #endif
23    
 #if 0 /* not needed right now. */  
24  #include <stdio.h>  #include <stdio.h>
25  #include <windows.h>  #include <windows.h>
26  #ifndef __MINGW32__  #ifndef __MINGW32__
27  #include <winscard.h>  #include <winscard.h>
28    #else
29    /* mingw32 has no win32 smartcard API definitions. */
30    typedef ULONG_PTR SCARDCONTEXT;
31    #define SCARD_SCOPE_SYSTEM 2
32    #define SCARD_S_SUCCESS NO_ERROR
33  #endif  #endif
34    
35  #include "gpgme.h"  #include "gpgme.h"
# Line 34  Line 37 
37  #include "wptCard.h"  #include "wptCard.h"
38    
39    
 /* Definitions usually found in winscard.h but not used here becuase  
    mingw does not come with winscard and we dlopen the stuff  
    anyway. */  
 typedef unsigned long pcsc_context_t;  
 struct pcsc_readerstate_s  
 {  
     const char *reader;  
     void *user_data;  
     unsigned long current_state;  
     unsigned long event_state;  
     unsigned long atrlen;  
     unsigned char atr[33];  
 };  
   
 typedef struct pcsc_readerstate_s *pcsc_readerstate_t;  
   
 /* PC/SC constants and function pointer. */  
 #define PCSC_SCOPE_USER      0  
 #define PCSC_SCOPE_TERMINAL  1  
 #define PCSC_SCOPE_SYSTEM    2  
 #define PCSC_SCOPE_GLOBAL    3  
   
 #define PCSC_PROTOCOL_T0     1  
 #define PCSC_PROTOCOL_T1     2  
 #define PCSC_PROTOCOL_RAW    4  
   
 #define PCSC_SHARE_EXCLUSIVE 1  
 #define PCSC_SHARE_SHARED    2  
 #define PCSC_SHARE_DIRECT    3  
   
 #define PCSC_LEAVE_CARD      0  
 #define PCSC_RESET_CARD      1  
 #define PCSC_UNPOWER_CARD    2  
 #define PCSC_EJECT_CARD      3  
   
 #define PCSC_UNKNOWN    0x0001  
 #define PCSC_ABSENT     0x0002  /* Card is absent.  */  
 #define PCSC_PRESENT    0x0004  /* Card is present.  */  
 #define PCSC_SWALLOWED  0x0008  /* Card is present and electrical connected. */  
 #define PCSC_POWERED    0x0010  /* Card is powered.  */  
 #define PCSC_NEGOTIABLE 0x0020  /* Card is awaiting PTS.  */  
 #define PCSC_SPECIFIC   0x0040  /* Card is ready for use.  */  
   
 #define PCSC_STATE_UNAWARE     0x0000  /* Want status.  */  
 #define PCSC_STATE_IGNORE      0x0001  /* Ignore this reader.  */  
 #define PCSC_STATE_CHANGED     0x0002  /* State has changed.  */  
 #define PCSC_STATE_UNKNOWN     0x0004  /* Reader unknown.  */  
 #define PCSC_STATE_UNAVAILABLE 0x0008  /* Status unavailable.  */  
 #define PCSC_STATE_EMPTY       0x0010  /* Card removed.  */  
 #define PCSC_STATE_PRESENT     0x0020  /* Card inserted.  */  
 #define PCSC_STATE_ATRMATCH    0x0040  /* ATR matches card. */  
 #define PCSC_STATE_EXCLUSIVE   0x0080  /* Exclusive Mode.  */  
 #define PCSC_STATE_INUSE       0x0100  /* Shared mode.  */  
 #define PCSC_STATE_MUTE        0x0200  /* Unresponsive card.  */  
   
 /* Some PC/SC error codes.  */  
 #define PCSC_E_CANCELLED               0x80100002  
 #define PCSC_E_CANT_DISPOSE            0x8010000E  
 #define PCSC_E_INSUFFICIENT_BUFFER     0x80100008  
 #define PCSC_E_INVALID_ATR             0x80100015  
 #define PCSC_E_INVALID_HANDLE          0x80100003  
 #define PCSC_E_INVALID_PARAMETER       0x80100004  
 #define PCSC_E_INVALID_TARGET          0x80100005  
 #define PCSC_E_INVALID_VALUE           0x80100011  
 #define PCSC_E_NO_MEMORY               0x80100006  
 #define PCSC_E_UNKNOWN_READER          0x80100009  
 #define PCSC_E_TIMEOUT                 0x8010000A  
 #define PCSC_E_SHARING_VIOLATION       0x8010000B  
 #define PCSC_E_NO_SMARTCARD            0x8010000C  
 #define PCSC_E_UNKNOWN_CARD            0x8010000D  
 #define PCSC_E_PROTO_MISMATCH          0x8010000F  
 #define PCSC_E_NOT_READY               0x80100010  
 #define PCSC_E_SYSTEM_CANCELLED        0x80100012  
 #define PCSC_E_NOT_TRANSACTED          0x80100016  
 #define PCSC_E_READER_UNAVAILABLE      0x80100017  
 #define PCSC_W_REMOVED_CARD            0x80100069  
   
   
 /* Possible card states. */  
 enum card_state_t {  
     CARD_STATE_NONE=0,  
     CARD_STATE_UNAWARE,  
     CARD_STATE_UNAVAIL,  
     CARD_STATE_PRESENT,  
     CARD_STATE_EXCLUSI,  
     CARD_STATE_EMPTY,  
     CARD_STATE_INUSE,  
     CARD_STATE_MUTE  
 };  
   
 #define MAX_READERS 8  
   
 struct pcsc_reader_s {  
     struct pcsc_readerstate_s reader_states[MAX_READERS];  
     int nreaders;  
     char * readers[MAX_READERS];  
 };  
 typedef struct pcsc_reader_s *pcsc_reader_t;  
   
   
40  static LONG (WINAPI *pcsc_establish_context) (unsigned long scope,  static LONG (WINAPI *pcsc_establish_context) (unsigned long scope,
41                                  const void *reserved1,                                  const void *reserved1,
42                                  const void *reserved2,                                  const void *reserved2,
43                                  unsigned long *r_context);                                  unsigned long *r_context);
44  static LONG (WINAPI *pcsc_release_context) (unsigned long context);  static LONG (WINAPI *pcsc_release_context) (unsigned long context);
 static LONG (WINAPI *pcsc_list_readers) (unsigned long context,  
                                          const char *groups,  
                                          char *readers,  
                                          unsigned long *readerslen);  
 static LONG (WINAPI *pcsc_connect) (unsigned long context,  
                       const char *reader,  
                       unsigned long share_mode,  
                       unsigned long preferred_protocols,  
                       unsigned long *r_card,  
                       unsigned long *r_active_protocol);  
 static LONG (WINAPI *pcsc_disconnect) (unsigned long card,  
                                        unsigned long disposition);  
 static LONG (WINAPI *pcsc_status) (unsigned long card,  
                      char *reader, unsigned long *readerlen,  
                      unsigned long *r_state, unsigned long *r_protocol,  
                      unsigned char *atr, unsigned long *atrlen);  
 static LONG (WINAPI *pcsc_get_status_change)(unsigned long ctx,  
                                              unsigned long timeout,  
                                              pcsc_readerstate_t readerstate,  
                                              unsigned long creaders);  
45    
46  static int pcsc_init = 0;  static int pcsc_init = 0;
47    
# Line 174  static int pcsc_init = 0; Line 57  static int pcsc_init = 0;
57  } while (0)  } while (0)
58    
59    
60  int  static int
61  pcsc_loadlib (int scard_support)  pcsc_loadlib (void)
62  {  {
63      HMODULE hlib;      HMODULE hlib;
64      FARPROC a;          FARPROC a;    
65    
66      if (!scard_support || pcsc_init)      if (pcsc_init)
67          return 0;          return 0;
68      hlib = LoadLibrary ("WINSCARD");      hlib = LoadLibrary ("WINSCARD");
69      if (!hlib)      if (!hlib)
70          goto fail;          goto fail;
71      load_one_fnc (pcsc_establish_context, hlib, "SCardEstablishContext");      load_one_fnc (pcsc_establish_context, hlib, "SCardEstablishContext");
72      load_one_fnc (pcsc_release_context, hlib, "SCardReleaseContext");      load_one_fnc (pcsc_release_context, hlib, "SCardReleaseContext");
     load_one_fnc (pcsc_list_readers, hlib, "SCardListReadersA");  
     load_one_fnc (pcsc_connect, hlib, "SCardConnectA");  
     load_one_fnc (pcsc_disconnect, hlib, "SCardDisconnect");  
     load_one_fnc (pcsc_status, hlib, "SCardStatusA");  
     load_one_fnc (pcsc_get_status_change, hlib, "SCardGetStatusChangeA");  
73      goto success;      goto success;
74    
75  fail:  fail:
76      FreeLibrary (hlib);      if (hlib != NULL)
77            FreeLibrary (hlib);
78      return -1;      return -1;
79    
80  success:  success:
81      pcsc_init = 1;      pcsc_init = 1;
     FreeLibrary (hlib);  
82      return 0;      return 0;
83  }  }
84    
85    
86  void  /* Return != 0 if the PC/SC smart card interface is available.
87  pcsc_free_readers (pcsc_reader_t rd)     The purpose of the function is to disable smart card releation
88  {     commands on systems with no scard readers. */
     int i;  
   
     if (!rd)  
         return;  
   
     for (i=0; i < rd->nreaders; i++)  
         safe_free (rd->readers[i]);  
     safe_free (rd);  
 }  
   
   
 const char *  
 pcsc_get_reader (pcsc_reader_t rd, int idx, int * ret_nrd)  
 {  
     if (!rd)  
         return NULL;  
     if (idx == -1 && ret_nrd) {  
         *ret_nrd = rd->nreaders;  
         return NULL;  
     }  
     if (idx >= rd->nreaders)  
         idx=0;  
     return rd->readers[idx];  
 }  
   
   
89  int  int
90  pcsc_scan_readers (pcsc_reader_t * ret_rd)  pcsc_available (void)
91  {  {
92      pcsc_reader_t rd;      SCARDCONTEXT ctx;
93      pcsc_context_t hctx;      LONG err;
     struct pcsc_readerstate_s rdstat;  
     DWORD readers;  
     LPSTR rdrstr;  
     char * p;  
     int i;  
     int rc, curr_rd=0;  
   
     *ret_rd = NULL;  
     if (!pcsc_init)  
         return -1;  
   
     rc = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, &hctx);  
     if (rc)  
         return -1;  
94    
95      rc = pcsc_list_readers (hctx, NULL, NULL, &readers);      if (pcsc_loadlib ())
     if (rc)  
         return -1;  
   
     rdrstr = malloc (sizeof(char)*readers);  
     if (!rdrstr)  
         BUG (0);  
   
     rc = pcsc_list_readers (hctx, NULL, rdrstr, &readers);  
     if (rc) {  
         safe_free (rdrstr);  
         return -1;  
     }  
   
     rd = calloc (1, sizeof *rd);  
     if (!rd)  
         BUG (0);  
           
     p = rdrstr;  
     while ((*p != '\0') && (rd->nreaders < MAX_READERS)) {        
         rd->readers[rd->nreaders] = strdup (p);  
         p += strlen (p)+1;  
         rd->nreaders++;  
     }  
   
     if (!rd->nreaders) {  
         safe_free (rdrstr);  
         safe_free (rd);  
96          return 0;          return 0;
     }  
   
     /* set the initial states */  
     for (i=0; i<rd->nreaders; i++) {  
         rd->reader_states[i].reader = rd->readers[i];  
         rd->reader_states[i].current_state = PCSC_STATE_EMPTY;  
     }  
97    
98      while (1) {      err = pcsc_establish_context (SCARD_SCOPE_SYSTEM, NULL, NULL, &ctx);
99          rdstat = rd->reader_states[curr_rd];                  if (err == SCARD_S_SUCCESS) {
100          rc = pcsc_get_status_change (hctx, 0, &rdstat, 1);          pcsc_release_context (ctx);
         if (rc == PCSC_E_TIMEOUT)  
             continue;  
         if (rc)  
             ; /* FIXME:  What is this?? */  
   
         /* next reader */  
         curr_rd++;  
         if (curr_rd >= rd->nreaders)  
             curr_rd = 0;  
     }  
       
     safe_free (rdrstr);  
     *ret_rd = rd;  
     rc = pcsc_release_context (hctx);  
     if (rc)  
101          return -1;          return -1;
102        }
103      return 0;      return 0;
104  }  }
   
   
 int  
 pcsc_get_card_status (void)  
 {  
     pcsc_reader_t rd;  
     struct pcsc_readerstate_s rdstat;  
     int rc, stat=0;  
   
     rc = pcsc_scan_readers (&rd);  
     if (rc)  
         return -1;  
     rdstat = rd->reader_states[0];  
     if (rdstat.current_state & PCSC_STATE_UNAVAILABLE)  
         stat |= CARD_STATE_UNAVAIL;  
     if (rdstat.current_state & PCSC_STATE_EMPTY)  
         stat |= CARD_STATE_EMPTY;  
     if (rdstat.current_state & PCSC_STATE_INUSE)  
         stat |= CARD_STATE_INUSE;  
     if (rdstat.current_state & PCSC_STATE_EXCLUSIVE)  
         stat |= CARD_STATE_EXCLUSI;  
     return stat;  
 }  
 #endif  

Legend:
Removed from v.261  
changed lines
  Added in v.262

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26