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

Annotation of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (hide annotations)
Mon Oct 31 21:14:11 2005 UTC (19 years, 4 months ago) by werner
File MIME type: text/plain
File size: 9432 byte(s)
More changes.  Compiles again but there are at least gettext issues with
w32-gettext.c.  I can't get a gpg-error build with ENABLE_NLS.

1 werner 36 /* wptCardPCSC.cpp - PC/SC card API interface
2     * Copyright (C) 2003 Timo Schulz
3 werner 48 * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 werner 36 *
5     * This file is part of WinPT.
6     *
7     * WinPT is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * WinPT is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with WinPT; if not, write to the Free Software Foundation,
19     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20     */
21    
22     #ifdef HAVE_CONFIG_H
23     #include <config.h>
24     #endif
25    
26     #include <stdio.h>
27     #include <stdio.h>
28     #include <windows.h>
29    
30     #include "gpgme.h"
31     #include "wptTypes.h"
32     #include "wptCard.h"
33    
34 werner 48
35     /* Definitions usually found in winscard.h but not used here becuase
36     mingw does not come with winscard and we dlopen the stuff
37     anyway. */
38     typedef unsigned long pcsc_context_t;
39    
40     struct pcsc_readerstate_s
41     {
42     const char *reader;
43     void *user_data;
44     unsigned long current_state;
45     unsigned long event_state;
46     unsigned long atrlen;
47     unsigned char atr[33];
48     };
49    
50     typedef struct pcsc_readerstate_s *pcsc_readerstate_t;
51    
52     /* PC/SC constants and function pointer. */
53     #define PCSC_SCOPE_USER 0
54     #define PCSC_SCOPE_TERMINAL 1
55     #define PCSC_SCOPE_SYSTEM 2
56     #define PCSC_SCOPE_GLOBAL 3
57    
58     #define PCSC_PROTOCOL_T0 1
59     #define PCSC_PROTOCOL_T1 2
60     #define PCSC_PROTOCOL_RAW 4
61    
62     #define PCSC_SHARE_EXCLUSIVE 1
63     #define PCSC_SHARE_SHARED 2
64     #define PCSC_SHARE_DIRECT 3
65    
66     #define PCSC_LEAVE_CARD 0
67     #define PCSC_RESET_CARD 1
68     #define PCSC_UNPOWER_CARD 2
69     #define PCSC_EJECT_CARD 3
70    
71     #define PCSC_UNKNOWN 0x0001
72     #define PCSC_ABSENT 0x0002 /* Card is absent. */
73     #define PCSC_PRESENT 0x0004 /* Card is present. */
74     #define PCSC_SWALLOWED 0x0008 /* Card is present and electrical connected. */
75     #define PCSC_POWERED 0x0010 /* Card is powered. */
76     #define PCSC_NEGOTIABLE 0x0020 /* Card is awaiting PTS. */
77     #define PCSC_SPECIFIC 0x0040 /* Card is ready for use. */
78    
79     #define PCSC_STATE_UNAWARE 0x0000 /* Want status. */
80     #define PCSC_STATE_IGNORE 0x0001 /* Ignore this reader. */
81     #define PCSC_STATE_CHANGED 0x0002 /* State has changed. */
82     #define PCSC_STATE_UNKNOWN 0x0004 /* Reader unknown. */
83     #define PCSC_STATE_UNAVAILABLE 0x0008 /* Status unavailable. */
84     #define PCSC_STATE_EMPTY 0x0010 /* Card removed. */
85     #define PCSC_STATE_PRESENT 0x0020 /* Card inserted. */
86     #define PCSC_STATE_ATRMATCH 0x0040 /* ATR matches card. */
87     #define PCSC_STATE_EXCLUSIVE 0x0080 /* Exclusive Mode. */
88     #define PCSC_STATE_INUSE 0x0100 /* Shared mode. */
89     #define PCSC_STATE_MUTE 0x0200 /* Unresponsive card. */
90    
91     /* Some PC/SC error codes. */
92     #define PCSC_E_CANCELLED 0x80100002
93     #define PCSC_E_CANT_DISPOSE 0x8010000E
94     #define PCSC_E_INSUFFICIENT_BUFFER 0x80100008
95     #define PCSC_E_INVALID_ATR 0x80100015
96     #define PCSC_E_INVALID_HANDLE 0x80100003
97     #define PCSC_E_INVALID_PARAMETER 0x80100004
98     #define PCSC_E_INVALID_TARGET 0x80100005
99     #define PCSC_E_INVALID_VALUE 0x80100011
100     #define PCSC_E_NO_MEMORY 0x80100006
101     #define PCSC_E_UNKNOWN_READER 0x80100009
102     #define PCSC_E_TIMEOUT 0x8010000A
103     #define PCSC_E_SHARING_VIOLATION 0x8010000B
104     #define PCSC_E_NO_SMARTCARD 0x8010000C
105     #define PCSC_E_UNKNOWN_CARD 0x8010000D
106     #define PCSC_E_PROTO_MISMATCH 0x8010000F
107     #define PCSC_E_NOT_READY 0x80100010
108     #define PCSC_E_SYSTEM_CANCELLED 0x80100012
109     #define PCSC_E_NOT_TRANSACTED 0x80100016
110     #define PCSC_E_READER_UNAVAILABLE 0x80100017
111     #define PCSC_W_REMOVED_CARD 0x80100069
112    
113 werner 36 /* Possible card states. */
114     enum card_state_t {
115     CARD_STATE_NONE=0,
116     CARD_STATE_UNAWARE,
117     CARD_STATE_UNAVAIL,
118     CARD_STATE_PRESENT,
119     CARD_STATE_EXCLUSI,
120     CARD_STATE_EMPTY,
121     CARD_STATE_INUSE,
122     CARD_STATE_MUTE
123     };
124    
125     #define MAX_READERS 8
126    
127     struct pcsc_reader_s {
128 werner 48 struct pcsc_readerstate_s reader_states[MAX_READERS];
129 werner 36 int nreaders;
130     char * readers[MAX_READERS];
131     };
132     typedef struct pcsc_reader_s *pcsc_reader_t;
133    
134    
135     static LONG (WINAPI *pcsc_establish_context) (unsigned long scope,
136     const void *reserved1,
137     const void *reserved2,
138     unsigned long *r_context);
139     static LONG (WINAPI *pcsc_release_context) (unsigned long context);
140     static LONG (WINAPI *pcsc_list_readers) (unsigned long context,
141     const char *groups,
142     char *readers,
143     unsigned long *readerslen);
144     static LONG (WINAPI *pcsc_connect) (unsigned long context,
145     const char *reader,
146     unsigned long share_mode,
147     unsigned long preferred_protocols,
148     unsigned long *r_card,
149     unsigned long *r_active_protocol);
150     static LONG (WINAPI *pcsc_disconnect) (unsigned long card,
151     unsigned long disposition);
152     static LONG (WINAPI *pcsc_status) (unsigned long card,
153     char *reader, unsigned long *readerlen,
154     unsigned long *r_state, unsigned long *r_protocol,
155     unsigned char *atr, unsigned long *atrlen);
156     static LONG (WINAPI *pcsc_get_status_change)(unsigned long ctx,
157     unsigned long timeout,
158 werner 48 pcsc_readerstate_t readerstate,
159 werner 36 unsigned long creaders);
160    
161     static int pcsc_init = 0;
162    
163    
164     #define load_one_fnc(ptr, hlib, name) do { \
165     a = ptr = (void *)GetProcAddress (hlib, name); \
166     if (!a) { \
167     char msg[256]; \
168     _snprintf (msg, sizeof msg-1, "Could not load '%s'", name); \
169     MessageBox (NULL, msg, "PC/SC Driver", MB_ICONERROR|MB_OK); \
170     goto fail; \
171     } \
172     } while (0)
173    
174    
175     int
176     pcsc_loadlib (int scard_support)
177     {
178     HMODULE hlib;
179     FARPROC a;
180    
181     if (!scard_support || pcsc_init)
182     return 0;
183     hlib = LoadLibrary ("WINSCARD");
184     if (!hlib)
185     goto fail;
186     load_one_fnc (pcsc_establish_context, hlib, "SCardEstablishContext");
187     load_one_fnc (pcsc_release_context, hlib, "SCardReleaseContext");
188     load_one_fnc (pcsc_list_readers, hlib, "SCardListReadersA");
189     load_one_fnc (pcsc_connect, hlib, "SCardConnectA");
190     load_one_fnc (pcsc_disconnect, hlib, "SCardDisconnect");
191     load_one_fnc (pcsc_status, hlib, "SCardStatusA");
192     load_one_fnc (pcsc_get_status_change, hlib, "SCardGetStatusChangeA");
193     goto success;
194    
195     fail:
196     FreeLibrary (hlib);
197     return -1;
198     success:
199     pcsc_init = 1;
200     FreeLibrary (hlib);
201     return 0;
202     }
203    
204    
205     void
206     pcsc_free_readers (pcsc_reader_t rd)
207     {
208     int i;
209    
210     if (!rd)
211     return;
212    
213     for (i=0; i < rd->nreaders; i++)
214     safe_free (rd->readers[i]);
215     safe_free (rd);
216     }
217    
218    
219     const char *
220     pcsc_get_reader (pcsc_reader_t rd, int idx, int * ret_nrd)
221     {
222     if (!rd)
223     return NULL;
224     if (idx == -1 && ret_nrd) {
225     *ret_nrd = rd->nreaders;
226     return NULL;
227     }
228     if (idx >= rd->nreaders)
229     idx=0;
230     return rd->readers[idx];
231     }
232    
233    
234     int
235     pcsc_scan_readers (pcsc_reader_t * ret_rd)
236     {
237     pcsc_reader_t rd;
238 werner 48 pcsc_context_t hctx;
239     struct pcsc_readerstate_s rdstat;
240 werner 36 DWORD readers;
241     LPSTR rdrstr;
242     char * p;
243     int i;
244     int rc, curr_rd=0;
245    
246     *ret_rd = NULL;
247     if (!pcsc_init)
248     return -1;
249    
250 werner 48 rc = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, &hctx);
251     if (rc)
252 werner 36 return -1;
253    
254     rc = pcsc_list_readers (hctx, NULL, NULL, &readers);
255 werner 48 if (rc)
256 werner 36 return -1;
257    
258     rdrstr = malloc (sizeof(char)*readers);
259     if (!rdrstr)
260     BUG (0);
261    
262     rc = pcsc_list_readers (hctx, NULL, rdrstr, &readers);
263 werner 48 if (rc) {
264 werner 36 safe_free (rdrstr);
265     return -1;
266     }
267    
268     rd = calloc (1, sizeof *rd);
269     if (!rd)
270     BUG (0);
271    
272     p = rdrstr;
273     while ((*p != '\0') && (rd->nreaders < MAX_READERS)) {
274     rd->readers[rd->nreaders] = strdup (p);
275     p += strlen (p)+1;
276     rd->nreaders++;
277     }
278    
279     if (!rd->nreaders) {
280     safe_free (rdrstr);
281     safe_free (rd);
282     return 0;
283     }
284    
285     /* set the initial states */
286     for (i=0; i<rd->nreaders; i++) {
287 werner 48 rd->reader_states[i].reader = rd->readers[i];
288     rd->reader_states[i].current_state = PCSC_STATE_EMPTY;
289 werner 36 }
290    
291     while (1) {
292     rdstat = rd->reader_states[curr_rd];
293     rc = pcsc_get_status_change (hctx, 0, &rdstat, 1);
294 werner 48 if (rc == PCSC_E_TIMEOUT)
295 werner 36 continue;
296 werner 48 if (rc)
297     ; /* FIXME: What is this?? */
298 werner 36
299     /* next reader */
300     curr_rd++;
301     if (curr_rd >= rd->nreaders)
302     curr_rd = 0;
303     }
304    
305     safe_free (rdrstr);
306     *ret_rd = rd;
307     rc = pcsc_release_context (hctx);
308 werner 48 if (rc)
309 werner 36 return -1;
310     return 0;
311     }
312    
313    
314     int
315     pcsc_get_card_status (void)
316     {
317     pcsc_reader_t rd;
318 werner 48 struct pcsc_readerstate_s rdstat;
319 werner 36 int rc, stat=0;
320    
321     rc = pcsc_scan_readers (&rd);
322     if (rc)
323     return -1;
324     rdstat = rd->reader_states[0];
325 werner 48 if (rdstat.current_state & PCSC_STATE_UNAVAILABLE)
326 werner 36 stat |= CARD_STATE_UNAVAIL;
327 werner 48 if (rdstat.current_state & PCSC_STATE_EMPTY)
328 werner 36 stat |= CARD_STATE_EMPTY;
329 werner 48 if (rdstat.current_state & PCSC_STATE_INUSE)
330 werner 36 stat |= CARD_STATE_INUSE;
331 werner 48 if (rdstat.current_state & PCSC_STATE_EXCLUSIVE)
332 werner 36 stat |= CARD_STATE_EXCLUSI;
333     return stat;
334     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26