22 #include <winpr/config.h>
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <sys/sysctl.h>
38 #include <winpr/crt.h>
39 #include <winpr/assert.h>
40 #include <winpr/synch.h>
41 #include <winpr/library.h>
42 #include <winpr/smartcard.h>
43 #include <winpr/collections.h>
44 #include <winpr/environment.h>
46 #include "smartcard_pcsc.h"
49 #define TAG WINPR_TAG("smartcard")
51 #define WINSCARD_LOAD_PROC_EX(module, pcsc, _fname, _name) \
54 WINPR_PRAGMA_DIAG_PUSH \
55 WINPR_PRAGMA_DIAG_IGNORED_PEDANTIC \
56 pcsc.pfn##_fname = GetProcAddressAs(module, #_name, fnPCSC##_fname); \
57 WINPR_PRAGMA_DIAG_POP \
60 #define WINSCARD_LOAD_PROC(module, pcsc, _name) WINSCARD_LOAD_PROC_EX(module, pcsc, _name, _name)
125 #include "smartcard_pcsc.h"
127 #define PCSC_SCARD_PCI_T0 (&g_PCSC_rgSCardT0Pci)
128 #define PCSC_SCARD_PCI_T1 (&g_PCSC_rgSCardT1Pci)
129 #define PCSC_SCARD_PCI_RAW (&g_PCSC_rgSCardRawPci)
131 typedef PCSC_LONG (*fnPCSCSCardEstablishContext)(PCSC_DWORD dwScope, LPCVOID pvReserved1,
132 LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
133 typedef PCSC_LONG (*fnPCSCSCardReleaseContext)(SCARDCONTEXT hContext);
134 typedef PCSC_LONG (*fnPCSCSCardIsValidContext)(SCARDCONTEXT hContext);
135 typedef PCSC_LONG (*fnPCSCSCardConnect)(SCARDCONTEXT hContext, LPCSTR szReader,
136 PCSC_DWORD dwShareMode, PCSC_DWORD dwPreferredProtocols,
137 LPSCARDHANDLE phCard, PCSC_LPDWORD pdwActiveProtocol);
138 typedef PCSC_LONG (*fnPCSCSCardReconnect)(SCARDHANDLE hCard, PCSC_DWORD dwShareMode,
139 PCSC_DWORD dwPreferredProtocols,
140 PCSC_DWORD dwInitialization,
141 PCSC_LPDWORD pdwActiveProtocol);
142 typedef PCSC_LONG (*fnPCSCSCardDisconnect)(SCARDHANDLE hCard, PCSC_DWORD dwDisposition);
143 typedef PCSC_LONG (*fnPCSCSCardBeginTransaction)(SCARDHANDLE hCard);
144 typedef PCSC_LONG (*fnPCSCSCardEndTransaction)(SCARDHANDLE hCard, PCSC_DWORD dwDisposition);
145 typedef PCSC_LONG (*fnPCSCSCardStatus)(SCARDHANDLE hCard, LPSTR mszReaderName,
146 PCSC_LPDWORD pcchReaderLen, PCSC_LPDWORD pdwState,
147 PCSC_LPDWORD pdwProtocol, LPBYTE pbAtr,
148 PCSC_LPDWORD pcbAtrLen);
149 typedef PCSC_LONG (*fnPCSCSCardGetStatusChange)(SCARDCONTEXT hContext, PCSC_DWORD dwTimeout,
151 PCSC_DWORD cReaders);
152 typedef PCSC_LONG (*fnPCSCSCardControl)(SCARDHANDLE hCard, PCSC_DWORD dwControlCode,
153 LPCVOID pbSendBuffer, PCSC_DWORD cbSendLength,
154 LPVOID pbRecvBuffer, PCSC_DWORD cbRecvLength,
155 PCSC_LPDWORD lpBytesReturned);
157 LPCBYTE pbSendBuffer, PCSC_DWORD cbSendLength,
159 PCSC_LPDWORD pcbRecvLength);
160 typedef PCSC_LONG (*fnPCSCSCardListReaderGroups)(SCARDCONTEXT hContext, LPSTR mszGroups,
161 PCSC_LPDWORD pcchGroups);
162 typedef PCSC_LONG (*fnPCSCSCardListReaders)(SCARDCONTEXT hContext, LPCSTR mszGroups,
163 LPSTR mszReaders, PCSC_LPDWORD pcchReaders);
164 typedef PCSC_LONG (*fnPCSCSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem);
165 typedef PCSC_LONG (*fnPCSCSCardCancel)(SCARDCONTEXT hContext);
166 typedef PCSC_LONG (*fnPCSCSCardGetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPBYTE pbAttr,
167 PCSC_LPDWORD pcbAttrLen);
168 typedef PCSC_LONG (*fnPCSCSCardSetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPCBYTE pbAttr,
169 PCSC_DWORD cbAttrLen);
173 fnPCSCSCardEstablishContext pfnSCardEstablishContext;
174 fnPCSCSCardReleaseContext pfnSCardReleaseContext;
175 fnPCSCSCardIsValidContext pfnSCardIsValidContext;
176 fnPCSCSCardConnect pfnSCardConnect;
177 fnPCSCSCardReconnect pfnSCardReconnect;
178 fnPCSCSCardDisconnect pfnSCardDisconnect;
179 fnPCSCSCardBeginTransaction pfnSCardBeginTransaction;
180 fnPCSCSCardEndTransaction pfnSCardEndTransaction;
181 fnPCSCSCardStatus pfnSCardStatus;
182 fnPCSCSCardGetStatusChange pfnSCardGetStatusChange;
183 fnPCSCSCardControl pfnSCardControl;
184 fnPCSCSCardTransmit pfnSCardTransmit;
185 fnPCSCSCardListReaderGroups pfnSCardListReaderGroups;
186 fnPCSCSCardListReaders pfnSCardListReaders;
187 fnPCSCSCardFreeMemory pfnSCardFreeMemory;
188 fnPCSCSCardCancel pfnSCardCancel;
189 fnPCSCSCardGetAttrib pfnSCardGetAttrib;
190 fnPCSCSCardSetAttrib pfnSCardSetAttrib;
204 SCARDCONTEXT hContext;
205 DWORD dwCardHandleCount;
206 BOOL isTransactionLocked;
213 SCARDCONTEXT hSharedContext;
216 static HMODULE g_PCSCModule = NULL;
217 static PCSCFunctionTable g_PCSC = { 0 };
219 static HANDLE g_StartedEvent = NULL;
220 static int g_StartedEventRefCount = 0;
222 static BOOL g_SCardAutoAllocate = FALSE;
223 static BOOL g_PnP_Notification = TRUE;
226 static unsigned int OSXVersion = 0;
229 static wListDictionary* g_CardHandles = NULL;
230 static wListDictionary* g_CardContexts = NULL;
231 static wListDictionary* g_MemoryBlocks = NULL;
233 static const char SMARTCARD_PNP_NOTIFICATION_A[] =
"\\\\?PnP?\\Notification";
242 static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPVOID pvMem);
243 static LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, LPCVOID pvReserved1,
245 LPSCARDCONTEXT phContext);
246 static LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext);
248 static LONG PCSC_SCard_LogError(
const char* what)
250 WLog_WARN(TAG,
"Missing function pointer %s=NULL", what);
251 return SCARD_E_UNSUPPORTED_FEATURE;
254 static LONG PCSC_MapErrorCodeToWinSCard(PCSC_LONG errorCode)
264 if (errorCode != SCARD_S_SUCCESS)
266 if (errorCode == SCARD_E_UNEXPECTED)
267 errorCode = SCARD_E_UNSUPPORTED_FEATURE;
270 return (LONG)errorCode;
273 static DWORD PCSC_ConvertCardStateToWinSCard(DWORD dwCardState, PCSC_LONG status)
291 if (status == SCARD_S_SUCCESS)
293 if ((dwCardState & PCSC_SCARD_NEGOTIABLE) || (dwCardState & PCSC_SCARD_SPECIFIC))
294 return SCARD_SPECIFIC;
297 if (dwCardState & PCSC_SCARD_POWERED)
298 return SCARD_POWERED;
300 if (dwCardState & PCSC_SCARD_NEGOTIABLE)
301 return SCARD_NEGOTIABLE;
303 if (dwCardState & PCSC_SCARD_SPECIFIC)
304 return SCARD_SPECIFIC;
306 if (dwCardState & PCSC_SCARD_ABSENT)
309 if (dwCardState & PCSC_SCARD_PRESENT)
310 return SCARD_PRESENT;
312 if (dwCardState & PCSC_SCARD_SWALLOWED)
313 return SCARD_SWALLOWED;
315 if (dwCardState & PCSC_SCARD_UNKNOWN)
316 return SCARD_UNKNOWN;
318 return SCARD_UNKNOWN;
321 static DWORD PCSC_ConvertProtocolsToWinSCard(PCSC_DWORD dwProtocols)
327 if (dwProtocols & PCSC_SCARD_PROTOCOL_RAW)
329 dwProtocols &= ~PCSC_SCARD_PROTOCOL_RAW;
330 dwProtocols |= SCARD_PROTOCOL_RAW;
333 if (dwProtocols & PCSC_SCARD_PROTOCOL_T15)
335 dwProtocols &= ~PCSC_SCARD_PROTOCOL_T15;
338 return (DWORD)dwProtocols;
341 static DWORD PCSC_ConvertProtocolsFromWinSCard(DWORD dwProtocols)
347 if (dwProtocols & SCARD_PROTOCOL_RAW)
349 dwProtocols &= ~SCARD_PROTOCOL_RAW;
350 dwProtocols |= PCSC_SCARD_PROTOCOL_RAW;
353 if (dwProtocols & SCARD_PROTOCOL_DEFAULT)
355 dwProtocols &= ~SCARD_PROTOCOL_DEFAULT;
358 if (dwProtocols == SCARD_PROTOCOL_UNDEFINED)
360 dwProtocols = SCARD_PROTOCOL_Tx;
366 static PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext)
368 PCSC_SCARDCONTEXT* pContext = NULL;
373 pContext = (PCSC_SCARDCONTEXT*)ListDictionary_GetItemValue(g_CardContexts, (
void*)hContext);
381 static void pcsc_cache_item_free(
void* ptr)
383 PCSC_CACHE_ITEM* data = ptr;
389 static PCSC_SCARDCONTEXT* PCSC_EstablishCardContext(SCARDCONTEXT hContext)
391 PCSC_SCARDCONTEXT* pContext = NULL;
392 pContext = (PCSC_SCARDCONTEXT*)calloc(1,
sizeof(PCSC_SCARDCONTEXT));
397 pContext->hContext = hContext;
399 if (!InitializeCriticalSectionAndSpinCount(&(pContext->lock), 4000))
402 pContext->cache = HashTable_New(FALSE);
403 if (!pContext->cache)
405 if (!HashTable_SetupForStringData(pContext->cache, FALSE))
408 wObject* obj = HashTable_ValueObject(pContext->cache);
409 obj->fnObjectFree = pcsc_cache_item_free;
414 g_CardContexts = ListDictionary_New(TRUE);
420 if (!ListDictionary_Add(g_CardContexts, (
void*)hContext, (
void*)pContext))
425 HashTable_Free(pContext->cache);
426 DeleteCriticalSection(&(pContext->lock));
432 static void PCSC_ReleaseCardContext(SCARDCONTEXT hContext)
434 PCSC_SCARDCONTEXT* pContext = NULL;
435 pContext = PCSC_GetCardContextData(hContext);
439 WLog_ERR(TAG,
"PCSC_ReleaseCardContext: null pContext!");
443 DeleteCriticalSection(&(pContext->lock));
444 HashTable_Free(pContext->cache);
450 ListDictionary_Remove(g_CardContexts, (
void*)hContext);
453 static BOOL PCSC_LockCardContext(SCARDCONTEXT hContext)
455 PCSC_SCARDCONTEXT* pContext = NULL;
456 pContext = PCSC_GetCardContextData(hContext);
460 WLog_ERR(TAG,
"PCSC_LockCardContext: invalid context (%p)", (
void*)hContext);
464 EnterCriticalSection(&(pContext->lock));
468 static BOOL PCSC_UnlockCardContext(SCARDCONTEXT hContext)
470 PCSC_SCARDCONTEXT* pContext = NULL;
471 pContext = PCSC_GetCardContextData(hContext);
475 WLog_ERR(TAG,
"PCSC_UnlockCardContext: invalid context (%p)", (
void*)hContext);
479 LeaveCriticalSection(&(pContext->lock));
483 static PCSC_SCARDHANDLE* PCSC_GetCardHandleData(SCARDHANDLE hCard)
485 PCSC_SCARDHANDLE* pCard = NULL;
490 pCard = (PCSC_SCARDHANDLE*)ListDictionary_GetItemValue(g_CardHandles, (
void*)hCard);
498 static SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard)
500 PCSC_SCARDHANDLE* pCard = NULL;
501 pCard = PCSC_GetCardHandleData(hCard);
506 return pCard->hSharedContext;
509 static BOOL PCSC_WaitForCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard, BOOL shared)
512 PCSC_SCARDHANDLE* pCard = NULL;
513 PCSC_SCARDCONTEXT* pContext = NULL;
518 pContext = PCSC_GetCardContextData(hContext);
523 if (!pContext->owner)
530 pCard = PCSC_GetCardHandleData(hCard);
535 shared = pCard->shared;
536 hContext = pCard->hSharedContext;
537 pContext = PCSC_GetCardContextData(hContext);
542 if (!pContext->owner)
546 pContext->owner = hCard;
551 if (pContext->owner == hCard)
563 static BOOL PCSC_ReleaseCardAccess(SCARDCONTEXT hContext, SCARDHANDLE hCard)
565 PCSC_SCARDHANDLE* pCard = NULL;
566 PCSC_SCARDCONTEXT* pContext = NULL;
571 pContext = PCSC_GetCardContextData(hContext);
576 hCard = pContext->owner;
581 pCard = PCSC_GetCardHandleData(hCard);
591 pCard = PCSC_GetCardHandleData(hCard);
596 hContext = pCard->hSharedContext;
597 pContext = PCSC_GetCardContextData(hContext);
602 if (pContext->owner == hCard)
611 static PCSC_SCARDHANDLE* PCSC_ConnectCardHandle(SCARDCONTEXT hSharedContext, SCARDHANDLE hCard)
613 PCSC_SCARDHANDLE* pCard = NULL;
614 PCSC_SCARDCONTEXT* pContext = NULL;
615 pContext = PCSC_GetCardContextData(hSharedContext);
619 WLog_ERR(TAG,
"PCSC_ConnectCardHandle: null pContext!");
623 pCard = (PCSC_SCARDHANDLE*)calloc(1,
sizeof(PCSC_SCARDHANDLE));
628 pCard->hSharedContext = hSharedContext;
632 g_CardHandles = ListDictionary_New(TRUE);
638 if (!ListDictionary_Add(g_CardHandles, (
void*)hCard, (
void*)pCard))
641 pContext->dwCardHandleCount++;
648 static void PCSC_DisconnectCardHandle(SCARDHANDLE hCard)
650 PCSC_SCARDHANDLE* pCard = NULL;
651 PCSC_SCARDCONTEXT* pContext = NULL;
652 pCard = PCSC_GetCardHandleData(hCard);
657 pContext = PCSC_GetCardContextData(pCard->hSharedContext);
663 ListDictionary_Remove(g_CardHandles, (
void*)hCard);
667 WLog_ERR(TAG,
"PCSC_DisconnectCardHandle: null pContext!");
671 pContext->dwCardHandleCount--;
674 static BOOL PCSC_AddMemoryBlock(SCARDCONTEXT hContext,
void* pvMem)
678 g_MemoryBlocks = ListDictionary_New(TRUE);
684 return ListDictionary_Add(g_MemoryBlocks, pvMem, (
void*)hContext);
687 static void* PCSC_RemoveMemoryBlock(SCARDCONTEXT hContext,
void* pvMem)
689 WINPR_UNUSED(hContext);
694 return ListDictionary_Take(g_MemoryBlocks, pvMem);
701 static LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, LPCVOID pvReserved1,
703 LPSCARDCONTEXT phContext)
705 WINPR_UNUSED(dwScope);
706 PCSC_LONG status = SCARD_S_SUCCESS;
708 if (!g_PCSC.pfnSCardEstablishContext)
709 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardEstablishContext");
712 g_PCSC.pfnSCardEstablishContext(SCARD_SCOPE_SYSTEM, pvReserved1, pvReserved2, phContext);
713 return PCSC_MapErrorCodeToWinSCard(status);
716 static LONG WINAPI PCSC_SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
717 LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
721 status = PCSC_SCardEstablishContext_Internal(dwScope, pvReserved1, pvReserved2, phContext);
723 if (status == SCARD_S_SUCCESS)
724 PCSC_EstablishCardContext(*phContext);
729 static LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext)
731 PCSC_LONG status = SCARD_S_SUCCESS;
733 if (!g_PCSC.pfnSCardReleaseContext)
734 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardReleaseContext");
738 WLog_ERR(TAG,
"SCardReleaseContext: null hContext");
739 return PCSC_MapErrorCodeToWinSCard(status);
742 status = g_PCSC.pfnSCardReleaseContext(hContext);
743 return PCSC_MapErrorCodeToWinSCard(status);
746 static LONG WINAPI PCSC_SCardReleaseContext(SCARDCONTEXT hContext)
748 LONG status = SCARD_S_SUCCESS;
750 status = PCSC_SCardReleaseContext_Internal(hContext);
752 if (status != SCARD_S_SUCCESS)
753 PCSC_ReleaseCardContext(hContext);
758 static LONG WINAPI PCSC_SCardIsValidContext(SCARDCONTEXT hContext)
760 PCSC_LONG status = SCARD_S_SUCCESS;
762 if (!g_PCSC.pfnSCardIsValidContext)
763 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardIsValidContext");
765 status = g_PCSC.pfnSCardIsValidContext(hContext);
766 return PCSC_MapErrorCodeToWinSCard(status);
769 static LONG WINAPI PCSC_SCardListReaderGroups_Internal(SCARDCONTEXT hContext, LPSTR mszGroups,
772 PCSC_LONG status = SCARD_S_SUCCESS;
773 BOOL pcchGroupsAlloc = FALSE;
774 PCSC_DWORD pcsc_cchGroups = 0;
777 return SCARD_E_INVALID_PARAMETER;
779 if (!g_PCSC.pfnSCardListReaderGroups)
780 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardListReaderGroups");
782 if (*pcchGroups == SCARD_AUTOALLOCATE)
783 pcchGroupsAlloc = TRUE;
785 pcsc_cchGroups = pcchGroupsAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD)*pcchGroups;
787 if (pcchGroupsAlloc && !g_SCardAutoAllocate)
790 status = g_PCSC.pfnSCardListReaderGroups(hContext, NULL, &pcsc_cchGroups);
792 if (status == SCARD_S_SUCCESS)
794 LPSTR tmp = calloc(1, pcsc_cchGroups);
797 return SCARD_E_NO_MEMORY;
799 status = g_PCSC.pfnSCardListReaderGroups(hContext, tmp, &pcsc_cchGroups);
801 if (status != SCARD_S_SUCCESS)
807 PCSC_AddMemoryBlock(hContext, tmp);
809 *(LPSTR*)mszGroups = tmp;
814 status = g_PCSC.pfnSCardListReaderGroups(hContext, mszGroups, &pcsc_cchGroups);
817 *pcchGroups = (DWORD)pcsc_cchGroups;
818 return PCSC_MapErrorCodeToWinSCard(status);
821 static LONG WINAPI PCSC_SCardListReaderGroupsA(SCARDCONTEXT hContext, LPSTR mszGroups,
824 LONG status = SCARD_S_SUCCESS;
826 if (!g_PCSC.pfnSCardListReaderGroups)
827 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardListReaderGroups");
829 if (!PCSC_LockCardContext(hContext))
830 return SCARD_E_INVALID_HANDLE;
832 status = PCSC_SCardListReaderGroups_Internal(hContext, mszGroups, pcchGroups);
834 if (!PCSC_UnlockCardContext(hContext))
835 return SCARD_E_INVALID_HANDLE;
840 static LONG WINAPI PCSC_SCardListReaderGroupsW(SCARDCONTEXT hContext, LPWSTR mszGroups,
843 LPSTR mszGroupsA = NULL;
844 LPSTR* pMszGroupsA = &mszGroupsA;
845 LONG status = SCARD_S_SUCCESS;
847 if (!g_PCSC.pfnSCardListReaderGroups)
848 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardListReaderGroups");
850 if (!PCSC_LockCardContext(hContext))
851 return SCARD_E_INVALID_HANDLE;
853 status = PCSC_SCardListReaderGroups_Internal(hContext, (LPSTR)&mszGroupsA, pcchGroups);
855 if (status == SCARD_S_SUCCESS)
858 WCHAR* str = ConvertMszUtf8NToWCharAlloc(*pMszGroupsA, *pcchGroups, &size);
860 return SCARD_E_NO_MEMORY;
861 *(WCHAR**)mszGroups = str;
862 *pcchGroups = (DWORD)size;
863 PCSC_AddMemoryBlock(hContext, str);
864 PCSC_SCardFreeMemory_Internal(hContext, *pMszGroupsA);
867 if (!PCSC_UnlockCardContext(hContext))
868 return SCARD_E_INVALID_HANDLE;
873 static LONG WINAPI PCSC_SCardListReaders_Internal(SCARDCONTEXT hContext, LPCSTR mszGroups,
874 LPSTR mszReaders, LPDWORD pcchReaders)
876 PCSC_LONG status = SCARD_S_SUCCESS;
877 BOOL pcchReadersAlloc = FALSE;
878 PCSC_DWORD pcsc_cchReaders = 0;
880 return SCARD_E_INVALID_PARAMETER;
882 if (!g_PCSC.pfnSCardListReaders)
883 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardListReaders");
887 if (*pcchReaders == SCARD_AUTOALLOCATE)
888 pcchReadersAlloc = TRUE;
890 pcsc_cchReaders = pcchReadersAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD)*pcchReaders;
892 if (pcchReadersAlloc && !g_SCardAutoAllocate)
895 status = g_PCSC.pfnSCardListReaders(hContext, mszGroups, NULL, &pcsc_cchReaders);
897 if (status == SCARD_S_SUCCESS)
899 char* tmp = calloc(1, pcsc_cchReaders);
902 return SCARD_E_NO_MEMORY;
904 status = g_PCSC.pfnSCardListReaders(hContext, mszGroups, tmp, &pcsc_cchReaders);
906 if (status != SCARD_S_SUCCESS)
912 PCSC_AddMemoryBlock(hContext, tmp);
914 *(
char**)mszReaders = tmp;
919 status = g_PCSC.pfnSCardListReaders(hContext, mszGroups, mszReaders, &pcsc_cchReaders);
922 *pcchReaders = (DWORD)pcsc_cchReaders;
923 return PCSC_MapErrorCodeToWinSCard(status);
926 static LONG WINAPI PCSC_SCardListReadersA(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
929 BOOL nullCardContext = FALSE;
930 LONG status = SCARD_S_SUCCESS;
932 if (!g_PCSC.pfnSCardListReaders)
933 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardListReaders");
937 status = PCSC_SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
939 if (status != SCARD_S_SUCCESS)
942 nullCardContext = TRUE;
945 if (!PCSC_LockCardContext(hContext))
946 return SCARD_E_INVALID_HANDLE;
948 status = PCSC_SCardListReaders_Internal(hContext, mszGroups, mszReaders, pcchReaders);
950 if (!PCSC_UnlockCardContext(hContext))
951 return SCARD_E_INVALID_HANDLE;
955 status = PCSC_SCardReleaseContext(hContext);
961 static LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext, LPCWSTR mszGroups,
962 LPWSTR mszReaders, LPDWORD pcchReaders)
964 LPSTR mszGroupsA = NULL;
965 LPSTR mszReadersA = NULL;
966 LONG status = SCARD_S_SUCCESS;
967 BOOL nullCardContext = FALSE;
969 if (!g_PCSC.pfnSCardListReaders)
970 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardListReaders");
974 status = PCSC_SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
976 if (status != SCARD_S_SUCCESS)
979 nullCardContext = TRUE;
982 if (!PCSC_LockCardContext(hContext))
983 return SCARD_E_INVALID_HANDLE;
989 mszGroupsA = ConvertWCharToUtf8Alloc(mszGroups, NULL);
991 return SCARD_E_NO_MEMORY;
999 cnv.ppc = &mszReadersA;
1001 status = PCSC_SCardListReaders_Internal(hContext, mszGroupsA, cnv.pc, pcchReaders);
1002 if (status == SCARD_S_SUCCESS)
1005 WCHAR* str = ConvertMszUtf8NToWCharAlloc(mszReadersA, *pcchReaders, &size);
1006 PCSC_SCardFreeMemory_Internal(hContext, mszReadersA);
1007 if (!str || (size > UINT32_MAX))
1010 return SCARD_E_NO_MEMORY;
1012 *(LPWSTR*)mszReaders = str;
1013 *pcchReaders = (DWORD)size;
1014 PCSC_AddMemoryBlock(hContext, str);
1019 if (!PCSC_UnlockCardContext(hContext))
1020 return SCARD_E_INVALID_HANDLE;
1022 if (nullCardContext)
1024 status = PCSC_SCardReleaseContext(hContext);
1034 const char* cardName;
1037 static PcscKnownAtr knownAtrs[] = {
1039 { { 0x3B, 0xFD, 0x13, 0x00, 0x00, 0x81, 0x31, 0xFE, 0x15, 0x80, 0x73, 0xC0,
1040 0x21, 0xC0, 0x57, 0x59, 0x75, 0x62, 0x69, 0x4B, 0x65, 0x79, 0x40 },
1042 "NIST SP 800-73 [PIV]" },
1044 { { 0x3B, 0xFC, 0x18, 0x00, 0x00, 0x81, 0x31, 0x80, 0x45, 0x90, 0x67,
1045 0x46, 0x4A, 0x00, 0x64, 0x16, 0x06, 0xF2, 0x72, 0x7E, 0x00, 0xE0 },
1047 "PIVKey Feitian (E0)" }
1050 #ifndef ARRAY_LENGTH
1051 #define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a)[0])
1054 static const char* findCardByAtr(LPCBYTE pbAtr)
1056 for (
size_t i = 0; i < ARRAY_LENGTH(knownAtrs); i++)
1058 if (memcmp(knownAtrs[i].atr, pbAtr, knownAtrs[i].atrLen) == 0)
1059 return knownAtrs[i].cardName;
1065 static LONG WINAPI PCSC_SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr,
1066 LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
1067 CHAR* mszCards, LPDWORD pcchCards)
1069 const char* cardName = NULL;
1070 DWORD outputLen = 1;
1071 CHAR* output = NULL;
1072 BOOL autoAllocate = 0;
1074 if (!pbAtr || rgquidInterfaces || cguidInterfaceCount)
1075 return SCARD_E_UNSUPPORTED_FEATURE;
1078 return SCARD_E_INVALID_PARAMETER;
1080 autoAllocate = (*pcchCards == SCARD_AUTOALLOCATE);
1082 cardName = findCardByAtr(pbAtr);
1084 outputLen += strlen(cardName) + 1;
1086 *pcchCards = outputLen;
1089 output = malloc(outputLen);
1091 return SCARD_E_NO_MEMORY;
1093 *((LPSTR*)mszCards) = output;
1098 return SCARD_S_SUCCESS;
1100 if (*pcchCards < outputLen)
1101 return SCARD_E_INSUFFICIENT_BUFFER;
1108 size_t toCopy = strlen(cardName) + 1;
1109 memcpy(output, cardName, toCopy);
1115 return SCARD_S_SUCCESS;
1118 static LONG WINAPI PCSC_SCardListCardsW(SCARDCONTEXT hContext, LPCBYTE pbAtr,
1119 LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
1120 WCHAR* mszCards, LPDWORD pcchCards)
1122 const char* cardName = NULL;
1123 DWORD outputLen = 1;
1124 WCHAR* output = NULL;
1125 BOOL autoAllocate = 0;
1127 if (!pbAtr || rgquidInterfaces || cguidInterfaceCount)
1128 return SCARD_E_UNSUPPORTED_FEATURE;
1131 return SCARD_E_INVALID_PARAMETER;
1133 autoAllocate = (*pcchCards == SCARD_AUTOALLOCATE);
1135 cardName = findCardByAtr(pbAtr);
1137 outputLen += strlen(cardName) + 1;
1139 *pcchCards = outputLen;
1142 output = calloc(outputLen,
sizeof(WCHAR));
1144 return SCARD_E_NO_MEMORY;
1146 *((LPWSTR*)mszCards) = output;
1151 return SCARD_S_SUCCESS;
1153 if (*pcchCards < outputLen)
1154 return SCARD_E_INSUFFICIENT_BUFFER;
1161 size_t toCopy = strlen(cardName) + 1;
1162 if (ConvertUtf8ToWChar(cardName, output, toCopy) < 0)
1163 return SCARD_F_INTERNAL_ERROR;
1169 return SCARD_S_SUCCESS;
1173 PCSC_SCardListInterfacesA(SCARDCONTEXT hContext, LPCSTR szCard, LPGUID pguidInterfaces,
1174 LPDWORD pcguidInterfaces )
1176 WINPR_UNUSED(hContext);
1177 WINPR_UNUSED(szCard);
1178 WINPR_UNUSED(pguidInterfaces);
1179 WINPR_UNUSED(pcguidInterfaces);
1180 return SCARD_E_UNSUPPORTED_FEATURE;
1184 PCSC_SCardListInterfacesW(SCARDCONTEXT hContext, LPCWSTR szCard, LPGUID pguidInterfaces,
1185 LPDWORD pcguidInterfaces )
1187 WINPR_UNUSED(hContext);
1188 WINPR_UNUSED(szCard);
1189 WINPR_UNUSED(pguidInterfaces);
1190 WINPR_UNUSED(pcguidInterfaces);
1191 return SCARD_E_UNSUPPORTED_FEATURE;
1194 static LONG WINAPI PCSC_SCardGetProviderIdA(SCARDCONTEXT hContext, LPCSTR szCard,
1195 LPGUID pguidProviderId)
1197 WINPR_UNUSED(hContext);
1198 WINPR_UNUSED(szCard);
1199 WINPR_UNUSED(pguidProviderId);
1200 return SCARD_E_UNSUPPORTED_FEATURE;
1203 static LONG WINAPI PCSC_SCardGetProviderIdW(SCARDCONTEXT hContext, LPCWSTR szCard,
1204 LPGUID pguidProviderId)
1206 WINPR_UNUSED(hContext);
1207 WINPR_UNUSED(szCard);
1208 WINPR_UNUSED(pguidProviderId);
1209 return SCARD_E_UNSUPPORTED_FEATURE;
1212 static LONG WINAPI PCSC_SCardGetCardTypeProviderNameA(
1213 SCARDCONTEXT hContext, LPCSTR szCardName, DWORD dwProviderId,
1215 LPDWORD pcchProvider )
1217 WINPR_UNUSED(hContext);
1218 WINPR_UNUSED(szCardName);
1219 WINPR_UNUSED(dwProviderId);
1220 WINPR_UNUSED(szProvider);
1221 WINPR_UNUSED(pcchProvider);
1222 return SCARD_E_UNSUPPORTED_FEATURE;
1225 static LONG WINAPI PCSC_SCardGetCardTypeProviderNameW(
1226 SCARDCONTEXT hContext, LPCWSTR szCardName, DWORD dwProviderId,
1228 LPDWORD pcchProvider )
1230 WINPR_UNUSED(hContext);
1231 WINPR_UNUSED(szCardName);
1232 WINPR_UNUSED(dwProviderId);
1233 WINPR_UNUSED(szProvider);
1234 WINPR_UNUSED(pcchProvider);
1235 return SCARD_E_UNSUPPORTED_FEATURE;
1238 static LONG WINAPI PCSC_SCardIntroduceReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName)
1240 WINPR_UNUSED(hContext);
1241 WINPR_UNUSED(szGroupName);
1242 return SCARD_E_UNSUPPORTED_FEATURE;
1245 static LONG WINAPI PCSC_SCardIntroduceReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName)
1247 WINPR_UNUSED(hContext);
1248 WINPR_UNUSED(szGroupName);
1249 return SCARD_E_UNSUPPORTED_FEATURE;
1252 static LONG WINAPI PCSC_SCardForgetReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName)
1254 WINPR_UNUSED(hContext);
1255 WINPR_UNUSED(szGroupName);
1256 return SCARD_E_UNSUPPORTED_FEATURE;
1259 static LONG WINAPI PCSC_SCardForgetReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName)
1261 WINPR_UNUSED(hContext);
1262 WINPR_UNUSED(szGroupName);
1263 return SCARD_E_UNSUPPORTED_FEATURE;
1266 static LONG WINAPI PCSC_SCardIntroduceReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName,
1267 LPCSTR szDeviceName)
1269 WINPR_UNUSED(hContext);
1270 WINPR_UNUSED(szReaderName);
1271 WINPR_UNUSED(szDeviceName);
1272 return SCARD_E_UNSUPPORTED_FEATURE;
1275 static LONG WINAPI PCSC_SCardIntroduceReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
1276 LPCWSTR szDeviceName)
1278 WINPR_UNUSED(hContext);
1279 WINPR_UNUSED(szReaderName);
1280 WINPR_UNUSED(szDeviceName);
1281 return SCARD_E_UNSUPPORTED_FEATURE;
1284 static LONG WINAPI PCSC_SCardForgetReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName)
1286 WINPR_UNUSED(hContext);
1287 WINPR_UNUSED(szReaderName);
1288 return SCARD_E_UNSUPPORTED_FEATURE;
1291 static LONG WINAPI PCSC_SCardForgetReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName)
1293 WINPR_UNUSED(hContext);
1294 WINPR_UNUSED(szReaderName);
1295 return SCARD_E_UNSUPPORTED_FEATURE;
1298 static LONG WINAPI PCSC_SCardAddReaderToGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName,
1301 WINPR_UNUSED(hContext);
1302 WINPR_UNUSED(szReaderName);
1303 WINPR_UNUSED(szGroupName);
1304 return SCARD_E_UNSUPPORTED_FEATURE;
1307 static LONG WINAPI PCSC_SCardAddReaderToGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
1308 LPCWSTR szGroupName)
1310 WINPR_UNUSED(hContext);
1311 WINPR_UNUSED(szReaderName);
1312 WINPR_UNUSED(szGroupName);
1313 return SCARD_E_UNSUPPORTED_FEATURE;
1316 static LONG WINAPI PCSC_SCardRemoveReaderFromGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName,
1319 WINPR_UNUSED(hContext);
1320 WINPR_UNUSED(szReaderName);
1321 WINPR_UNUSED(szGroupName);
1322 return SCARD_E_UNSUPPORTED_FEATURE;
1325 static LONG WINAPI PCSC_SCardRemoveReaderFromGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
1326 LPCWSTR szGroupName)
1328 WINPR_UNUSED(hContext);
1329 WINPR_UNUSED(szReaderName);
1330 WINPR_UNUSED(szGroupName);
1331 return SCARD_E_UNSUPPORTED_FEATURE;
1334 static LONG WINAPI PCSC_SCardIntroduceCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName,
1335 LPCGUID pguidPrimaryProvider,
1336 LPCGUID rgguidInterfaces, DWORD dwInterfaceCount,
1337 LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen)
1339 WINPR_UNUSED(hContext);
1340 WINPR_UNUSED(szCardName);
1341 WINPR_UNUSED(pguidPrimaryProvider);
1342 WINPR_UNUSED(rgguidInterfaces);
1343 WINPR_UNUSED(dwInterfaceCount);
1344 WINPR_UNUSED(pbAtr);
1345 WINPR_UNUSED(pbAtrMask);
1346 WINPR_UNUSED(cbAtrLen);
1347 return SCARD_E_UNSUPPORTED_FEATURE;
1350 static LONG WINAPI PCSC_SCardIntroduceCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName,
1351 LPCGUID pguidPrimaryProvider,
1352 LPCGUID rgguidInterfaces, DWORD dwInterfaceCount,
1353 LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen)
1355 WINPR_UNUSED(hContext);
1356 WINPR_UNUSED(szCardName);
1357 WINPR_UNUSED(pguidPrimaryProvider);
1358 WINPR_UNUSED(rgguidInterfaces);
1359 WINPR_UNUSED(dwInterfaceCount);
1360 WINPR_UNUSED(pbAtr);
1361 WINPR_UNUSED(pbAtrMask);
1362 WINPR_UNUSED(cbAtrLen);
1363 return SCARD_E_UNSUPPORTED_FEATURE;
1366 static LONG WINAPI PCSC_SCardSetCardTypeProviderNameA(SCARDCONTEXT hContext, LPCSTR szCardName,
1367 DWORD dwProviderId, LPCSTR szProvider)
1369 WINPR_UNUSED(hContext);
1370 WINPR_UNUSED(szCardName);
1371 WINPR_UNUSED(dwProviderId);
1372 WINPR_UNUSED(szProvider);
1373 return SCARD_E_UNSUPPORTED_FEATURE;
1376 static LONG WINAPI PCSC_SCardSetCardTypeProviderNameW(SCARDCONTEXT hContext, LPCWSTR szCardName,
1377 DWORD dwProviderId, LPCWSTR szProvider)
1379 WINPR_UNUSED(hContext);
1380 WINPR_UNUSED(szCardName);
1381 WINPR_UNUSED(dwProviderId);
1382 WINPR_UNUSED(szProvider);
1383 return SCARD_E_UNSUPPORTED_FEATURE;
1386 static LONG WINAPI PCSC_SCardForgetCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName)
1388 WINPR_UNUSED(hContext);
1389 WINPR_UNUSED(szCardName);
1390 return SCARD_E_UNSUPPORTED_FEATURE;
1393 static LONG WINAPI PCSC_SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName)
1395 WINPR_UNUSED(hContext);
1396 WINPR_UNUSED(szCardName);
1397 return SCARD_E_UNSUPPORTED_FEATURE;
1400 static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPVOID pvMem)
1402 PCSC_LONG status = SCARD_S_SUCCESS;
1404 if (PCSC_RemoveMemoryBlock(hContext, pvMem))
1407 status = SCARD_S_SUCCESS;
1411 if (g_PCSC.pfnSCardFreeMemory)
1413 status = g_PCSC.pfnSCardFreeMemory(hContext, pvMem);
1417 return PCSC_MapErrorCodeToWinSCard(status);
1420 static LONG WINAPI PCSC_SCardFreeMemory(SCARDCONTEXT hContext, LPVOID pvMem)
1422 LONG status = SCARD_S_SUCCESS;
1426 if (!PCSC_LockCardContext(hContext))
1427 return SCARD_E_INVALID_HANDLE;
1430 status = PCSC_SCardFreeMemory_Internal(hContext, pvMem);
1434 if (!PCSC_UnlockCardContext(hContext))
1435 return SCARD_E_INVALID_HANDLE;
1441 static HANDLE WINAPI PCSC_SCardAccessStartedEvent(
void)
1444 SCARDCONTEXT hContext = 0;
1446 status = PCSC_SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
1448 if (status != SCARD_S_SUCCESS)
1451 status = PCSC_SCardReleaseContext(hContext);
1453 if (status != SCARD_S_SUCCESS)
1456 if (!g_StartedEvent)
1458 if (!(g_StartedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
1461 if (!SetEvent(g_StartedEvent))
1463 (void)CloseHandle(g_StartedEvent);
1468 g_StartedEventRefCount++;
1469 return g_StartedEvent;
1472 static void WINAPI PCSC_SCardReleaseStartedEvent(
void)
1474 g_StartedEventRefCount--;
1476 if (g_StartedEventRefCount == 0)
1480 (void)CloseHandle(g_StartedEvent);
1481 g_StartedEvent = NULL;
1486 static LONG WINAPI PCSC_SCardLocateCardsA(SCARDCONTEXT hContext, LPCSTR mszCards,
1489 WINPR_UNUSED(hContext);
1490 WINPR_UNUSED(mszCards);
1491 WINPR_UNUSED(rgReaderStates);
1492 WINPR_UNUSED(cReaders);
1493 return SCARD_E_UNSUPPORTED_FEATURE;
1496 static LONG WINAPI PCSC_SCardLocateCardsW(SCARDCONTEXT hContext, LPCWSTR mszCards,
1499 WINPR_UNUSED(hContext);
1500 WINPR_UNUSED(mszCards);
1501 WINPR_UNUSED(rgReaderStates);
1502 WINPR_UNUSED(cReaders);
1503 return SCARD_E_UNSUPPORTED_FEATURE;
1506 static LONG WINAPI PCSC_SCardLocateCardsByATRA(SCARDCONTEXT hContext,
LPSCARD_ATRMASK rgAtrMasks,
1510 WINPR_UNUSED(hContext);
1511 WINPR_UNUSED(rgAtrMasks);
1512 WINPR_UNUSED(cAtrs);
1513 WINPR_UNUSED(rgReaderStates);
1514 WINPR_UNUSED(cReaders);
1515 return SCARD_E_UNSUPPORTED_FEATURE;
1518 static LONG WINAPI PCSC_SCardLocateCardsByATRW(SCARDCONTEXT hContext,
LPSCARD_ATRMASK rgAtrMasks,
1522 WINPR_UNUSED(hContext);
1523 WINPR_UNUSED(rgAtrMasks);
1524 WINPR_UNUSED(cAtrs);
1525 WINPR_UNUSED(rgReaderStates);
1526 WINPR_UNUSED(cReaders);
1527 return SCARD_E_UNSUPPORTED_FEATURE;
1530 static LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, DWORD dwTimeout,
1535 PCSC_DWORD cMappedReaders = 0;
1537 PCSC_LONG status = SCARD_S_SUCCESS;
1538 PCSC_DWORD pcsc_dwTimeout = (PCSC_DWORD)dwTimeout;
1539 PCSC_DWORD pcsc_cReaders = (PCSC_DWORD)cReaders;
1541 if (!g_PCSC.pfnSCardGetStatusChange)
1542 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardGetStatusChange");
1545 return SCARD_S_SUCCESS;
1548 pcsc_dwTimeout = pcsc_dwTimeout ? pcsc_dwTimeout : 1;
1562 map = (INT64*)calloc(pcsc_cReaders,
sizeof(INT64));
1565 return SCARD_E_NO_MEMORY;
1572 return SCARD_E_NO_MEMORY;
1576 for (PCSC_DWORD i = 0; i < pcsc_cReaders; i++)
1578 if (!g_PnP_Notification)
1581 if (!reader->szReader)
1583 if (0 == _stricmp(reader->szReader, SMARTCARD_PNP_NOTIFICATION_A))
1591 states[j].szReader = rgReaderStates[i].szReader;
1592 states[j].dwCurrentState = rgReaderStates[i].dwCurrentState;
1593 states[j].pvUserData = rgReaderStates[i].pvUserData;
1594 states[j].dwEventState = rgReaderStates[i].dwEventState;
1595 states[j].cbAtr = rgReaderStates[i].cbAtr;
1596 CopyMemory(&(states[j].rgbAtr), &(rgReaderStates[i].rgbAtr), PCSC_MAX_ATR_SIZE);
1602 if (cMappedReaders > 0)
1604 status = g_PCSC.pfnSCardGetStatusChange(hContext, pcsc_dwTimeout, states, cMappedReaders);
1608 status = SCARD_S_SUCCESS;
1611 for (PCSC_DWORD i = 0; i < pcsc_cReaders; i++)
1616 PCSC_DWORD k = (PCSC_DWORD)map[i];
1617 rgReaderStates[i].dwCurrentState = (DWORD)states[k].dwCurrentState;
1618 rgReaderStates[i].cbAtr = (DWORD)states[k].cbAtr;
1619 CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[k].rgbAtr), PCSC_MAX_ATR_SIZE);
1620 rgReaderStates[i].dwEventState = (DWORD)states[k].dwEventState;
1625 return PCSC_MapErrorCodeToWinSCard(status);
1628 static LONG WINAPI PCSC_SCardGetStatusChangeA(SCARDCONTEXT hContext, DWORD dwTimeout,
1631 LONG status = SCARD_S_SUCCESS;
1633 if (!PCSC_LockCardContext(hContext))
1634 return SCARD_E_INVALID_HANDLE;
1636 status = PCSC_SCardGetStatusChange_Internal(hContext, dwTimeout, rgReaderStates, cReaders);
1638 if (!PCSC_UnlockCardContext(hContext))
1639 return SCARD_E_INVALID_HANDLE;
1644 static LONG WINAPI PCSC_SCardGetStatusChangeW(SCARDCONTEXT hContext, DWORD dwTimeout,
1648 LONG status = SCARD_S_SUCCESS;
1650 if (!g_PCSC.pfnSCardGetStatusChange)
1651 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardGetStatusChange");
1653 if (!PCSC_LockCardContext(hContext))
1654 return SCARD_E_INVALID_HANDLE;
1660 (void)PCSC_UnlockCardContext(hContext);
1661 return SCARD_E_NO_MEMORY;
1664 for (DWORD index = 0; index < cReaders; index++)
1669 cur->szReader = ConvertWCharToUtf8Alloc(curReader->szReader, NULL);
1670 cur->pvUserData = curReader->pvUserData;
1671 cur->dwCurrentState = curReader->dwCurrentState;
1672 cur->dwEventState = curReader->dwEventState;
1673 cur->cbAtr = curReader->cbAtr;
1674 CopyMemory(&(cur->rgbAtr), &(curReader->rgbAtr), ARRAYSIZE(cur->rgbAtr));
1677 status = PCSC_SCardGetStatusChange_Internal(hContext, dwTimeout, states, cReaders);
1679 for (DWORD index = 0; index < cReaders; index++)
1681 free((
void*)states[index].szReader);
1682 rgReaderStates[index].pvUserData = states[index].pvUserData;
1683 rgReaderStates[index].dwCurrentState = states[index].dwCurrentState;
1684 rgReaderStates[index].dwEventState = states[index].dwEventState;
1685 rgReaderStates[index].cbAtr = states[index].cbAtr;
1686 CopyMemory(&(rgReaderStates[index].rgbAtr), &(states[index].rgbAtr), 36);
1691 if (!PCSC_UnlockCardContext(hContext))
1692 return SCARD_E_INVALID_HANDLE;
1697 static LONG WINAPI PCSC_SCardCancel(SCARDCONTEXT hContext)
1699 PCSC_LONG status = SCARD_S_SUCCESS;
1701 if (!g_PCSC.pfnSCardCancel)
1702 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardCancel");
1704 status = g_PCSC.pfnSCardCancel(hContext);
1705 return PCSC_MapErrorCodeToWinSCard(status);
1708 static LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPCSTR szReader,
1709 DWORD dwShareMode, DWORD dwPreferredProtocols,
1710 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1713 const char* szReaderPCSC = NULL;
1714 PCSC_LONG status = SCARD_S_SUCCESS;
1715 PCSC_SCARDHANDLE* pCard = NULL;
1716 PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD)dwShareMode;
1717 PCSC_DWORD pcsc_dwPreferredProtocols = 0;
1718 PCSC_DWORD pcsc_dwActiveProtocol = 0;
1720 if (!g_PCSC.pfnSCardConnect)
1721 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardConnect");
1723 shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE;
1724 PCSC_WaitForCardAccess(hContext, 0, shared);
1725 szReaderPCSC = szReader;
1734 if (pcsc_dwShareMode == SCARD_SHARE_DIRECT && dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED)
1735 pcsc_dwPreferredProtocols = SCARD_PROTOCOL_UNDEFINED;
1737 pcsc_dwPreferredProtocols =
1738 (PCSC_DWORD)PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
1740 status = g_PCSC.pfnSCardConnect(hContext, szReaderPCSC, pcsc_dwShareMode,
1741 pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol);
1743 if (status == SCARD_S_SUCCESS)
1745 pCard = PCSC_ConnectCardHandle(hContext, *phCard);
1746 *pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwActiveProtocol);
1747 pCard->shared = shared;
1750 PCSC_WaitForCardAccess(hContext, pCard->hSharedContext, shared);
1753 return PCSC_MapErrorCodeToWinSCard(status);
1756 static LONG WINAPI PCSC_SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
1757 DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
1758 LPDWORD pdwActiveProtocol)
1760 LONG status = SCARD_S_SUCCESS;
1762 if (!PCSC_LockCardContext(hContext))
1763 return SCARD_E_INVALID_HANDLE;
1765 status = PCSC_SCardConnect_Internal(hContext, szReader, dwShareMode, dwPreferredProtocols,
1766 phCard, pdwActiveProtocol);
1768 if (!PCSC_UnlockCardContext(hContext))
1769 return SCARD_E_INVALID_HANDLE;
1774 static LONG WINAPI PCSC_SCardConnectW(SCARDCONTEXT hContext, LPCWSTR szReader, DWORD dwShareMode,
1775 DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
1776 LPDWORD pdwActiveProtocol)
1778 LPSTR szReaderA = NULL;
1779 LONG status = SCARD_S_SUCCESS;
1781 if (!PCSC_LockCardContext(hContext))
1782 return SCARD_E_INVALID_HANDLE;
1786 szReaderA = ConvertWCharToUtf8Alloc(szReader, NULL);
1788 return SCARD_E_INSUFFICIENT_BUFFER;
1791 status = PCSC_SCardConnect_Internal(hContext, szReaderA, dwShareMode, dwPreferredProtocols,
1792 phCard, pdwActiveProtocol);
1795 if (!PCSC_UnlockCardContext(hContext))
1796 return SCARD_E_INVALID_HANDLE;
1801 static LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
1802 DWORD dwPreferredProtocols, DWORD dwInitialization,
1803 LPDWORD pdwActiveProtocol)
1806 PCSC_LONG status = SCARD_S_SUCCESS;
1807 PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD)dwShareMode;
1808 PCSC_DWORD pcsc_dwPreferredProtocols = 0;
1809 PCSC_DWORD pcsc_dwInitialization = (PCSC_DWORD)dwInitialization;
1810 PCSC_DWORD pcsc_dwActiveProtocol = 0;
1812 if (!g_PCSC.pfnSCardReconnect)
1813 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardReconnect");
1815 shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE;
1816 PCSC_WaitForCardAccess(0, hCard, shared);
1817 pcsc_dwPreferredProtocols = (PCSC_DWORD)PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
1818 status = g_PCSC.pfnSCardReconnect(hCard, pcsc_dwShareMode, pcsc_dwPreferredProtocols,
1819 pcsc_dwInitialization, &pcsc_dwActiveProtocol);
1821 *pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwActiveProtocol);
1822 return PCSC_MapErrorCodeToWinSCard(status);
1825 static LONG WINAPI PCSC_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
1827 PCSC_LONG status = SCARD_S_SUCCESS;
1828 PCSC_DWORD pcsc_dwDisposition = (PCSC_DWORD)dwDisposition;
1830 if (!g_PCSC.pfnSCardDisconnect)
1831 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardDisconnect");
1833 status = g_PCSC.pfnSCardDisconnect(hCard, pcsc_dwDisposition);
1835 if (status == SCARD_S_SUCCESS)
1837 PCSC_DisconnectCardHandle(hCard);
1840 PCSC_ReleaseCardAccess(0, hCard);
1841 return PCSC_MapErrorCodeToWinSCard(status);
1844 static LONG WINAPI PCSC_SCardBeginTransaction(SCARDHANDLE hCard)
1846 PCSC_LONG status = SCARD_S_SUCCESS;
1847 PCSC_SCARDHANDLE* pCard = NULL;
1848 PCSC_SCARDCONTEXT* pContext = NULL;
1850 if (!g_PCSC.pfnSCardBeginTransaction)
1851 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardBeginTransaction");
1853 pCard = PCSC_GetCardHandleData(hCard);
1856 return SCARD_E_INVALID_HANDLE;
1858 pContext = PCSC_GetCardContextData(pCard->hSharedContext);
1861 return SCARD_E_INVALID_HANDLE;
1863 if (pContext->isTransactionLocked)
1864 return SCARD_S_SUCCESS;
1866 status = g_PCSC.pfnSCardBeginTransaction(hCard);
1868 pContext->isTransactionLocked = TRUE;
1869 return PCSC_MapErrorCodeToWinSCard(status);
1872 static LONG WINAPI PCSC_SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
1874 PCSC_LONG status = SCARD_S_SUCCESS;
1875 PCSC_SCARDHANDLE* pCard = NULL;
1876 PCSC_SCARDCONTEXT* pContext = NULL;
1877 PCSC_DWORD pcsc_dwDisposition = (PCSC_DWORD)dwDisposition;
1879 if (!g_PCSC.pfnSCardEndTransaction)
1880 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardEndTransaction");
1882 pCard = PCSC_GetCardHandleData(hCard);
1885 return SCARD_E_INVALID_HANDLE;
1887 pContext = PCSC_GetCardContextData(pCard->hSharedContext);
1890 return SCARD_E_INVALID_HANDLE;
1892 PCSC_ReleaseCardAccess(0, hCard);
1894 if (!pContext->isTransactionLocked)
1895 return SCARD_S_SUCCESS;
1897 status = g_PCSC.pfnSCardEndTransaction(hCard, pcsc_dwDisposition);
1899 pContext->isTransactionLocked = FALSE;
1900 return PCSC_MapErrorCodeToWinSCard(status);
1903 static LONG WINAPI PCSC_SCardCancelTransaction(SCARDHANDLE hCard)
1905 WINPR_UNUSED(hCard);
1906 return SCARD_S_SUCCESS;
1913 static LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderNames,
1914 LPDWORD pcchReaderLen, LPDWORD pdwState,
1915 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen,
1918 PCSC_SCARDHANDLE* pCard = NULL;
1919 SCARDCONTEXT hContext = 0;
1920 PCSC_LONG status = 0;
1921 PCSC_DWORD pcsc_cchReaderLen = 0;
1922 PCSC_DWORD pcsc_cbAtrLen = 0;
1923 PCSC_DWORD pcsc_dwState = 0;
1924 PCSC_DWORD pcsc_dwProtocol = 0;
1925 BOOL allocateReader = FALSE;
1926 BOOL allocateAtr = FALSE;
1927 LPSTR readerNames = mszReaderNames;
1929 LPSTR tReader = NULL;
1932 if (!g_PCSC.pfnSCardStatus)
1933 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardStatus");
1935 pCard = PCSC_GetCardHandleData(hCard);
1938 return SCARD_E_INVALID_VALUE;
1940 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
1941 hContext = PCSC_GetCardContextFromHandle(hCard);
1944 return SCARD_E_INVALID_VALUE;
1947 g_PCSC.pfnSCardStatus(hCard, NULL, &pcsc_cchReaderLen, NULL, NULL, NULL, &pcsc_cbAtrLen);
1949 if (status != STATUS_SUCCESS)
1950 return PCSC_MapErrorCodeToWinSCard(status);
1952 pcsc_cchReaderLen++;
1955 pcsc_cchReaderLen *= 2;
1959 if (*pcchReaderLen == SCARD_AUTOALLOCATE)
1960 allocateReader = TRUE;
1961 else if (mszReaderNames && (*pcchReaderLen < pcsc_cchReaderLen))
1962 return SCARD_E_INSUFFICIENT_BUFFER;
1964 pcsc_cchReaderLen = *pcchReaderLen;
1969 if (*pcbAtrLen == SCARD_AUTOALLOCATE)
1971 else if (pbAtr && (*pcbAtrLen < pcsc_cbAtrLen))
1972 return SCARD_E_INSUFFICIENT_BUFFER;
1974 pcsc_cbAtrLen = *pcbAtrLen;
1977 if (allocateReader && pcsc_cchReaderLen > 0 && mszReaderNames)
1984 if (OSXVersion == 0x10100000)
1985 pcsc_cchReaderLen++;
1988 tReader = calloc(
sizeof(CHAR), pcsc_cchReaderLen + 1);
1992 status = ERROR_NOT_ENOUGH_MEMORY;
1996 readerNames = tReader;
1999 if (allocateAtr && pcsc_cbAtrLen > 0 && pbAtr)
2001 tATR = calloc(1, pcsc_cbAtrLen);
2005 status = ERROR_NOT_ENOUGH_MEMORY;
2012 status = g_PCSC.pfnSCardStatus(hCard, readerNames, &pcsc_cchReaderLen, &pcsc_dwState,
2013 &pcsc_dwProtocol, atr, &pcsc_cbAtrLen);
2015 if (status != STATUS_SUCCESS)
2020 PCSC_AddMemoryBlock(hContext, tATR);
2021 *(BYTE**)pbAtr = tATR;
2029 WCHAR* tmp = ConvertMszUtf8NToWCharAlloc(tReader, pcsc_cchReaderLen + 1, &size);
2033 status = ERROR_NOT_ENOUGH_MEMORY;
2039 PCSC_AddMemoryBlock(hContext, tmp);
2040 *(WCHAR**)mszReaderNames = tmp;
2044 tReader[pcsc_cchReaderLen - 1] =
'\0';
2045 PCSC_AddMemoryBlock(hContext, tReader);
2046 *(
char**)mszReaderNames = tReader;
2050 pcsc_dwState &= 0xFFFF;
2053 *pdwState = PCSC_ConvertCardStateToWinSCard((DWORD)pcsc_dwState, status);
2056 *pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwProtocol);
2059 *pcbAtrLen = (DWORD)pcsc_cbAtrLen;
2063 WINPR_ASSERT(pcsc_cchReaderLen < UINT32_MAX);
2064 *pcchReaderLen = (DWORD)pcsc_cchReaderLen + 1u;
2067 return (LONG)status;
2071 return (LONG)status;
2074 static LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD pdwProtocol,
2075 LPBYTE pbAtr, LPDWORD pcbAtrLen)
2077 DWORD cchReaderLen = 0;
2078 SCARDCONTEXT hContext = 0;
2079 LPSTR mszReaderNames = NULL;
2080 PCSC_LONG status = SCARD_S_SUCCESS;
2081 PCSC_SCARDHANDLE* pCard = NULL;
2082 DWORD pcsc_dwState = 0;
2083 DWORD pcsc_dwProtocol = 0;
2084 DWORD pcsc_cbAtrLen = 0;
2087 pcsc_cbAtrLen = (DWORD)*pcbAtrLen;
2089 if (!g_PCSC.pfnSCardStatus)
2090 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardStatus");
2092 pCard = PCSC_GetCardHandleData(hCard);
2095 return SCARD_E_INVALID_VALUE;
2097 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2098 hContext = PCSC_GetCardContextFromHandle(hCard);
2101 return SCARD_E_INVALID_VALUE;
2103 cchReaderLen = SCARD_AUTOALLOCATE;
2104 status = PCSC_SCardStatus_Internal(hCard, (LPSTR)&mszReaderNames, &cchReaderLen, &pcsc_dwState,
2105 &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen, FALSE);
2108 PCSC_SCardFreeMemory_Internal(hContext, mszReaderNames);
2110 *pdwState = pcsc_dwState;
2111 *pdwProtocol = PCSC_ConvertProtocolsToWinSCard(pcsc_dwProtocol);
2113 *pcbAtrLen = pcsc_cbAtrLen;
2114 return PCSC_MapErrorCodeToWinSCard(status);
2117 static LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen,
2118 LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
2122 return PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol,
2123 pbAtr, pcbAtrLen, FALSE);
2126 static LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, LPWSTR mszReaderNames,
2127 LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol,
2128 LPBYTE pbAtr, LPDWORD pcbAtrLen)
2131 return PCSC_SCardStatus_Internal(hCard, (LPSTR)mszReaderNames, pcchReaderLen, pdwState,
2132 pdwProtocol, pbAtr, pcbAtrLen, TRUE);
2136 LPCBYTE pbSendBuffer, DWORD cbSendLength,
2138 LPDWORD pcbRecvLength)
2140 PCSC_LONG status = SCARD_S_SUCCESS;
2141 PCSC_SCARDHANDLE* pCard = NULL;
2142 PCSC_DWORD cbExtraBytes = 0;
2143 BYTE* pbExtraBytes = NULL;
2144 BYTE* pcsc_pbExtraBytes = NULL;
2145 PCSC_DWORD pcsc_cbSendLength = (PCSC_DWORD)cbSendLength;
2146 PCSC_DWORD pcsc_cbRecvLength = 0;
2154 } sendPci, recvPci, inRecvPci, inSendPci;
2158 inRecvPci.lps = pioRecvPci;
2159 inSendPci.lpcs = pioSendPci;
2161 if (!g_PCSC.pfnSCardTransmit)
2162 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardTransmit");
2164 pCard = PCSC_GetCardHandleData(hCard);
2167 return SCARD_E_INVALID_VALUE;
2169 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2172 return SCARD_E_INVALID_PARAMETER;
2174 if (*pcbRecvLength == SCARD_AUTOALLOCATE)
2175 return SCARD_E_INVALID_PARAMETER;
2177 pcsc_cbRecvLength = (PCSC_DWORD)*pcbRecvLength;
2179 if (!inSendPci.lpcs)
2181 PCSC_DWORD dwState = 0;
2182 PCSC_DWORD cbAtrLen = 0;
2183 PCSC_DWORD dwProtocol = 0;
2184 PCSC_DWORD cchReaderLen = 0;
2189 status = g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL,
2192 if (status == SCARD_S_SUCCESS)
2194 if (dwProtocol == SCARD_PROTOCOL_T0)
2195 sendPci.pcs = PCSC_SCARD_PCI_T0;
2196 else if (dwProtocol == SCARD_PROTOCOL_T1)
2197 sendPci.pcs = PCSC_SCARD_PCI_T1;
2198 else if (dwProtocol == PCSC_SCARD_PROTOCOL_RAW)
2199 sendPci.pcs = PCSC_SCARD_PCI_RAW;
2208 return SCARD_E_NO_MEMORY;
2210 sendPci.ps->dwProtocol = (PCSC_DWORD)inSendPci.lpcs->dwProtocol;
2214 CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes);
2227 return SCARD_E_NO_MEMORY;
2230 recvPci.ps->dwProtocol = (PCSC_DWORD)inRecvPci.lps->dwProtocol;
2234 CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes);
2237 status = g_PCSC.pfnSCardTransmit(hCard, sendPci.ps, pbSendBuffer, pcsc_cbSendLength, recvPci.ps,
2238 pbRecvBuffer, &pcsc_cbRecvLength);
2240 *pcbRecvLength = (DWORD)pcsc_cbRecvLength;
2251 CopyMemory(pbExtraBytes, pcsc_pbExtraBytes, cbExtraBytes);
2256 return PCSC_MapErrorCodeToWinSCard(status);
2260 static LONG WINAPI PCSC_SCardGetTransmitCount(SCARDHANDLE hCard, LPDWORD pcTransmitCount)
2262 WINPR_UNUSED(pcTransmitCount);
2263 PCSC_SCARDHANDLE* pCard = NULL;
2265 pCard = PCSC_GetCardHandleData(hCard);
2268 return SCARD_E_INVALID_VALUE;
2270 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2271 return SCARD_S_SUCCESS;
2274 static LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID lpInBuffer,
2275 DWORD cbInBufferSize, LPVOID lpOutBuffer,
2276 DWORD cbOutBufferSize, LPDWORD lpBytesReturned)
2278 DWORD IoCtlFunction = 0;
2279 DWORD IoCtlDeviceType = 0;
2280 BOOL getFeatureRequest = FALSE;
2281 PCSC_LONG status = SCARD_S_SUCCESS;
2282 PCSC_SCARDHANDLE* pCard = NULL;
2283 PCSC_DWORD pcsc_dwControlCode = 0;
2284 PCSC_DWORD pcsc_cbInBufferSize = (PCSC_DWORD)cbInBufferSize;
2285 PCSC_DWORD pcsc_cbOutBufferSize = (PCSC_DWORD)cbOutBufferSize;
2286 PCSC_DWORD pcsc_BytesReturned = 0;
2288 if (!g_PCSC.pfnSCardControl)
2289 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardControl");
2291 pCard = PCSC_GetCardHandleData(hCard);
2294 return SCARD_E_INVALID_VALUE;
2296 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2307 IoCtlFunction = FUNCTION_FROM_CTL_CODE(dwControlCode);
2308 IoCtlDeviceType = DEVICE_TYPE_FROM_CTL_CODE(dwControlCode);
2310 if (dwControlCode == IOCTL_SMARTCARD_GET_FEATURE_REQUEST)
2311 getFeatureRequest = TRUE;
2313 if (IoCtlDeviceType == FILE_DEVICE_SMARTCARD)
2314 dwControlCode = PCSC_SCARD_CTL_CODE(IoCtlFunction);
2316 pcsc_dwControlCode = (PCSC_DWORD)dwControlCode;
2317 status = g_PCSC.pfnSCardControl(hCard, pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize,
2318 lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned);
2320 *lpBytesReturned = (DWORD)pcsc_BytesReturned;
2322 if (getFeatureRequest)
2328 return SCARD_E_UNEXPECTED;
2332 for (DWORD index = 0; index < count; index++)
2334 if (tlv[index].length != 4)
2335 return SCARD_E_UNEXPECTED;
2339 return PCSC_MapErrorCodeToWinSCard(status);
2342 static LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
2345 SCARDCONTEXT hContext = 0;
2346 BOOL pcbAttrLenAlloc = FALSE;
2347 PCSC_LONG status = SCARD_S_SUCCESS;
2348 PCSC_SCARDHANDLE* pCard = NULL;
2349 PCSC_DWORD pcsc_dwAttrId = (PCSC_DWORD)dwAttrId;
2350 PCSC_DWORD pcsc_cbAttrLen = 0;
2352 if (!g_PCSC.pfnSCardGetAttrib)
2353 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardGetAttrib");
2355 pCard = PCSC_GetCardHandleData(hCard);
2358 return SCARD_E_INVALID_VALUE;
2360 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2361 hContext = PCSC_GetCardContextFromHandle(hCard);
2364 return SCARD_E_INVALID_HANDLE;
2367 return SCARD_E_INVALID_PARAMETER;
2369 if (*pcbAttrLen == SCARD_AUTOALLOCATE)
2372 return SCARD_E_INVALID_PARAMETER;
2373 pcbAttrLenAlloc = TRUE;
2376 pcsc_cbAttrLen = pcbAttrLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD)*pcbAttrLen;
2378 if (pcbAttrLenAlloc && !g_SCardAutoAllocate)
2381 status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, NULL, &pcsc_cbAttrLen);
2383 if (status == SCARD_S_SUCCESS)
2385 BYTE* tmp = (BYTE*)calloc(1, pcsc_cbAttrLen);
2388 return SCARD_E_NO_MEMORY;
2390 status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, tmp, &pcsc_cbAttrLen);
2392 if (status != SCARD_S_SUCCESS)
2398 PCSC_AddMemoryBlock(hContext, tmp);
2399 *(BYTE**)pbAttr = tmp;
2404 status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, pbAttr, &pcsc_cbAttrLen);
2407 if (status == SCARD_S_SUCCESS)
2408 *pcbAttrLen = (DWORD)pcsc_cbAttrLen;
2409 return PCSC_MapErrorCodeToWinSCard(status);
2412 static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwAttrId,
2413 LPBYTE pbAttr, LPDWORD pcbAttrLen)
2416 char* namePCSC = NULL;
2417 char* pbAttrA = NULL;
2418 DWORD cbAttrLen = 0;
2419 WCHAR* pbAttrW = NULL;
2420 SCARDCONTEXT hContext = 0;
2421 LONG status = SCARD_S_SUCCESS;
2423 hContext = PCSC_GetCardContextFromHandle(hCard);
2426 return SCARD_E_INVALID_HANDLE;
2429 return SCARD_E_INVALID_PARAMETER;
2430 cbAttrLen = *pcbAttrLen;
2431 *pcbAttrLen = SCARD_AUTOALLOCATE;
2432 status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A,
2433 (LPBYTE)&pbAttrA, pcbAttrLen);
2435 if (status != SCARD_S_SUCCESS)
2437 *pcbAttrLen = SCARD_AUTOALLOCATE;
2438 status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W,
2439 (LPBYTE)&pbAttrW, pcbAttrLen);
2441 if (status != SCARD_S_SUCCESS)
2444 namePCSC = ConvertMszWCharNToUtf8Alloc(pbAttrW, *pcbAttrLen, NULL);
2445 PCSC_SCardFreeMemory_Internal(hContext, pbAttrW);
2449 namePCSC = _strdup(pbAttrA);
2452 return SCARD_E_NO_MEMORY;
2454 PCSC_SCardFreeMemory_Internal(hContext, pbAttrA);
2457 length = strlen(namePCSC);
2459 if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)
2462 WCHAR* friendlyNameW = ConvertUtf8ToWCharAlloc(namePCSC, &size);
2466 status = SCARD_E_NO_MEMORY;
2471 if (cbAttrLen == SCARD_AUTOALLOCATE)
2473 WINPR_ASSERT(length <= UINT32_MAX /
sizeof(WCHAR));
2474 *(WCHAR**)pbAttr = friendlyNameW;
2475 *pcbAttrLen = (UINT32)length *
sizeof(WCHAR);
2476 PCSC_AddMemoryBlock(hContext, friendlyNameW);
2480 if ((length * 2) > cbAttrLen)
2481 status = SCARD_E_INSUFFICIENT_BUFFER;
2484 WINPR_ASSERT(length <= UINT32_MAX /
sizeof(WCHAR));
2485 CopyMemory(pbAttr, (BYTE*)friendlyNameW, (length *
sizeof(WCHAR)));
2486 *pcbAttrLen = (UINT32)length *
sizeof(WCHAR);
2488 free(friendlyNameW);
2495 if (cbAttrLen == SCARD_AUTOALLOCATE)
2497 *(CHAR**)pbAttr = namePCSC;
2498 WINPR_ASSERT(length <= UINT32_MAX);
2499 *pcbAttrLen = (UINT32)length;
2500 PCSC_AddMemoryBlock(hContext, namePCSC);
2504 if ((length + 1) > cbAttrLen)
2505 status = SCARD_E_INSUFFICIENT_BUFFER;
2508 CopyMemory(pbAttr, namePCSC, length + 1);
2509 WINPR_ASSERT(length <= UINT32_MAX);
2510 *pcbAttrLen = (UINT32)length;
2519 static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
2522 DWORD cbAttrLen = 0;
2523 SCARDCONTEXT hContext = 0;
2524 BOOL pcbAttrLenAlloc = FALSE;
2525 LONG status = SCARD_S_SUCCESS;
2527 if (NULL == pcbAttrLen)
2528 return SCARD_E_INVALID_PARAMETER;
2530 cbAttrLen = *pcbAttrLen;
2532 if (*pcbAttrLen == SCARD_AUTOALLOCATE)
2535 return SCARD_E_INVALID_PARAMETER;
2537 pcbAttrLenAlloc = TRUE;
2538 *(BYTE**)pbAttr = NULL;
2546 if (*pcbAttrLen > PCSC_MAX_BUFFER_SIZE)
2547 *pcbAttrLen = PCSC_MAX_BUFFER_SIZE;
2550 hContext = PCSC_GetCardContextFromHandle(hCard);
2553 return SCARD_E_INVALID_HANDLE;
2555 if ((dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A) ||
2556 (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W))
2558 status = PCSC_SCardGetAttrib_FriendlyName(hCard, dwAttrId, pbAttr, pcbAttrLen);
2562 status = PCSC_SCardGetAttrib_Internal(hCard, dwAttrId, pbAttr, pcbAttrLen);
2564 if (status == SCARD_S_SUCCESS)
2566 if (dwAttrId == SCARD_ATTR_VENDOR_NAME)
2570 const char* vendorName = NULL;
2577 if (pcbAttrLenAlloc)
2578 vendorName = (
char*)*(BYTE**)pbAttr;
2580 vendorName = (
char*)pbAttr;
2584 size_t len = strnlen(vendorName, *pcbAttrLen);
2585 WINPR_ASSERT(len <= UINT32_MAX);
2586 *pcbAttrLen = (DWORD)len;
2596 if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE)
2598 if (!pcbAttrLenAlloc)
2600 PCSC_DWORD dwState = 0;
2601 PCSC_DWORD cbAtrLen = 0;
2602 PCSC_DWORD dwProtocol = 0;
2603 PCSC_DWORD cchReaderLen = 0;
2604 status = (LONG)g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState,
2605 &dwProtocol, NULL, &cbAtrLen);
2607 if (status == SCARD_S_SUCCESS)
2609 if (cbAttrLen <
sizeof(DWORD))
2610 return SCARD_E_INSUFFICIENT_BUFFER;
2612 *(DWORD*)pbAttr = PCSC_ConvertProtocolsToWinSCard(dwProtocol);
2613 *pcbAttrLen =
sizeof(DWORD);
2617 else if (dwAttrId == SCARD_ATTR_CHANNEL_ID)
2619 if (!pcbAttrLenAlloc)
2621 UINT32 channelType = 0x20;
2622 UINT32 channelNumber = 0;
2624 if (cbAttrLen <
sizeof(DWORD))
2625 return SCARD_E_INSUFFICIENT_BUFFER;
2627 status = SCARD_S_SUCCESS;
2628 *(DWORD*)pbAttr = (channelType << 16u) | channelNumber;
2629 *pcbAttrLen =
sizeof(DWORD);
2632 else if (dwAttrId == SCARD_ATTR_VENDOR_IFD_TYPE)
2635 else if (dwAttrId == SCARD_ATTR_DEFAULT_CLK)
2638 else if (dwAttrId == SCARD_ATTR_DEFAULT_DATA_RATE)
2641 else if (dwAttrId == SCARD_ATTR_MAX_CLK)
2644 else if (dwAttrId == SCARD_ATTR_MAX_DATA_RATE)
2647 else if (dwAttrId == SCARD_ATTR_MAX_IFSD)
2650 else if (dwAttrId == SCARD_ATTR_CHARACTERISTICS)
2653 else if (dwAttrId == SCARD_ATTR_DEVICE_SYSTEM_NAME_A)
2656 else if (dwAttrId == SCARD_ATTR_DEVICE_UNIT)
2659 else if (dwAttrId == SCARD_ATTR_POWER_MGMT_SUPPORT)
2662 else if (dwAttrId == SCARD_ATTR_CURRENT_CLK)
2665 else if (dwAttrId == SCARD_ATTR_CURRENT_F)
2668 else if (dwAttrId == SCARD_ATTR_CURRENT_D)
2671 else if (dwAttrId == SCARD_ATTR_CURRENT_N)
2674 else if (dwAttrId == SCARD_ATTR_CURRENT_CWT)
2677 else if (dwAttrId == SCARD_ATTR_CURRENT_BWT)
2680 else if (dwAttrId == SCARD_ATTR_CURRENT_IFSC)
2683 else if (dwAttrId == SCARD_ATTR_CURRENT_EBC_ENCODING)
2686 else if (dwAttrId == SCARD_ATTR_CURRENT_IFSD)
2689 else if (dwAttrId == SCARD_ATTR_ICC_TYPE_PER_ATR)
2697 static LONG WINAPI PCSC_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
2700 PCSC_LONG status = SCARD_S_SUCCESS;
2701 PCSC_SCARDHANDLE* pCard = NULL;
2702 PCSC_DWORD pcsc_dwAttrId = (PCSC_DWORD)dwAttrId;
2703 PCSC_DWORD pcsc_cbAttrLen = (PCSC_DWORD)cbAttrLen;
2705 if (!g_PCSC.pfnSCardSetAttrib)
2706 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardSetAttrib");
2708 pCard = PCSC_GetCardHandleData(hCard);
2711 return SCARD_E_INVALID_VALUE;
2713 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2714 status = g_PCSC.pfnSCardSetAttrib(hCard, pcsc_dwAttrId, pbAttr, pcsc_cbAttrLen);
2715 return PCSC_MapErrorCodeToWinSCard(status);
2718 static LONG WINAPI PCSC_SCardUIDlgSelectCardA(LPOPENCARDNAMEA_EX pDlgStruc)
2720 WINPR_UNUSED(pDlgStruc);
2722 return SCARD_E_UNSUPPORTED_FEATURE;
2725 static LONG WINAPI PCSC_SCardUIDlgSelectCardW(LPOPENCARDNAMEW_EX pDlgStruc)
2727 WINPR_UNUSED(pDlgStruc);
2728 return SCARD_E_UNSUPPORTED_FEATURE;
2733 WINPR_UNUSED(pDlgStruc);
2734 return SCARD_E_UNSUPPORTED_FEATURE;
2739 WINPR_UNUSED(pDlgStruc);
2740 return SCARD_E_UNSUPPORTED_FEATURE;
2743 static LONG WINAPI PCSC_SCardDlgExtendedError(
void)
2746 return SCARD_E_UNSUPPORTED_FEATURE;
2749 static char* card_id_and_name_a(
const UUID* CardIdentifier, LPCSTR LookupName)
2751 WINPR_ASSERT(CardIdentifier);
2752 WINPR_ASSERT(LookupName);
2754 size_t len = strlen(LookupName) + 34;
2755 char*
id = malloc(len);
2759 (void)snprintf(
id, len,
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X\\%s",
2760 CardIdentifier->Data1, CardIdentifier->Data2, CardIdentifier->Data3,
2761 CardIdentifier->Data4[0], CardIdentifier->Data4[1], CardIdentifier->Data4[2],
2762 CardIdentifier->Data4[3], CardIdentifier->Data4[4], CardIdentifier->Data4[5],
2763 CardIdentifier->Data4[6], CardIdentifier->Data4[7], LookupName);
2767 static char* card_id_and_name_w(
const UUID* CardIdentifier, LPCWSTR LookupName)
2770 char* tmp = ConvertWCharToUtf8Alloc(LookupName, NULL);
2773 res = card_id_and_name_a(CardIdentifier, tmp);
2778 static LONG WINAPI PCSC_SCardReadCacheA(SCARDCONTEXT hContext, UUID* CardIdentifier,
2779 DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data,
2782 PCSC_CACHE_ITEM* data = NULL;
2783 PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext);
2785 return SCARD_E_INVALID_HANDLE;
2787 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2789 data = HashTable_GetItemValue(ctx->cache,
id);
2794 return SCARD_W_CACHE_ITEM_NOT_FOUND;
2797 if (FreshnessCounter != data->freshness)
2800 return SCARD_W_CACHE_ITEM_STALE;
2803 if (*DataLen == SCARD_AUTOALLOCATE)
2805 BYTE* mem = calloc(1, data->len);
2807 return SCARD_E_NO_MEMORY;
2809 if (!PCSC_AddMemoryBlock(hContext, mem))
2812 return SCARD_E_NO_MEMORY;
2815 memcpy(mem, data->data, data->len);
2816 *(BYTE**)Data = mem;
2819 memcpy(Data, data->data, data->len);
2820 *DataLen = data->len;
2821 return SCARD_S_SUCCESS;
2824 static LONG WINAPI PCSC_SCardReadCacheW(SCARDCONTEXT hContext, UUID* CardIdentifier,
2825 DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data,
2828 PCSC_CACHE_ITEM* data = NULL;
2829 PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext);
2831 return SCARD_E_INVALID_HANDLE;
2833 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2835 data = HashTable_GetItemValue(ctx->cache,
id);
2841 return SCARD_W_CACHE_ITEM_NOT_FOUND;
2844 if (FreshnessCounter != data->freshness)
2847 return SCARD_W_CACHE_ITEM_STALE;
2850 if (*DataLen == SCARD_AUTOALLOCATE)
2852 BYTE* mem = calloc(1, data->len);
2854 return SCARD_E_NO_MEMORY;
2856 if (!PCSC_AddMemoryBlock(hContext, mem))
2859 return SCARD_E_NO_MEMORY;
2862 memcpy(mem, data->data, data->len);
2863 *(BYTE**)Data = mem;
2866 memcpy(Data, data->data, data->len);
2867 *DataLen = data->len;
2868 return SCARD_S_SUCCESS;
2871 static LONG WINAPI PCSC_SCardWriteCacheA(SCARDCONTEXT hContext, UUID* CardIdentifier,
2872 DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data,
2875 PCSC_CACHE_ITEM* data = NULL;
2876 PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext);
2880 return SCARD_E_FILE_NOT_FOUND;
2882 id = card_id_and_name_a(CardIdentifier, LookupName);
2885 return SCARD_E_NO_MEMORY;
2887 data = malloc(
sizeof(PCSC_CACHE_ITEM));
2891 return SCARD_E_NO_MEMORY;
2893 data->data = calloc(DataLen, 1);
2898 return SCARD_E_NO_MEMORY;
2900 data->len = DataLen;
2901 data->freshness = FreshnessCounter;
2902 memcpy(data->data, Data, data->len);
2904 HashTable_Remove(ctx->cache,
id);
2905 const BOOL rc = HashTable_Insert(ctx->cache,
id, data);
2910 pcsc_cache_item_free(data);
2911 return SCARD_E_NO_MEMORY;
2915 return SCARD_S_SUCCESS;
2918 static LONG WINAPI PCSC_SCardWriteCacheW(SCARDCONTEXT hContext, UUID* CardIdentifier,
2919 DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data,
2922 PCSC_CACHE_ITEM* data = NULL;
2923 PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext);
2926 return SCARD_E_FILE_NOT_FOUND;
2928 id = card_id_and_name_w(CardIdentifier, LookupName);
2931 return SCARD_E_NO_MEMORY;
2933 data = malloc(
sizeof(PCSC_CACHE_ITEM));
2937 return SCARD_E_NO_MEMORY;
2939 data->data = malloc(DataLen);
2944 return SCARD_E_NO_MEMORY;
2946 data->len = DataLen;
2947 data->freshness = FreshnessCounter;
2948 memcpy(data->data, Data, data->len);
2950 HashTable_Remove(ctx->cache,
id);
2951 const BOOL rc = HashTable_Insert(ctx->cache,
id, data);
2956 pcsc_cache_item_free(data);
2957 return SCARD_E_NO_MEMORY;
2961 return SCARD_S_SUCCESS;
2965 PCSC_SCardGetReaderIconA(SCARDCONTEXT hContext, LPCSTR szReaderName,
2969 WINPR_UNUSED(hContext);
2970 WINPR_UNUSED(szReaderName);
2971 WINPR_UNUSED(pbIcon);
2972 WINPR_UNUSED(pcbIcon);
2973 return SCARD_E_UNSUPPORTED_FEATURE;
2977 PCSC_SCardGetReaderIconW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
2981 WINPR_UNUSED(hContext);
2982 WINPR_UNUSED(szReaderName);
2983 WINPR_UNUSED(pbIcon);
2984 WINPR_UNUSED(pcbIcon);
2985 return SCARD_E_UNSUPPORTED_FEATURE;
2988 static LONG WINAPI PCSC_SCardGetDeviceTypeIdA(SCARDCONTEXT hContext, LPCSTR szReaderName,
2989 LPDWORD pdwDeviceTypeId)
2991 WINPR_UNUSED(hContext);
2992 WINPR_UNUSED(szReaderName);
2993 WINPR_UNUSED(pdwDeviceTypeId);
2994 if (pdwDeviceTypeId)
2995 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2996 return SCARD_S_SUCCESS;
2999 static LONG WINAPI PCSC_SCardGetDeviceTypeIdW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
3000 LPDWORD pdwDeviceTypeId)
3002 WINPR_UNUSED(hContext);
3003 WINPR_UNUSED(szReaderName);
3004 if (pdwDeviceTypeId)
3005 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
3006 return SCARD_S_SUCCESS;
3009 static LONG WINAPI PCSC_SCardGetReaderDeviceInstanceIdA(
3010 SCARDCONTEXT hContext, LPCSTR szReaderName,
3011 LPSTR szDeviceInstanceId ,
3012 LPDWORD pcchDeviceInstanceId )
3014 WINPR_UNUSED(hContext);
3015 WINPR_UNUSED(szReaderName);
3016 WINPR_UNUSED(szDeviceInstanceId);
3017 WINPR_UNUSED(pcchDeviceInstanceId);
3018 return SCARD_E_UNSUPPORTED_FEATURE;
3021 static LONG WINAPI PCSC_SCardGetReaderDeviceInstanceIdW(
3022 SCARDCONTEXT hContext, LPCWSTR szReaderName,
3023 LPWSTR szDeviceInstanceId ,
3024 LPDWORD pcchDeviceInstanceId )
3026 WINPR_UNUSED(hContext);
3027 WINPR_UNUSED(szReaderName);
3028 WINPR_UNUSED(szDeviceInstanceId);
3029 WINPR_UNUSED(pcchDeviceInstanceId);
3030 return SCARD_E_UNSUPPORTED_FEATURE;
3033 static LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdA(
3034 SCARDCONTEXT hContext, LPCSTR szDeviceInstanceId,
3036 LPDWORD pcchReaders )
3038 WINPR_UNUSED(hContext);
3039 WINPR_UNUSED(szDeviceInstanceId);
3040 WINPR_UNUSED(mszReaders);
3041 WINPR_UNUSED(pcchReaders);
3042 return SCARD_E_UNSUPPORTED_FEATURE;
3045 static LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdW(
3046 SCARDCONTEXT hContext, LPCWSTR szDeviceInstanceId,
3048 LPDWORD pcchReaders )
3050 WINPR_UNUSED(hContext);
3051 WINPR_UNUSED(szDeviceInstanceId);
3052 WINPR_UNUSED(mszReaders);
3053 WINPR_UNUSED(pcchReaders);
3054 return SCARD_E_UNSUPPORTED_FEATURE;
3057 static LONG WINAPI PCSC_SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent)
3060 WINPR_UNUSED(hContext);
3061 WINPR_UNUSED(dwEvent);
3062 return SCARD_E_UNSUPPORTED_FEATURE;
3066 unsigned int determineMacOSXVersion(
void)
3070 char* kernelVersion = NULL;
3072 unsigned int version = 0;
3073 long majorVersion = 0;
3074 long minorVersion = 0;
3075 long patchVersion = 0;
3077 char* context = NULL;
3079 mib[1] = KERN_OSRELEASE;
3081 if (sysctl(mib, 2, NULL, &len, NULL, 0) != 0)
3084 kernelVersion = calloc(len,
sizeof(
char));
3089 if (sysctl(mib, 2, kernelVersion, &len, NULL, 0) != 0)
3091 free(kernelVersion);
3095 tok = strtok_s(kernelVersion,
".", &context);
3103 majorVersion = strtol(tok, NULL, 0);
3111 minorVersion = strtol(tok, NULL, 0);
3119 patchVersion = strtol(tok, NULL, 0);
3127 tok = strtok_s(NULL,
".", &context);
3134 if (majorVersion < 5)
3136 if (minorVersion < 4)
3137 version = 0x10000000;
3139 version = 0x10010000;
3143 switch (majorVersion)
3146 version = 0x10010000;
3150 version = 0x10020000;
3154 version = 0x10030000;
3158 version = 0x10040000;
3162 version = 0x10050000;
3166 version = 0x10060000;
3170 version = 0x10070000;
3174 version = 0x10080000;
3178 version = 0x10090000;
3182 version = 0x10100000;
3186 version |= (minorVersion << 8) | (patchVersion);
3190 free(kernelVersion);
3199 PCSC_SCardEstablishContext,
3200 PCSC_SCardReleaseContext,
3201 PCSC_SCardIsValidContext,
3202 PCSC_SCardListReaderGroupsA,
3203 PCSC_SCardListReaderGroupsW,
3204 PCSC_SCardListReadersA,
3205 PCSC_SCardListReadersW,
3206 PCSC_SCardListCardsA,
3207 PCSC_SCardListCardsW,
3208 PCSC_SCardListInterfacesA,
3209 PCSC_SCardListInterfacesW,
3210 PCSC_SCardGetProviderIdA,
3211 PCSC_SCardGetProviderIdW,
3212 PCSC_SCardGetCardTypeProviderNameA,
3213 PCSC_SCardGetCardTypeProviderNameW,
3214 PCSC_SCardIntroduceReaderGroupA,
3215 PCSC_SCardIntroduceReaderGroupW,
3216 PCSC_SCardForgetReaderGroupA,
3217 PCSC_SCardForgetReaderGroupW,
3218 PCSC_SCardIntroduceReaderA,
3219 PCSC_SCardIntroduceReaderW,
3220 PCSC_SCardForgetReaderA,
3221 PCSC_SCardForgetReaderW,
3222 PCSC_SCardAddReaderToGroupA,
3223 PCSC_SCardAddReaderToGroupW,
3224 PCSC_SCardRemoveReaderFromGroupA,
3225 PCSC_SCardRemoveReaderFromGroupW,
3226 PCSC_SCardIntroduceCardTypeA,
3227 PCSC_SCardIntroduceCardTypeW,
3228 PCSC_SCardSetCardTypeProviderNameA,
3229 PCSC_SCardSetCardTypeProviderNameW,
3230 PCSC_SCardForgetCardTypeA,
3231 PCSC_SCardForgetCardTypeW,
3232 PCSC_SCardFreeMemory,
3233 PCSC_SCardAccessStartedEvent,
3234 PCSC_SCardReleaseStartedEvent,
3235 PCSC_SCardLocateCardsA,
3236 PCSC_SCardLocateCardsW,
3237 PCSC_SCardLocateCardsByATRA,
3238 PCSC_SCardLocateCardsByATRW,
3239 PCSC_SCardGetStatusChangeA,
3240 PCSC_SCardGetStatusChangeW,
3244 PCSC_SCardReconnect,
3245 PCSC_SCardDisconnect,
3246 PCSC_SCardBeginTransaction,
3247 PCSC_SCardEndTransaction,
3248 PCSC_SCardCancelTransaction,
3253 PCSC_SCardGetTransmitCount,
3255 PCSC_SCardGetAttrib,
3256 PCSC_SCardSetAttrib,
3257 PCSC_SCardUIDlgSelectCardA,
3258 PCSC_SCardUIDlgSelectCardW,
3259 PCSC_GetOpenCardNameA,
3260 PCSC_GetOpenCardNameW,
3261 PCSC_SCardDlgExtendedError,
3262 PCSC_SCardReadCacheA,
3263 PCSC_SCardReadCacheW,
3264 PCSC_SCardWriteCacheA,
3265 PCSC_SCardWriteCacheW,
3266 PCSC_SCardGetReaderIconA,
3267 PCSC_SCardGetReaderIconW,
3268 PCSC_SCardGetDeviceTypeIdA,
3269 PCSC_SCardGetDeviceTypeIdW,
3270 PCSC_SCardGetReaderDeviceInstanceIdA,
3271 PCSC_SCardGetReaderDeviceInstanceIdW,
3272 PCSC_SCardListReadersWithDeviceInstanceIdA,
3273 PCSC_SCardListReadersWithDeviceInstanceIdW,
3279 return &PCSC_SCardApiFunctionTable;
3282 int PCSC_InitializeSCardApi(
void)
3285 SetEnvironmentVariableA(
"PCSCLITE_NO_BLOCKING",
"1");
3287 g_PCSCModule = LoadLibraryX(
"/System/Library/Frameworks/PCSC.framework/PCSC");
3288 OSXVersion = determineMacOSXVersion();
3290 if (OSXVersion == 0)
3294 g_PCSCModule = LoadLibraryA(
"libpcsclite.so.1");
3297 g_PCSCModule = LoadLibraryA(
"libpcsclite.so");
3306 #undef SCardListReaderGroups
3307 #undef SCardListReaders
3308 #undef SCardListCards
3309 #undef SCardListInterfaces
3310 #undef SCardGetProviderId
3311 #undef SCardGetCardTypeProviderName
3312 #undef SCardIntroduceReaderGroup
3313 #undef SCardForgetReaderGroup
3314 #undef SCardIntroduceReader
3315 #undef SCardForgetReader
3316 #undef SCardAddReaderToGroup
3317 #undef SCardRemoveReaderFromGroup
3318 #undef SCardIntroduceCardType
3319 #undef SCardSetCardTypeProviderName
3320 #undef SCardForgetCardType
3321 #undef SCardLocateCards
3322 #undef SCardLocateCardsByATR
3323 #undef SCardGetStatusChange
3326 #undef SCardUIDlgSelectCard
3327 #undef GetOpenCardName
3328 #undef SCardReadCache
3329 #undef SCardWriteCache
3330 #undef SCardGetReaderIcon
3331 #undef SCardGetDeviceTypeId
3332 #undef SCardGetReaderDeviceInstanceId
3333 #undef SCardListReadersWithDeviceInstanceId
3335 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardEstablishContext);
3336 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardReleaseContext);
3337 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardIsValidContext);
3338 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardConnect);
3339 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardReconnect);
3340 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardDisconnect);
3341 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardBeginTransaction);
3342 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardEndTransaction);
3343 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardStatus);
3344 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardGetStatusChange);
3348 if (OSXVersion >= 0x10050600)
3350 WINSCARD_LOAD_PROC_EX(g_PCSCModule, g_PCSC, SCardControl, SCardControl132);
3354 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardControl);
3357 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardControl);
3359 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardTransmit);
3360 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardListReaderGroups);
3361 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardListReaders);
3362 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardCancel);
3363 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardGetAttrib);
3364 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardSetAttrib);
3365 g_PCSC.pfnSCardFreeMemory = NULL;
3367 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardFreeMemory);
3370 if (g_PCSC.pfnSCardFreeMemory)
3371 g_SCardAutoAllocate = TRUE;
3373 #ifdef DISABLE_PCSC_SCARD_AUTOALLOCATE
3374 g_PCSC.pfnSCardFreeMemory = NULL;
3375 g_SCardAutoAllocate = FALSE;
3378 g_PnP_Notification = FALSE;
This struct contains function pointer to initialize/free objects.