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

Annotation of /trunk/Src/wptCardPCSC.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (hide annotations)
Wed Oct 12 10:04:26 2005 UTC (19 years, 4 months ago) by twoaday
File MIME type: text/plain
File size: 6359 byte(s)
First testing phase finished.
Provide bug fixes for a lot of (minor) problems.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26