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

Contents of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File MIME type: text/plain
File size: 6364 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


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 "w32gpgme.h"
26 #include "wptTypes.h"
27 #include "wptCard.h"
28
29
30 #define MAX_READERS 8
31
32 struct pcsc_reader_s {
33 SCARD_READERSTATE_A reader_states[MAX_READERS];
34 int nreaders;
35 char * readers[MAX_READERS];
36 };
37 typedef struct pcsc_reader_s *pcsc_reader_t;
38
39
40 static LONG (WINAPI *pcsc_establish_context) (unsigned long scope,
41 const void *reserved1,
42 const void *reserved2,
43 unsigned long *r_context);
44 static LONG (WINAPI *pcsc_release_context) (unsigned long context);
45 static LONG (WINAPI *pcsc_list_readers) (unsigned long context,
46 const char *groups,
47 char *readers,
48 unsigned long *readerslen);
49 static LONG (WINAPI *pcsc_connect) (unsigned long context,
50 const char *reader,
51 unsigned long share_mode,
52 unsigned long preferred_protocols,
53 unsigned long *r_card,
54 unsigned long *r_active_protocol);
55 static LONG (WINAPI *pcsc_disconnect) (unsigned long card,
56 unsigned long disposition);
57 static LONG (WINAPI *pcsc_status) (unsigned long card,
58 char *reader, unsigned long *readerlen,
59 unsigned long *r_state, unsigned long *r_protocol,
60 unsigned char *atr, unsigned long *atrlen);
61 static LONG (WINAPI *pcsc_get_status_change)(unsigned long ctx,
62 unsigned long timeout,
63 SCARD_READERSTATE * readerstate,
64 unsigned long creaders);
65
66 static int pcsc_init = 0;
67
68
69 #define load_one_fnc(ptr, hlib, name) do { \
70 a = ptr = (void *)GetProcAddress (hlib, name); \
71 if (!a) { \
72 char msg[256]; \
73 _snprintf (msg, sizeof msg-1, "Could not load '%s'", name); \
74 MessageBox (NULL, msg, "PC/SC Driver", MB_ICONERROR|MB_OK); \
75 goto fail; \
76 } \
77 } while (0)
78
79
80 int
81 pcsc_loadlib (int scard_support)
82 {
83 HMODULE hlib;
84 FARPROC a;
85
86 if (!scard_support || pcsc_init)
87 return 0;
88 hlib = LoadLibrary ("WINSCARD");
89 if (!hlib)
90 goto fail;
91 load_one_fnc (pcsc_establish_context, hlib, "SCardEstablishContext");
92 load_one_fnc (pcsc_release_context, hlib, "SCardReleaseContext");
93 load_one_fnc (pcsc_list_readers, hlib, "SCardListReadersA");
94 load_one_fnc (pcsc_connect, hlib, "SCardConnectA");
95 load_one_fnc (pcsc_disconnect, hlib, "SCardDisconnect");
96 load_one_fnc (pcsc_status, hlib, "SCardStatusA");
97 load_one_fnc (pcsc_get_status_change, hlib, "SCardGetStatusChangeA");
98 goto success;
99
100 fail:
101 FreeLibrary (hlib);
102 return -1;
103 success:
104 pcsc_init = 1;
105 FreeLibrary (hlib);
106 return 0;
107 }
108
109
110 void
111 pcsc_free_readers (pcsc_reader_t rd)
112 {
113 int i;
114
115 if (!rd)
116 return;
117
118 for (i=0; i < rd->nreaders; i++)
119 safe_free (rd->readers[i]);
120 safe_free (rd);
121 }
122
123
124 const char *
125 pcsc_get_reader (pcsc_reader_t rd, int idx, int * ret_nrd)
126 {
127 if (!rd)
128 return NULL;
129 if (idx == -1 && ret_nrd) {
130 *ret_nrd = rd->nreaders;
131 return NULL;
132 }
133 if (idx >= rd->nreaders)
134 idx=0;
135 return rd->readers[idx];
136 }
137
138
139 int
140 pcsc_scan_readers (pcsc_reader_t * ret_rd)
141 {
142 pcsc_reader_t rd;
143 SCARDCONTEXT hctx;
144 SCARD_READERSTATE_A rdstat;
145 DWORD readers;
146 LPSTR rdrstr;
147 char * p;
148 int i;
149 int rc, curr_rd=0;
150
151 *ret_rd = NULL;
152 if (!pcsc_init)
153 return -1;
154
155 rc = pcsc_establish_context (SCARD_SCOPE_SYSTEM, NULL, NULL, &hctx);
156 if (rc != SCARD_S_SUCCESS)
157 return -1;
158
159 rc = pcsc_list_readers (hctx, NULL, NULL, &readers);
160 if (rc != SCARD_S_SUCCESS)
161 return -1;
162
163 rdrstr = malloc (sizeof(char)*readers);
164 if (!rdrstr)
165 BUG (0);
166
167 rc = pcsc_list_readers (hctx, NULL, rdrstr, &readers);
168 if (rc != SCARD_S_SUCCESS) {
169 safe_free (rdrstr);
170 return -1;
171 }
172
173 rd = calloc (1, sizeof *rd);
174 if (!rd)
175 BUG (0);
176
177 p = rdrstr;
178 while ((*p != '\0') && (rd->nreaders < MAX_READERS)) {
179 rd->readers[rd->nreaders] = strdup (p);
180 p += strlen (p)+1;
181 rd->nreaders++;
182 }
183
184 if (!rd->nreaders) {
185 safe_free (rdrstr);
186 safe_free (rd);
187 return 0;
188 }
189
190 /* set the initial states */
191 for (i=0; i<rd->nreaders; i++) {
192 rd->reader_states[i].szReader = rd->readers[i];
193 rd->reader_states[i].dwCurrentState = SCARD_STATE_EMPTY;
194 }
195
196 while (1) {
197 rdstat = rd->reader_states[curr_rd];
198 rc = pcsc_get_status_change (hctx, 0, &rdstat, 1);
199 if (rc == SCARD_E_TIMEOUT)
200 continue;
201 if (rc != SCARD_S_SUCCESS)
202 ;
203
204 /* next reader */
205 curr_rd++;
206 if (curr_rd >= rd->nreaders)
207 curr_rd = 0;
208 }
209
210 safe_free (rdrstr);
211 *ret_rd = rd;
212 rc = pcsc_release_context (hctx);
213 if (rc != SCARD_S_SUCCESS)
214 return -1;
215 return 0;
216 }
217
218
219 int
220 pcsc_get_card_status (void)
221 {
222 pcsc_reader_t rd;
223 SCARD_READERSTATE_A rdstat;
224 int rc, stat=0;
225
226 rc = pcsc_scan_readers (&rd);
227 if (rc)
228 return -1;
229 rdstat = rd->reader_states[0];
230 if (rdstat.dwCurrentState & SCARD_STATE_UNAVAILABLE)
231 stat |= CARD_STATE_UNAVAIL;
232 if (rdstat.dwCurrentState & SCARD_STATE_EMPTY)
233 stat |= CARD_STATE_EMPTY;
234 if (rdstat.dwCurrentState & SCARD_STATE_INUSE)
235 stat |= CARD_STATE_INUSE;
236 if (rdstat.dwCurrentState & SCARD_STATE_EXCLUSIVE)
237 stat |= CARD_STATE_EXCLUSI;
238 return stat;
239 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26