/[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 35 by twoaday, Tue Oct 25 07:46:20 2005 UTC revision 36 by werner, Thu Oct 27 15:25:13 2005 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 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
6   * WinPT is free software; you can redistribute it and/or modify   * WinPT is free software; you can redistribute it and/or modify
7   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
8   * the Free Software Foundation; either version 2 of the License, or   * the Free Software Foundation; either version 2 of the License, or
9   * (at your option) any later version.   * (at your option) any later version.
10   *   *
11   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
15   *   *
16   * You should have received a copy of the GNU General Public License   * You should have received a copy of the GNU General Public License
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19   */   */
20    
21  #include <stdio.h>  #ifdef HAVE_CONFIG_H
22  #include <windows.h>  #include <config.h>
23  #include <winscard.h>  #endif
24    
25  #include "gpgme.h"  #include <stdio.h>
26  #include "wptTypes.h"  #include <stdio.h>
27  #include "wptCard.h"  #include <windows.h>
28    #include <winscard.h>
29  /* Possible card states. */  
30  enum card_state_t {  #include "gpgme.h"
31      CARD_STATE_NONE=0,  #include "wptTypes.h"
32      CARD_STATE_UNAWARE,  #include "wptCard.h"
33      CARD_STATE_UNAVAIL,  
34      CARD_STATE_PRESENT,  /* Possible card states. */
35      CARD_STATE_EXCLUSI,  enum card_state_t {
36      CARD_STATE_EMPTY,      CARD_STATE_NONE=0,
37      CARD_STATE_INUSE,      CARD_STATE_UNAWARE,
38      CARD_STATE_MUTE      CARD_STATE_UNAVAIL,
39  };      CARD_STATE_PRESENT,
40        CARD_STATE_EXCLUSI,
41  #define MAX_READERS 8      CARD_STATE_EMPTY,
42        CARD_STATE_INUSE,
43  struct pcsc_reader_s {      CARD_STATE_MUTE
44      SCARD_READERSTATE_A reader_states[MAX_READERS];  };
45      int nreaders;  
46      char * readers[MAX_READERS];  #define MAX_READERS 8
47  };  
48  typedef struct pcsc_reader_s *pcsc_reader_t;  struct pcsc_reader_s {
49        SCARD_READERSTATE_A reader_states[MAX_READERS];
50        int nreaders;
51  static LONG (WINAPI *pcsc_establish_context) (unsigned long scope,      char * readers[MAX_READERS];
52                                  const void *reserved1,  };
53                                  const void *reserved2,  typedef struct pcsc_reader_s *pcsc_reader_t;
54                                  unsigned long *r_context);  
55  static LONG (WINAPI *pcsc_release_context) (unsigned long context);  
56  static LONG (WINAPI *pcsc_list_readers) (unsigned long context,  static LONG (WINAPI *pcsc_establish_context) (unsigned long scope,
57                                           const char *groups,                                  const void *reserved1,
58                                           char *readers,                                  const void *reserved2,
59                                           unsigned long *readerslen);                                  unsigned long *r_context);
60  static LONG (WINAPI *pcsc_connect) (unsigned long context,  static LONG (WINAPI *pcsc_release_context) (unsigned long context);
61                        const char *reader,  static LONG (WINAPI *pcsc_list_readers) (unsigned long context,
62                        unsigned long share_mode,                                           const char *groups,
63                        unsigned long preferred_protocols,                                           char *readers,
64                        unsigned long *r_card,                                           unsigned long *readerslen);
65                        unsigned long *r_active_protocol);  static LONG (WINAPI *pcsc_connect) (unsigned long context,
66  static LONG (WINAPI *pcsc_disconnect) (unsigned long card,                        const char *reader,
67                                         unsigned long disposition);                        unsigned long share_mode,
68  static LONG (WINAPI *pcsc_status) (unsigned long card,                        unsigned long preferred_protocols,
69                       char *reader, unsigned long *readerlen,                        unsigned long *r_card,
70                       unsigned long *r_state, unsigned long *r_protocol,                        unsigned long *r_active_protocol);
71                       unsigned char *atr, unsigned long *atrlen);  static LONG (WINAPI *pcsc_disconnect) (unsigned long card,
72  static LONG (WINAPI *pcsc_get_status_change)(unsigned long ctx,                                         unsigned long disposition);
73                                               unsigned long timeout,  static LONG (WINAPI *pcsc_status) (unsigned long card,
74                                               SCARD_READERSTATE * readerstate,                       char *reader, unsigned long *readerlen,
75                                               unsigned long creaders);                       unsigned long *r_state, unsigned long *r_protocol,
76                         unsigned char *atr, unsigned long *atrlen);
77  static int pcsc_init = 0;  static LONG (WINAPI *pcsc_get_status_change)(unsigned long ctx,
78                                                 unsigned long timeout,
79                                                 SCARD_READERSTATE * readerstate,
80  #define load_one_fnc(ptr, hlib, name) do {                          \                                               unsigned long creaders);
81      a = ptr = (void *)GetProcAddress (hlib, name);                  \  
82      if (!a) {                                                       \  static int pcsc_init = 0;
83          char msg[256];                                              \  
84          _snprintf (msg, sizeof msg-1, "Could not load '%s'", name); \  
85          MessageBox (NULL, msg, "PC/SC Driver", MB_ICONERROR|MB_OK); \  #define load_one_fnc(ptr, hlib, name) do {                          \
86          goto fail;                                                  \      a = ptr = (void *)GetProcAddress (hlib, name);                  \
87      } \      if (!a) {                                                       \
88  } while (0)          char msg[256];                                              \
89            _snprintf (msg, sizeof msg-1, "Could not load '%s'", name); \
90            MessageBox (NULL, msg, "PC/SC Driver", MB_ICONERROR|MB_OK); \
91  int          goto fail;                                                  \
92  pcsc_loadlib (int scard_support)      } \
93  {  } while (0)
94      HMODULE hlib;  
95      FARPROC a;      
96    int
97      if (!scard_support || pcsc_init)  pcsc_loadlib (int scard_support)
98          return 0;  {
99      hlib = LoadLibrary ("WINSCARD");      HMODULE hlib;
100      if (!hlib)      FARPROC a;    
101          goto fail;  
102      load_one_fnc (pcsc_establish_context, hlib, "SCardEstablishContext");      if (!scard_support || pcsc_init)
103      load_one_fnc (pcsc_release_context, hlib, "SCardReleaseContext");          return 0;
104      load_one_fnc (pcsc_list_readers, hlib, "SCardListReadersA");      hlib = LoadLibrary ("WINSCARD");
105      load_one_fnc (pcsc_connect, hlib, "SCardConnectA");      if (!hlib)
106      load_one_fnc (pcsc_disconnect, hlib, "SCardDisconnect");          goto fail;
107      load_one_fnc (pcsc_status, hlib, "SCardStatusA");      load_one_fnc (pcsc_establish_context, hlib, "SCardEstablishContext");
108      load_one_fnc (pcsc_get_status_change, hlib, "SCardGetStatusChangeA");      load_one_fnc (pcsc_release_context, hlib, "SCardReleaseContext");
109      goto success;      load_one_fnc (pcsc_list_readers, hlib, "SCardListReadersA");
110        load_one_fnc (pcsc_connect, hlib, "SCardConnectA");
111  fail:      load_one_fnc (pcsc_disconnect, hlib, "SCardDisconnect");
112      FreeLibrary (hlib);      load_one_fnc (pcsc_status, hlib, "SCardStatusA");
113      return -1;      load_one_fnc (pcsc_get_status_change, hlib, "SCardGetStatusChangeA");
114  success:      goto success;
115      pcsc_init = 1;  
116      FreeLibrary (hlib);  fail:
117      return 0;      FreeLibrary (hlib);
118  }      return -1;
119    success:
120        pcsc_init = 1;
121  void      FreeLibrary (hlib);
122  pcsc_free_readers (pcsc_reader_t rd)      return 0;
123  {  }
124      int i;  
125    
126      if (!rd)  void
127          return;  pcsc_free_readers (pcsc_reader_t rd)
128    {
129      for (i=0; i < rd->nreaders; i++)      int i;
130          safe_free (rd->readers[i]);  
131      safe_free (rd);      if (!rd)
132  }          return;
133    
134        for (i=0; i < rd->nreaders; i++)
135  const char *          safe_free (rd->readers[i]);
136  pcsc_get_reader (pcsc_reader_t rd, int idx, int * ret_nrd)      safe_free (rd);
137  {  }
138      if (!rd)  
139          return NULL;  
140      if (idx == -1 && ret_nrd) {  const char *
141          *ret_nrd = rd->nreaders;  pcsc_get_reader (pcsc_reader_t rd, int idx, int * ret_nrd)
142          return NULL;  {
143      }      if (!rd)
144      if (idx >= rd->nreaders)          return NULL;
145          idx=0;      if (idx == -1 && ret_nrd) {
146      return rd->readers[idx];          *ret_nrd = rd->nreaders;
147  }          return NULL;
148        }
149        if (idx >= rd->nreaders)
150  int          idx=0;
151  pcsc_scan_readers (pcsc_reader_t * ret_rd)      return rd->readers[idx];
152  {  }
153      pcsc_reader_t rd;  
154      SCARDCONTEXT hctx;  
155      SCARD_READERSTATE_A rdstat;  int
156      DWORD readers;  pcsc_scan_readers (pcsc_reader_t * ret_rd)
157      LPSTR rdrstr;  {
158      char * p;      pcsc_reader_t rd;
159      int i;      SCARDCONTEXT hctx;
160      int rc, curr_rd=0;      SCARD_READERSTATE_A rdstat;
161        DWORD readers;
162      *ret_rd = NULL;      LPSTR rdrstr;
163      if (!pcsc_init)      char * p;
164          return -1;      int i;
165        int rc, curr_rd=0;
166      rc = pcsc_establish_context (SCARD_SCOPE_SYSTEM, NULL, NULL, &hctx);  
167      if (rc != SCARD_S_SUCCESS)      *ret_rd = NULL;
168          return -1;      if (!pcsc_init)
169            return -1;
170      rc = pcsc_list_readers (hctx, NULL, NULL, &readers);  
171      if (rc != SCARD_S_SUCCESS)      rc = pcsc_establish_context (SCARD_SCOPE_SYSTEM, NULL, NULL, &hctx);
172          return -1;      if (rc != SCARD_S_SUCCESS)
173            return -1;
174      rdrstr = malloc (sizeof(char)*readers);  
175      if (!rdrstr)      rc = pcsc_list_readers (hctx, NULL, NULL, &readers);
176          BUG (0);      if (rc != SCARD_S_SUCCESS)
177            return -1;
178      rc = pcsc_list_readers (hctx, NULL, rdrstr, &readers);  
179      if (rc != SCARD_S_SUCCESS) {      rdrstr = malloc (sizeof(char)*readers);
180          safe_free (rdrstr);      if (!rdrstr)
181          return -1;          BUG (0);
182      }  
183        rc = pcsc_list_readers (hctx, NULL, rdrstr, &readers);
184      rd = calloc (1, sizeof *rd);      if (rc != SCARD_S_SUCCESS) {
185      if (!rd)          safe_free (rdrstr);
186          BUG (0);          return -1;
187                }
188      p = rdrstr;  
189      while ((*p != '\0') && (rd->nreaders < MAX_READERS)) {            rd = calloc (1, sizeof *rd);
190          rd->readers[rd->nreaders] = strdup (p);      if (!rd)
191          p += strlen (p)+1;          BUG (0);
192          rd->nreaders++;          
193      }      p = rdrstr;
194        while ((*p != '\0') && (rd->nreaders < MAX_READERS)) {      
195      if (!rd->nreaders) {          rd->readers[rd->nreaders] = strdup (p);
196          safe_free (rdrstr);          p += strlen (p)+1;
197          safe_free (rd);          rd->nreaders++;
198          return 0;      }
199      }  
200        if (!rd->nreaders) {
201      /* set the initial states */          safe_free (rdrstr);
202      for (i=0; i<rd->nreaders; i++) {          safe_free (rd);
203          rd->reader_states[i].szReader = rd->readers[i];          return 0;
204          rd->reader_states[i].dwCurrentState = SCARD_STATE_EMPTY;      }
205      }  
206        /* set the initial states */
207      while (1) {      for (i=0; i<rd->nreaders; i++) {
208          rdstat = rd->reader_states[curr_rd];                      rd->reader_states[i].szReader = rd->readers[i];
209          rc = pcsc_get_status_change (hctx, 0, &rdstat, 1);          rd->reader_states[i].dwCurrentState = SCARD_STATE_EMPTY;
210          if (rc == SCARD_E_TIMEOUT)      }
211              continue;  
212          if (rc != SCARD_S_SUCCESS)      while (1) {
213              ;          rdstat = rd->reader_states[curr_rd];            
214            rc = pcsc_get_status_change (hctx, 0, &rdstat, 1);
215          /* next reader */          if (rc == SCARD_E_TIMEOUT)
216          curr_rd++;              continue;
217          if (curr_rd >= rd->nreaders)          if (rc != SCARD_S_SUCCESS)
218              curr_rd = 0;              ;
219      }  
220                /* next reader */
221      safe_free (rdrstr);          curr_rd++;
222      *ret_rd = rd;          if (curr_rd >= rd->nreaders)
223      rc = pcsc_release_context (hctx);              curr_rd = 0;
224      if (rc != SCARD_S_SUCCESS)      }
225          return -1;      
226      return 0;      safe_free (rdrstr);
227  }      *ret_rd = rd;
228        rc = pcsc_release_context (hctx);
229        if (rc != SCARD_S_SUCCESS)
230  int          return -1;
231  pcsc_get_card_status (void)      return 0;
232  {  }
233      pcsc_reader_t rd;  
234      SCARD_READERSTATE_A rdstat;  
235      int rc, stat=0;  int
236    pcsc_get_card_status (void)
237      rc = pcsc_scan_readers (&rd);  {
238      if (rc)      pcsc_reader_t rd;
239          return -1;      SCARD_READERSTATE_A rdstat;
240      rdstat = rd->reader_states[0];      int rc, stat=0;
241      if (rdstat.dwCurrentState & SCARD_STATE_UNAVAILABLE)  
242          stat |= CARD_STATE_UNAVAIL;      rc = pcsc_scan_readers (&rd);
243      if (rdstat.dwCurrentState & SCARD_STATE_EMPTY)      if (rc)
244          stat |= CARD_STATE_EMPTY;          return -1;
245      if (rdstat.dwCurrentState & SCARD_STATE_INUSE)      rdstat = rd->reader_states[0];
246          stat |= CARD_STATE_INUSE;      if (rdstat.dwCurrentState & SCARD_STATE_UNAVAILABLE)
247      if (rdstat.dwCurrentState & SCARD_STATE_EXCLUSIVE)          stat |= CARD_STATE_UNAVAIL;
248          stat |= CARD_STATE_EXCLUSI;      if (rdstat.dwCurrentState & SCARD_STATE_EMPTY)
249      return stat;          stat |= CARD_STATE_EMPTY;
250  }      if (rdstat.dwCurrentState & SCARD_STATE_INUSE)
251            stat |= CARD_STATE_INUSE;
252        if (rdstat.dwCurrentState & SCARD_STATE_EXCLUSIVE)
253            stat |= CARD_STATE_EXCLUSI;
254        return stat;
255    }

Legend:
Removed from v.35  
changed lines
  Added in v.36

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26