|
1 /* |
|
2 * Copyright (c) 2003-2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #define g_rgSCardT0Pci _g_rgSCardT0Pci |
|
20 #define g_rgSCardT1Pci _g_rgSCardT1Pci |
|
21 #define g_rgSCardRawPci _g_rgSCardRawPci |
|
22 #define WINSCARDDATA |
|
23 #define WINSCARDAPI |
|
24 |
|
25 #define TRACE_PREFIX "SCARD: [WinsCard] " |
|
26 #include "SdkCardDebug.h" |
|
27 |
|
28 #include <windows.h> |
|
29 #include <winioctl.h> |
|
30 #undef FILE_DEVICE_SMARTCARD /* redefined in <winscard.h> */ |
|
31 #include <winscard.h> |
|
32 |
|
33 #undef g_rgSCardT0Pci |
|
34 #undef g_rgSCardT1Pci |
|
35 #undef g_rgSCardRawPci |
|
36 |
|
37 /** |
|
38 * We can't use TRACE macros here because some of these functions may be |
|
39 * called from within Emulator::Escape()/Reenter() block. |
|
40 */ |
|
41 #ifdef _REALLY_DEBUG |
|
42 # define WINSCARD_TRACE(s) OutputDebugStringA(TRACE_PREFIX s "\n") |
|
43 #else |
|
44 # define WINSCARD_TRACE(s) |
|
45 #endif // _REALLY_DEBUG |
|
46 |
|
47 /* ************************************************************************* |
|
48 * Support for WINSCARD.DLL |
|
49 * This code will run on the systems that don't have WINSCARD.DLL installed |
|
50 * *************************************************************************/ |
|
51 |
|
52 /* handle to WINSCARD.DLL */ |
|
53 static HMODULE WINSCARD_handle = NULL; |
|
54 |
|
55 /* |
|
56 * This flag is set to TRUE if we determine that WINSCARD.DLL is missing |
|
57 * or unusable (i.e. some required exports are missing), so that we don't |
|
58 * try to load it more than once. |
|
59 */ |
|
60 static BOOL WINSCARD_missing = FALSE; |
|
61 |
|
62 static LPCSTR WINSCARD_DLL = "WINSCARD.DLL"; |
|
63 |
|
64 /* |
|
65 * these are entry points used by this module. These are NOT all entry |
|
66 * points exported by WINSCARD.DLL, just those we need here |
|
67 */ |
|
68 |
|
69 /* SCardConnectW */ |
|
70 #define WINSCARD_PROC_CONNECT_W "SCardConnectW" |
|
71 #define WINSCARD_PROC_CONNECT WINSCARD_PROC_CONNECT_W |
|
72 #define WINSCARD_CONNECT WINSCARD_CONNECT_W |
|
73 #define WINSCARD_Connect WINSCARD_ConnectW |
|
74 typedef LONG (WINAPI * WINSCARD_CONNECT_W)( |
|
75 IN SCARDCONTEXT hContext, |
|
76 IN LPCWSTR szReader, |
|
77 IN DWORD dwShareMode, |
|
78 IN DWORD dwPreferredProtocols, |
|
79 OUT LPSCARDHANDLE phCard, |
|
80 OUT LPDWORD pdwActiveProtocol); |
|
81 |
|
82 /* SCardDisconnect */ |
|
83 #define WINSCARD_PROC_DISCONNECT "SCardDisconnect" |
|
84 typedef LONG (WINAPI * WINSCARD_DISCONNECT)( |
|
85 IN SCARDHANDLE hCard, |
|
86 IN DWORD dwDisposition); |
|
87 |
|
88 /* SCardEstablishContext */ |
|
89 #define WINSCARD_PROC_ESTABLISH_CONTEXT "SCardEstablishContext" |
|
90 typedef LONG (WINAPI * WINSCARD_ESTABLISH_CONTEXT)( |
|
91 IN DWORD dwScope, |
|
92 IN LPCVOID pvReserved1, |
|
93 IN LPCVOID pvReserved2, |
|
94 OUT LPSCARDCONTEXT phContext); |
|
95 |
|
96 /* SCardListReadersW */ |
|
97 #define WINSCARD_PROC_LIST_READERS_W "SCardListReadersW" |
|
98 #define WINSCARD_PROC_LIST_READERS WINSCARD_PROC_LIST_READERS_W |
|
99 #define WINSCARD_LIST_READERS WINSCARD_LIST_READERS_W |
|
100 #define WINSCARD_ListReaders WINSCARD_ListReadersW |
|
101 typedef LONG (WINAPI * WINSCARD_LIST_READERS_W)( |
|
102 IN SCARDCONTEXT hContext, |
|
103 IN LPCWSTR mszGroups, |
|
104 OUT LPWSTR mszReaders, |
|
105 IN OUT LPDWORD pcchReaders); |
|
106 |
|
107 /* SCardReleaseContext */ |
|
108 #define WINSCARD_PROC_RELEASE_CONTEXT "SCardReleaseContext" |
|
109 typedef LONG (WINAPI * WINSCARD_RELEASE_CONTEXT)( |
|
110 IN SCARDCONTEXT hContext); |
|
111 |
|
112 /* SCardTransmit */ |
|
113 #define WINSCARD_PROC_TRANSMIT "SCardTransmit" |
|
114 typedef LONG (WINAPI * WINSCARD_TRANSMIT)( |
|
115 IN SCARDHANDLE hCard, |
|
116 IN LPCSCARD_IO_REQUEST pioSendPci, |
|
117 IN LPCBYTE pbSendBuffer, |
|
118 IN DWORD cbSendLength, |
|
119 IN OUT LPSCARD_IO_REQUEST pioRecvPci, |
|
120 OUT LPBYTE pbRecvBuffer, |
|
121 IN OUT LPDWORD pcbRecvLength); |
|
122 |
|
123 /* SCardStatusW */ |
|
124 #define WINSCARD_PROC_STATUS_W "SCardStatusW" |
|
125 #define WINSCARD_PROC_STATUS WINSCARD_PROC_STATUS_W |
|
126 #define WINSCARD_STATUS WINSCARD_STATUS_W |
|
127 #define WINSCARD_Status WINSCARD_StatusW |
|
128 typedef LONG (WINAPI * WINSCARD_STATUS_W)( |
|
129 IN SCARDHANDLE hCard, |
|
130 OUT LPWSTR szReaderName, |
|
131 IN OUT LPDWORD pcchReaderLen, |
|
132 OUT LPDWORD pdwState, |
|
133 OUT LPDWORD pdwProtocol, |
|
134 OUT LPBYTE pbAtr, |
|
135 OUT LPDWORD pcbAtrLen); |
|
136 |
|
137 /* SCardGetStatusChangeW */ |
|
138 #define WINSCARD_PROC_GET_STATUS_CHANGE_W "SCardGetStatusChangeW" |
|
139 #define WINSCARD_PROC_GET_STATUS_CHANGE WINSCARD_PROC_GET_STATUS_CHANGE_W |
|
140 #define WINSCARD_GET_STATUS_CHANGE WINSCARD_GET_STATUS_CHANGE_W |
|
141 #define WINSCARD_GetStatusChange WINSCARD_GetStatusChangeW |
|
142 typedef LONG (WINAPI * WINSCARD_GET_STATUS_CHANGE_W)( |
|
143 IN SCARDCONTEXT hContext, |
|
144 IN DWORD dwTimeout, |
|
145 IN OUT LPSCARD_READERSTATE_W rgReaderStates, |
|
146 IN DWORD cReaders); |
|
147 |
|
148 /* SCardCancel */ |
|
149 #define WINSCARD_PROC_CANCEL "SCardCancel" |
|
150 typedef LONG (WINAPI * WINSCARD_CANCEL)( |
|
151 IN SCARDCONTEXT hContext); |
|
152 |
|
153 /* addresses of functions */ |
|
154 static WINSCARD_CONNECT WINSCARD_Connect = NULL; |
|
155 static WINSCARD_DISCONNECT WINSCARD_Disconnect = NULL; |
|
156 static WINSCARD_ESTABLISH_CONTEXT WINSCARD_EstablishContext = NULL; |
|
157 static WINSCARD_LIST_READERS WINSCARD_ListReaders = NULL; |
|
158 static WINSCARD_RELEASE_CONTEXT WINSCARD_ReleaseContext = NULL; |
|
159 static WINSCARD_TRANSMIT WINSCARD_Transmit = NULL; |
|
160 static WINSCARD_STATUS WINSCARD_Status = NULL; |
|
161 static WINSCARD_GET_STATUS_CHANGE WINSCARD_GetStatusChange = NULL; |
|
162 static WINSCARD_CANCEL WINSCARD_Cancel = NULL; |
|
163 |
|
164 /* and some variables, too */ |
|
165 static SCARD_IO_REQUEST * WINSCARD_g_rgSCardT0Pci = NULL; |
|
166 static SCARD_IO_REQUEST * WINSCARD_g_rgSCardT1Pci = NULL; |
|
167 static SCARD_IO_REQUEST * WINSCARD_g_rgSCardRawPci = NULL; |
|
168 |
|
169 extern "C" SCARD_IO_REQUEST g_rgSCardT0Pci; |
|
170 extern "C" SCARD_IO_REQUEST g_rgSCardT1Pci; |
|
171 extern "C" SCARD_IO_REQUEST g_rgSCardRawPci; |
|
172 |
|
173 SCARD_IO_REQUEST g_rgSCardT0Pci; |
|
174 SCARD_IO_REQUEST g_rgSCardT1Pci; |
|
175 SCARD_IO_REQUEST g_rgSCardRawPci; |
|
176 |
|
177 static struct _WINSCARD_Export { |
|
178 const char* name; |
|
179 FARPROC * value_ptr; |
|
180 } WINSCARD_exports [] = { |
|
181 |
|
182 /* functions */ |
|
183 {WINSCARD_PROC_CONNECT, (FARPROC*)&WINSCARD_Connect}, |
|
184 {WINSCARD_PROC_DISCONNECT, (FARPROC*)&WINSCARD_Disconnect}, |
|
185 {WINSCARD_PROC_ESTABLISH_CONTEXT, (FARPROC*)&WINSCARD_EstablishContext}, |
|
186 {WINSCARD_PROC_LIST_READERS, (FARPROC*)&WINSCARD_ListReaders}, |
|
187 {WINSCARD_PROC_RELEASE_CONTEXT, (FARPROC*)&WINSCARD_ReleaseContext}, |
|
188 {WINSCARD_PROC_TRANSMIT, (FARPROC*)&WINSCARD_Transmit}, |
|
189 {WINSCARD_PROC_STATUS, (FARPROC*)&WINSCARD_Status}, |
|
190 {WINSCARD_PROC_GET_STATUS_CHANGE, (FARPROC*)&WINSCARD_GetStatusChange}, |
|
191 {WINSCARD_PROC_CANCEL, (FARPROC*)&WINSCARD_Cancel}, |
|
192 |
|
193 /* variables */ |
|
194 {"g_rgSCardT0Pci", (FARPROC*)&WINSCARD_g_rgSCardT0Pci}, |
|
195 {"g_rgSCardT1Pci", (FARPROC*)&WINSCARD_g_rgSCardT1Pci}, |
|
196 {"g_rgSCardRawPci", (FARPROC*)&WINSCARD_g_rgSCardRawPci}, |
|
197 }; |
|
198 |
|
199 #define COUNT(array) (sizeof(array)/sizeof(array[0])) |
|
200 |
|
201 /** |
|
202 * Checks if WINSCARD.DLL has been loaded; if not, attempts to load it |
|
203 * Returns TRUE if WINSCARD.DLL has been successfully loaded, FALSE |
|
204 * it the DLL or some entry points are missing. |
|
205 */ |
|
206 static BOOL WINSCARD_IsAvailable() |
|
207 { |
|
208 if (!WINSCARD_handle && !WINSCARD_missing) |
|
209 { |
|
210 HINSTANCE handle = LoadLibraryA(WINSCARD_DLL); |
|
211 if (handle) |
|
212 { |
|
213 int i; |
|
214 for( i=0; i<COUNT(WINSCARD_exports); i++) |
|
215 { |
|
216 LPCSTR name = WINSCARD_exports[i].name; |
|
217 FARPROC addr = GetProcAddress(handle,name); |
|
218 if (addr) |
|
219 { |
|
220 *(WINSCARD_exports[i].value_ptr) = addr; |
|
221 } |
|
222 else |
|
223 { |
|
224 TRACE2("ERROR: export %hs is missing from %hs\n", |
|
225 name, WINSCARD_DLL); |
|
226 |
|
227 /* bad library, don't use it */ |
|
228 WINSCARD_missing = TRUE; |
|
229 FreeLibrary(handle); |
|
230 handle = NULL; |
|
231 break; |
|
232 } |
|
233 } |
|
234 g_rgSCardT0Pci = *WINSCARD_g_rgSCardT0Pci; |
|
235 g_rgSCardT1Pci = *WINSCARD_g_rgSCardT1Pci; |
|
236 g_rgSCardRawPci = *WINSCARD_g_rgSCardRawPci; |
|
237 WINSCARD_handle = handle; |
|
238 } |
|
239 else |
|
240 { |
|
241 TRACE1("ERROR: failed to load %hs\n",WINSCARD_DLL); |
|
242 WINSCARD_missing = TRUE; |
|
243 } |
|
244 } |
|
245 return (WINSCARD_handle != NULL); |
|
246 } |
|
247 |
|
248 /* ************************************************************************* |
|
249 * Functions that redirect WINSCARD calls to the real DLL if possible |
|
250 * *************************************************************************/ |
|
251 |
|
252 LONG WINAPI |
|
253 SCardConnectW( |
|
254 IN SCARDCONTEXT hContext, |
|
255 IN LPCWSTR szReader, |
|
256 IN DWORD dwShareMode, |
|
257 IN DWORD dwPreferredProtocols, |
|
258 OUT LPSCARDHANDLE phCard, |
|
259 OUT LPDWORD pdwActiveProtocol) |
|
260 { |
|
261 WINSCARD_TRACE("SCardConnect"); |
|
262 if (WINSCARD_IsAvailable()) |
|
263 { |
|
264 return WINSCARD_ConnectW(hContext,szReader,dwShareMode, |
|
265 dwPreferredProtocols, phCard, |
|
266 pdwActiveProtocol); |
|
267 } |
|
268 return SCARD_E_NO_SERVICE; |
|
269 } |
|
270 |
|
271 LONG WINAPI |
|
272 SCardDisconnect( |
|
273 IN SCARDHANDLE hCard, |
|
274 IN DWORD dwDisposition) |
|
275 { |
|
276 WINSCARD_TRACE("SCardDisconnect"); |
|
277 if (WINSCARD_IsAvailable()) |
|
278 { |
|
279 return WINSCARD_Disconnect(hCard,dwDisposition); |
|
280 } |
|
281 return SCARD_E_NO_SERVICE; |
|
282 } |
|
283 |
|
284 LONG WINAPI |
|
285 SCardEstablishContext( |
|
286 IN DWORD dwScope, |
|
287 IN LPCVOID pvReserved1, |
|
288 IN LPCVOID pvReserved2, |
|
289 OUT LPSCARDCONTEXT phContext) |
|
290 { |
|
291 WINSCARD_TRACE("SCardEstablishContext"); |
|
292 if (WINSCARD_IsAvailable()) |
|
293 { |
|
294 return WINSCARD_EstablishContext(dwScope,pvReserved1, |
|
295 pvReserved2,phContext); |
|
296 } |
|
297 return SCARD_E_NO_SERVICE; |
|
298 } |
|
299 |
|
300 LONG WINAPI |
|
301 SCardListReadersW( |
|
302 IN SCARDCONTEXT hContext, |
|
303 IN LPCWSTR mszGroups, |
|
304 OUT LPWSTR mszReaders, |
|
305 IN OUT LPDWORD pcchReaders) |
|
306 { |
|
307 WINSCARD_TRACE("SCardListReaders"); |
|
308 if (WINSCARD_IsAvailable()) |
|
309 { |
|
310 return WINSCARD_ListReadersW(hContext,mszGroups, |
|
311 mszReaders,pcchReaders); |
|
312 } |
|
313 return SCARD_E_NO_SERVICE; |
|
314 } |
|
315 |
|
316 LONG WINAPI |
|
317 SCardReleaseContext( |
|
318 IN SCARDCONTEXT hContext) |
|
319 { |
|
320 WINSCARD_TRACE("SCardReleaseContext"); |
|
321 if (WINSCARD_IsAvailable()) |
|
322 { |
|
323 return WINSCARD_ReleaseContext(hContext); |
|
324 } |
|
325 return SCARD_E_NO_SERVICE; |
|
326 } |
|
327 |
|
328 LONG WINAPI |
|
329 SCardTransmit( |
|
330 IN SCARDHANDLE hCard, |
|
331 IN LPCSCARD_IO_REQUEST pioSendPci, |
|
332 IN LPCBYTE pbSendBuffer, |
|
333 IN DWORD cbSendLength, |
|
334 IN OUT LPSCARD_IO_REQUEST pioRecvPci, |
|
335 OUT LPBYTE pbRecvBuffer, |
|
336 IN OUT LPDWORD pcbRecvLength) |
|
337 { |
|
338 WINSCARD_TRACE("SCardTransmit"); |
|
339 if (WINSCARD_IsAvailable()) |
|
340 { |
|
341 return WINSCARD_Transmit(hCard, pioSendPci, pbSendBuffer, |
|
342 cbSendLength, pioRecvPci, pbRecvBuffer, |
|
343 pcbRecvLength); |
|
344 } |
|
345 return SCARD_E_NO_SERVICE; |
|
346 } |
|
347 |
|
348 LONG WINAPI |
|
349 SCardStatusW( |
|
350 IN SCARDHANDLE hCard, |
|
351 OUT LPWSTR szReaderName, |
|
352 IN OUT LPDWORD pcchReaderLen, |
|
353 OUT LPDWORD pdwState, |
|
354 OUT LPDWORD pdwProtocol, |
|
355 OUT LPBYTE pbAtr, |
|
356 OUT LPDWORD pcbAtrLen) |
|
357 { |
|
358 WINSCARD_TRACE("SCardStatus"); |
|
359 if (WINSCARD_IsAvailable()) |
|
360 { |
|
361 return WINSCARD_StatusW(hCard, szReaderName, pcchReaderLen, |
|
362 pdwState, pdwProtocol, pbAtr, pcbAtrLen); |
|
363 } |
|
364 return SCARD_E_NO_SERVICE; |
|
365 } |
|
366 |
|
367 LONG WINAPI |
|
368 SCardGetStatusChangeW( |
|
369 IN SCARDCONTEXT hContext, |
|
370 IN DWORD dwTimeout, |
|
371 IN OUT LPSCARD_READERSTATE_W rgReaderStates, |
|
372 IN DWORD cReaders) |
|
373 { |
|
374 //WINSCARD_TRACE("SCardGetStatusChange"); |
|
375 if (WINSCARD_IsAvailable()) |
|
376 { |
|
377 return WINSCARD_GetStatusChangeW(hContext, dwTimeout, rgReaderStates, |
|
378 cReaders); |
|
379 } |
|
380 return SCARD_E_NO_SERVICE; |
|
381 } |
|
382 |
|
383 LONG WINAPI |
|
384 SCardCancel( |
|
385 IN SCARDCONTEXT hContext) |
|
386 { |
|
387 WINSCARD_TRACE("SCardCancel"); |
|
388 if (WINSCARD_IsAvailable()) |
|
389 { |
|
390 return WINSCARD_Cancel(hContext); |
|
391 } |
|
392 return SCARD_E_NO_SERVICE; |
|
393 } |