1 /**
2  * WinPR: Windows Portable Runtime
3  * Smart Card API
4  *
5  * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  * Copyright 2020 Armin Novak <armin.novak@thincast.com>
7  * Copyright 2020 Thincast Technologies GmbH
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *     http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <winpr/crt.h>
27 #include <winpr/library.h>
28 #include <winpr/smartcard.h>
29 #include <winpr/synch.h>
30 #include <winpr/wlog.h>
31 
32 #include "../log.h"
33 
34 #include "smartcard.h"
35 
36 #include "smartcard_inspect.h"
37 
38 static INIT_ONCE g_Initialized = INIT_ONCE_STATIC_INIT;
39 static const SCardApiFunctionTable* g_SCardApi = NULL;
40 
41 #define TAG WINPR_TAG("smartcard")
42 
43 #define xstr(s) str(s)
44 #define str(s) #s
45 
46 #define SCARDAPI_STUB_CALL_LONG(_name, ...)                                              \
47 	InitOnceExecuteOnce(&g_Initialized, InitializeSCardApiStubs, NULL, NULL);            \
48 	if (!g_SCardApi || !g_SCardApi->pfn##_name)                                          \
49 	{                                                                                    \
50 		WLog_DBG(TAG, "Missing function pointer g_SCardApi=%p->" xstr(pfn##_name) "=%p", \
51 		         g_SCardApi, g_SCardApi ? g_SCardApi->pfn##_name : NULL);                \
52 		return SCARD_E_NO_SERVICE;                                                       \
53 	}                                                                                    \
54 	return g_SCardApi->pfn##_name(__VA_ARGS__)
55 
56 #define SCARDAPI_STUB_CALL_HANDLE(_name, ...)                                 \
57 	InitOnceExecuteOnce(&g_Initialized, InitializeSCardApiStubs, NULL, NULL); \
58 	if (!g_SCardApi || !g_SCardApi->pfn##_name)                               \
59 		return NULL;                                                          \
60 	return g_SCardApi->pfn##_name(__VA_ARGS__)
61 
62 #define SCARDAPI_STUB_CALL_VOID(_name, ...)                                   \
63 	InitOnceExecuteOnce(&g_Initialized, InitializeSCardApiStubs, NULL, NULL); \
64 	if (!g_SCardApi || !g_SCardApi->pfn##_name)                               \
65 		return;                                                               \
66 	g_SCardApi->pfn##_name(__VA_ARGS__)
67 
68 /**
69  * Standard Windows Smart Card API
70  */
71 
72 const SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
73 const SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
74 const SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
75 
InitializeSCardApiStubs(PINIT_ONCE once,PVOID param,PVOID * context)76 static BOOL CALLBACK InitializeSCardApiStubs(PINIT_ONCE once, PVOID param, PVOID* context)
77 {
78 #ifndef _WIN32
79 
80 	if (PCSC_InitializeSCardApi() >= 0)
81 		g_SCardApi = PCSC_GetSCardApiFunctionTable();
82 
83 #else
84 
85 	if (WinSCard_InitializeSCardApi() >= 0)
86 		g_SCardApi = WinSCard_GetSCardApiFunctionTable();
87 
88 #endif
89 #ifdef WITH_SMARTCARD_INSPECT
90 	g_SCardApi = Inspect_RegisterSCardApi(g_SCardApi);
91 #endif
92 	return TRUE;
93 }
94 
SCardEstablishContext(DWORD dwScope,LPCVOID pvReserved1,LPCVOID pvReserved2,LPSCARDCONTEXT phContext)95 WINSCARDAPI LONG WINAPI SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
96                                               LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
97 {
98 	SCARDAPI_STUB_CALL_LONG(SCardEstablishContext, dwScope, pvReserved1, pvReserved2, phContext);
99 }
100 
SCardReleaseContext(SCARDCONTEXT hContext)101 WINSCARDAPI LONG WINAPI SCardReleaseContext(SCARDCONTEXT hContext)
102 {
103 	SCARDAPI_STUB_CALL_LONG(SCardReleaseContext, hContext);
104 }
105 
SCardIsValidContext(SCARDCONTEXT hContext)106 WINSCARDAPI LONG WINAPI SCardIsValidContext(SCARDCONTEXT hContext)
107 {
108 	SCARDAPI_STUB_CALL_LONG(SCardIsValidContext, hContext);
109 }
110 
SCardListReaderGroupsA(SCARDCONTEXT hContext,LPSTR mszGroups,LPDWORD pcchGroups)111 WINSCARDAPI LONG WINAPI SCardListReaderGroupsA(SCARDCONTEXT hContext, LPSTR mszGroups,
112                                                LPDWORD pcchGroups)
113 {
114 	SCARDAPI_STUB_CALL_LONG(SCardListReaderGroupsA, hContext, mszGroups, pcchGroups);
115 }
116 
SCardListReaderGroupsW(SCARDCONTEXT hContext,LPWSTR mszGroups,LPDWORD pcchGroups)117 WINSCARDAPI LONG WINAPI SCardListReaderGroupsW(SCARDCONTEXT hContext, LPWSTR mszGroups,
118                                                LPDWORD pcchGroups)
119 {
120 	SCARDAPI_STUB_CALL_LONG(SCardListReaderGroupsW, hContext, mszGroups, pcchGroups);
121 }
122 
SCardListReadersA(SCARDCONTEXT hContext,LPCSTR mszGroups,LPSTR mszReaders,LPDWORD pcchReaders)123 WINSCARDAPI LONG WINAPI SCardListReadersA(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
124                                           LPDWORD pcchReaders)
125 {
126 	SCARDAPI_STUB_CALL_LONG(SCardListReadersA, hContext, mszGroups, mszReaders, pcchReaders);
127 }
128 
SCardListReadersW(SCARDCONTEXT hContext,LPCWSTR mszGroups,LPWSTR mszReaders,LPDWORD pcchReaders)129 WINSCARDAPI LONG WINAPI SCardListReadersW(SCARDCONTEXT hContext, LPCWSTR mszGroups,
130                                           LPWSTR mszReaders, LPDWORD pcchReaders)
131 {
132 	SCARDAPI_STUB_CALL_LONG(SCardListReadersW, hContext, mszGroups, mszReaders, pcchReaders);
133 }
134 
SCardListCardsA(SCARDCONTEXT hContext,LPCBYTE pbAtr,LPCGUID rgquidInterfaces,DWORD cguidInterfaceCount,CHAR * mszCards,LPDWORD pcchCards)135 WINSCARDAPI LONG WINAPI SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr,
136                                         LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
137                                         CHAR* mszCards, LPDWORD pcchCards)
138 {
139 	SCARDAPI_STUB_CALL_LONG(SCardListCardsA, hContext, pbAtr, rgquidInterfaces, cguidInterfaceCount,
140 	                        mszCards, pcchCards);
141 }
142 
SCardListCardsW(SCARDCONTEXT hContext,LPCBYTE pbAtr,LPCGUID rgquidInterfaces,DWORD cguidInterfaceCount,WCHAR * mszCards,LPDWORD pcchCards)143 WINSCARDAPI LONG WINAPI SCardListCardsW(SCARDCONTEXT hContext, LPCBYTE pbAtr,
144                                         LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
145                                         WCHAR* mszCards, LPDWORD pcchCards)
146 {
147 	SCARDAPI_STUB_CALL_LONG(SCardListCardsW, hContext, pbAtr, rgquidInterfaces, cguidInterfaceCount,
148 	                        mszCards, pcchCards);
149 }
150 
SCardListInterfacesA(SCARDCONTEXT hContext,LPCSTR szCard,LPGUID pguidInterfaces,LPDWORD pcguidInterfaces)151 WINSCARDAPI LONG WINAPI SCardListInterfacesA(SCARDCONTEXT hContext, LPCSTR szCard,
152                                              LPGUID pguidInterfaces, LPDWORD pcguidInterfaces)
153 {
154 	SCARDAPI_STUB_CALL_LONG(SCardListInterfacesA, hContext, szCard, pguidInterfaces,
155 	                        pcguidInterfaces);
156 }
157 
SCardListInterfacesW(SCARDCONTEXT hContext,LPCWSTR szCard,LPGUID pguidInterfaces,LPDWORD pcguidInterfaces)158 WINSCARDAPI LONG WINAPI SCardListInterfacesW(SCARDCONTEXT hContext, LPCWSTR szCard,
159                                              LPGUID pguidInterfaces, LPDWORD pcguidInterfaces)
160 {
161 	SCARDAPI_STUB_CALL_LONG(SCardListInterfacesW, hContext, szCard, pguidInterfaces,
162 	                        pcguidInterfaces);
163 }
164 
SCardGetProviderIdA(SCARDCONTEXT hContext,LPCSTR szCard,LPGUID pguidProviderId)165 WINSCARDAPI LONG WINAPI SCardGetProviderIdA(SCARDCONTEXT hContext, LPCSTR szCard,
166                                             LPGUID pguidProviderId)
167 {
168 	SCARDAPI_STUB_CALL_LONG(SCardGetProviderIdA, hContext, szCard, pguidProviderId);
169 }
170 
SCardGetProviderIdW(SCARDCONTEXT hContext,LPCWSTR szCard,LPGUID pguidProviderId)171 WINSCARDAPI LONG WINAPI SCardGetProviderIdW(SCARDCONTEXT hContext, LPCWSTR szCard,
172                                             LPGUID pguidProviderId)
173 {
174 	SCARDAPI_STUB_CALL_LONG(SCardGetProviderIdW, hContext, szCard, pguidProviderId);
175 }
176 
SCardGetCardTypeProviderNameA(SCARDCONTEXT hContext,LPCSTR szCardName,DWORD dwProviderId,CHAR * szProvider,LPDWORD pcchProvider)177 WINSCARDAPI LONG WINAPI SCardGetCardTypeProviderNameA(SCARDCONTEXT hContext, LPCSTR szCardName,
178                                                       DWORD dwProviderId, CHAR* szProvider,
179                                                       LPDWORD pcchProvider)
180 {
181 	SCARDAPI_STUB_CALL_LONG(SCardGetCardTypeProviderNameA, hContext, szCardName, dwProviderId,
182 	                        szProvider, pcchProvider);
183 }
184 
SCardGetCardTypeProviderNameW(SCARDCONTEXT hContext,LPCWSTR szCardName,DWORD dwProviderId,WCHAR * szProvider,LPDWORD pcchProvider)185 WINSCARDAPI LONG WINAPI SCardGetCardTypeProviderNameW(SCARDCONTEXT hContext, LPCWSTR szCardName,
186                                                       DWORD dwProviderId, WCHAR* szProvider,
187                                                       LPDWORD pcchProvider)
188 {
189 	SCARDAPI_STUB_CALL_LONG(SCardGetCardTypeProviderNameW, hContext, szCardName, dwProviderId,
190 	                        szProvider, pcchProvider);
191 }
192 
SCardIntroduceReaderGroupA(SCARDCONTEXT hContext,LPCSTR szGroupName)193 WINSCARDAPI LONG WINAPI SCardIntroduceReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName)
194 {
195 	SCARDAPI_STUB_CALL_LONG(SCardIntroduceReaderGroupA, hContext, szGroupName);
196 }
197 
SCardIntroduceReaderGroupW(SCARDCONTEXT hContext,LPCWSTR szGroupName)198 WINSCARDAPI LONG WINAPI SCardIntroduceReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName)
199 {
200 	SCARDAPI_STUB_CALL_LONG(SCardIntroduceReaderGroupW, hContext, szGroupName);
201 }
202 
SCardForgetReaderGroupA(SCARDCONTEXT hContext,LPCSTR szGroupName)203 WINSCARDAPI LONG WINAPI SCardForgetReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName)
204 {
205 	SCARDAPI_STUB_CALL_LONG(SCardForgetReaderGroupA, hContext, szGroupName);
206 }
207 
SCardForgetReaderGroupW(SCARDCONTEXT hContext,LPCWSTR szGroupName)208 WINSCARDAPI LONG WINAPI SCardForgetReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName)
209 {
210 	SCARDAPI_STUB_CALL_LONG(SCardForgetReaderGroupW, hContext, szGroupName);
211 }
212 
SCardIntroduceReaderA(SCARDCONTEXT hContext,LPCSTR szReaderName,LPCSTR szDeviceName)213 WINSCARDAPI LONG WINAPI SCardIntroduceReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName,
214                                               LPCSTR szDeviceName)
215 {
216 	SCARDAPI_STUB_CALL_LONG(SCardIntroduceReaderA, hContext, szReaderName, szDeviceName);
217 }
218 
SCardIntroduceReaderW(SCARDCONTEXT hContext,LPCWSTR szReaderName,LPCWSTR szDeviceName)219 WINSCARDAPI LONG WINAPI SCardIntroduceReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
220                                               LPCWSTR szDeviceName)
221 {
222 	SCARDAPI_STUB_CALL_LONG(SCardIntroduceReaderW, hContext, szReaderName, szDeviceName);
223 }
224 
SCardForgetReaderA(SCARDCONTEXT hContext,LPCSTR szReaderName)225 WINSCARDAPI LONG WINAPI SCardForgetReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName)
226 {
227 	SCARDAPI_STUB_CALL_LONG(SCardForgetReaderA, hContext, szReaderName);
228 }
229 
SCardForgetReaderW(SCARDCONTEXT hContext,LPCWSTR szReaderName)230 WINSCARDAPI LONG WINAPI SCardForgetReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName)
231 {
232 	SCARDAPI_STUB_CALL_LONG(SCardForgetReaderW, hContext, szReaderName);
233 }
234 
SCardAddReaderToGroupA(SCARDCONTEXT hContext,LPCSTR szReaderName,LPCSTR szGroupName)235 WINSCARDAPI LONG WINAPI SCardAddReaderToGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName,
236                                                LPCSTR szGroupName)
237 {
238 	SCARDAPI_STUB_CALL_LONG(SCardAddReaderToGroupA, hContext, szReaderName, szGroupName);
239 }
240 
SCardAddReaderToGroupW(SCARDCONTEXT hContext,LPCWSTR szReaderName,LPCWSTR szGroupName)241 WINSCARDAPI LONG WINAPI SCardAddReaderToGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
242                                                LPCWSTR szGroupName)
243 {
244 	SCARDAPI_STUB_CALL_LONG(SCardAddReaderToGroupW, hContext, szReaderName, szGroupName);
245 }
246 
SCardRemoveReaderFromGroupA(SCARDCONTEXT hContext,LPCSTR szReaderName,LPCSTR szGroupName)247 WINSCARDAPI LONG WINAPI SCardRemoveReaderFromGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName,
248                                                     LPCSTR szGroupName)
249 {
250 	SCARDAPI_STUB_CALL_LONG(SCardRemoveReaderFromGroupA, hContext, szReaderName, szGroupName);
251 }
252 
SCardRemoveReaderFromGroupW(SCARDCONTEXT hContext,LPCWSTR szReaderName,LPCWSTR szGroupName)253 WINSCARDAPI LONG WINAPI SCardRemoveReaderFromGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
254                                                     LPCWSTR szGroupName)
255 {
256 	SCARDAPI_STUB_CALL_LONG(SCardRemoveReaderFromGroupW, hContext, szReaderName, szGroupName);
257 }
258 
SCardIntroduceCardTypeA(SCARDCONTEXT hContext,LPCSTR szCardName,LPCGUID pguidPrimaryProvider,LPCGUID rgguidInterfaces,DWORD dwInterfaceCount,LPCBYTE pbAtr,LPCBYTE pbAtrMask,DWORD cbAtrLen)259 WINSCARDAPI LONG WINAPI SCardIntroduceCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName,
260                                                 LPCGUID pguidPrimaryProvider,
261                                                 LPCGUID rgguidInterfaces, DWORD dwInterfaceCount,
262                                                 LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen)
263 {
264 	SCARDAPI_STUB_CALL_LONG(SCardIntroduceCardTypeA, hContext, szCardName, pguidPrimaryProvider,
265 	                        rgguidInterfaces, dwInterfaceCount, pbAtr, pbAtrMask, cbAtrLen);
266 }
267 
SCardIntroduceCardTypeW(SCARDCONTEXT hContext,LPCWSTR szCardName,LPCGUID pguidPrimaryProvider,LPCGUID rgguidInterfaces,DWORD dwInterfaceCount,LPCBYTE pbAtr,LPCBYTE pbAtrMask,DWORD cbAtrLen)268 WINSCARDAPI LONG WINAPI SCardIntroduceCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName,
269                                                 LPCGUID pguidPrimaryProvider,
270                                                 LPCGUID rgguidInterfaces, DWORD dwInterfaceCount,
271                                                 LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen)
272 {
273 	SCARDAPI_STUB_CALL_LONG(SCardIntroduceCardTypeW, hContext, szCardName, pguidPrimaryProvider,
274 	                        rgguidInterfaces, dwInterfaceCount, pbAtr, pbAtrMask, cbAtrLen);
275 }
276 
SCardSetCardTypeProviderNameA(SCARDCONTEXT hContext,LPCSTR szCardName,DWORD dwProviderId,LPCSTR szProvider)277 WINSCARDAPI LONG WINAPI SCardSetCardTypeProviderNameA(SCARDCONTEXT hContext, LPCSTR szCardName,
278                                                       DWORD dwProviderId, LPCSTR szProvider)
279 {
280 	SCARDAPI_STUB_CALL_LONG(SCardSetCardTypeProviderNameA, hContext, szCardName, dwProviderId,
281 	                        szProvider);
282 }
283 
SCardSetCardTypeProviderNameW(SCARDCONTEXT hContext,LPCWSTR szCardName,DWORD dwProviderId,LPCWSTR szProvider)284 WINSCARDAPI LONG WINAPI SCardSetCardTypeProviderNameW(SCARDCONTEXT hContext, LPCWSTR szCardName,
285                                                       DWORD dwProviderId, LPCWSTR szProvider)
286 {
287 	SCARDAPI_STUB_CALL_LONG(SCardSetCardTypeProviderNameW, hContext, szCardName, dwProviderId,
288 	                        szProvider);
289 }
290 
SCardForgetCardTypeA(SCARDCONTEXT hContext,LPCSTR szCardName)291 WINSCARDAPI LONG WINAPI SCardForgetCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName)
292 {
293 	SCARDAPI_STUB_CALL_LONG(SCardForgetCardTypeA, hContext, szCardName);
294 }
295 
SCardForgetCardTypeW(SCARDCONTEXT hContext,LPCWSTR szCardName)296 WINSCARDAPI LONG WINAPI SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName)
297 {
298 	SCARDAPI_STUB_CALL_LONG(SCardForgetCardTypeW, hContext, szCardName);
299 }
300 
SCardFreeMemory(SCARDCONTEXT hContext,LPVOID pvMem)301 WINSCARDAPI LONG WINAPI SCardFreeMemory(SCARDCONTEXT hContext, LPVOID pvMem)
302 {
303 	SCARDAPI_STUB_CALL_LONG(SCardFreeMemory, hContext, pvMem);
304 }
305 
SCardAccessStartedEvent(void)306 WINSCARDAPI HANDLE WINAPI SCardAccessStartedEvent(void)
307 {
308 	SCARDAPI_STUB_CALL_HANDLE(SCardAccessStartedEvent);
309 }
310 
SCardReleaseStartedEvent(void)311 WINSCARDAPI void WINAPI SCardReleaseStartedEvent(void)
312 {
313 	SCARDAPI_STUB_CALL_VOID(SCardReleaseStartedEvent);
314 }
315 
SCardLocateCardsA(SCARDCONTEXT hContext,LPCSTR mszCards,LPSCARD_READERSTATEA rgReaderStates,DWORD cReaders)316 WINSCARDAPI LONG WINAPI SCardLocateCardsA(SCARDCONTEXT hContext, LPCSTR mszCards,
317                                           LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders)
318 {
319 	SCARDAPI_STUB_CALL_LONG(SCardLocateCardsA, hContext, mszCards, rgReaderStates, cReaders);
320 }
321 
SCardLocateCardsW(SCARDCONTEXT hContext,LPCWSTR mszCards,LPSCARD_READERSTATEW rgReaderStates,DWORD cReaders)322 WINSCARDAPI LONG WINAPI SCardLocateCardsW(SCARDCONTEXT hContext, LPCWSTR mszCards,
323                                           LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders)
324 {
325 	SCARDAPI_STUB_CALL_LONG(SCardLocateCardsW, hContext, mszCards, rgReaderStates, cReaders);
326 }
327 
SCardLocateCardsByATRA(SCARDCONTEXT hContext,LPSCARD_ATRMASK rgAtrMasks,DWORD cAtrs,LPSCARD_READERSTATEA rgReaderStates,DWORD cReaders)328 WINSCARDAPI LONG WINAPI SCardLocateCardsByATRA(SCARDCONTEXT hContext, LPSCARD_ATRMASK rgAtrMasks,
329                                                DWORD cAtrs, LPSCARD_READERSTATEA rgReaderStates,
330                                                DWORD cReaders)
331 {
332 	SCARDAPI_STUB_CALL_LONG(SCardLocateCardsByATRA, hContext, rgAtrMasks, cAtrs, rgReaderStates,
333 	                        cReaders);
334 }
335 
SCardLocateCardsByATRW(SCARDCONTEXT hContext,LPSCARD_ATRMASK rgAtrMasks,DWORD cAtrs,LPSCARD_READERSTATEW rgReaderStates,DWORD cReaders)336 WINSCARDAPI LONG WINAPI SCardLocateCardsByATRW(SCARDCONTEXT hContext, LPSCARD_ATRMASK rgAtrMasks,
337                                                DWORD cAtrs, LPSCARD_READERSTATEW rgReaderStates,
338                                                DWORD cReaders)
339 {
340 	SCARDAPI_STUB_CALL_LONG(SCardLocateCardsByATRW, hContext, rgAtrMasks, cAtrs, rgReaderStates,
341 	                        cReaders);
342 }
343 
SCardGetStatusChangeA(SCARDCONTEXT hContext,DWORD dwTimeout,LPSCARD_READERSTATEA rgReaderStates,DWORD cReaders)344 WINSCARDAPI LONG WINAPI SCardGetStatusChangeA(SCARDCONTEXT hContext, DWORD dwTimeout,
345                                               LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders)
346 {
347 	SCARDAPI_STUB_CALL_LONG(SCardGetStatusChangeA, hContext, dwTimeout, rgReaderStates, cReaders);
348 }
349 
SCardGetStatusChangeW(SCARDCONTEXT hContext,DWORD dwTimeout,LPSCARD_READERSTATEW rgReaderStates,DWORD cReaders)350 WINSCARDAPI LONG WINAPI SCardGetStatusChangeW(SCARDCONTEXT hContext, DWORD dwTimeout,
351                                               LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders)
352 {
353 	SCARDAPI_STUB_CALL_LONG(SCardGetStatusChangeW, hContext, dwTimeout, rgReaderStates, cReaders);
354 }
355 
SCardCancel(SCARDCONTEXT hContext)356 WINSCARDAPI LONG WINAPI SCardCancel(SCARDCONTEXT hContext)
357 {
358 	SCARDAPI_STUB_CALL_LONG(SCardCancel, hContext);
359 }
360 
SCardConnectA(SCARDCONTEXT hContext,LPCSTR szReader,DWORD dwShareMode,DWORD dwPreferredProtocols,LPSCARDHANDLE phCard,LPDWORD pdwActiveProtocol)361 WINSCARDAPI LONG WINAPI SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
362                                       DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
363                                       LPDWORD pdwActiveProtocol)
364 {
365 	SCARDAPI_STUB_CALL_LONG(SCardConnectA, hContext, szReader, dwShareMode, dwPreferredProtocols,
366 	                        phCard, pdwActiveProtocol);
367 }
368 
SCardConnectW(SCARDCONTEXT hContext,LPCWSTR szReader,DWORD dwShareMode,DWORD dwPreferredProtocols,LPSCARDHANDLE phCard,LPDWORD pdwActiveProtocol)369 WINSCARDAPI LONG WINAPI SCardConnectW(SCARDCONTEXT hContext, LPCWSTR szReader, DWORD dwShareMode,
370                                       DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
371                                       LPDWORD pdwActiveProtocol)
372 {
373 	SCARDAPI_STUB_CALL_LONG(SCardConnectW, hContext, szReader, dwShareMode, dwPreferredProtocols,
374 	                        phCard, pdwActiveProtocol);
375 }
376 
SCardReconnect(SCARDHANDLE hCard,DWORD dwShareMode,DWORD dwPreferredProtocols,DWORD dwInitialization,LPDWORD pdwActiveProtocol)377 WINSCARDAPI LONG WINAPI SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
378                                        DWORD dwPreferredProtocols, DWORD dwInitialization,
379                                        LPDWORD pdwActiveProtocol)
380 {
381 	SCARDAPI_STUB_CALL_LONG(SCardReconnect, hCard, dwShareMode, dwPreferredProtocols,
382 	                        dwInitialization, pdwActiveProtocol);
383 }
384 
SCardDisconnect(SCARDHANDLE hCard,DWORD dwDisposition)385 WINSCARDAPI LONG WINAPI SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
386 {
387 	SCARDAPI_STUB_CALL_LONG(SCardDisconnect, hCard, dwDisposition);
388 }
389 
SCardBeginTransaction(SCARDHANDLE hCard)390 WINSCARDAPI LONG WINAPI SCardBeginTransaction(SCARDHANDLE hCard)
391 {
392 	SCARDAPI_STUB_CALL_LONG(SCardBeginTransaction, hCard);
393 }
394 
SCardEndTransaction(SCARDHANDLE hCard,DWORD dwDisposition)395 WINSCARDAPI LONG WINAPI SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
396 {
397 	SCARDAPI_STUB_CALL_LONG(SCardEndTransaction, hCard, dwDisposition);
398 }
399 
SCardCancelTransaction(SCARDHANDLE hCard)400 WINSCARDAPI LONG WINAPI SCardCancelTransaction(SCARDHANDLE hCard)
401 {
402 	SCARDAPI_STUB_CALL_LONG(SCardCancelTransaction, hCard);
403 }
404 
SCardState(SCARDHANDLE hCard,LPDWORD pdwState,LPDWORD pdwProtocol,LPBYTE pbAtr,LPDWORD pcbAtrLen)405 WINSCARDAPI LONG WINAPI SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD pdwProtocol,
406                                    LPBYTE pbAtr, LPDWORD pcbAtrLen)
407 {
408 	SCARDAPI_STUB_CALL_LONG(SCardState, hCard, pdwState, pdwProtocol, pbAtr, pcbAtrLen);
409 }
410 
SCardStatusA(SCARDHANDLE hCard,LPSTR mszReaderNames,LPDWORD pcchReaderLen,LPDWORD pdwState,LPDWORD pdwProtocol,LPBYTE pbAtr,LPDWORD pcbAtrLen)411 WINSCARDAPI LONG WINAPI SCardStatusA(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen,
412                                      LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
413                                      LPDWORD pcbAtrLen)
414 {
415 	SCARDAPI_STUB_CALL_LONG(SCardStatusA, hCard, mszReaderNames, pcchReaderLen, pdwState,
416 	                        pdwProtocol, pbAtr, pcbAtrLen);
417 }
418 
SCardStatusW(SCARDHANDLE hCard,LPWSTR mszReaderNames,LPDWORD pcchReaderLen,LPDWORD pdwState,LPDWORD pdwProtocol,LPBYTE pbAtr,LPDWORD pcbAtrLen)419 WINSCARDAPI LONG WINAPI SCardStatusW(SCARDHANDLE hCard, LPWSTR mszReaderNames,
420                                      LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol,
421                                      LPBYTE pbAtr, LPDWORD pcbAtrLen)
422 {
423 	SCARDAPI_STUB_CALL_LONG(SCardStatusW, hCard, mszReaderNames, pcchReaderLen, pdwState,
424 	                        pdwProtocol, pbAtr, pcbAtrLen);
425 }
426 
SCardTransmit(SCARDHANDLE hCard,LPCSCARD_IO_REQUEST pioSendPci,LPCBYTE pbSendBuffer,DWORD cbSendLength,LPSCARD_IO_REQUEST pioRecvPci,LPBYTE pbRecvBuffer,LPDWORD pcbRecvLength)427 WINSCARDAPI LONG WINAPI SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
428                                       LPCBYTE pbSendBuffer, DWORD cbSendLength,
429                                       LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
430                                       LPDWORD pcbRecvLength)
431 {
432 	SCARDAPI_STUB_CALL_LONG(SCardTransmit, hCard, pioSendPci, pbSendBuffer, cbSendLength,
433 	                        pioRecvPci, pbRecvBuffer, pcbRecvLength);
434 }
435 
SCardGetTransmitCount(SCARDHANDLE hCard,LPDWORD pcTransmitCount)436 WINSCARDAPI LONG WINAPI SCardGetTransmitCount(SCARDHANDLE hCard, LPDWORD pcTransmitCount)
437 {
438 	SCARDAPI_STUB_CALL_LONG(SCardGetTransmitCount, hCard, pcTransmitCount);
439 }
440 
SCardControl(SCARDHANDLE hCard,DWORD dwControlCode,LPCVOID lpInBuffer,DWORD cbInBufferSize,LPVOID lpOutBuffer,DWORD cbOutBufferSize,LPDWORD lpBytesReturned)441 WINSCARDAPI LONG WINAPI SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID lpInBuffer,
442                                      DWORD cbInBufferSize, LPVOID lpOutBuffer,
443                                      DWORD cbOutBufferSize, LPDWORD lpBytesReturned)
444 {
445 	SCARDAPI_STUB_CALL_LONG(SCardControl, hCard, dwControlCode, lpInBuffer, cbInBufferSize,
446 	                        lpOutBuffer, cbOutBufferSize, lpBytesReturned);
447 }
448 
SCardGetAttrib(SCARDHANDLE hCard,DWORD dwAttrId,LPBYTE pbAttr,LPDWORD pcbAttrLen)449 WINSCARDAPI LONG WINAPI SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
450                                        LPDWORD pcbAttrLen)
451 {
452 	SCARDAPI_STUB_CALL_LONG(SCardGetAttrib, hCard, dwAttrId, pbAttr, pcbAttrLen);
453 }
454 
SCardSetAttrib(SCARDHANDLE hCard,DWORD dwAttrId,LPCBYTE pbAttr,DWORD cbAttrLen)455 WINSCARDAPI LONG WINAPI SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
456                                        DWORD cbAttrLen)
457 {
458 	SCARDAPI_STUB_CALL_LONG(SCardSetAttrib, hCard, dwAttrId, pbAttr, cbAttrLen);
459 }
460 
SCardUIDlgSelectCardA(LPOPENCARDNAMEA_EX pDlgStruc)461 WINSCARDAPI LONG WINAPI SCardUIDlgSelectCardA(LPOPENCARDNAMEA_EX pDlgStruc)
462 {
463 	SCARDAPI_STUB_CALL_LONG(SCardUIDlgSelectCardA, pDlgStruc);
464 }
465 
SCardUIDlgSelectCardW(LPOPENCARDNAMEW_EX pDlgStruc)466 WINSCARDAPI LONG WINAPI SCardUIDlgSelectCardW(LPOPENCARDNAMEW_EX pDlgStruc)
467 {
468 	SCARDAPI_STUB_CALL_LONG(SCardUIDlgSelectCardW, pDlgStruc);
469 }
470 
GetOpenCardNameA(LPOPENCARDNAMEA pDlgStruc)471 WINSCARDAPI LONG WINAPI GetOpenCardNameA(LPOPENCARDNAMEA pDlgStruc)
472 {
473 	SCARDAPI_STUB_CALL_LONG(GetOpenCardNameA, pDlgStruc);
474 }
475 
GetOpenCardNameW(LPOPENCARDNAMEW pDlgStruc)476 WINSCARDAPI LONG WINAPI GetOpenCardNameW(LPOPENCARDNAMEW pDlgStruc)
477 {
478 	SCARDAPI_STUB_CALL_LONG(GetOpenCardNameW, pDlgStruc);
479 }
480 
SCardDlgExtendedError(void)481 WINSCARDAPI LONG WINAPI SCardDlgExtendedError(void)
482 {
483 	SCARDAPI_STUB_CALL_LONG(SCardDlgExtendedError);
484 }
485 
SCardReadCacheA(SCARDCONTEXT hContext,UUID * CardIdentifier,DWORD FreshnessCounter,LPSTR LookupName,PBYTE Data,DWORD * DataLen)486 WINSCARDAPI LONG WINAPI SCardReadCacheA(SCARDCONTEXT hContext, UUID* CardIdentifier,
487                                         DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data,
488                                         DWORD* DataLen)
489 {
490 	SCARDAPI_STUB_CALL_LONG(SCardReadCacheA, hContext, CardIdentifier, FreshnessCounter, LookupName,
491 	                        Data, DataLen);
492 }
493 
SCardReadCacheW(SCARDCONTEXT hContext,UUID * CardIdentifier,DWORD FreshnessCounter,LPWSTR LookupName,PBYTE Data,DWORD * DataLen)494 WINSCARDAPI LONG WINAPI SCardReadCacheW(SCARDCONTEXT hContext, UUID* CardIdentifier,
495                                         DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data,
496                                         DWORD* DataLen)
497 {
498 	SCARDAPI_STUB_CALL_LONG(SCardReadCacheW, hContext, CardIdentifier, FreshnessCounter, LookupName,
499 	                        Data, DataLen);
500 }
501 
SCardWriteCacheA(SCARDCONTEXT hContext,UUID * CardIdentifier,DWORD FreshnessCounter,LPSTR LookupName,PBYTE Data,DWORD DataLen)502 WINSCARDAPI LONG WINAPI SCardWriteCacheA(SCARDCONTEXT hContext, UUID* CardIdentifier,
503                                          DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data,
504                                          DWORD DataLen)
505 {
506 	SCARDAPI_STUB_CALL_LONG(SCardWriteCacheA, hContext, CardIdentifier, FreshnessCounter,
507 	                        LookupName, Data, DataLen);
508 }
509 
SCardWriteCacheW(SCARDCONTEXT hContext,UUID * CardIdentifier,DWORD FreshnessCounter,LPWSTR LookupName,PBYTE Data,DWORD DataLen)510 WINSCARDAPI LONG WINAPI SCardWriteCacheW(SCARDCONTEXT hContext, UUID* CardIdentifier,
511                                          DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data,
512                                          DWORD DataLen)
513 {
514 	SCARDAPI_STUB_CALL_LONG(SCardWriteCacheW, hContext, CardIdentifier, FreshnessCounter,
515 	                        LookupName, Data, DataLen);
516 }
517 
SCardGetReaderIconA(SCARDCONTEXT hContext,LPCSTR szReaderName,LPBYTE pbIcon,LPDWORD pcbIcon)518 WINSCARDAPI LONG WINAPI SCardGetReaderIconA(SCARDCONTEXT hContext, LPCSTR szReaderName,
519                                             LPBYTE pbIcon, LPDWORD pcbIcon)
520 {
521 	SCARDAPI_STUB_CALL_LONG(SCardGetReaderIconA, hContext, szReaderName, pbIcon, pcbIcon);
522 }
523 
SCardGetReaderIconW(SCARDCONTEXT hContext,LPCWSTR szReaderName,LPBYTE pbIcon,LPDWORD pcbIcon)524 WINSCARDAPI LONG WINAPI SCardGetReaderIconW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
525                                             LPBYTE pbIcon, LPDWORD pcbIcon)
526 {
527 	SCARDAPI_STUB_CALL_LONG(SCardGetReaderIconW, hContext, szReaderName, pbIcon, pcbIcon);
528 }
529 
SCardGetDeviceTypeIdA(SCARDCONTEXT hContext,LPCSTR szReaderName,LPDWORD pdwDeviceTypeId)530 WINSCARDAPI LONG WINAPI SCardGetDeviceTypeIdA(SCARDCONTEXT hContext, LPCSTR szReaderName,
531                                               LPDWORD pdwDeviceTypeId)
532 {
533 	SCARDAPI_STUB_CALL_LONG(SCardGetDeviceTypeIdA, hContext, szReaderName, pdwDeviceTypeId);
534 }
535 
SCardGetDeviceTypeIdW(SCARDCONTEXT hContext,LPCWSTR szReaderName,LPDWORD pdwDeviceTypeId)536 WINSCARDAPI LONG WINAPI SCardGetDeviceTypeIdW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
537                                               LPDWORD pdwDeviceTypeId)
538 {
539 	SCARDAPI_STUB_CALL_LONG(SCardGetDeviceTypeIdW, hContext, szReaderName, pdwDeviceTypeId);
540 }
541 
SCardGetReaderDeviceInstanceIdA(SCARDCONTEXT hContext,LPCSTR szReaderName,LPSTR szDeviceInstanceId,LPDWORD pcchDeviceInstanceId)542 WINSCARDAPI LONG WINAPI SCardGetReaderDeviceInstanceIdA(SCARDCONTEXT hContext, LPCSTR szReaderName,
543                                                         LPSTR szDeviceInstanceId,
544                                                         LPDWORD pcchDeviceInstanceId)
545 {
546 	SCARDAPI_STUB_CALL_LONG(SCardGetReaderDeviceInstanceIdA, hContext, szReaderName,
547 	                        szDeviceInstanceId, pcchDeviceInstanceId);
548 }
549 
SCardGetReaderDeviceInstanceIdW(SCARDCONTEXT hContext,LPCWSTR szReaderName,LPWSTR szDeviceInstanceId,LPDWORD pcchDeviceInstanceId)550 WINSCARDAPI LONG WINAPI SCardGetReaderDeviceInstanceIdW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
551                                                         LPWSTR szDeviceInstanceId,
552                                                         LPDWORD pcchDeviceInstanceId)
553 {
554 	SCARDAPI_STUB_CALL_LONG(SCardGetReaderDeviceInstanceIdW, hContext, szReaderName,
555 	                        szDeviceInstanceId, pcchDeviceInstanceId);
556 }
557 
SCardListReadersWithDeviceInstanceIdA(SCARDCONTEXT hContext,LPCSTR szDeviceInstanceId,LPSTR mszReaders,LPDWORD pcchReaders)558 WINSCARDAPI LONG WINAPI SCardListReadersWithDeviceInstanceIdA(SCARDCONTEXT hContext,
559                                                               LPCSTR szDeviceInstanceId,
560                                                               LPSTR mszReaders, LPDWORD pcchReaders)
561 {
562 	SCARDAPI_STUB_CALL_LONG(SCardListReadersWithDeviceInstanceIdA, hContext, szDeviceInstanceId,
563 	                        mszReaders, pcchReaders);
564 }
565 
SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hContext,LPCWSTR szDeviceInstanceId,LPWSTR mszReaders,LPDWORD pcchReaders)566 WINSCARDAPI LONG WINAPI SCardListReadersWithDeviceInstanceIdW(SCARDCONTEXT hContext,
567                                                               LPCWSTR szDeviceInstanceId,
568                                                               LPWSTR mszReaders,
569                                                               LPDWORD pcchReaders)
570 {
571 	SCARDAPI_STUB_CALL_LONG(SCardListReadersWithDeviceInstanceIdW, hContext, szDeviceInstanceId,
572 	                        mszReaders, pcchReaders);
573 }
574 
SCardAudit(SCARDCONTEXT hContext,DWORD dwEvent)575 WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent)
576 {
577 	SCARDAPI_STUB_CALL_LONG(SCardAudit, hContext, dwEvent);
578 }
579 
580 /**
581  * Extended API
582  */
583 
SCardGetErrorString(LONG errorCode)584 WINSCARDAPI const char* WINAPI SCardGetErrorString(LONG errorCode)
585 {
586 	switch (errorCode)
587 	{
588 		case SCARD_S_SUCCESS:
589 			return "SCARD_S_SUCCESS";
590 
591 		case SCARD_F_INTERNAL_ERROR:
592 			return "SCARD_F_INTERNAL_ERROR";
593 
594 		case SCARD_E_CANCELLED:
595 			return "SCARD_E_CANCELLED";
596 
597 		case SCARD_E_INVALID_HANDLE:
598 			return "SCARD_E_INVALID_HANDLE";
599 
600 		case SCARD_E_INVALID_PARAMETER:
601 			return "SCARD_E_INVALID_PARAMETER";
602 
603 		case SCARD_E_INVALID_TARGET:
604 			return "SCARD_E_INVALID_TARGET";
605 
606 		case SCARD_E_NO_MEMORY:
607 			return "SCARD_E_NO_MEMORY";
608 
609 		case SCARD_F_WAITED_TOO_LONG:
610 			return "SCARD_F_WAITED_TOO_LONG";
611 
612 		case SCARD_E_INSUFFICIENT_BUFFER:
613 			return "SCARD_E_INSUFFICIENT_BUFFER";
614 
615 		case SCARD_E_UNKNOWN_READER:
616 			return "SCARD_E_UNKNOWN_READER";
617 
618 		case SCARD_E_TIMEOUT:
619 			return "SCARD_E_TIMEOUT";
620 
621 		case SCARD_E_SHARING_VIOLATION:
622 			return "SCARD_E_SHARING_VIOLATION";
623 
624 		case SCARD_E_NO_SMARTCARD:
625 			return "SCARD_E_NO_SMARTCARD";
626 
627 		case SCARD_E_UNKNOWN_CARD:
628 			return "SCARD_E_UNKNOWN_CARD";
629 
630 		case SCARD_E_CANT_DISPOSE:
631 			return "SCARD_E_CANT_DISPOSE";
632 
633 		case SCARD_E_PROTO_MISMATCH:
634 			return "SCARD_E_PROTO_MISMATCH";
635 
636 		case SCARD_E_NOT_READY:
637 			return "SCARD_E_NOT_READY";
638 
639 		case SCARD_E_INVALID_VALUE:
640 			return "SCARD_E_INVALID_VALUE";
641 
642 		case SCARD_E_SYSTEM_CANCELLED:
643 			return "SCARD_E_SYSTEM_CANCELLED";
644 
645 		case SCARD_F_COMM_ERROR:
646 			return "SCARD_F_COMM_ERROR";
647 
648 		case SCARD_F_UNKNOWN_ERROR:
649 			return "SCARD_F_UNKNOWN_ERROR";
650 
651 		case SCARD_E_INVALID_ATR:
652 			return "SCARD_E_INVALID_ATR";
653 
654 		case SCARD_E_NOT_TRANSACTED:
655 			return "SCARD_E_NOT_TRANSACTED";
656 
657 		case SCARD_E_READER_UNAVAILABLE:
658 			return "SCARD_E_READER_UNAVAILABLE";
659 
660 		case SCARD_P_SHUTDOWN:
661 			return "SCARD_P_SHUTDOWN";
662 
663 		case SCARD_E_PCI_TOO_SMALL:
664 			return "SCARD_E_PCI_TOO_SMALL";
665 
666 		case SCARD_E_READER_UNSUPPORTED:
667 			return "SCARD_E_READER_UNSUPPORTED";
668 
669 		case SCARD_E_DUPLICATE_READER:
670 			return "SCARD_E_DUPLICATE_READER";
671 
672 		case SCARD_E_CARD_UNSUPPORTED:
673 			return "SCARD_E_CARD_UNSUPPORTED";
674 
675 		case SCARD_E_NO_SERVICE:
676 			return "SCARD_E_NO_SERVICE";
677 
678 		case SCARD_E_SERVICE_STOPPED:
679 			return "SCARD_E_SERVICE_STOPPED";
680 
681 		case SCARD_E_UNEXPECTED:
682 			return "SCARD_E_UNEXPECTED";
683 
684 		case SCARD_E_ICC_INSTALLATION:
685 			return "SCARD_E_ICC_INSTALLATION";
686 
687 		case SCARD_E_ICC_CREATEORDER:
688 			return "SCARD_E_ICC_CREATEORDER";
689 
690 		case SCARD_E_UNSUPPORTED_FEATURE:
691 			return "SCARD_E_UNSUPPORTED_FEATURE";
692 
693 		case SCARD_E_DIR_NOT_FOUND:
694 			return "SCARD_E_DIR_NOT_FOUND";
695 
696 		case SCARD_E_FILE_NOT_FOUND:
697 			return "SCARD_E_FILE_NOT_FOUND";
698 
699 		case SCARD_E_NO_DIR:
700 			return "SCARD_E_NO_DIR";
701 
702 		case SCARD_E_NO_FILE:
703 			return "SCARD_E_NO_FILE";
704 
705 		case SCARD_E_NO_ACCESS:
706 			return "SCARD_E_NO_ACCESS";
707 
708 		case SCARD_E_WRITE_TOO_MANY:
709 			return "SCARD_E_WRITE_TOO_MANY";
710 
711 		case SCARD_E_BAD_SEEK:
712 			return "SCARD_E_BAD_SEEK";
713 
714 		case SCARD_E_INVALID_CHV:
715 			return "SCARD_E_INVALID_CHV";
716 
717 		case SCARD_E_UNKNOWN_RES_MNG:
718 			return "SCARD_E_UNKNOWN_RES_MNG";
719 
720 		case SCARD_E_NO_SUCH_CERTIFICATE:
721 			return "SCARD_E_NO_SUCH_CERTIFICATE";
722 
723 		case SCARD_E_CERTIFICATE_UNAVAILABLE:
724 			return "SCARD_E_CERTIFICATE_UNAVAILABLE";
725 
726 		case SCARD_E_NO_READERS_AVAILABLE:
727 			return "SCARD_E_NO_READERS_AVAILABLE";
728 
729 		case SCARD_E_COMM_DATA_LOST:
730 			return "SCARD_E_COMM_DATA_LOST";
731 
732 		case SCARD_E_NO_KEY_CONTAINER:
733 			return "SCARD_E_NO_KEY_CONTAINER";
734 
735 		case SCARD_E_SERVER_TOO_BUSY:
736 			return "SCARD_E_SERVER_TOO_BUSY";
737 
738 		case SCARD_E_PIN_CACHE_EXPIRED:
739 			return "SCARD_E_PIN_CACHE_EXPIRED";
740 
741 		case SCARD_E_NO_PIN_CACHE:
742 			return "SCARD_E_NO_PIN_CACHE";
743 
744 		case SCARD_E_READ_ONLY_CARD:
745 			return "SCARD_E_READ_ONLY_CARD";
746 
747 		case SCARD_W_UNSUPPORTED_CARD:
748 			return "SCARD_W_UNSUPPORTED_CARD";
749 
750 		case SCARD_W_UNRESPONSIVE_CARD:
751 			return "SCARD_W_UNRESPONSIVE_CARD";
752 
753 		case SCARD_W_UNPOWERED_CARD:
754 			return "SCARD_W_UNPOWERED_CARD";
755 
756 		case SCARD_W_RESET_CARD:
757 			return "SCARD_W_RESET_CARD";
758 
759 		case SCARD_W_REMOVED_CARD:
760 			return "SCARD_W_REMOVED_CARD";
761 
762 		case SCARD_W_SECURITY_VIOLATION:
763 			return "SCARD_W_SECURITY_VIOLATION";
764 
765 		case SCARD_W_WRONG_CHV:
766 			return "SCARD_W_WRONG_CHV";
767 
768 		case SCARD_W_CHV_BLOCKED:
769 			return "SCARD_W_CHV_BLOCKED";
770 
771 		case SCARD_W_EOF:
772 			return "SCARD_W_EOF";
773 
774 		case SCARD_W_CANCELLED_BY_USER:
775 			return "SCARD_W_CANCELLED_BY_USER";
776 
777 		case SCARD_W_CARD_NOT_AUTHENTICATED:
778 			return "SCARD_W_CARD_NOT_AUTHENTICATED";
779 
780 		case SCARD_W_CACHE_ITEM_NOT_FOUND:
781 			return "SCARD_W_CACHE_ITEM_NOT_FOUND";
782 
783 		case SCARD_W_CACHE_ITEM_STALE:
784 			return "SCARD_W_CACHE_ITEM_STALE";
785 
786 		case SCARD_W_CACHE_ITEM_TOO_BIG:
787 			return "SCARD_W_CACHE_ITEM_TOO_BIG";
788 
789 		default:
790 			return "SCARD_E_UNKNOWN";
791 	}
792 }
793 
SCardGetAttributeString(DWORD dwAttrId)794 WINSCARDAPI const char* WINAPI SCardGetAttributeString(DWORD dwAttrId)
795 {
796 	switch (dwAttrId)
797 	{
798 		case SCARD_ATTR_VENDOR_NAME:
799 			return "SCARD_ATTR_VENDOR_NAME";
800 
801 		case SCARD_ATTR_VENDOR_IFD_TYPE:
802 			return "SCARD_ATTR_VENDOR_IFD_TYPE";
803 
804 		case SCARD_ATTR_VENDOR_IFD_VERSION:
805 			return "SCARD_ATTR_VENDOR_IFD_VERSION";
806 
807 		case SCARD_ATTR_VENDOR_IFD_SERIAL_NO:
808 			return "SCARD_ATTR_VENDOR_IFD_SERIAL_NO";
809 
810 		case SCARD_ATTR_CHANNEL_ID:
811 			return "SCARD_ATTR_CHANNEL_ID";
812 
813 		case SCARD_ATTR_PROTOCOL_TYPES:
814 			return "SCARD_ATTR_PROTOCOL_TYPES";
815 
816 		case SCARD_ATTR_DEFAULT_CLK:
817 			return "SCARD_ATTR_DEFAULT_CLK";
818 
819 		case SCARD_ATTR_MAX_CLK:
820 			return "SCARD_ATTR_MAX_CLK";
821 
822 		case SCARD_ATTR_DEFAULT_DATA_RATE:
823 			return "SCARD_ATTR_DEFAULT_DATA_RATE";
824 
825 		case SCARD_ATTR_MAX_DATA_RATE:
826 			return "SCARD_ATTR_MAX_DATA_RATE";
827 
828 		case SCARD_ATTR_MAX_IFSD:
829 			return "SCARD_ATTR_MAX_IFSD";
830 
831 		case SCARD_ATTR_POWER_MGMT_SUPPORT:
832 			return "SCARD_ATTR_POWER_MGMT_SUPPORT";
833 
834 		case SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE:
835 			return "SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE";
836 
837 		case SCARD_ATTR_USER_AUTH_INPUT_DEVICE:
838 			return "SCARD_ATTR_USER_AUTH_INPUT_DEVICE";
839 
840 		case SCARD_ATTR_CHARACTERISTICS:
841 			return "SCARD_ATTR_CHARACTERISTICS";
842 
843 		case SCARD_ATTR_CURRENT_PROTOCOL_TYPE:
844 			return "SCARD_ATTR_CURRENT_PROTOCOL_TYPE";
845 
846 		case SCARD_ATTR_CURRENT_CLK:
847 			return "SCARD_ATTR_CURRENT_CLK";
848 
849 		case SCARD_ATTR_CURRENT_F:
850 			return "SCARD_ATTR_CURRENT_F";
851 
852 		case SCARD_ATTR_CURRENT_D:
853 			return "SCARD_ATTR_CURRENT_D";
854 
855 		case SCARD_ATTR_CURRENT_N:
856 			return "SCARD_ATTR_CURRENT_N";
857 
858 		case SCARD_ATTR_CURRENT_W:
859 			return "SCARD_ATTR_CURRENT_W";
860 
861 		case SCARD_ATTR_CURRENT_IFSC:
862 			return "SCARD_ATTR_CURRENT_IFSC";
863 
864 		case SCARD_ATTR_CURRENT_IFSD:
865 			return "SCARD_ATTR_CURRENT_IFSD";
866 
867 		case SCARD_ATTR_CURRENT_BWT:
868 			return "SCARD_ATTR_CURRENT_BWT";
869 
870 		case SCARD_ATTR_CURRENT_CWT:
871 			return "SCARD_ATTR_CURRENT_CWT";
872 
873 		case SCARD_ATTR_CURRENT_EBC_ENCODING:
874 			return "SCARD_ATTR_CURRENT_EBC_ENCODING";
875 
876 		case SCARD_ATTR_EXTENDED_BWT:
877 			return "SCARD_ATTR_EXTENDED_BWT";
878 
879 		case SCARD_ATTR_ICC_PRESENCE:
880 			return "SCARD_ATTR_ICC_PRESENCE";
881 
882 		case SCARD_ATTR_ICC_INTERFACE_STATUS:
883 			return "SCARD_ATTR_ICC_INTERFACE_STATUS";
884 
885 		case SCARD_ATTR_CURRENT_IO_STATE:
886 			return "SCARD_ATTR_CURRENT_IO_STATE";
887 
888 		case SCARD_ATTR_ATR_STRING:
889 			return "SCARD_ATTR_ATR_STRING";
890 
891 		case SCARD_ATTR_ICC_TYPE_PER_ATR:
892 			return "SCARD_ATTR_ICC_TYPE_PER_ATR";
893 
894 		case SCARD_ATTR_ESC_RESET:
895 			return "SCARD_ATTR_ESC_RESET";
896 
897 		case SCARD_ATTR_ESC_CANCEL:
898 			return "SCARD_ATTR_ESC_CANCEL";
899 
900 		case SCARD_ATTR_ESC_AUTHREQUEST:
901 			return "SCARD_ATTR_ESC_AUTHREQUEST";
902 
903 		case SCARD_ATTR_MAXINPUT:
904 			return "SCARD_ATTR_MAXINPUT";
905 
906 		case SCARD_ATTR_DEVICE_UNIT:
907 			return "SCARD_ATTR_DEVICE_UNIT";
908 
909 		case SCARD_ATTR_DEVICE_IN_USE:
910 			return "SCARD_ATTR_DEVICE_IN_USE";
911 
912 		case SCARD_ATTR_DEVICE_FRIENDLY_NAME_A:
913 			return "SCARD_ATTR_DEVICE_FRIENDLY_NAME_A";
914 
915 		case SCARD_ATTR_DEVICE_SYSTEM_NAME_A:
916 			return "SCARD_ATTR_DEVICE_SYSTEM_NAME_A";
917 
918 		case SCARD_ATTR_DEVICE_FRIENDLY_NAME_W:
919 			return "SCARD_ATTR_DEVICE_FRIENDLY_NAME_W";
920 
921 		case SCARD_ATTR_DEVICE_SYSTEM_NAME_W:
922 			return "SCARD_ATTR_DEVICE_SYSTEM_NAME_W";
923 
924 		case SCARD_ATTR_SUPRESS_T1_IFS_REQUEST:
925 			return "SCARD_ATTR_SUPRESS_T1_IFS_REQUEST";
926 
927 		default:
928 			return "SCARD_ATTR_UNKNOWN";
929 	}
930 }
931 
SCardGetProtocolString(DWORD dwProtocols)932 WINSCARDAPI const char* WINAPI SCardGetProtocolString(DWORD dwProtocols)
933 {
934 	if (dwProtocols == SCARD_PROTOCOL_UNDEFINED)
935 		return "SCARD_PROTOCOL_UNDEFINED";
936 
937 	if (dwProtocols == SCARD_PROTOCOL_T0)
938 		return "SCARD_PROTOCOL_T0";
939 
940 	if (dwProtocols == SCARD_PROTOCOL_T1)
941 		return "SCARD_PROTOCOL_T1";
942 
943 	if (dwProtocols == SCARD_PROTOCOL_Tx)
944 		return "SCARD_PROTOCOL_Tx";
945 
946 	if (dwProtocols == SCARD_PROTOCOL_RAW)
947 		return "SCARD_PROTOCOL_RAW";
948 
949 	if (dwProtocols == SCARD_PROTOCOL_DEFAULT)
950 		return "SCARD_PROTOCOL_DEFAULT";
951 
952 	if (dwProtocols == (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_RAW))
953 		return "SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_RAW";
954 
955 	if (dwProtocols == (SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_RAW))
956 		return "SCARD_PROTOCOL_T1 | SCARD_PROTOCOL_RAW";
957 
958 	if (dwProtocols == (SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW))
959 		return "SCARD_PROTOCOL_Tx | SCARD_PROTOCOL_RAW";
960 
961 	return "SCARD_PROTOCOL_UNKNOWN";
962 }
963 
SCardGetShareModeString(DWORD dwShareMode)964 WINSCARDAPI const char* WINAPI SCardGetShareModeString(DWORD dwShareMode)
965 {
966 	switch (dwShareMode)
967 	{
968 		case SCARD_SHARE_EXCLUSIVE:
969 			return "SCARD_SHARE_EXCLUSIVE";
970 
971 		case SCARD_SHARE_SHARED:
972 			return "SCARD_SHARE_SHARED";
973 
974 		case SCARD_SHARE_DIRECT:
975 			return "SCARD_SHARE_DIRECT";
976 
977 		default:
978 			return "SCARD_SHARE_UNKNOWN";
979 	}
980 }
981 
SCardGetDispositionString(DWORD dwDisposition)982 WINSCARDAPI const char* WINAPI SCardGetDispositionString(DWORD dwDisposition)
983 {
984 	switch (dwDisposition)
985 	{
986 		case SCARD_LEAVE_CARD:
987 			return "SCARD_LEAVE_CARD";
988 
989 		case SCARD_RESET_CARD:
990 			return "SCARD_RESET_CARD";
991 
992 		case SCARD_UNPOWER_CARD:
993 			return "SCARD_UNPOWER_CARD";
994 
995 		default:
996 			return "SCARD_UNKNOWN_CARD";
997 	}
998 }
999 
SCardGetScopeString(DWORD dwScope)1000 WINSCARDAPI const char* WINAPI SCardGetScopeString(DWORD dwScope)
1001 {
1002 	switch (dwScope)
1003 	{
1004 		case SCARD_SCOPE_USER:
1005 			return "SCARD_SCOPE_USER";
1006 
1007 		case SCARD_SCOPE_TERMINAL:
1008 			return "SCARD_SCOPE_TERMINAL";
1009 
1010 		case SCARD_SCOPE_SYSTEM:
1011 			return "SCARD_SCOPE_SYSTEM";
1012 
1013 		default:
1014 			return "SCARD_SCOPE_UNKNOWN";
1015 	}
1016 }
1017 
SCardGetCardStateString(DWORD dwCardState)1018 WINSCARDAPI const char* WINAPI SCardGetCardStateString(DWORD dwCardState)
1019 {
1020 	switch (dwCardState)
1021 	{
1022 		case SCARD_UNKNOWN:
1023 			return "SCARD_UNKNOWN";
1024 
1025 		case SCARD_ABSENT:
1026 			return "SCARD_ABSENT";
1027 
1028 		case SCARD_PRESENT:
1029 			return "SCARD_PRESENT";
1030 
1031 		case SCARD_SWALLOWED:
1032 			return "SCARD_SWALLOWED";
1033 
1034 		case SCARD_POWERED:
1035 			return "SCARD_POWERED";
1036 
1037 		case SCARD_NEGOTIABLE:
1038 			return "SCARD_NEGOTIABLE";
1039 
1040 		case SCARD_SPECIFIC:
1041 			return "SCARD_SPECIFIC";
1042 
1043 		default:
1044 			return "SCARD_UNKNOWN";
1045 	}
1046 }
1047 
SCardGetReaderStateString(DWORD dwReaderState)1048 WINSCARDAPI char* WINAPI SCardGetReaderStateString(DWORD dwReaderState)
1049 {
1050 	char* szReaderState = malloc(512);
1051 
1052 	if (!szReaderState)
1053 		return NULL;
1054 
1055 	szReaderState[0] = '\0';
1056 
1057 	if (dwReaderState & SCARD_STATE_IGNORE)
1058 	{
1059 		if (szReaderState[0])
1060 			strcat(szReaderState, " | ");
1061 
1062 		strcat(szReaderState, "SCARD_STATE_IGNORE");
1063 	}
1064 
1065 	if (dwReaderState & SCARD_STATE_CHANGED)
1066 	{
1067 		if (szReaderState[0])
1068 			strcat(szReaderState, " | ");
1069 
1070 		strcat(szReaderState, "SCARD_STATE_CHANGED");
1071 	}
1072 
1073 	if (dwReaderState & SCARD_STATE_UNKNOWN)
1074 	{
1075 		if (szReaderState[0])
1076 			strcat(szReaderState, " | ");
1077 
1078 		strcat(szReaderState, "SCARD_STATE_UNKNOWN");
1079 	}
1080 
1081 	if (dwReaderState & SCARD_STATE_UNAVAILABLE)
1082 	{
1083 		if (szReaderState[0])
1084 			strcat(szReaderState, " | ");
1085 
1086 		strcat(szReaderState, "SCARD_STATE_UNAVAILABLE");
1087 	}
1088 
1089 	if (dwReaderState & SCARD_STATE_EMPTY)
1090 	{
1091 		if (szReaderState[0])
1092 			strcat(szReaderState, " | ");
1093 
1094 		strcat(szReaderState, "SCARD_STATE_EMPTY");
1095 	}
1096 
1097 	if (dwReaderState & SCARD_STATE_PRESENT)
1098 	{
1099 		if (szReaderState[0])
1100 			strcat(szReaderState, " | ");
1101 
1102 		strcat(szReaderState, "SCARD_STATE_PRESENT");
1103 	}
1104 
1105 	if (dwReaderState & SCARD_STATE_ATRMATCH)
1106 	{
1107 		if (szReaderState[0])
1108 			strcat(szReaderState, " | ");
1109 
1110 		strcat(szReaderState, "SCARD_STATE_ATRMATCH");
1111 	}
1112 
1113 	if (dwReaderState & SCARD_STATE_EXCLUSIVE)
1114 	{
1115 		if (szReaderState[0])
1116 			strcat(szReaderState, " | ");
1117 
1118 		strcat(szReaderState, "SCARD_STATE_EXCLUSIVE");
1119 	}
1120 
1121 	if (dwReaderState & SCARD_STATE_INUSE)
1122 	{
1123 		if (szReaderState[0])
1124 			strcat(szReaderState, " | ");
1125 
1126 		strcat(szReaderState, "SCARD_STATE_INUSE");
1127 	}
1128 
1129 	if (dwReaderState & SCARD_STATE_MUTE)
1130 	{
1131 		if (szReaderState[0])
1132 			strcat(szReaderState, " | ");
1133 
1134 		strcat(szReaderState, "SCARD_STATE_MUTE");
1135 	}
1136 
1137 	if (dwReaderState & SCARD_STATE_UNPOWERED)
1138 	{
1139 		if (szReaderState[0])
1140 			strcat(szReaderState, " | ");
1141 
1142 		strcat(szReaderState, "SCARD_STATE_UNPOWERED");
1143 	}
1144 
1145 	if (!szReaderState[0])
1146 		strcat(szReaderState, "SCARD_STATE_UNAWARE");
1147 
1148 	return szReaderState;
1149 }
1150