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

Contents of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (show 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 /* wptCardPCSC.cpp - PC/SC card API interface
2 * Copyright (C) 2003 Timo Schulz
3 * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 *
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
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 /* 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 struct pcsc_readerstate_s reader_states[MAX_READERS];
129 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 pcsc_readerstate_t readerstate,
159 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 pcsc_context_t hctx;
239 struct pcsc_readerstate_s rdstat;
240 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 rc = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, &hctx);
251 if (rc)
252 return -1;
253
254 rc = pcsc_list_readers (hctx, NULL, NULL, &readers);
255 if (rc)
256 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 if (rc) {
264 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 rd->reader_states[i].reader = rd->readers[i];
288 rd->reader_states[i].current_state = PCSC_STATE_EMPTY;
289 }
290
291 while (1) {
292 rdstat = rd->reader_states[curr_rd];
293 rc = pcsc_get_status_change (hctx, 0, &rdstat, 1);
294 if (rc == PCSC_E_TIMEOUT)
295 continue;
296 if (rc)
297 ; /* FIXME: What is this?? */
298
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 if (rc)
309 return -1;
310 return 0;
311 }
312
313
314 int
315 pcsc_get_card_status (void)
316 {
317 pcsc_reader_t rd;
318 struct pcsc_readerstate_s rdstat;
319 int rc, stat=0;
320
321 rc = pcsc_scan_readers (&rd);
322 if (rc)
323 return -1;
324 rdstat = rd->reader_states[0];
325 if (rdstat.current_state & PCSC_STATE_UNAVAILABLE)
326 stat |= CARD_STATE_UNAVAIL;
327 if (rdstat.current_state & PCSC_STATE_EMPTY)
328 stat |= CARD_STATE_EMPTY;
329 if (rdstat.current_state & PCSC_STATE_INUSE)
330 stat |= CARD_STATE_INUSE;
331 if (rdstat.current_state & PCSC_STATE_EXCLUSIVE)
332 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