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

Annotation of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26