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

Contents of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (show annotations)
Mon Oct 17 08:49:30 2005 UTC (19 years, 4 months ago) by twoaday
File MIME type: text/plain
File size: 6593 byte(s)
More bug fixes all over the place.
See ChangeLog for details.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26