1 /*==============================================================================
2 Copyright 2001-2012 gemalto
3 Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
4 
5 This file is part of pyscard.
6 
7 pyscard is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11 
12 pyscard is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with pyscard; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ==============================================================================*/
21 #include <stdio.h>
22 #ifdef __APPLE__
23     #include <stdint.h>
24 #endif
25 #include "pcsctypes.h"
26 #include "winscarddll.h"
27 
28 #ifdef PCSCLITE
29     #include <dlfcn.h>
30     #include <string.h>
31 #endif // PCSCLITE
32 
33 #ifndef NULL
34     #define NULL    ((void*)0)
35 #endif //NULL
36 
37 //
38 // these functions are only available on win32 PCSC
39 //
40 #ifdef WIN32
41     WINSCARDAPI HANDLE
_defaultSCARDACCESSSTARTEDEVENT(void)42     WINAPI _defaultSCARDACCESSSTARTEDEVENT(void)
43     {
44         return NULL;
45     }
46 
47     WINSCARDAPI SCARDRETCODE
_defaultSCARDADDREADERTOGROUPA(IN SCARDCONTEXT hContext,IN LPCSTR szReaderName,IN LPCSTR szGroupName)48     WINAPI _defaultSCARDADDREADERTOGROUPA(
49         IN SCARDCONTEXT hContext,
50         IN LPCSTR szReaderName,
51         IN LPCSTR szGroupName)
52     {
53         return SCARD_E_NO_SERVICE;
54     }
55 
56     WINSCARDAPI SCARDRETCODE
_defaultSCARDFORGETCARDTYPEA(IN SCARDCONTEXT hContext,IN LPCSTR szCardName)57     WINAPI _defaultSCARDFORGETCARDTYPEA(
58         IN SCARDCONTEXT hContext,
59         IN LPCSTR szCardName)
60     {
61         return SCARD_E_NO_SERVICE;
62     }
63 
64     WINSCARDAPI SCARDRETCODE
_defaultSCARDFORGETREADERA(IN SCARDCONTEXT hContext,IN LPCSTR szReaderName)65     WINAPI _defaultSCARDFORGETREADERA(
66         IN SCARDCONTEXT hContext,
67         IN LPCSTR szReaderName)
68     {
69         return SCARD_E_NO_SERVICE;
70     }
71 
72     WINSCARDAPI SCARDRETCODE
_defaultSCARDFORGETREADERGROUPA(IN SCARDCONTEXT hContext,IN LPCSTR szGroupName)73     WINAPI _defaultSCARDFORGETREADERGROUPA(
74         IN SCARDCONTEXT hContext,
75         IN LPCSTR szGroupName)
76     {
77         return SCARD_E_NO_SERVICE;
78     }
79 
80     WINSCARDAPI SCARDRETCODE
_defaultSCARDGETPROVIDERIDA(IN SCARDCONTEXT hContext,IN LPCSTR szCard,OUT LPGUID pguidProviderId)81     WINAPI _defaultSCARDGETPROVIDERIDA(
82         IN      SCARDCONTEXT hContext,
83         IN      LPCSTR szCard,
84         OUT     LPGUID pguidProviderId)
85     {
86         return SCARD_E_NO_SERVICE;
87     }
88 
89     WINSCARDAPI SCARDRETCODE
_defaultSCARDGETCARDTYPEPROVIDERNAMEA(IN SCARDCONTEXT hContext,IN LPCSTR szCardName,IN SCARDDWORDARG dwProviderId,OUT LPTSTR szProvider,IN OUT SCARDDWORDARG * pcchProvider)90     WINAPI _defaultSCARDGETCARDTYPEPROVIDERNAMEA(
91         IN SCARDCONTEXT hContext,
92         IN LPCSTR szCardName,
93         IN SCARDDWORDARG dwProviderId,
94         OUT LPTSTR szProvider,
95         IN OUT SCARDDWORDARG* pcchProvider)
96     {
97         return SCARD_E_NO_SERVICE;
98     }
99 
100     WINSCARDAPI SCARDRETCODE
_defaultSCARDINTRODUCECARDTYPEA(IN SCARDCONTEXT hContext,IN LPCSTR szCardName,IN LPCGUID pguidPrimaryProvider,IN LPCGUID rgguidInterfaces,IN SCARDDWORDARG dwInterfaceCount,IN LPCBYTE pbAtr,IN LPCBYTE pbAtrMask,IN SCARDDWORDARG cbAtrLen)101     WINAPI _defaultSCARDINTRODUCECARDTYPEA(
102         IN SCARDCONTEXT hContext,
103         IN LPCSTR szCardName,
104         IN LPCGUID pguidPrimaryProvider,
105         IN LPCGUID rgguidInterfaces,
106         IN SCARDDWORDARG dwInterfaceCount,
107         IN LPCBYTE pbAtr,
108         IN LPCBYTE pbAtrMask,
109         IN SCARDDWORDARG cbAtrLen)
110     {
111         return SCARD_E_NO_SERVICE;
112     }
113 
114 
115     WINSCARDAPI SCARDRETCODE
_defaultSCARDINTRODUCEREADERA(IN SCARDCONTEXT hContext,IN LPCSTR szReaderName,IN LPCSTR szDeviceName)116     WINAPI _defaultSCARDINTRODUCEREADERA(
117         IN SCARDCONTEXT hContext,
118         IN LPCSTR szReaderName,
119         IN LPCSTR szDeviceName)
120     {
121         return SCARD_E_NO_SERVICE;
122     }
123 
124     WINSCARDAPI SCARDRETCODE
_defaultSCARDINTRODUCEREADERGROUPA(IN SCARDCONTEXT hContext,IN LPCSTR szGroupName)125     WINAPI _defaultSCARDINTRODUCEREADERGROUPA(
126         IN SCARDCONTEXT hContext,
127         IN LPCSTR szGroupName)
128     {
129         return SCARD_E_NO_SERVICE;
130     }
131 
132     WINSCARDAPI SCARDRETCODE
_defaultSCARDLISTCARDSA(IN SCARDCONTEXT hContext,IN LPCBYTE pbAtr,IN LPCGUID rgquidInterfaces,IN SCARDDWORDARG cguidInterfaceCount,OUT LPTSTR mszCards,IN OUT SCARDDWORDARG * pcchCards)133     WINAPI _defaultSCARDLISTCARDSA(
134         IN      SCARDCONTEXT hContext,
135         IN      LPCBYTE pbAtr,
136         IN      LPCGUID rgquidInterfaces,
137         IN      SCARDDWORDARG cguidInterfaceCount,
138         OUT     LPTSTR mszCards,
139         IN OUT  SCARDDWORDARG* pcchCards)
140     {
141         return SCARD_E_NO_SERVICE;
142     }
143 
144     WINSCARDAPI SCARDRETCODE
_defaultSCARDLISTINTERFACESA(IN SCARDCONTEXT hContext,IN LPCSTR szCard,OUT LPGUID pguidInterfaces,IN OUT SCARDDWORDARG * pcguidInterfaces)145     WINAPI _defaultSCARDLISTINTERFACESA(
146         IN      SCARDCONTEXT hContext,
147         IN      LPCSTR szCard,
148         OUT     LPGUID pguidInterfaces,
149         IN OUT  SCARDDWORDARG* pcguidInterfaces)
150     {
151         return SCARD_E_NO_SERVICE;
152     }
153 
154     WINSCARDAPI SCARDRETCODE
_defaultSCARDLOCATECARDSA(IN SCARDCONTEXT hContext,IN LPCSTR mszCards,IN OUT LPSCARD_READERSTATEA rgReaderStates,IN SCARDDWORDARG cReaders)155     WINAPI _defaultSCARDLOCATECARDSA(
156         IN      SCARDCONTEXT hContext,
157         IN      LPCSTR mszCards,
158         IN OUT  LPSCARD_READERSTATEA rgReaderStates,
159         IN      SCARDDWORDARG cReaders)
160     {
161         return SCARD_E_NO_SERVICE;
162     }
163 
164     WINSCARDAPI SCARDRETCODE
_defaultSCARDLOCATECARDSBYATRA(IN SCARDCONTEXT hContext,IN LPSCARD_ATRMASK rgAtrMasks,IN SCARDDWORDARG cAtrs,IN OUT LPSCARD_READERSTATEA rgReaderStates,IN SCARDDWORDARG cReaders)165     WINAPI _defaultSCARDLOCATECARDSBYATRA(
166         IN      SCARDCONTEXT hContext,
167         IN      LPSCARD_ATRMASK rgAtrMasks,
168         IN      SCARDDWORDARG cAtrs,
169         IN OUT  LPSCARD_READERSTATEA rgReaderStates,
170         IN      SCARDDWORDARG cReaders)
171     {
172         return SCARD_E_NO_SERVICE;
173     }
174 
175     WINSCARDAPI void
_defaultSCARDRELEASESTARTEDEVENT(void)176     WINAPI _defaultSCARDRELEASESTARTEDEVENT(void)
177     {
178         return;
179     }
180 
181     WINSCARDAPI SCARDRETCODE
_defaultSCARDREMOVEREADERFROMGROUPA(IN SCARDCONTEXT hContext,IN LPCSTR szReaderName,IN LPCSTR szGroupName)182     WINAPI _defaultSCARDREMOVEREADERFROMGROUPA(
183         IN SCARDCONTEXT hContext,
184         IN LPCSTR szReaderName,
185         IN LPCSTR szGroupName)
186     {
187         return SCARD_E_NO_SERVICE;
188     }
189 
190     WINSCARDAPI SCARDRETCODE
_defaultSCARDSETCARDTYPEPROVIDERNAMEA(IN SCARDCONTEXT hContext,IN LPCSTR szCardName,IN SCARDDWORDARG dwProviderId,IN LPCSTR szProvider)191     WINAPI _defaultSCARDSETCARDTYPEPROVIDERNAMEA(
192         IN SCARDCONTEXT hContext,
193         IN LPCSTR szCardName,
194         IN SCARDDWORDARG dwProviderId,
195         IN LPCSTR szProvider)
196     {
197         return SCARD_E_NO_SERVICE;
198     }
199 
200     WINSCARDAPI SCARDRETCODE
_defaultSCARDSTATE(IN SCARDHANDLE hCard,OUT SCARDDWORDARG * pdwState,OUT SCARDDWORDARG * pdwProtocol,OUT LPBYTE pbAtr,IN OUT SCARDDWORDARG * pcbAtrLen)201     WINAPI _defaultSCARDSTATE(
202         IN SCARDHANDLE hCard,
203         OUT SCARDDWORDARG* pdwState,
204         OUT SCARDDWORDARG* pdwProtocol,
205         OUT LPBYTE pbAtr,
206         IN OUT SCARDDWORDARG* pcbAtrLen)
207     {
208         return SCARD_E_NO_SERVICE;
209     }
210 
211     SCARDACCESSSTARTEDEVENT         mySCardAccessStartedEvent           = _defaultSCARDACCESSSTARTEDEVENT;
212     SCARDADDREADERTOGROUPA          mySCardAddReaderToGroupA            = _defaultSCARDADDREADERTOGROUPA;
213     SCARDFORGETCARDTYPEA            mySCardForgetCardTypeA              = _defaultSCARDFORGETCARDTYPEA;
214     SCARDFORGETREADERA              mySCardForgetReaderA                = _defaultSCARDFORGETREADERA;
215     SCARDFORGETREADERGROUPA         mySCardForgetReaderGroupA           = _defaultSCARDFORGETREADERGROUPA;
216     SCARDGETPROVIDERIDA             mySCardGetProviderIdA               = _defaultSCARDGETPROVIDERIDA;
217     SCARDGETCARDTYPEPROVIDERNAMEA   mySCardGetCardTypeProviderNameA     = _defaultSCARDGETCARDTYPEPROVIDERNAMEA;
218     SCARDINTRODUCECARDTYPEA         mySCardIntroduceCardTypeA           = _defaultSCARDINTRODUCECARDTYPEA;
219     SCARDINTRODUCEREADERA           mySCardIntroduceReaderA             = _defaultSCARDINTRODUCEREADERA;
220     SCARDINTRODUCEREADERGROUPA      mySCardIntroduceReaderGroupA        = _defaultSCARDINTRODUCEREADERGROUPA;
221     SCARDLISTCARDSA                 mySCardListCardsA                   = _defaultSCARDLISTCARDSA;
222     SCARDLISTINTERFACESA            mySCardListInterfacesA              = _defaultSCARDLISTINTERFACESA;
223     SCARDLOCATECARDSA               mySCardLocateCardsA                 = _defaultSCARDLOCATECARDSA;
224     SCARDLOCATECARDSBYATRA          mySCardLocateCardsByATRA            = _defaultSCARDLOCATECARDSBYATRA;
225     SCARDRELEASESTARTEDEVENT        mySCardReleaseStartedEvent          = _defaultSCARDRELEASESTARTEDEVENT;
226     SCARDREMOVEREADERFROMGROUPA     mySCardRemoveReaderFromGroupA       = _defaultSCARDREMOVEREADERFROMGROUPA;
227     SCARDSETCARDTYPEPROVIDERNAMEA   mySCardSetCardTypeProviderNameA     = _defaultSCARDSETCARDTYPEPROVIDERNAMEA;
228     SCARDSTATE                      mySCardState                        = _defaultSCARDSTATE;
229 #endif // WIN32
230 
231     static WINSCARDAPI SCARDRETCODE
_defaultSCARDISVALIDCONTEXT(IN SCARDCONTEXT hContext)232     WINAPI _defaultSCARDISVALIDCONTEXT(
233         IN      SCARDCONTEXT hContext)
234     {
235         (void)hContext;
236 
237         return SCARD_E_NO_SERVICE;
238     }
239 
240     static WINSCARDAPI SCARDRETCODE
_defaultSCARDGETATTRIB(IN SCARDHANDLE hCard,IN SCARDDWORDARG dwAttrId,OUT LPBYTE pbAttr,IN OUT SCARDDWORDARG * pcbAttrLen)241     WINAPI _defaultSCARDGETATTRIB(
242         IN SCARDHANDLE hCard,
243         IN SCARDDWORDARG dwAttrId,
244         OUT LPBYTE pbAttr,
245         IN OUT SCARDDWORDARG* pcbAttrLen)
246     {
247         (void)hCard;
248         (void)dwAttrId;
249         (void)pbAttr;
250         (void)pcbAttrLen;
251 
252         return SCARD_E_NO_SERVICE;
253     }
254 
255     static WINSCARDAPI SCARDRETCODE
_defaultSCARDSETATTRIB(IN SCARDHANDLE hCard,IN SCARDDWORDARG dwAttrId,IN LPCBYTE pbAttr,IN SCARDDWORDARG cbAttrLen)256     WINAPI _defaultSCARDSETATTRIB(
257         IN SCARDHANDLE hCard,
258         IN SCARDDWORDARG dwAttrId,
259         IN LPCBYTE pbAttr,
260         IN SCARDDWORDARG cbAttrLen)
261     {
262         (void)hCard;
263         (void)dwAttrId;
264         (void)pbAttr;
265         (void)cbAttrLen;
266 
267         return SCARD_E_NO_SERVICE;
268     }
269 
270     SCARDISVALIDCONTEXT             mySCardIsValidContext               = _defaultSCARDISVALIDCONTEXT;
271     SCARDGETATTRIB                  mySCardGetAttrib                    = _defaultSCARDGETATTRIB;
272     SCARDSETATTRIB                  mySCardSetAttrib                    = _defaultSCARDSETATTRIB;
273 
274     static WINSCARDAPI SCARDRETCODE
_defaultSCARDCONTROL(IN SCARDHANDLE hCard,IN SCARDDWORDARG dwControlCode,IN LPCVOID lpInBuffer,IN SCARDDWORDARG nInBufferSize,OUT LPVOID lpOutBuffer,IN SCARDDWORDARG nOutBufferSize,OUT SCARDDWORDARG * lpBytesReturned)275     WINAPI _defaultSCARDCONTROL(
276         IN      SCARDHANDLE hCard,
277         IN      SCARDDWORDARG dwControlCode,
278         IN      LPCVOID lpInBuffer,
279         IN      SCARDDWORDARG nInBufferSize,
280         OUT     LPVOID lpOutBuffer,
281         IN      SCARDDWORDARG nOutBufferSize,
282         OUT     SCARDDWORDARG* lpBytesReturned)
283     {
284         (void)hCard;
285         (void)dwControlCode;
286         (void)lpInBuffer;
287         (void)nInBufferSize;
288         (void)lpOutBuffer;
289         (void)nOutBufferSize;
290         (void)lpBytesReturned;
291 
292         return SCARD_E_NO_SERVICE;
293     }
294 
295 #ifdef PCSCLITE
296 ///////////////////////////////////////////////////////////////////////////////
297 // some pcsclite versions (e.g. on Max OS X Tiger) have no pcsc_stringify
298 // this function was taken from pcsclite
299 //
_defaultPCSCSTRINGIFYERROR(SCARDRETCODE pcscError)300 static char* _defaultPCSCSTRINGIFYERROR( SCARDRETCODE pcscError )
301 {
302     static char strError[75];
303 
304     switch(pcscError )
305     {
306         case SCARD_S_SUCCESS:
307             strncpy( strError, "Command successful.", sizeof( strError ) );
308             break;
309         case SCARD_E_CANCELLED:
310             strncpy( strError, "Command cancelled.", sizeof( strError ) );
311             break;
312         case SCARD_E_CANT_DISPOSE:
313             strncpy( strError, "Cannot dispose handle.", sizeof( strError ) );
314             break;
315         case SCARD_E_INSUFFICIENT_BUFFER:
316             strncpy( strError, "Insufficient buffer.", sizeof( strError ) );
317             break;
318         case SCARD_E_INVALID_ATR:
319             strncpy( strError, "Invalid ATR.", sizeof( strError ) );
320             break;
321         case SCARD_E_INVALID_HANDLE:
322             strncpy( strError, "Invalid handle.", sizeof( strError ) );
323             break;
324         case SCARD_E_INVALID_PARAMETER:
325             strncpy( strError, "Invalid parameter given.", sizeof( strError ) );
326             break;
327         case SCARD_E_INVALID_TARGET:
328             strncpy( strError, "Invalid target given.", sizeof( strError ) );
329             break;
330         case SCARD_E_INVALID_VALUE:
331             strncpy( strError, "Invalid value given.", sizeof( strError ) );
332             break;
333         case SCARD_E_NO_MEMORY:
334             strncpy( strError, "Not enough memory.", sizeof( strError ) );
335             break;
336         case SCARD_F_COMM_ERROR:
337             strncpy( strError, "RPC transport error.", sizeof( strError ) );
338             break;
339         case SCARD_F_INTERNAL_ERROR:
340             strncpy( strError, "Internal error.", sizeof( strError ) );
341             break;
342         case SCARD_F_UNKNOWN_ERROR:
343             strncpy( strError, "Unknown error.", sizeof( strError ) );
344             break;
345         case SCARD_F_WAITED_TOO_LONG:
346             strncpy( strError, "Waited too long.", sizeof( strError ) );
347             break;
348         case SCARD_E_UNKNOWN_READER:
349             strncpy( strError, "Unknown reader specified.", sizeof( strError ) );
350             break;
351         case SCARD_E_TIMEOUT:
352             strncpy( strError, "Command timeout.", sizeof( strError ) );
353             break;
354         case SCARD_E_SHARING_VIOLATION:
355             strncpy( strError, "Sharing violation.", sizeof( strError ) );
356             break;
357         case SCARD_E_NO_SMARTCARD:
358             strncpy( strError, "No smart card inserted.", sizeof( strError ) );
359             break;
360         case SCARD_E_UNKNOWN_CARD:
361             strncpy( strError, "Unknown card.", sizeof( strError ) );
362             break;
363         case SCARD_E_PROTO_MISMATCH:
364             strncpy( strError, "Card protocol mismatch.", sizeof( strError ) );
365             break;
366         case SCARD_E_NOT_READY:
367             strncpy( strError, "Subsystem not ready.", sizeof( strError ) );
368             break;
369         case SCARD_E_SYSTEM_CANCELLED:
370             strncpy( strError, "System cancelled.", sizeof( strError ) );
371             break;
372         case SCARD_E_NOT_TRANSACTED:
373             strncpy( strError, "Transaction failed.", sizeof( strError ) );
374             break;
375         case SCARD_E_READER_UNAVAILABLE:
376             strncpy( strError, "Reader is unavailable.", sizeof( strError ) );
377             break;
378         case SCARD_W_UNSUPPORTED_CARD:
379             strncpy( strError, "Card is not supported.", sizeof( strError ) );
380             break;
381         case SCARD_W_UNRESPONSIVE_CARD:
382             strncpy( strError, "Card is unresponsive.", sizeof( strError ) );
383             break;
384         case SCARD_W_UNPOWERED_CARD:
385             strncpy( strError, "Card is unpowered.", sizeof( strError ) );
386             break;
387         case SCARD_W_RESET_CARD:
388             strncpy( strError, "Card was reset.", sizeof( strError ) );
389             break;
390         case SCARD_W_REMOVED_CARD:
391             strncpy( strError, "Card was removed.", sizeof( strError ) );
392             break;
393         case SCARD_E_UNSUPPORTED_FEATURE:
394             strncpy( strError, "Feature not supported.", sizeof( strError ) );
395             break;
396         case SCARD_E_PCI_TOO_SMALL:
397             strncpy( strError, "PCI struct too small.", sizeof( strError ) );
398             break;
399         case SCARD_E_READER_UNSUPPORTED:
400             strncpy( strError, "Reader is unsupported.", sizeof( strError ) );
401             break;
402         case SCARD_E_DUPLICATE_READER:
403             strncpy( strError, "Reader already exists.", sizeof( strError ) );
404             break;
405         case SCARD_E_CARD_UNSUPPORTED:
406             strncpy( strError, "Card is unsupported.", sizeof( strError ) );
407             break;
408         case SCARD_E_NO_SERVICE:
409             strncpy( strError, "Service not available.", sizeof( strError ) );
410             break;
411         case SCARD_E_SERVICE_STOPPED:
412             strncpy( strError, "Service was stopped.", sizeof( strError ) );
413             break;
414         default:
415             snprintf(strError, sizeof(strError)-1, "Unknown error: %ld, 0x%08lx", (long)pcscError, (long unsigned int)pcscError);
416     };
417 
418     // zero terminates string
419     strError[sizeof(strError)-1] = '\0';
420 
421     return strError;
422 }
423 #endif
424 
425 static WINSCARDAPI SCARDRETCODE
_defaultSCARDBEGINTRANSACTION(IN SCARDHANDLE hCard)426 WINAPI _defaultSCARDBEGINTRANSACTION(
427     IN      SCARDHANDLE hCard)
428 {
429     (void)hCard;
430 
431     return SCARD_E_NO_SERVICE;
432 }
433 
434 static WINSCARDAPI SCARDRETCODE
_defaultSCARDCANCEL(IN SCARDCONTEXT hContext)435 WINAPI _defaultSCARDCANCEL(
436     IN      SCARDCONTEXT hContext)
437 {
438     (void)hContext;
439 
440     return SCARD_E_NO_SERVICE;
441 }
442 
443 static WINSCARDAPI SCARDRETCODE
_defaultSCARDCONNECTA(IN SCARDCONTEXT hContext,IN LPCTSTR szReader,IN SCARDDWORDARG dwShareMode,IN SCARDDWORDARG dwPreferredProtocols,OUT LPSCARDHANDLE phCard,OUT SCARDDWORDARG * pdwActiveProtocol)444 WINAPI _defaultSCARDCONNECTA(
445     IN      SCARDCONTEXT hContext,
446     IN      LPCTSTR szReader,
447     IN      SCARDDWORDARG dwShareMode,
448     IN      SCARDDWORDARG dwPreferredProtocols,
449     OUT     LPSCARDHANDLE phCard,
450     OUT     SCARDDWORDARG* pdwActiveProtocol)
451 {
452     (void)hContext;
453     (void)szReader;
454     (void)dwShareMode;
455     (void)dwPreferredProtocols;
456     (void)phCard;
457     (void)pdwActiveProtocol;
458 
459     return SCARD_E_NO_SERVICE;
460 }
461 
462 static WINSCARDAPI SCARDRETCODE
_defaultSCARDDISCONNECT(IN SCARDHANDLE hCard,IN SCARDDWORDARG dwDisposition)463 WINAPI _defaultSCARDDISCONNECT(
464     IN      SCARDHANDLE hCard,
465     IN      SCARDDWORDARG dwDisposition)
466 {
467     (void)hCard;
468     (void)dwDisposition;
469 
470     return SCARD_E_NO_SERVICE;
471 }
472 
473 static WINSCARDAPI SCARDRETCODE
_defaultSCARDENDTRANSACTION(IN SCARDHANDLE hCard,IN SCARDDWORDARG dwDisposition)474 WINAPI _defaultSCARDENDTRANSACTION(
475     IN      SCARDHANDLE hCard,
476     IN      SCARDDWORDARG dwDisposition)
477 {
478     (void)hCard;
479     (void)dwDisposition;
480 
481     return SCARD_E_NO_SERVICE;
482 }
483 
484 static WINSCARDAPI SCARDRETCODE
_defaultSCARDESTABLISHCONTEXT(IN SCARDDWORDARG dwScope,IN LPCVOID pvReserved1,IN LPCVOID pvReserved2,OUT LPSCARDCONTEXT phContext)485 WINAPI _defaultSCARDESTABLISHCONTEXT(
486     IN  SCARDDWORDARG dwScope,
487     IN  LPCVOID pvReserved1,
488     IN  LPCVOID pvReserved2,
489     OUT LPSCARDCONTEXT phContext)
490 {
491     (void)dwScope;
492     (void)pvReserved1;
493     (void)pvReserved2;
494     (void)phContext;
495 
496     return SCARD_E_NO_SERVICE;
497 }
498 
499 static WINSCARDAPI SCARDRETCODE
_defaultSCARDFREEMEMORY(IN SCARDCONTEXT hContext,IN LPCVOID pvMem)500 WINAPI _defaultSCARDFREEMEMORY(
501     IN SCARDCONTEXT hContext,
502     IN LPCVOID pvMem)
503 {
504     (void)hContext;
505     (void)pvMem;
506 
507     return SCARD_E_NO_SERVICE;
508 }
509 
510 static WINSCARDAPI SCARDRETCODE
_defaultSCARDGETSTATUSCHANGEA(IN SCARDCONTEXT hContext,IN SCARDDWORDARG dwTimeout,IN OUT LPSCARD_READERSTATEA rgReaderStates,IN SCARDDWORDARG cReaders)511 WINAPI _defaultSCARDGETSTATUSCHANGEA(
512     IN      SCARDCONTEXT hContext,
513     IN      SCARDDWORDARG dwTimeout,
514     IN OUT  LPSCARD_READERSTATEA rgReaderStates,
515     IN      SCARDDWORDARG cReaders)
516 {
517     (void)hContext;
518     (void)dwTimeout;
519     (void)rgReaderStates;
520     (void)cReaders;
521 
522     return SCARD_E_NO_SERVICE;
523 }
524 
525 static WINSCARDAPI SCARDRETCODE
_defaultSCARDLISTREADERSA(IN SCARDCONTEXT hContext,IN LPCTSTR mszGroups,OUT LPTSTR mszReaders,IN OUT SCARDDWORDARG * pcchReaders)526 WINAPI _defaultSCARDLISTREADERSA(
527     IN      SCARDCONTEXT hContext,
528     IN      LPCTSTR mszGroups,
529     OUT     LPTSTR mszReaders,
530     IN OUT  SCARDDWORDARG* pcchReaders)
531 {
532     (void)hContext;
533     (void)mszGroups;
534     (void)mszReaders;
535     (void)pcchReaders;
536 
537     return SCARD_E_NO_SERVICE;
538 }
539 
540 static WINSCARDAPI SCARDRETCODE
_defaultSCARDLISTREADERGROUPSA(IN SCARDCONTEXT hContext,OUT LPTSTR mszGroups,IN OUT SCARDDWORDARG * pcchGroups)541 WINAPI _defaultSCARDLISTREADERGROUPSA(
542     IN      SCARDCONTEXT hContext,
543     OUT     LPTSTR mszGroups,
544     IN OUT  SCARDDWORDARG* pcchGroups)
545 {
546     (void)hContext;
547     (void)mszGroups;
548     (void)pcchGroups;
549 
550     return SCARD_E_NO_SERVICE;
551 }
552 
553 static WINSCARDAPI SCARDRETCODE
_defaultSCARDRECONNECT(IN SCARDHANDLE hCard,IN SCARDDWORDARG dwShareMode,IN SCARDDWORDARG dwPreferredProtocols,IN SCARDDWORDARG dwInitialization,OUT SCARDDWORDARG * pdwActiveProtocol)554 WINAPI _defaultSCARDRECONNECT(
555     IN      SCARDHANDLE hCard,
556     IN      SCARDDWORDARG dwShareMode,
557     IN      SCARDDWORDARG dwPreferredProtocols,
558     IN      SCARDDWORDARG dwInitialization,
559     OUT     SCARDDWORDARG* pdwActiveProtocol)
560 {
561     (void)hCard;
562     (void)dwShareMode;
563     (void)dwPreferredProtocols;
564     (void)dwInitialization;
565     (void)pdwActiveProtocol;
566 
567     return SCARD_E_NO_SERVICE;
568 }
569 
570 static WINSCARDAPI SCARDRETCODE
_defaultSCARDRELEASECONTEXT(IN SCARDCONTEXT hContext)571 WINAPI _defaultSCARDRELEASECONTEXT(
572     IN      SCARDCONTEXT hContext)
573 {
574     (void)hContext;
575 
576     return SCARD_E_NO_SERVICE;
577 }
578 
579 static WINSCARDAPI SCARDRETCODE
_defaultSCARDSTATUSA(IN SCARDHANDLE hCard,OUT LPTSTR szReaderName,IN OUT SCARDDWORDARG * pcchReaderLen,OUT SCARDDWORDARG * pdwState,OUT SCARDDWORDARG * pdwProtocol,OUT LPBYTE pbAtr,IN OUT SCARDDWORDARG * pcbAtrLen)580 WINAPI _defaultSCARDSTATUSA(
581     IN SCARDHANDLE hCard,
582     OUT LPTSTR szReaderName,
583     IN OUT SCARDDWORDARG* pcchReaderLen,
584     OUT SCARDDWORDARG* pdwState,
585     OUT SCARDDWORDARG* pdwProtocol,
586     OUT LPBYTE pbAtr,
587     IN OUT SCARDDWORDARG* pcbAtrLen)
588 {
589     (void)hCard;
590     (void)szReaderName;
591     (void)pcchReaderLen;
592     (void)pdwState;
593     (void)pdwProtocol;
594     (void)pbAtr;
595     (void)pcbAtrLen;
596 
597     return SCARD_E_NO_SERVICE;
598 }
599 
600 static WINSCARDAPI SCARDRETCODE
_defaultSCARDTRANSMIT(IN SCARDHANDLE hCard,IN LPCSCARD_IO_REQUEST pioSendPci,IN LPCBYTE pbSendBuffer,IN SCARDDWORDARG cbSendLength,IN OUT LPSCARD_IO_REQUEST pioRecvPci,OUT LPBYTE pbRecvBuffer,IN OUT SCARDDWORDARG * pcbRecvLength)601 WINAPI _defaultSCARDTRANSMIT(
602     IN SCARDHANDLE hCard,
603     IN LPCSCARD_IO_REQUEST pioSendPci,
604     IN LPCBYTE pbSendBuffer,
605     IN SCARDDWORDARG cbSendLength,
606     IN OUT LPSCARD_IO_REQUEST pioRecvPci,
607     OUT LPBYTE pbRecvBuffer,
608     IN OUT SCARDDWORDARG* pcbRecvLength)
609 {
610     (void)hCard;
611     (void)pioSendPci;
612     (void)pbSendBuffer;
613     (void)cbSendLength;
614     (void)pioRecvPci;
615     (void)pbRecvBuffer;
616     (void)pcbRecvLength;
617 
618     return SCARD_E_NO_SERVICE;
619 }
620 
621 SCARDBEGINTRANSACTION           mySCardBeginTransaction             = _defaultSCARDBEGINTRANSACTION;
622 SCARDCANCEL                     mySCardCancel                       = _defaultSCARDCANCEL;
623 SCARDCONNECTA                   mySCardConnectA                     = _defaultSCARDCONNECTA;
624 SCARDCONTROL                    mySCardControl                      = _defaultSCARDCONTROL;
625 SCARDDISCONNECT                 mySCardDisconnect                   = _defaultSCARDDISCONNECT;
626 SCARDENDTRANSACTION             mySCardEndTransaction               = _defaultSCARDENDTRANSACTION;
627 SCARDESTABLISHCONTEXT           mySCardEstablishContext             = _defaultSCARDESTABLISHCONTEXT;
628 SCARDFREEMEMORY                 mySCardFreeMemory                   = _defaultSCARDFREEMEMORY;
629 SCARDGETSTATUSCHANGEA           mySCardGetStatusChangeA             = _defaultSCARDGETSTATUSCHANGEA;
630 SCARDLISTREADERSA               mySCardListReadersA                 = _defaultSCARDLISTREADERSA;
631 SCARDLISTREADERGROUPSA          mySCardListReaderGroupsA            = _defaultSCARDLISTREADERGROUPSA;
632 SCARDRECONNECT                  mySCardReconnect                    = _defaultSCARDRECONNECT;
633 SCARDRELEASECONTEXT             mySCardReleaseContext               = _defaultSCARDRELEASECONTEXT;
634 SCARDSTATUSA                    mySCardStatusA                      = _defaultSCARDSTATUSA;
635 SCARDTRANSMIT                   mySCardTransmit                     = _defaultSCARDTRANSMIT;
636 
637 
638 #ifdef PCSCLITE
639     PCSCSTRINGIFYERROR myPcscStringifyError = _defaultPCSCSTRINGIFYERROR;
640 #endif // PCSCLITE
641 
642 
643 void * myg_prgSCardT0Pci=NULL;
644 void * myg_prgSCardT1Pci=NULL;
645 void * myg_prgSCardRawPci=NULL;
646 
winscard_init(void)647 long winscard_init(void)
648 {
649     static BOOL bFirstCall=TRUE;
650     static long lRetCode=SCARD_E_NO_SERVICE;
651     #ifdef WIN32
652         #define  GETPROCADDRESS(type,name)       my##name=(type)GetProcAddress(hinstDLL, #name );
653         HINSTANCE hinstDLL=NULL;
654 
655         if( bFirstCall )
656         {
657             bFirstCall=FALSE;
658             hinstDLL = LoadLibrary( "winscard.dll" );
659             if( NULL!=hinstDLL )
660             {
661                 lRetCode=SCARD_S_SUCCESS;
662                 GETPROCADDRESS( SCARDADDREADERTOGROUPA          , SCardAddReaderToGroupA );
663                 GETPROCADDRESS( SCARDACCESSSTARTEDEVENT         , SCardAccessStartedEvent );
664                 GETPROCADDRESS( SCARDBEGINTRANSACTION           , SCardBeginTransaction );
665                 GETPROCADDRESS( SCARDCANCEL                     , SCardCancel );
666                 GETPROCADDRESS( SCARDCONNECTA                   , SCardConnectA );
667                 GETPROCADDRESS( SCARDCONTROL                    , SCardControl );
668                 GETPROCADDRESS( SCARDDISCONNECT                 , SCardDisconnect );
669                 GETPROCADDRESS( SCARDENDTRANSACTION             , SCardEndTransaction );
670                 GETPROCADDRESS( SCARDESTABLISHCONTEXT           , SCardEstablishContext );
671                 GETPROCADDRESS( SCARDFORGETCARDTYPEA            , SCardForgetCardTypeA );
672                 GETPROCADDRESS( SCARDFORGETREADERA              , SCardForgetReaderA );
673                 GETPROCADDRESS( SCARDFORGETREADERGROUPA         , SCardForgetReaderGroupA );
674                 GETPROCADDRESS( SCARDFREEMEMORY                 , SCardFreeMemory );
675                 GETPROCADDRESS( SCARDGETCARDTYPEPROVIDERNAMEA   , SCardGetCardTypeProviderNameA );
676                 GETPROCADDRESS( SCARDGETATTRIB                  , SCardGetAttrib );
677                 GETPROCADDRESS( SCARDGETPROVIDERIDA             , SCardGetProviderIdA );
678                 GETPROCADDRESS( SCARDGETSTATUSCHANGEA           , SCardGetStatusChangeA );
679                 GETPROCADDRESS( SCARDINTRODUCECARDTYPEA         , SCardIntroduceCardTypeA );
680                 GETPROCADDRESS( SCARDINTRODUCEREADERA           , SCardIntroduceReaderA );
681                 GETPROCADDRESS( SCARDINTRODUCEREADERGROUPA      , SCardIntroduceReaderGroupA );
682                 GETPROCADDRESS( SCARDISVALIDCONTEXT             , SCardIsValidContext );
683                 GETPROCADDRESS( SCARDLISTCARDSA                 , SCardListCardsA );
684                 GETPROCADDRESS( SCARDLISTINTERFACESA            , SCardListInterfacesA );
685                 GETPROCADDRESS( SCARDLISTREADERSA               , SCardListReadersA );
686                 GETPROCADDRESS( SCARDLISTREADERGROUPSA          , SCardListReaderGroupsA );
687                 GETPROCADDRESS( SCARDLOCATECARDSA               , SCardLocateCardsA );
688                 GETPROCADDRESS( SCARDLOCATECARDSBYATRA          , SCardLocateCardsByATRA );
689                 GETPROCADDRESS( SCARDRECONNECT                  , SCardReconnect );
690                 GETPROCADDRESS( SCARDRELEASECONTEXT             , SCardReleaseContext );
691                 GETPROCADDRESS( SCARDRELEASESTARTEDEVENT        , SCardReleaseStartedEvent );
692                 GETPROCADDRESS( SCARDREMOVEREADERFROMGROUPA     , SCardRemoveReaderFromGroupA );
693                 GETPROCADDRESS( SCARDSETATTRIB                  , SCardSetAttrib );
694                 GETPROCADDRESS( SCARDSETCARDTYPEPROVIDERNAMEA   , SCardSetCardTypeProviderNameA );
695                 GETPROCADDRESS( SCARDSTATE                      , SCardState );
696                 GETPROCADDRESS( SCARDSTATUSA                    , SCardStatusA );
697                 GETPROCADDRESS( SCARDTRANSMIT                   , SCardTransmit );
698 
699 
700                 myg_prgSCardT0Pci   = GetProcAddress( hinstDLL, "g_rgSCardT0Pci"  );
701                 myg_prgSCardT1Pci   = GetProcAddress( hinstDLL, "g_rgSCardT1Pci"  );
702                 myg_prgSCardRawPci  = GetProcAddress( hinstDLL, "g_rgSCardRawPci" );
703 
704             }
705          }
706     #endif // WIN32
707 
708     #ifdef PCSCLITE
709         #define  GETPROCADDRESS( type, name, realname )  my##name=(type)dlsym( handle, #realname ); \
710                                                          dlsym_error = dlerror(); \
711                                                          if (NULL!=dlsym_error) \
712                                                          { \
713                                                             printf( "Failed to load symbol for: %s, %s!\n", #realname, (char*)dlsym_error ); \
714                                                          }
715 
716         // some functions are not available on older releases of pcsc-lite, such
717         // as SCardIsValidContext; don't complain if they are not located
718         #define  SILENTGETPROCADDRESS( type, name, realname )  my##name=(type)dlsym( handle, #realname ); \
719                                                          dlsym_error = dlerror();
720 
721         void* handle=NULL;
722         char* dlsym_error;
723         const char *lib = NULL;
724         #ifdef __APPLE__
725             lib = "/System/Library/Frameworks/PCSC.framework/PCSC";
726         #else
727             lib = "libpcsclite.so.1";
728         #endif
729 
730         if( bFirstCall )
731         {
732             dlerror();
733             handle = dlopen( lib, RTLD_NOW );
734             if( NULL!=handle )
735             {
736                 lRetCode=SCARD_S_SUCCESS;
737                 GETPROCADDRESS( SCARDBEGINTRANSACTION  , SCardBeginTransaction  , SCardBeginTransaction  );
738                 GETPROCADDRESS( SCARDCANCEL            , SCardCancel            , SCardCancel );
739                 GETPROCADDRESS( SCARDCONNECTA          , SCardConnectA          , SCardConnect           );
740                 GETPROCADDRESS( SCARDDISCONNECT        , SCardDisconnect        , SCardDisconnect        );
741                 GETPROCADDRESS( SCARDENDTRANSACTION    , SCardEndTransaction    , SCardEndTransaction    );
742                 GETPROCADDRESS( SCARDESTABLISHCONTEXT  , SCardEstablishContext  , SCardEstablishContext  );
743                 GETPROCADDRESS( SCARDGETSTATUSCHANGEA  , SCardGetStatusChangeA  , SCardGetStatusChange   );
744                 GETPROCADDRESS( SCARDLISTREADERSA      , SCardListReadersA      , SCardListReaders       );
745                 GETPROCADDRESS( SCARDLISTREADERGROUPSA , SCardListReaderGroupsA , SCardListReaderGroups  );
746                 GETPROCADDRESS( SCARDRECONNECT         , SCardReconnect         , SCardReconnect         );
747                 GETPROCADDRESS( SCARDRELEASECONTEXT    , SCardReleaseContext    , SCardReleaseContext    );
748                 GETPROCADDRESS( SCARDSTATUSA           , SCardStatusA           , SCardStatus            );
749                 GETPROCADDRESS( SCARDTRANSMIT          , SCardTransmit          , SCardTransmit          );
750                 SILENTGETPROCADDRESS( PCSCSTRINGIFYERROR     , PcscStringifyError   , pcsc_stringify_error   );
751 
752                 #ifndef __APPLE__
753                     GETPROCADDRESS( SCARDCONTROL, SCardControl, SCardControl );
754                 #else // !__APPLE__
755                     GETPROCADDRESS( SCARDCONTROL, SCardControl, SCardControl132 );
756                 #endif // __APPLE__
757 
758                     SILENTGETPROCADDRESS( SCARDISVALIDCONTEXT    , SCardIsValidContext    , SCardIsValidContext    );
759                     GETPROCADDRESS( SCARDGETATTRIB         , SCardGetAttrib         , SCardGetAttrib         );
760                     GETPROCADDRESS( SCARDSETATTRIB         , SCardSetAttrib         , SCardSetAttrib         );
761 
762                 myg_prgSCardT0Pci  = dlsym( handle, "g_rgSCardT0Pci"  );
763                 myg_prgSCardT1Pci  = dlsym( handle, "g_rgSCardT1Pci"  );
764                 myg_prgSCardRawPci = dlsym( handle, "g_rgSCardRawPci" );
765 
766                 dlsym_error = dlerror();
767                 if( NULL!= dlsym_error )
768                 {
769                     printf( "Failed to load symbol address from %s: %s!", lib, (char*)dlsym_error );
770                 }
771             }
772             else
773             {
774                 dlsym_error = dlerror();
775                 if( NULL!= dlsym_error )
776                 {
777                     printf( "Failed to dlopen %s: %s!", lib, (dlsym_error==NULL) ? "" : (char*)dlsym_error );
778                 }
779             }
780             bFirstCall=FALSE;
781          }
782     #endif // PCSCLITE
783     return lRetCode;
784 };
785 
786