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

Annotation of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File MIME type: text/plain
File size: 6361 byte(s)
WinPT initial checkin.


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     #include "gpgme.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