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

Annotation of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 26 - (hide 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 twoaday 2 /* 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 twoaday 25 #include "gpgme.h"
26 twoaday 2 #include "wptTypes.h"
27     #include "wptCard.h"
28    
29 twoaday 26 /* 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 twoaday 2 #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