22#include <winpr/config.h>
29#include <sys/sysctl.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)
131typedef PCSC_LONG (*fnPCSCSCardEstablishContext)(PCSC_DWORD dwScope, LPCVOID pvReserved1,
132 LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
133typedef PCSC_LONG (*fnPCSCSCardReleaseContext)(SCARDCONTEXT hContext);
134typedef PCSC_LONG (*fnPCSCSCardIsValidContext)(SCARDCONTEXT hContext);
135typedef PCSC_LONG (*fnPCSCSCardConnect)(SCARDCONTEXT hContext, LPCSTR szReader,
136 PCSC_DWORD dwShareMode, PCSC_DWORD dwPreferredProtocols,
137 LPSCARDHANDLE phCard, PCSC_LPDWORD pdwActiveProtocol);
138typedef PCSC_LONG (*fnPCSCSCardReconnect)(SCARDHANDLE hCard, PCSC_DWORD dwShareMode,
139 PCSC_DWORD dwPreferredProtocols,
140 PCSC_DWORD dwInitialization,
141 PCSC_LPDWORD pdwActiveProtocol);
142typedef PCSC_LONG (*fnPCSCSCardDisconnect)(SCARDHANDLE hCard, PCSC_DWORD dwDisposition);
143typedef PCSC_LONG (*fnPCSCSCardBeginTransaction)(SCARDHANDLE hCard);
144typedef PCSC_LONG (*fnPCSCSCardEndTransaction)(SCARDHANDLE hCard, PCSC_DWORD dwDisposition);
145typedef PCSC_LONG (*fnPCSCSCardStatus)(SCARDHANDLE hCard, LPSTR mszReaderName,
146 PCSC_LPDWORD pcchReaderLen, PCSC_LPDWORD pdwState,
147 PCSC_LPDWORD pdwProtocol, LPBYTE pbAtr,
148 PCSC_LPDWORD pcbAtrLen);
149typedef PCSC_LONG (*fnPCSCSCardGetStatusChange)(SCARDCONTEXT hContext, PCSC_DWORD dwTimeout,
151 PCSC_DWORD cReaders);
152typedef 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);
160typedef PCSC_LONG (*fnPCSCSCardListReaderGroups)(SCARDCONTEXT hContext, LPSTR mszGroups,
161 PCSC_LPDWORD pcchGroups);
162typedef PCSC_LONG (*fnPCSCSCardListReaders)(SCARDCONTEXT hContext, LPCSTR mszGroups,
163 LPSTR mszReaders, PCSC_LPDWORD pcchReaders);
164typedef PCSC_LONG (*fnPCSCSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem);
165typedef PCSC_LONG (*fnPCSCSCardCancel)(SCARDCONTEXT hContext);
166typedef PCSC_LONG (*fnPCSCSCardGetAttrib)(SCARDHANDLE hCard, PCSC_DWORD dwAttrId, LPBYTE pbAttr,
167 PCSC_LPDWORD pcbAttrLen);
168typedef 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;
216static HMODULE g_PCSCModule = NULL;
217static PCSCFunctionTable g_PCSC = { 0 };
219static HANDLE g_StartedEvent = NULL;
220static int g_StartedEventRefCount = 0;
222static BOOL g_SCardAutoAllocate = FALSE;
223static BOOL g_PnP_Notification = TRUE;
226static unsigned int OSXVersion = 0;
229static wListDictionary* g_CardHandles = NULL;
230static wListDictionary* g_CardContexts = NULL;
231static wListDictionary* g_MemoryBlocks = NULL;
233static const char SMARTCARD_PNP_NOTIFICATION_A[] =
"\\\\?PnP?\\Notification";
242static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPVOID pvMem);
243static LONG WINAPI PCSC_SCardEstablishContext_Internal(DWORD dwScope, LPCVOID pvReserved1,
245 LPSCARDCONTEXT phContext);
246static LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext);
248static LONG PCSC_SCard_LogError(
const char* what)
250 WLog_WARN(TAG,
"Missing function pointer %s=NULL", what);
251 return SCARD_E_UNSUPPORTED_FEATURE;
254static 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;
273static 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;
321static 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;
341static 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;
366static PCSC_SCARDCONTEXT* PCSC_GetCardContextData(SCARDCONTEXT hContext)
368 PCSC_SCARDCONTEXT* pContext = NULL;
373 pContext = (PCSC_SCARDCONTEXT*)ListDictionary_GetItemValue(g_CardContexts, (
void*)hContext);
381static void pcsc_cache_item_free(
void* ptr)
383 PCSC_CACHE_ITEM* data = ptr;
389static 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));
432static 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);
453static 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));
468static 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));
483static PCSC_SCARDHANDLE* PCSC_GetCardHandleData(SCARDHANDLE hCard)
485 PCSC_SCARDHANDLE* pCard = NULL;
490 pCard = (PCSC_SCARDHANDLE*)ListDictionary_GetItemValue(g_CardHandles, (
void*)hCard);
498static SCARDCONTEXT PCSC_GetCardContextFromHandle(SCARDHANDLE hCard)
500 PCSC_SCARDHANDLE* pCard = NULL;
501 pCard = PCSC_GetCardHandleData(hCard);
506 return pCard->hSharedContext;
509static 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)
563static 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)
611static 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++;
648static 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--;
674static BOOL PCSC_AddMemoryBlock(SCARDCONTEXT hContext,
void* pvMem)
678 g_MemoryBlocks = ListDictionary_New(TRUE);
684 return ListDictionary_Add(g_MemoryBlocks, pvMem, (
void*)hContext);
687static void* PCSC_RemoveMemoryBlock(SCARDCONTEXT hContext,
void* pvMem)
689 WINPR_UNUSED(hContext);
694 return ListDictionary_Take(g_MemoryBlocks, pvMem);
701static 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);
716static 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);
729static 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);
746static 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);
758static 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);
769static 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);
821static 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;
840static 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;
873static 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);
926static 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);
961static 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;
987 mszGroupsA = ConvertWCharToUtf8Alloc(mszGroups, NULL);
989 return SCARD_E_NO_MEMORY;
997 cnv.ppc = &mszReadersA;
999 status = PCSC_SCardListReaders_Internal(hContext, mszGroupsA, cnv.pc, pcchReaders);
1001 if (status == SCARD_S_SUCCESS)
1004 WCHAR* str = ConvertMszUtf8NToWCharAlloc(mszReadersA, *pcchReaders, &size);
1005 PCSC_SCardFreeMemory_Internal(hContext, mszReadersA);
1006 if (!str || (size > UINT32_MAX))
1007 return SCARD_E_NO_MEMORY;
1009 *(LPWSTR*)mszReaders = str;
1010 *pcchReaders = (DWORD)size;
1011 PCSC_AddMemoryBlock(hContext, str);
1014 if (!PCSC_UnlockCardContext(hContext))
1015 return SCARD_E_INVALID_HANDLE;
1017 if (nullCardContext)
1019 status = PCSC_SCardReleaseContext(hContext);
1029 const char* cardName;
1032static PcscKnownAtr knownAtrs[] = {
1034 { { 0x3B, 0xFD, 0x13, 0x00, 0x00, 0x81, 0x31, 0xFE, 0x15, 0x80, 0x73, 0xC0,
1035 0x21, 0xC0, 0x57, 0x59, 0x75, 0x62, 0x69, 0x4B, 0x65, 0x79, 0x40 },
1037 "NIST SP 800-73 [PIV]" },
1039 { { 0x3B, 0xFC, 0x18, 0x00, 0x00, 0x81, 0x31, 0x80, 0x45, 0x90, 0x67,
1040 0x46, 0x4A, 0x00, 0x64, 0x16, 0x06, 0xF2, 0x72, 0x7E, 0x00, 0xE0 },
1042 "PIVKey Feitian (E0)" }
1046#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a)[0])
1049static const char* findCardByAtr(LPCBYTE pbAtr)
1051 for (
size_t i = 0; i < ARRAY_LENGTH(knownAtrs); i++)
1053 if (memcmp(knownAtrs[i].atr, pbAtr, knownAtrs[i].atrLen) == 0)
1054 return knownAtrs[i].cardName;
1060static LONG WINAPI PCSC_SCardListCardsA(WINPR_ATTR_UNUSED SCARDCONTEXT hContext, LPCBYTE pbAtr,
1061 LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
1062 CHAR* mszCards, LPDWORD pcchCards)
1064 const char* cardName = NULL;
1065 DWORD outputLen = 1;
1066 CHAR* output = NULL;
1067 BOOL autoAllocate = 0;
1069 if (!pbAtr || rgquidInterfaces || cguidInterfaceCount)
1070 return SCARD_E_UNSUPPORTED_FEATURE;
1073 return SCARD_E_INVALID_PARAMETER;
1075 autoAllocate = (*pcchCards == SCARD_AUTOALLOCATE);
1077 cardName = findCardByAtr(pbAtr);
1079 outputLen += strlen(cardName) + 1;
1081 *pcchCards = outputLen;
1084 output = malloc(outputLen);
1086 return SCARD_E_NO_MEMORY;
1088 *((LPSTR*)mszCards) = output;
1093 return SCARD_S_SUCCESS;
1095 if (*pcchCards < outputLen)
1096 return SCARD_E_INSUFFICIENT_BUFFER;
1103 size_t toCopy = strlen(cardName) + 1;
1104 memcpy(output, cardName, toCopy);
1110 return SCARD_S_SUCCESS;
1113static LONG WINAPI PCSC_SCardListCardsW(WINPR_ATTR_UNUSED SCARDCONTEXT hContext, LPCBYTE pbAtr,
1114 LPCGUID rgquidInterfaces, DWORD cguidInterfaceCount,
1115 WCHAR* mszCards, LPDWORD pcchCards)
1117 const char* cardName = NULL;
1118 DWORD outputLen = 1;
1119 WCHAR* output = NULL;
1120 BOOL autoAllocate = 0;
1122 if (!pbAtr || rgquidInterfaces || cguidInterfaceCount)
1123 return SCARD_E_UNSUPPORTED_FEATURE;
1126 return SCARD_E_INVALID_PARAMETER;
1128 autoAllocate = (*pcchCards == SCARD_AUTOALLOCATE);
1130 cardName = findCardByAtr(pbAtr);
1132 outputLen += strlen(cardName) + 1;
1134 *pcchCards = outputLen;
1137 output = calloc(outputLen,
sizeof(WCHAR));
1139 return SCARD_E_NO_MEMORY;
1141 *((LPWSTR*)mszCards) = output;
1146 return SCARD_S_SUCCESS;
1148 if (*pcchCards < outputLen)
1149 return SCARD_E_INSUFFICIENT_BUFFER;
1156 size_t toCopy = strlen(cardName) + 1;
1157 if (ConvertUtf8ToWChar(cardName, output, toCopy) < 0)
1158 return SCARD_F_INTERNAL_ERROR;
1164 return SCARD_S_SUCCESS;
1168PCSC_SCardListInterfacesA(SCARDCONTEXT hContext, LPCSTR szCard, LPGUID pguidInterfaces,
1169 LPDWORD pcguidInterfaces )
1171 WINPR_UNUSED(hContext);
1172 WINPR_UNUSED(szCard);
1173 WINPR_UNUSED(pguidInterfaces);
1174 WINPR_UNUSED(pcguidInterfaces);
1175 return SCARD_E_UNSUPPORTED_FEATURE;
1179PCSC_SCardListInterfacesW(SCARDCONTEXT hContext, LPCWSTR szCard, LPGUID pguidInterfaces,
1180 LPDWORD pcguidInterfaces )
1182 WINPR_UNUSED(hContext);
1183 WINPR_UNUSED(szCard);
1184 WINPR_UNUSED(pguidInterfaces);
1185 WINPR_UNUSED(pcguidInterfaces);
1186 return SCARD_E_UNSUPPORTED_FEATURE;
1189static LONG WINAPI PCSC_SCardGetProviderIdA(SCARDCONTEXT hContext, LPCSTR szCard,
1190 LPGUID pguidProviderId)
1192 WINPR_UNUSED(hContext);
1193 WINPR_UNUSED(szCard);
1194 WINPR_UNUSED(pguidProviderId);
1195 return SCARD_E_UNSUPPORTED_FEATURE;
1198static LONG WINAPI PCSC_SCardGetProviderIdW(SCARDCONTEXT hContext, LPCWSTR szCard,
1199 LPGUID pguidProviderId)
1201 WINPR_UNUSED(hContext);
1202 WINPR_UNUSED(szCard);
1203 WINPR_UNUSED(pguidProviderId);
1204 return SCARD_E_UNSUPPORTED_FEATURE;
1207static LONG WINAPI PCSC_SCardGetCardTypeProviderNameA(
1208 SCARDCONTEXT hContext, LPCSTR szCardName, DWORD dwProviderId,
1210 LPDWORD pcchProvider )
1212 WINPR_UNUSED(hContext);
1213 WINPR_UNUSED(szCardName);
1214 WINPR_UNUSED(dwProviderId);
1215 WINPR_UNUSED(szProvider);
1216 WINPR_UNUSED(pcchProvider);
1217 return SCARD_E_UNSUPPORTED_FEATURE;
1220static LONG WINAPI PCSC_SCardGetCardTypeProviderNameW(
1221 SCARDCONTEXT hContext, LPCWSTR szCardName, DWORD dwProviderId,
1223 LPDWORD pcchProvider )
1225 WINPR_UNUSED(hContext);
1226 WINPR_UNUSED(szCardName);
1227 WINPR_UNUSED(dwProviderId);
1228 WINPR_UNUSED(szProvider);
1229 WINPR_UNUSED(pcchProvider);
1230 return SCARD_E_UNSUPPORTED_FEATURE;
1233static LONG WINAPI PCSC_SCardIntroduceReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName)
1235 WINPR_UNUSED(hContext);
1236 WINPR_UNUSED(szGroupName);
1237 return SCARD_E_UNSUPPORTED_FEATURE;
1240static LONG WINAPI PCSC_SCardIntroduceReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName)
1242 WINPR_UNUSED(hContext);
1243 WINPR_UNUSED(szGroupName);
1244 return SCARD_E_UNSUPPORTED_FEATURE;
1247static LONG WINAPI PCSC_SCardForgetReaderGroupA(SCARDCONTEXT hContext, LPCSTR szGroupName)
1249 WINPR_UNUSED(hContext);
1250 WINPR_UNUSED(szGroupName);
1251 return SCARD_E_UNSUPPORTED_FEATURE;
1254static LONG WINAPI PCSC_SCardForgetReaderGroupW(SCARDCONTEXT hContext, LPCWSTR szGroupName)
1256 WINPR_UNUSED(hContext);
1257 WINPR_UNUSED(szGroupName);
1258 return SCARD_E_UNSUPPORTED_FEATURE;
1261static LONG WINAPI PCSC_SCardIntroduceReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName,
1262 LPCSTR szDeviceName)
1264 WINPR_UNUSED(hContext);
1265 WINPR_UNUSED(szReaderName);
1266 WINPR_UNUSED(szDeviceName);
1267 return SCARD_E_UNSUPPORTED_FEATURE;
1270static LONG WINAPI PCSC_SCardIntroduceReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
1271 LPCWSTR szDeviceName)
1273 WINPR_UNUSED(hContext);
1274 WINPR_UNUSED(szReaderName);
1275 WINPR_UNUSED(szDeviceName);
1276 return SCARD_E_UNSUPPORTED_FEATURE;
1279static LONG WINAPI PCSC_SCardForgetReaderA(SCARDCONTEXT hContext, LPCSTR szReaderName)
1281 WINPR_UNUSED(hContext);
1282 WINPR_UNUSED(szReaderName);
1283 return SCARD_E_UNSUPPORTED_FEATURE;
1286static LONG WINAPI PCSC_SCardForgetReaderW(SCARDCONTEXT hContext, LPCWSTR szReaderName)
1288 WINPR_UNUSED(hContext);
1289 WINPR_UNUSED(szReaderName);
1290 return SCARD_E_UNSUPPORTED_FEATURE;
1293static LONG WINAPI PCSC_SCardAddReaderToGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName,
1296 WINPR_UNUSED(hContext);
1297 WINPR_UNUSED(szReaderName);
1298 WINPR_UNUSED(szGroupName);
1299 return SCARD_E_UNSUPPORTED_FEATURE;
1302static LONG WINAPI PCSC_SCardAddReaderToGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
1303 LPCWSTR szGroupName)
1305 WINPR_UNUSED(hContext);
1306 WINPR_UNUSED(szReaderName);
1307 WINPR_UNUSED(szGroupName);
1308 return SCARD_E_UNSUPPORTED_FEATURE;
1311static LONG WINAPI PCSC_SCardRemoveReaderFromGroupA(SCARDCONTEXT hContext, LPCSTR szReaderName,
1314 WINPR_UNUSED(hContext);
1315 WINPR_UNUSED(szReaderName);
1316 WINPR_UNUSED(szGroupName);
1317 return SCARD_E_UNSUPPORTED_FEATURE;
1320static LONG WINAPI PCSC_SCardRemoveReaderFromGroupW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
1321 LPCWSTR szGroupName)
1323 WINPR_UNUSED(hContext);
1324 WINPR_UNUSED(szReaderName);
1325 WINPR_UNUSED(szGroupName);
1326 return SCARD_E_UNSUPPORTED_FEATURE;
1329static LONG WINAPI PCSC_SCardIntroduceCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName,
1330 LPCGUID pguidPrimaryProvider,
1331 LPCGUID rgguidInterfaces, DWORD dwInterfaceCount,
1332 LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen)
1334 WINPR_UNUSED(hContext);
1335 WINPR_UNUSED(szCardName);
1336 WINPR_UNUSED(pguidPrimaryProvider);
1337 WINPR_UNUSED(rgguidInterfaces);
1338 WINPR_UNUSED(dwInterfaceCount);
1339 WINPR_UNUSED(pbAtr);
1340 WINPR_UNUSED(pbAtrMask);
1341 WINPR_UNUSED(cbAtrLen);
1342 return SCARD_E_UNSUPPORTED_FEATURE;
1345static LONG WINAPI PCSC_SCardIntroduceCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName,
1346 LPCGUID pguidPrimaryProvider,
1347 LPCGUID rgguidInterfaces, DWORD dwInterfaceCount,
1348 LPCBYTE pbAtr, LPCBYTE pbAtrMask, DWORD cbAtrLen)
1350 WINPR_UNUSED(hContext);
1351 WINPR_UNUSED(szCardName);
1352 WINPR_UNUSED(pguidPrimaryProvider);
1353 WINPR_UNUSED(rgguidInterfaces);
1354 WINPR_UNUSED(dwInterfaceCount);
1355 WINPR_UNUSED(pbAtr);
1356 WINPR_UNUSED(pbAtrMask);
1357 WINPR_UNUSED(cbAtrLen);
1358 return SCARD_E_UNSUPPORTED_FEATURE;
1361static LONG WINAPI PCSC_SCardSetCardTypeProviderNameA(SCARDCONTEXT hContext, LPCSTR szCardName,
1362 DWORD dwProviderId, LPCSTR szProvider)
1364 WINPR_UNUSED(hContext);
1365 WINPR_UNUSED(szCardName);
1366 WINPR_UNUSED(dwProviderId);
1367 WINPR_UNUSED(szProvider);
1368 return SCARD_E_UNSUPPORTED_FEATURE;
1371static LONG WINAPI PCSC_SCardSetCardTypeProviderNameW(SCARDCONTEXT hContext, LPCWSTR szCardName,
1372 DWORD dwProviderId, LPCWSTR szProvider)
1374 WINPR_UNUSED(hContext);
1375 WINPR_UNUSED(szCardName);
1376 WINPR_UNUSED(dwProviderId);
1377 WINPR_UNUSED(szProvider);
1378 return SCARD_E_UNSUPPORTED_FEATURE;
1381static LONG WINAPI PCSC_SCardForgetCardTypeA(SCARDCONTEXT hContext, LPCSTR szCardName)
1383 WINPR_UNUSED(hContext);
1384 WINPR_UNUSED(szCardName);
1385 return SCARD_E_UNSUPPORTED_FEATURE;
1388static LONG WINAPI PCSC_SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCardName)
1390 WINPR_UNUSED(hContext);
1391 WINPR_UNUSED(szCardName);
1392 return SCARD_E_UNSUPPORTED_FEATURE;
1395static LONG WINAPI PCSC_SCardFreeMemory_Internal(SCARDCONTEXT hContext, LPVOID pvMem)
1397 PCSC_LONG status = SCARD_S_SUCCESS;
1399 if (PCSC_RemoveMemoryBlock(hContext, pvMem))
1402 status = SCARD_S_SUCCESS;
1406 if (g_PCSC.pfnSCardFreeMemory)
1408 status = g_PCSC.pfnSCardFreeMemory(hContext, pvMem);
1412 return PCSC_MapErrorCodeToWinSCard(status);
1415static LONG WINAPI PCSC_SCardFreeMemory(SCARDCONTEXT hContext, LPVOID pvMem)
1417 LONG status = SCARD_S_SUCCESS;
1421 if (!PCSC_LockCardContext(hContext))
1422 return SCARD_E_INVALID_HANDLE;
1425 status = PCSC_SCardFreeMemory_Internal(hContext, pvMem);
1429 if (!PCSC_UnlockCardContext(hContext))
1430 return SCARD_E_INVALID_HANDLE;
1436static HANDLE WINAPI PCSC_SCardAccessStartedEvent(
void)
1439 SCARDCONTEXT hContext = 0;
1441 status = PCSC_SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
1443 if (status != SCARD_S_SUCCESS)
1446 status = PCSC_SCardReleaseContext(hContext);
1448 if (status != SCARD_S_SUCCESS)
1451 if (!g_StartedEvent)
1453 if (!(g_StartedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
1456 if (!SetEvent(g_StartedEvent))
1458 (void)CloseHandle(g_StartedEvent);
1463 g_StartedEventRefCount++;
1464 return g_StartedEvent;
1467static void WINAPI PCSC_SCardReleaseStartedEvent(
void)
1469 g_StartedEventRefCount--;
1471 if (g_StartedEventRefCount == 0)
1475 (void)CloseHandle(g_StartedEvent);
1476 g_StartedEvent = NULL;
1481static LONG WINAPI PCSC_SCardLocateCardsA(SCARDCONTEXT hContext, LPCSTR mszCards,
1484 WINPR_UNUSED(hContext);
1485 WINPR_UNUSED(mszCards);
1486 WINPR_UNUSED(rgReaderStates);
1487 WINPR_UNUSED(cReaders);
1488 return SCARD_E_UNSUPPORTED_FEATURE;
1491static LONG WINAPI PCSC_SCardLocateCardsW(SCARDCONTEXT hContext, LPCWSTR mszCards,
1494 WINPR_UNUSED(hContext);
1495 WINPR_UNUSED(mszCards);
1496 WINPR_UNUSED(rgReaderStates);
1497 WINPR_UNUSED(cReaders);
1498 return SCARD_E_UNSUPPORTED_FEATURE;
1501static LONG WINAPI PCSC_SCardLocateCardsByATRA(SCARDCONTEXT hContext,
LPSCARD_ATRMASK rgAtrMasks,
1505 WINPR_UNUSED(hContext);
1506 WINPR_UNUSED(rgAtrMasks);
1507 WINPR_UNUSED(cAtrs);
1508 WINPR_UNUSED(rgReaderStates);
1509 WINPR_UNUSED(cReaders);
1510 return SCARD_E_UNSUPPORTED_FEATURE;
1513static LONG WINAPI PCSC_SCardLocateCardsByATRW(SCARDCONTEXT hContext,
LPSCARD_ATRMASK rgAtrMasks,
1517 WINPR_UNUSED(hContext);
1518 WINPR_UNUSED(rgAtrMasks);
1519 WINPR_UNUSED(cAtrs);
1520 WINPR_UNUSED(rgReaderStates);
1521 WINPR_UNUSED(cReaders);
1522 return SCARD_E_UNSUPPORTED_FEATURE;
1525static LONG WINAPI PCSC_SCardGetStatusChange_Internal(SCARDCONTEXT hContext, DWORD dwTimeout,
1530 PCSC_DWORD cMappedReaders = 0;
1532 PCSC_LONG status = SCARD_S_SUCCESS;
1533 PCSC_DWORD pcsc_dwTimeout = (PCSC_DWORD)dwTimeout;
1534 PCSC_DWORD pcsc_cReaders = (PCSC_DWORD)cReaders;
1536 if (!g_PCSC.pfnSCardGetStatusChange)
1537 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardGetStatusChange");
1540 return SCARD_S_SUCCESS;
1543 pcsc_dwTimeout = pcsc_dwTimeout ? pcsc_dwTimeout : 1;
1557 map = (INT64*)calloc(pcsc_cReaders,
sizeof(INT64));
1560 return SCARD_E_NO_MEMORY;
1567 return SCARD_E_NO_MEMORY;
1571 for (PCSC_DWORD i = 0; i < pcsc_cReaders; i++)
1573 if (!g_PnP_Notification)
1576 if (!reader->szReader)
1578 if (0 == _stricmp(reader->szReader, SMARTCARD_PNP_NOTIFICATION_A))
1586 states[j].szReader = rgReaderStates[i].szReader;
1587 states[j].dwCurrentState = rgReaderStates[i].dwCurrentState;
1588 states[j].pvUserData = rgReaderStates[i].pvUserData;
1589 states[j].dwEventState = rgReaderStates[i].dwEventState;
1590 states[j].cbAtr = rgReaderStates[i].cbAtr;
1591 CopyMemory(&(states[j].rgbAtr), &(rgReaderStates[i].rgbAtr), PCSC_MAX_ATR_SIZE);
1597 if (cMappedReaders > 0)
1599 status = g_PCSC.pfnSCardGetStatusChange(hContext, pcsc_dwTimeout, states, cMappedReaders);
1603 status = SCARD_S_SUCCESS;
1606 for (PCSC_DWORD i = 0; i < pcsc_cReaders; i++)
1611 PCSC_DWORD k = (PCSC_DWORD)map[i];
1612 rgReaderStates[i].dwCurrentState = (DWORD)states[k].dwCurrentState;
1613 rgReaderStates[i].cbAtr = (DWORD)states[k].cbAtr;
1614 CopyMemory(&(rgReaderStates[i].rgbAtr), &(states[k].rgbAtr), PCSC_MAX_ATR_SIZE);
1615 rgReaderStates[i].dwEventState = (DWORD)states[k].dwEventState;
1620 return PCSC_MapErrorCodeToWinSCard(status);
1623static LONG WINAPI PCSC_SCardGetStatusChangeA(SCARDCONTEXT hContext, DWORD dwTimeout,
1626 LONG status = SCARD_S_SUCCESS;
1628 if (!PCSC_LockCardContext(hContext))
1629 return SCARD_E_INVALID_HANDLE;
1631 status = PCSC_SCardGetStatusChange_Internal(hContext, dwTimeout, rgReaderStates, cReaders);
1633 if (!PCSC_UnlockCardContext(hContext))
1634 return SCARD_E_INVALID_HANDLE;
1639static LONG WINAPI PCSC_SCardGetStatusChangeW(SCARDCONTEXT hContext, DWORD dwTimeout,
1643 LONG status = SCARD_S_SUCCESS;
1645 if (!g_PCSC.pfnSCardGetStatusChange)
1646 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardGetStatusChange");
1648 if (!PCSC_LockCardContext(hContext))
1649 return SCARD_E_INVALID_HANDLE;
1655 (void)PCSC_UnlockCardContext(hContext);
1656 return SCARD_E_NO_MEMORY;
1659 for (DWORD index = 0; index < cReaders; index++)
1664 cur->szReader = ConvertWCharToUtf8Alloc(curReader->szReader, NULL);
1665 cur->pvUserData = curReader->pvUserData;
1666 cur->dwCurrentState = curReader->dwCurrentState;
1667 cur->dwEventState = curReader->dwEventState;
1668 cur->cbAtr = curReader->cbAtr;
1669 CopyMemory(&(cur->rgbAtr), &(curReader->rgbAtr), ARRAYSIZE(cur->rgbAtr));
1672 status = PCSC_SCardGetStatusChange_Internal(hContext, dwTimeout, states, cReaders);
1674 for (DWORD index = 0; index < cReaders; index++)
1676 free((
void*)states[index].szReader);
1677 rgReaderStates[index].pvUserData = states[index].pvUserData;
1678 rgReaderStates[index].dwCurrentState = states[index].dwCurrentState;
1679 rgReaderStates[index].dwEventState = states[index].dwEventState;
1680 rgReaderStates[index].cbAtr = states[index].cbAtr;
1681 CopyMemory(&(rgReaderStates[index].rgbAtr), &(states[index].rgbAtr), 36);
1686 if (!PCSC_UnlockCardContext(hContext))
1687 return SCARD_E_INVALID_HANDLE;
1692static LONG WINAPI PCSC_SCardCancel(SCARDCONTEXT hContext)
1694 PCSC_LONG status = SCARD_S_SUCCESS;
1696 if (!g_PCSC.pfnSCardCancel)
1697 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardCancel");
1699 status = g_PCSC.pfnSCardCancel(hContext);
1700 return PCSC_MapErrorCodeToWinSCard(status);
1703static LONG WINAPI PCSC_SCardConnect_Internal(SCARDCONTEXT hContext, LPCSTR szReader,
1704 DWORD dwShareMode, DWORD dwPreferredProtocols,
1705 LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
1708 const char* szReaderPCSC = NULL;
1709 PCSC_LONG status = SCARD_S_SUCCESS;
1710 PCSC_SCARDHANDLE* pCard = NULL;
1711 PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD)dwShareMode;
1712 PCSC_DWORD pcsc_dwPreferredProtocols = 0;
1713 PCSC_DWORD pcsc_dwActiveProtocol = 0;
1715 if (!g_PCSC.pfnSCardConnect)
1716 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardConnect");
1718 shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE;
1719 PCSC_WaitForCardAccess(hContext, 0, shared);
1720 szReaderPCSC = szReader;
1729 if (pcsc_dwShareMode == SCARD_SHARE_DIRECT && dwPreferredProtocols == SCARD_PROTOCOL_UNDEFINED)
1730 pcsc_dwPreferredProtocols = SCARD_PROTOCOL_UNDEFINED;
1732 pcsc_dwPreferredProtocols =
1733 (PCSC_DWORD)PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
1735 status = g_PCSC.pfnSCardConnect(hContext, szReaderPCSC, pcsc_dwShareMode,
1736 pcsc_dwPreferredProtocols, phCard, &pcsc_dwActiveProtocol);
1738 if (status == SCARD_S_SUCCESS)
1740 pCard = PCSC_ConnectCardHandle(hContext, *phCard);
1741 *pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwActiveProtocol);
1742 pCard->shared = shared;
1745 PCSC_WaitForCardAccess(hContext, pCard->hSharedContext, shared);
1748 return PCSC_MapErrorCodeToWinSCard(status);
1751static LONG WINAPI PCSC_SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
1752 DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
1753 LPDWORD pdwActiveProtocol)
1755 LONG status = SCARD_S_SUCCESS;
1757 if (!PCSC_LockCardContext(hContext))
1758 return SCARD_E_INVALID_HANDLE;
1760 status = PCSC_SCardConnect_Internal(hContext, szReader, dwShareMode, dwPreferredProtocols,
1761 phCard, pdwActiveProtocol);
1763 if (!PCSC_UnlockCardContext(hContext))
1764 return SCARD_E_INVALID_HANDLE;
1769static LONG WINAPI PCSC_SCardConnectW(SCARDCONTEXT hContext, LPCWSTR szReader, DWORD dwShareMode,
1770 DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
1771 LPDWORD pdwActiveProtocol)
1773 LPSTR szReaderA = NULL;
1774 LONG status = SCARD_S_SUCCESS;
1776 if (!PCSC_LockCardContext(hContext))
1777 return SCARD_E_INVALID_HANDLE;
1781 szReaderA = ConvertWCharToUtf8Alloc(szReader, NULL);
1783 return SCARD_E_INSUFFICIENT_BUFFER;
1786 status = PCSC_SCardConnect_Internal(hContext, szReaderA, dwShareMode, dwPreferredProtocols,
1787 phCard, pdwActiveProtocol);
1790 if (!PCSC_UnlockCardContext(hContext))
1791 return SCARD_E_INVALID_HANDLE;
1796static LONG WINAPI PCSC_SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
1797 DWORD dwPreferredProtocols, DWORD dwInitialization,
1798 LPDWORD pdwActiveProtocol)
1801 PCSC_LONG status = SCARD_S_SUCCESS;
1802 PCSC_DWORD pcsc_dwShareMode = (PCSC_DWORD)dwShareMode;
1803 PCSC_DWORD pcsc_dwPreferredProtocols = 0;
1804 PCSC_DWORD pcsc_dwInitialization = (PCSC_DWORD)dwInitialization;
1805 PCSC_DWORD pcsc_dwActiveProtocol = 0;
1807 if (!g_PCSC.pfnSCardReconnect)
1808 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardReconnect");
1810 shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE;
1811 PCSC_WaitForCardAccess(0, hCard, shared);
1812 pcsc_dwPreferredProtocols = (PCSC_DWORD)PCSC_ConvertProtocolsFromWinSCard(dwPreferredProtocols);
1813 status = g_PCSC.pfnSCardReconnect(hCard, pcsc_dwShareMode, pcsc_dwPreferredProtocols,
1814 pcsc_dwInitialization, &pcsc_dwActiveProtocol);
1816 *pdwActiveProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwActiveProtocol);
1817 return PCSC_MapErrorCodeToWinSCard(status);
1820static LONG WINAPI PCSC_SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
1822 PCSC_LONG status = SCARD_S_SUCCESS;
1823 PCSC_DWORD pcsc_dwDisposition = (PCSC_DWORD)dwDisposition;
1825 if (!g_PCSC.pfnSCardDisconnect)
1826 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardDisconnect");
1828 status = g_PCSC.pfnSCardDisconnect(hCard, pcsc_dwDisposition);
1830 if (status == SCARD_S_SUCCESS)
1832 PCSC_DisconnectCardHandle(hCard);
1835 PCSC_ReleaseCardAccess(0, hCard);
1836 return PCSC_MapErrorCodeToWinSCard(status);
1839static LONG WINAPI PCSC_SCardBeginTransaction(SCARDHANDLE hCard)
1841 PCSC_LONG status = SCARD_S_SUCCESS;
1842 PCSC_SCARDHANDLE* pCard = NULL;
1843 PCSC_SCARDCONTEXT* pContext = NULL;
1845 if (!g_PCSC.pfnSCardBeginTransaction)
1846 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardBeginTransaction");
1848 pCard = PCSC_GetCardHandleData(hCard);
1851 return SCARD_E_INVALID_HANDLE;
1853 pContext = PCSC_GetCardContextData(pCard->hSharedContext);
1856 return SCARD_E_INVALID_HANDLE;
1858 if (pContext->isTransactionLocked)
1859 return SCARD_S_SUCCESS;
1861 status = g_PCSC.pfnSCardBeginTransaction(hCard);
1863 pContext->isTransactionLocked = TRUE;
1864 return PCSC_MapErrorCodeToWinSCard(status);
1867static LONG WINAPI PCSC_SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
1869 PCSC_LONG status = SCARD_S_SUCCESS;
1870 PCSC_SCARDHANDLE* pCard = NULL;
1871 PCSC_SCARDCONTEXT* pContext = NULL;
1872 PCSC_DWORD pcsc_dwDisposition = (PCSC_DWORD)dwDisposition;
1874 if (!g_PCSC.pfnSCardEndTransaction)
1875 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardEndTransaction");
1877 pCard = PCSC_GetCardHandleData(hCard);
1880 return SCARD_E_INVALID_HANDLE;
1882 pContext = PCSC_GetCardContextData(pCard->hSharedContext);
1885 return SCARD_E_INVALID_HANDLE;
1887 PCSC_ReleaseCardAccess(0, hCard);
1889 if (!pContext->isTransactionLocked)
1890 return SCARD_S_SUCCESS;
1892 status = g_PCSC.pfnSCardEndTransaction(hCard, pcsc_dwDisposition);
1894 pContext->isTransactionLocked = FALSE;
1895 return PCSC_MapErrorCodeToWinSCard(status);
1898static LONG WINAPI PCSC_SCardCancelTransaction(SCARDHANDLE hCard)
1900 WINPR_UNUSED(hCard);
1901 return SCARD_S_SUCCESS;
1908static LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderNames,
1909 LPDWORD pcchReaderLen, LPDWORD pdwState,
1910 LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen,
1913 PCSC_SCARDHANDLE* pCard = NULL;
1914 SCARDCONTEXT hContext = 0;
1915 PCSC_LONG status = 0;
1916 PCSC_DWORD pcsc_cchReaderLen = 0;
1917 PCSC_DWORD pcsc_cbAtrLen = 0;
1918 PCSC_DWORD pcsc_dwState = 0;
1919 PCSC_DWORD pcsc_dwProtocol = 0;
1920 BOOL allocateReader = FALSE;
1921 BOOL allocateAtr = FALSE;
1922 LPSTR readerNames = mszReaderNames;
1924 LPSTR tReader = NULL;
1927 if (!g_PCSC.pfnSCardStatus)
1928 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardStatus");
1930 pCard = PCSC_GetCardHandleData(hCard);
1933 return SCARD_E_INVALID_VALUE;
1935 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
1936 hContext = PCSC_GetCardContextFromHandle(hCard);
1939 return SCARD_E_INVALID_VALUE;
1942 g_PCSC.pfnSCardStatus(hCard, NULL, &pcsc_cchReaderLen, NULL, NULL, NULL, &pcsc_cbAtrLen);
1944 if (status != STATUS_SUCCESS)
1945 return PCSC_MapErrorCodeToWinSCard(status);
1947 pcsc_cchReaderLen++;
1950 pcsc_cchReaderLen *= 2;
1954 if (*pcchReaderLen == SCARD_AUTOALLOCATE)
1955 allocateReader = TRUE;
1956 else if (mszReaderNames && (*pcchReaderLen < pcsc_cchReaderLen))
1957 return SCARD_E_INSUFFICIENT_BUFFER;
1959 pcsc_cchReaderLen = *pcchReaderLen;
1964 if (*pcbAtrLen == SCARD_AUTOALLOCATE)
1966 else if (pbAtr && (*pcbAtrLen < pcsc_cbAtrLen))
1967 return SCARD_E_INSUFFICIENT_BUFFER;
1969 pcsc_cbAtrLen = *pcbAtrLen;
1972 if (allocateReader && pcsc_cchReaderLen > 0 && mszReaderNames)
1979 if (OSXVersion == 0x10100000)
1980 pcsc_cchReaderLen++;
1983 tReader = calloc(
sizeof(CHAR), pcsc_cchReaderLen + 1);
1987 status = ERROR_NOT_ENOUGH_MEMORY;
1991 readerNames = tReader;
1994 if (allocateAtr && pcsc_cbAtrLen > 0 && pbAtr)
1996 tATR = calloc(1, pcsc_cbAtrLen);
2000 status = ERROR_NOT_ENOUGH_MEMORY;
2007 status = g_PCSC.pfnSCardStatus(hCard, readerNames, &pcsc_cchReaderLen, &pcsc_dwState,
2008 &pcsc_dwProtocol, atr, &pcsc_cbAtrLen);
2010 if (status != STATUS_SUCCESS)
2015 PCSC_AddMemoryBlock(hContext, tATR);
2016 *(BYTE**)pbAtr = tATR;
2024 WCHAR* tmp = ConvertMszUtf8NToWCharAlloc(tReader, pcsc_cchReaderLen + 1, &size);
2028 status = ERROR_NOT_ENOUGH_MEMORY;
2034 PCSC_AddMemoryBlock(hContext, tmp);
2035 *(WCHAR**)mszReaderNames = tmp;
2039 tReader[pcsc_cchReaderLen - 1] =
'\0';
2040 PCSC_AddMemoryBlock(hContext, tReader);
2041 *(
char**)mszReaderNames = tReader;
2045 pcsc_dwState &= 0xFFFF;
2048 *pdwState = PCSC_ConvertCardStateToWinSCard((DWORD)pcsc_dwState, status);
2051 *pdwProtocol = PCSC_ConvertProtocolsToWinSCard((DWORD)pcsc_dwProtocol);
2054 *pcbAtrLen = (DWORD)pcsc_cbAtrLen;
2058 WINPR_ASSERT(pcsc_cchReaderLen < UINT32_MAX);
2059 *pcchReaderLen = (DWORD)pcsc_cchReaderLen + 1u;
2062 return (LONG)status;
2066 return (LONG)status;
2069static LONG WINAPI PCSC_SCardState(SCARDHANDLE hCard, LPDWORD pdwState, LPDWORD pdwProtocol,
2070 LPBYTE pbAtr, LPDWORD pcbAtrLen)
2072 DWORD cchReaderLen = 0;
2073 SCARDCONTEXT hContext = 0;
2074 LPSTR mszReaderNames = NULL;
2075 PCSC_LONG status = SCARD_S_SUCCESS;
2076 PCSC_SCARDHANDLE* pCard = NULL;
2077 DWORD pcsc_dwState = 0;
2078 DWORD pcsc_dwProtocol = 0;
2079 DWORD pcsc_cbAtrLen = 0;
2082 pcsc_cbAtrLen = (DWORD)*pcbAtrLen;
2084 if (!g_PCSC.pfnSCardStatus)
2085 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardStatus");
2087 pCard = PCSC_GetCardHandleData(hCard);
2090 return SCARD_E_INVALID_VALUE;
2092 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2093 hContext = PCSC_GetCardContextFromHandle(hCard);
2096 return SCARD_E_INVALID_VALUE;
2098 cchReaderLen = SCARD_AUTOALLOCATE;
2099 status = PCSC_SCardStatus_Internal(hCard, (LPSTR)&mszReaderNames, &cchReaderLen, &pcsc_dwState,
2100 &pcsc_dwProtocol, pbAtr, &pcsc_cbAtrLen, FALSE);
2103 PCSC_SCardFreeMemory_Internal(hContext, mszReaderNames);
2105 *pdwState = pcsc_dwState;
2106 *pdwProtocol = PCSC_ConvertProtocolsToWinSCard(pcsc_dwProtocol);
2108 *pcbAtrLen = pcsc_cbAtrLen;
2109 return PCSC_MapErrorCodeToWinSCard(status);
2112static LONG WINAPI PCSC_SCardStatusA(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen,
2113 LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
2117 return PCSC_SCardStatus_Internal(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol,
2118 pbAtr, pcbAtrLen, FALSE);
2121static LONG WINAPI PCSC_SCardStatusW(SCARDHANDLE hCard, LPWSTR mszReaderNames,
2122 LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol,
2123 LPBYTE pbAtr, LPDWORD pcbAtrLen)
2126 return PCSC_SCardStatus_Internal(hCard, (LPSTR)mszReaderNames, pcchReaderLen, pdwState,
2127 pdwProtocol, pbAtr, pcbAtrLen, TRUE);
2131 LPCBYTE pbSendBuffer, DWORD cbSendLength,
2133 LPDWORD pcbRecvLength)
2135 PCSC_LONG status = SCARD_S_SUCCESS;
2136 PCSC_SCARDHANDLE* pCard = NULL;
2137 PCSC_DWORD cbExtraBytes = 0;
2138 BYTE* pbExtraBytes = NULL;
2139 BYTE* pcsc_pbExtraBytes = NULL;
2140 PCSC_DWORD pcsc_cbSendLength = (PCSC_DWORD)cbSendLength;
2141 PCSC_DWORD pcsc_cbRecvLength = 0;
2149 } sendPci, recvPci, inRecvPci, inSendPci;
2153 inRecvPci.lps = pioRecvPci;
2154 inSendPci.lpcs = pioSendPci;
2156 if (!g_PCSC.pfnSCardTransmit)
2157 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardTransmit");
2159 pCard = PCSC_GetCardHandleData(hCard);
2162 return SCARD_E_INVALID_VALUE;
2164 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2167 return SCARD_E_INVALID_PARAMETER;
2169 if (*pcbRecvLength == SCARD_AUTOALLOCATE)
2170 return SCARD_E_INVALID_PARAMETER;
2172 pcsc_cbRecvLength = (PCSC_DWORD)*pcbRecvLength;
2174 if (!inSendPci.lpcs)
2176 PCSC_DWORD dwState = 0;
2177 PCSC_DWORD cbAtrLen = 0;
2178 PCSC_DWORD dwProtocol = 0;
2179 PCSC_DWORD cchReaderLen = 0;
2184 status = g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState, &dwProtocol, NULL,
2187 if (status == SCARD_S_SUCCESS)
2189 if (dwProtocol == SCARD_PROTOCOL_T0)
2190 sendPci.pcs = PCSC_SCARD_PCI_T0;
2191 else if (dwProtocol == SCARD_PROTOCOL_T1)
2192 sendPci.pcs = PCSC_SCARD_PCI_T1;
2193 else if (dwProtocol == PCSC_SCARD_PROTOCOL_RAW)
2194 sendPci.pcs = PCSC_SCARD_PCI_RAW;
2203 return SCARD_E_NO_MEMORY;
2205 sendPci.ps->dwProtocol = (PCSC_DWORD)inSendPci.lpcs->dwProtocol;
2209 CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes);
2222 return SCARD_E_NO_MEMORY;
2225 recvPci.ps->dwProtocol = (PCSC_DWORD)inRecvPci.lps->dwProtocol;
2229 CopyMemory(pcsc_pbExtraBytes, pbExtraBytes, cbExtraBytes);
2232 status = g_PCSC.pfnSCardTransmit(hCard, sendPci.ps, pbSendBuffer, pcsc_cbSendLength, recvPci.ps,
2233 pbRecvBuffer, &pcsc_cbRecvLength);
2235 *pcbRecvLength = (DWORD)pcsc_cbRecvLength;
2246 CopyMemory(pbExtraBytes, pcsc_pbExtraBytes, cbExtraBytes);
2251 return PCSC_MapErrorCodeToWinSCard(status);
2255static LONG WINAPI PCSC_SCardGetTransmitCount(SCARDHANDLE hCard, LPDWORD pcTransmitCount)
2257 WINPR_UNUSED(pcTransmitCount);
2258 PCSC_SCARDHANDLE* pCard = NULL;
2260 pCard = PCSC_GetCardHandleData(hCard);
2263 return SCARD_E_INVALID_VALUE;
2265 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2266 return SCARD_S_SUCCESS;
2269static LONG WINAPI PCSC_SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID lpInBuffer,
2270 DWORD cbInBufferSize, LPVOID lpOutBuffer,
2271 DWORD cbOutBufferSize, LPDWORD lpBytesReturned)
2273 DWORD IoCtlFunction = 0;
2274 DWORD IoCtlDeviceType = 0;
2275 BOOL getFeatureRequest = FALSE;
2276 PCSC_LONG status = SCARD_S_SUCCESS;
2277 PCSC_SCARDHANDLE* pCard = NULL;
2278 PCSC_DWORD pcsc_dwControlCode = 0;
2279 PCSC_DWORD pcsc_cbInBufferSize = (PCSC_DWORD)cbInBufferSize;
2280 PCSC_DWORD pcsc_cbOutBufferSize = (PCSC_DWORD)cbOutBufferSize;
2281 PCSC_DWORD pcsc_BytesReturned = 0;
2283 if (!g_PCSC.pfnSCardControl)
2284 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardControl");
2286 pCard = PCSC_GetCardHandleData(hCard);
2289 return SCARD_E_INVALID_VALUE;
2291 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2302 IoCtlFunction = FUNCTION_FROM_CTL_CODE(dwControlCode);
2303 IoCtlDeviceType = DEVICE_TYPE_FROM_CTL_CODE(dwControlCode);
2305 if (dwControlCode == IOCTL_SMARTCARD_GET_FEATURE_REQUEST)
2306 getFeatureRequest = TRUE;
2308 if (IoCtlDeviceType == FILE_DEVICE_SMARTCARD)
2309 dwControlCode = PCSC_SCARD_CTL_CODE(IoCtlFunction);
2311 pcsc_dwControlCode = (PCSC_DWORD)dwControlCode;
2312 status = g_PCSC.pfnSCardControl(hCard, pcsc_dwControlCode, lpInBuffer, pcsc_cbInBufferSize,
2313 lpOutBuffer, pcsc_cbOutBufferSize, &pcsc_BytesReturned);
2315 *lpBytesReturned = (DWORD)pcsc_BytesReturned;
2317 if (getFeatureRequest)
2323 return SCARD_E_UNEXPECTED;
2327 for (DWORD index = 0; index < count; index++)
2329 if (tlv[index].length != 4)
2330 return SCARD_E_UNEXPECTED;
2334 return PCSC_MapErrorCodeToWinSCard(status);
2337static LONG WINAPI PCSC_SCardGetAttrib_Internal(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
2340 SCARDCONTEXT hContext = 0;
2341 BOOL pcbAttrLenAlloc = FALSE;
2342 PCSC_LONG status = SCARD_S_SUCCESS;
2343 PCSC_SCARDHANDLE* pCard = NULL;
2344 PCSC_DWORD pcsc_dwAttrId = (PCSC_DWORD)dwAttrId;
2345 PCSC_DWORD pcsc_cbAttrLen = 0;
2347 if (!g_PCSC.pfnSCardGetAttrib)
2348 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardGetAttrib");
2350 pCard = PCSC_GetCardHandleData(hCard);
2353 return SCARD_E_INVALID_VALUE;
2355 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2356 hContext = PCSC_GetCardContextFromHandle(hCard);
2359 return SCARD_E_INVALID_HANDLE;
2362 return SCARD_E_INVALID_PARAMETER;
2364 if (*pcbAttrLen == SCARD_AUTOALLOCATE)
2367 return SCARD_E_INVALID_PARAMETER;
2368 pcbAttrLenAlloc = TRUE;
2371 pcsc_cbAttrLen = pcbAttrLenAlloc ? PCSC_SCARD_AUTOALLOCATE : (PCSC_DWORD)*pcbAttrLen;
2373 if (pcbAttrLenAlloc && !g_SCardAutoAllocate)
2376 status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, NULL, &pcsc_cbAttrLen);
2378 if (status == SCARD_S_SUCCESS)
2380 BYTE* tmp = (BYTE*)calloc(1, pcsc_cbAttrLen);
2383 return SCARD_E_NO_MEMORY;
2385 status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, tmp, &pcsc_cbAttrLen);
2387 if (status != SCARD_S_SUCCESS)
2393 PCSC_AddMemoryBlock(hContext, tmp);
2394 *(BYTE**)pbAttr = tmp;
2399 status = g_PCSC.pfnSCardGetAttrib(hCard, pcsc_dwAttrId, pbAttr, &pcsc_cbAttrLen);
2402 if (status == SCARD_S_SUCCESS)
2403 *pcbAttrLen = (DWORD)pcsc_cbAttrLen;
2404 return PCSC_MapErrorCodeToWinSCard(status);
2407static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwAttrId,
2408 LPBYTE pbAttr, LPDWORD pcbAttrLen)
2411 char* namePCSC = NULL;
2412 char* pbAttrA = NULL;
2413 DWORD cbAttrLen = 0;
2414 WCHAR* pbAttrW = NULL;
2415 SCARDCONTEXT hContext = 0;
2416 LONG status = SCARD_S_SUCCESS;
2418 hContext = PCSC_GetCardContextFromHandle(hCard);
2421 return SCARD_E_INVALID_HANDLE;
2424 return SCARD_E_INVALID_PARAMETER;
2425 cbAttrLen = *pcbAttrLen;
2426 *pcbAttrLen = SCARD_AUTOALLOCATE;
2427 status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A,
2428 (LPBYTE)&pbAttrA, pcbAttrLen);
2430 if (status != SCARD_S_SUCCESS)
2432 *pcbAttrLen = SCARD_AUTOALLOCATE;
2433 status = PCSC_SCardGetAttrib_Internal(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W,
2434 (LPBYTE)&pbAttrW, pcbAttrLen);
2436 if (status != SCARD_S_SUCCESS)
2439 namePCSC = ConvertMszWCharNToUtf8Alloc(pbAttrW, *pcbAttrLen, NULL);
2440 PCSC_SCardFreeMemory_Internal(hContext, pbAttrW);
2444 namePCSC = _strdup(pbAttrA);
2447 return SCARD_E_NO_MEMORY;
2449 PCSC_SCardFreeMemory_Internal(hContext, pbAttrA);
2452 length = strlen(namePCSC);
2454 if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W)
2457 WCHAR* friendlyNameW = ConvertUtf8ToWCharAlloc(namePCSC, &size);
2461 status = SCARD_E_NO_MEMORY;
2466 if (cbAttrLen == SCARD_AUTOALLOCATE)
2468 WINPR_ASSERT(length <= UINT32_MAX /
sizeof(WCHAR));
2469 *(WCHAR**)pbAttr = friendlyNameW;
2470 *pcbAttrLen = (UINT32)length *
sizeof(WCHAR);
2471 PCSC_AddMemoryBlock(hContext, friendlyNameW);
2475 if ((length * 2) > cbAttrLen)
2476 status = SCARD_E_INSUFFICIENT_BUFFER;
2479 WINPR_ASSERT(length <= UINT32_MAX /
sizeof(WCHAR));
2480 CopyMemory(pbAttr, (BYTE*)friendlyNameW, (length *
sizeof(WCHAR)));
2481 *pcbAttrLen = (UINT32)length *
sizeof(WCHAR);
2483 free(friendlyNameW);
2490 if (cbAttrLen == SCARD_AUTOALLOCATE)
2492 *(CHAR**)pbAttr = namePCSC;
2493 WINPR_ASSERT(length <= UINT32_MAX);
2494 *pcbAttrLen = (UINT32)length;
2495 PCSC_AddMemoryBlock(hContext, namePCSC);
2499 if ((length + 1) > cbAttrLen)
2500 status = SCARD_E_INSUFFICIENT_BUFFER;
2503 CopyMemory(pbAttr, namePCSC, length + 1);
2504 WINPR_ASSERT(length <= UINT32_MAX);
2505 *pcbAttrLen = (UINT32)length;
2514static LONG WINAPI PCSC_SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr,
2517 DWORD cbAttrLen = 0;
2518 SCARDCONTEXT hContext = 0;
2519 BOOL pcbAttrLenAlloc = FALSE;
2520 LONG status = SCARD_S_SUCCESS;
2522 if (NULL == pcbAttrLen)
2523 return SCARD_E_INVALID_PARAMETER;
2525 cbAttrLen = *pcbAttrLen;
2527 if (*pcbAttrLen == SCARD_AUTOALLOCATE)
2530 return SCARD_E_INVALID_PARAMETER;
2532 pcbAttrLenAlloc = TRUE;
2533 *(BYTE**)pbAttr = NULL;
2541 if (*pcbAttrLen > PCSC_MAX_BUFFER_SIZE)
2542 *pcbAttrLen = PCSC_MAX_BUFFER_SIZE;
2545 hContext = PCSC_GetCardContextFromHandle(hCard);
2548 return SCARD_E_INVALID_HANDLE;
2550 if ((dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A) ||
2551 (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W))
2553 status = PCSC_SCardGetAttrib_FriendlyName(hCard, dwAttrId, pbAttr, pcbAttrLen);
2557 status = PCSC_SCardGetAttrib_Internal(hCard, dwAttrId, pbAttr, pcbAttrLen);
2559 if (status == SCARD_S_SUCCESS)
2561 if (dwAttrId == SCARD_ATTR_VENDOR_NAME)
2565 const char* vendorName = NULL;
2572 if (pcbAttrLenAlloc)
2573 vendorName = (
char*)*(BYTE**)pbAttr;
2575 vendorName = (
char*)pbAttr;
2579 size_t len = strnlen(vendorName, *pcbAttrLen);
2580 WINPR_ASSERT(len <= UINT32_MAX);
2581 *pcbAttrLen = (DWORD)len;
2591 if (dwAttrId == SCARD_ATTR_CURRENT_PROTOCOL_TYPE)
2593 if (!pcbAttrLenAlloc)
2595 PCSC_DWORD dwState = 0;
2596 PCSC_DWORD cbAtrLen = 0;
2597 PCSC_DWORD dwProtocol = 0;
2598 PCSC_DWORD cchReaderLen = 0;
2599 status = (LONG)g_PCSC.pfnSCardStatus(hCard, NULL, &cchReaderLen, &dwState,
2600 &dwProtocol, NULL, &cbAtrLen);
2602 if (status == SCARD_S_SUCCESS)
2604 if (cbAttrLen <
sizeof(DWORD))
2605 return SCARD_E_INSUFFICIENT_BUFFER;
2607 *(DWORD*)pbAttr = PCSC_ConvertProtocolsToWinSCard(dwProtocol);
2608 *pcbAttrLen =
sizeof(DWORD);
2612 else if (dwAttrId == SCARD_ATTR_CHANNEL_ID)
2614 if (!pcbAttrLenAlloc)
2616 UINT32 channelType = 0x20;
2617 UINT32 channelNumber = 0;
2619 if (cbAttrLen <
sizeof(DWORD))
2620 return SCARD_E_INSUFFICIENT_BUFFER;
2622 status = SCARD_S_SUCCESS;
2623 *(DWORD*)pbAttr = (channelType << 16u) | channelNumber;
2624 *pcbAttrLen =
sizeof(DWORD);
2627 else if (dwAttrId == SCARD_ATTR_VENDOR_IFD_TYPE)
2630 else if (dwAttrId == SCARD_ATTR_DEFAULT_CLK)
2633 else if (dwAttrId == SCARD_ATTR_DEFAULT_DATA_RATE)
2636 else if (dwAttrId == SCARD_ATTR_MAX_CLK)
2639 else if (dwAttrId == SCARD_ATTR_MAX_DATA_RATE)
2642 else if (dwAttrId == SCARD_ATTR_MAX_IFSD)
2645 else if (dwAttrId == SCARD_ATTR_CHARACTERISTICS)
2648 else if (dwAttrId == SCARD_ATTR_DEVICE_SYSTEM_NAME_A)
2651 else if (dwAttrId == SCARD_ATTR_DEVICE_UNIT)
2654 else if (dwAttrId == SCARD_ATTR_POWER_MGMT_SUPPORT)
2657 else if (dwAttrId == SCARD_ATTR_CURRENT_CLK)
2660 else if (dwAttrId == SCARD_ATTR_CURRENT_F)
2663 else if (dwAttrId == SCARD_ATTR_CURRENT_D)
2666 else if (dwAttrId == SCARD_ATTR_CURRENT_N)
2669 else if (dwAttrId == SCARD_ATTR_CURRENT_CWT)
2672 else if (dwAttrId == SCARD_ATTR_CURRENT_BWT)
2675 else if (dwAttrId == SCARD_ATTR_CURRENT_IFSC)
2678 else if (dwAttrId == SCARD_ATTR_CURRENT_EBC_ENCODING)
2681 else if (dwAttrId == SCARD_ATTR_CURRENT_IFSD)
2684 else if (dwAttrId == SCARD_ATTR_ICC_TYPE_PER_ATR)
2692static LONG WINAPI PCSC_SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
2695 PCSC_LONG status = SCARD_S_SUCCESS;
2696 PCSC_SCARDHANDLE* pCard = NULL;
2697 PCSC_DWORD pcsc_dwAttrId = (PCSC_DWORD)dwAttrId;
2698 PCSC_DWORD pcsc_cbAttrLen = (PCSC_DWORD)cbAttrLen;
2700 if (!g_PCSC.pfnSCardSetAttrib)
2701 return PCSC_SCard_LogError(
"g_PCSC.pfnSCardSetAttrib");
2703 pCard = PCSC_GetCardHandleData(hCard);
2706 return SCARD_E_INVALID_VALUE;
2708 PCSC_WaitForCardAccess(0, hCard, pCard->shared);
2709 status = g_PCSC.pfnSCardSetAttrib(hCard, pcsc_dwAttrId, pbAttr, pcsc_cbAttrLen);
2710 return PCSC_MapErrorCodeToWinSCard(status);
2713static LONG WINAPI PCSC_SCardUIDlgSelectCardA(LPOPENCARDNAMEA_EX pDlgStruc)
2715 WINPR_UNUSED(pDlgStruc);
2717 return SCARD_E_UNSUPPORTED_FEATURE;
2720static LONG WINAPI PCSC_SCardUIDlgSelectCardW(LPOPENCARDNAMEW_EX pDlgStruc)
2722 WINPR_UNUSED(pDlgStruc);
2723 return SCARD_E_UNSUPPORTED_FEATURE;
2728 WINPR_UNUSED(pDlgStruc);
2729 return SCARD_E_UNSUPPORTED_FEATURE;
2734 WINPR_UNUSED(pDlgStruc);
2735 return SCARD_E_UNSUPPORTED_FEATURE;
2738static LONG WINAPI PCSC_SCardDlgExtendedError(
void)
2741 return SCARD_E_UNSUPPORTED_FEATURE;
2744static char* card_id_and_name_a(
const UUID* CardIdentifier, LPCSTR LookupName)
2746 WINPR_ASSERT(CardIdentifier);
2747 WINPR_ASSERT(LookupName);
2749 size_t len = strlen(LookupName) + 34;
2750 char*
id = malloc(len);
2754 (void)snprintf(
id, len,
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X\\%s",
2755 CardIdentifier->Data1, CardIdentifier->Data2, CardIdentifier->Data3,
2756 CardIdentifier->Data4[0], CardIdentifier->Data4[1], CardIdentifier->Data4[2],
2757 CardIdentifier->Data4[3], CardIdentifier->Data4[4], CardIdentifier->Data4[5],
2758 CardIdentifier->Data4[6], CardIdentifier->Data4[7], LookupName);
2762static char* card_id_and_name_w(
const UUID* CardIdentifier, LPCWSTR LookupName)
2765 char* tmp = ConvertWCharToUtf8Alloc(LookupName, NULL);
2768 res = card_id_and_name_a(CardIdentifier, tmp);
2773static LONG WINAPI PCSC_SCardReadCacheA(SCARDCONTEXT hContext,
UUID* CardIdentifier,
2774 DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data,
2777 PCSC_CACHE_ITEM* data = NULL;
2778 PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext);
2780 return SCARD_E_INVALID_HANDLE;
2782 char*
id = card_id_and_name_a(CardIdentifier, LookupName);
2784 data = HashTable_GetItemValue(ctx->cache,
id);
2789 return SCARD_W_CACHE_ITEM_NOT_FOUND;
2792 if (FreshnessCounter != data->freshness)
2795 return SCARD_W_CACHE_ITEM_STALE;
2798 if (*DataLen == SCARD_AUTOALLOCATE)
2800 BYTE* mem = calloc(1, data->len);
2802 return SCARD_E_NO_MEMORY;
2804 if (!PCSC_AddMemoryBlock(hContext, mem))
2807 return SCARD_E_NO_MEMORY;
2810 memcpy(mem, data->data, data->len);
2811 *(BYTE**)Data = mem;
2814 memcpy(Data, data->data, data->len);
2815 *DataLen = data->len;
2816 return SCARD_S_SUCCESS;
2819static LONG WINAPI PCSC_SCardReadCacheW(SCARDCONTEXT hContext,
UUID* CardIdentifier,
2820 DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data,
2823 PCSC_CACHE_ITEM* data = NULL;
2824 PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext);
2826 return SCARD_E_INVALID_HANDLE;
2828 char*
id = card_id_and_name_w(CardIdentifier, LookupName);
2830 data = HashTable_GetItemValue(ctx->cache,
id);
2836 return SCARD_W_CACHE_ITEM_NOT_FOUND;
2839 if (FreshnessCounter != data->freshness)
2842 return SCARD_W_CACHE_ITEM_STALE;
2845 if (*DataLen == SCARD_AUTOALLOCATE)
2847 BYTE* mem = calloc(1, data->len);
2849 return SCARD_E_NO_MEMORY;
2851 if (!PCSC_AddMemoryBlock(hContext, mem))
2854 return SCARD_E_NO_MEMORY;
2857 memcpy(mem, data->data, data->len);
2858 *(BYTE**)Data = mem;
2861 memcpy(Data, data->data, data->len);
2862 *DataLen = data->len;
2863 return SCARD_S_SUCCESS;
2866static LONG WINAPI PCSC_SCardWriteCacheA(SCARDCONTEXT hContext,
UUID* CardIdentifier,
2867 DWORD FreshnessCounter, LPSTR LookupName, PBYTE Data,
2870 PCSC_CACHE_ITEM* data = NULL;
2871 PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext);
2875 return SCARD_E_FILE_NOT_FOUND;
2877 id = card_id_and_name_a(CardIdentifier, LookupName);
2880 return SCARD_E_NO_MEMORY;
2882 data = malloc(
sizeof(PCSC_CACHE_ITEM));
2886 return SCARD_E_NO_MEMORY;
2888 data->data = calloc(DataLen, 1);
2893 return SCARD_E_NO_MEMORY;
2895 data->len = DataLen;
2896 data->freshness = FreshnessCounter;
2897 memcpy(data->data, Data, data->len);
2899 HashTable_Remove(ctx->cache,
id);
2900 const BOOL rc = HashTable_Insert(ctx->cache,
id, data);
2905 pcsc_cache_item_free(data);
2906 return SCARD_E_NO_MEMORY;
2910 return SCARD_S_SUCCESS;
2913static LONG WINAPI PCSC_SCardWriteCacheW(SCARDCONTEXT hContext,
UUID* CardIdentifier,
2914 DWORD FreshnessCounter, LPWSTR LookupName, PBYTE Data,
2917 PCSC_CACHE_ITEM* data = NULL;
2918 PCSC_SCARDCONTEXT* ctx = PCSC_GetCardContextData(hContext);
2921 return SCARD_E_FILE_NOT_FOUND;
2923 id = card_id_and_name_w(CardIdentifier, LookupName);
2926 return SCARD_E_NO_MEMORY;
2928 data = malloc(
sizeof(PCSC_CACHE_ITEM));
2932 return SCARD_E_NO_MEMORY;
2934 data->data = malloc(DataLen);
2939 return SCARD_E_NO_MEMORY;
2941 data->len = DataLen;
2942 data->freshness = FreshnessCounter;
2943 memcpy(data->data, Data, data->len);
2945 HashTable_Remove(ctx->cache,
id);
2946 const BOOL rc = HashTable_Insert(ctx->cache,
id, data);
2951 pcsc_cache_item_free(data);
2952 return SCARD_E_NO_MEMORY;
2956 return SCARD_S_SUCCESS;
2959static LONG WINAPI PCSC_SCardGetReaderIconA(
2960 SCARDCONTEXT hContext, LPCSTR szReaderName,
2961 LPBYTE pbIcon , LPDWORD pcbIcon)
2963 WINPR_UNUSED(hContext);
2964 WINPR_UNUSED(szReaderName);
2965 WINPR_UNUSED(pbIcon);
2966 WINPR_ASSERT(pcbIcon);
2968 return SCARD_E_UNSUPPORTED_FEATURE;
2971static LONG WINAPI PCSC_SCardGetReaderIconW(
2972 SCARDCONTEXT hContext, LPCWSTR szReaderName,
2973 LPBYTE pbIcon , LPDWORD pcbIcon)
2975 WINPR_UNUSED(hContext);
2976 WINPR_UNUSED(szReaderName);
2977 WINPR_UNUSED(pbIcon);
2978 WINPR_ASSERT(pcbIcon);
2980 return SCARD_E_UNSUPPORTED_FEATURE;
2983static LONG WINAPI PCSC_SCardGetDeviceTypeIdA(SCARDCONTEXT hContext, LPCSTR szReaderName,
2984 LPDWORD pdwDeviceTypeId)
2986 WINPR_UNUSED(hContext);
2987 WINPR_UNUSED(szReaderName);
2988 WINPR_UNUSED(pdwDeviceTypeId);
2989 if (pdwDeviceTypeId)
2990 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
2991 return SCARD_S_SUCCESS;
2994static LONG WINAPI PCSC_SCardGetDeviceTypeIdW(SCARDCONTEXT hContext, LPCWSTR szReaderName,
2995 LPDWORD pdwDeviceTypeId)
2997 WINPR_UNUSED(hContext);
2998 WINPR_UNUSED(szReaderName);
2999 if (pdwDeviceTypeId)
3000 *pdwDeviceTypeId = SCARD_READER_TYPE_USB;
3001 return SCARD_S_SUCCESS;
3004static LONG WINAPI PCSC_SCardGetReaderDeviceInstanceIdA(
3005 SCARDCONTEXT hContext, LPCSTR szReaderName,
3006 LPSTR szDeviceInstanceId ,
3007 LPDWORD pcchDeviceInstanceId )
3009 WINPR_UNUSED(hContext);
3010 WINPR_UNUSED(szReaderName);
3011 WINPR_UNUSED(szDeviceInstanceId);
3012 WINPR_UNUSED(pcchDeviceInstanceId);
3013 return SCARD_E_UNSUPPORTED_FEATURE;
3016static LONG WINAPI PCSC_SCardGetReaderDeviceInstanceIdW(
3017 SCARDCONTEXT hContext, LPCWSTR szReaderName,
3018 LPWSTR szDeviceInstanceId ,
3019 LPDWORD pcchDeviceInstanceId )
3021 WINPR_UNUSED(hContext);
3022 WINPR_UNUSED(szReaderName);
3023 WINPR_UNUSED(szDeviceInstanceId);
3024 WINPR_UNUSED(pcchDeviceInstanceId);
3025 return SCARD_E_UNSUPPORTED_FEATURE;
3028static LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdA(
3029 SCARDCONTEXT hContext, LPCSTR szDeviceInstanceId,
3031 LPDWORD pcchReaders )
3033 WINPR_UNUSED(hContext);
3034 WINPR_UNUSED(szDeviceInstanceId);
3035 WINPR_UNUSED(mszReaders);
3036 WINPR_UNUSED(pcchReaders);
3037 return SCARD_E_UNSUPPORTED_FEATURE;
3040static LONG WINAPI PCSC_SCardListReadersWithDeviceInstanceIdW(
3041 SCARDCONTEXT hContext, LPCWSTR szDeviceInstanceId,
3043 LPDWORD pcchReaders )
3045 WINPR_UNUSED(hContext);
3046 WINPR_UNUSED(szDeviceInstanceId);
3047 WINPR_UNUSED(mszReaders);
3048 WINPR_UNUSED(pcchReaders);
3049 return SCARD_E_UNSUPPORTED_FEATURE;
3052static LONG WINAPI PCSC_SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent)
3055 WINPR_UNUSED(hContext);
3056 WINPR_UNUSED(dwEvent);
3057 return SCARD_E_UNSUPPORTED_FEATURE;
3061unsigned int determineMacOSXVersion(
void)
3065 char* kernelVersion = NULL;
3067 unsigned int version = 0;
3068 long majorVersion = 0;
3069 long minorVersion = 0;
3070 long patchVersion = 0;
3072 char* context = NULL;
3074 mib[1] = KERN_OSRELEASE;
3076 if (sysctl(mib, 2, NULL, &len, NULL, 0) != 0)
3079 kernelVersion = calloc(len,
sizeof(
char));
3084 if (sysctl(mib, 2, kernelVersion, &len, NULL, 0) != 0)
3086 free(kernelVersion);
3090 tok = strtok_s(kernelVersion,
".", &context);
3098 majorVersion = strtol(tok, NULL, 0);
3106 minorVersion = strtol(tok, NULL, 0);
3114 patchVersion = strtol(tok, NULL, 0);
3122 tok = strtok_s(NULL,
".", &context);
3129 if (majorVersion < 5)
3131 if (minorVersion < 4)
3132 version = 0x10000000;
3134 version = 0x10010000;
3138 switch (majorVersion)
3141 version = 0x10010000;
3145 version = 0x10020000;
3149 version = 0x10030000;
3153 version = 0x10040000;
3157 version = 0x10050000;
3161 version = 0x10060000;
3165 version = 0x10070000;
3169 version = 0x10080000;
3173 version = 0x10090000;
3177 version = 0x10100000;
3181 version |= (minorVersion << 8) | (patchVersion);
3185 free(kernelVersion);
3194 PCSC_SCardEstablishContext,
3195 PCSC_SCardReleaseContext,
3196 PCSC_SCardIsValidContext,
3197 PCSC_SCardListReaderGroupsA,
3198 PCSC_SCardListReaderGroupsW,
3199 PCSC_SCardListReadersA,
3200 PCSC_SCardListReadersW,
3201 PCSC_SCardListCardsA,
3202 PCSC_SCardListCardsW,
3203 PCSC_SCardListInterfacesA,
3204 PCSC_SCardListInterfacesW,
3205 PCSC_SCardGetProviderIdA,
3206 PCSC_SCardGetProviderIdW,
3207 PCSC_SCardGetCardTypeProviderNameA,
3208 PCSC_SCardGetCardTypeProviderNameW,
3209 PCSC_SCardIntroduceReaderGroupA,
3210 PCSC_SCardIntroduceReaderGroupW,
3211 PCSC_SCardForgetReaderGroupA,
3212 PCSC_SCardForgetReaderGroupW,
3213 PCSC_SCardIntroduceReaderA,
3214 PCSC_SCardIntroduceReaderW,
3215 PCSC_SCardForgetReaderA,
3216 PCSC_SCardForgetReaderW,
3217 PCSC_SCardAddReaderToGroupA,
3218 PCSC_SCardAddReaderToGroupW,
3219 PCSC_SCardRemoveReaderFromGroupA,
3220 PCSC_SCardRemoveReaderFromGroupW,
3221 PCSC_SCardIntroduceCardTypeA,
3222 PCSC_SCardIntroduceCardTypeW,
3223 PCSC_SCardSetCardTypeProviderNameA,
3224 PCSC_SCardSetCardTypeProviderNameW,
3225 PCSC_SCardForgetCardTypeA,
3226 PCSC_SCardForgetCardTypeW,
3227 PCSC_SCardFreeMemory,
3228 PCSC_SCardAccessStartedEvent,
3229 PCSC_SCardReleaseStartedEvent,
3230 PCSC_SCardLocateCardsA,
3231 PCSC_SCardLocateCardsW,
3232 PCSC_SCardLocateCardsByATRA,
3233 PCSC_SCardLocateCardsByATRW,
3234 PCSC_SCardGetStatusChangeA,
3235 PCSC_SCardGetStatusChangeW,
3239 PCSC_SCardReconnect,
3240 PCSC_SCardDisconnect,
3241 PCSC_SCardBeginTransaction,
3242 PCSC_SCardEndTransaction,
3243 PCSC_SCardCancelTransaction,
3248 PCSC_SCardGetTransmitCount,
3250 PCSC_SCardGetAttrib,
3251 PCSC_SCardSetAttrib,
3252 PCSC_SCardUIDlgSelectCardA,
3253 PCSC_SCardUIDlgSelectCardW,
3254 PCSC_GetOpenCardNameA,
3255 PCSC_GetOpenCardNameW,
3256 PCSC_SCardDlgExtendedError,
3257 PCSC_SCardReadCacheA,
3258 PCSC_SCardReadCacheW,
3259 PCSC_SCardWriteCacheA,
3260 PCSC_SCardWriteCacheW,
3261 PCSC_SCardGetReaderIconA,
3262 PCSC_SCardGetReaderIconW,
3263 PCSC_SCardGetDeviceTypeIdA,
3264 PCSC_SCardGetDeviceTypeIdW,
3265 PCSC_SCardGetReaderDeviceInstanceIdA,
3266 PCSC_SCardGetReaderDeviceInstanceIdW,
3267 PCSC_SCardListReadersWithDeviceInstanceIdA,
3268 PCSC_SCardListReadersWithDeviceInstanceIdW,
3274 return &PCSC_SCardApiFunctionTable;
3277int PCSC_InitializeSCardApi(
void)
3280 SetEnvironmentVariableA(
"PCSCLITE_NO_BLOCKING",
"1");
3282 g_PCSCModule = LoadLibraryX(
"/System/Library/Frameworks/PCSC.framework/PCSC");
3283 OSXVersion = determineMacOSXVersion();
3285 if (OSXVersion == 0)
3289 g_PCSCModule = LoadLibraryA(
"libpcsclite.so.1");
3292 g_PCSCModule = LoadLibraryA(
"libpcsclite.so");
3301#undef SCardListReaderGroups
3302#undef SCardListReaders
3303#undef SCardListCards
3304#undef SCardListInterfaces
3305#undef SCardGetProviderId
3306#undef SCardGetCardTypeProviderName
3307#undef SCardIntroduceReaderGroup
3308#undef SCardForgetReaderGroup
3309#undef SCardIntroduceReader
3310#undef SCardForgetReader
3311#undef SCardAddReaderToGroup
3312#undef SCardRemoveReaderFromGroup
3313#undef SCardIntroduceCardType
3314#undef SCardSetCardTypeProviderName
3315#undef SCardForgetCardType
3316#undef SCardLocateCards
3317#undef SCardLocateCardsByATR
3318#undef SCardGetStatusChange
3321#undef SCardUIDlgSelectCard
3322#undef GetOpenCardName
3323#undef SCardReadCache
3324#undef SCardWriteCache
3325#undef SCardGetReaderIcon
3326#undef SCardGetDeviceTypeId
3327#undef SCardGetReaderDeviceInstanceId
3328#undef SCardListReadersWithDeviceInstanceId
3330 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardEstablishContext);
3331 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardReleaseContext);
3332 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardIsValidContext);
3333 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardConnect);
3334 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardReconnect);
3335 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardDisconnect);
3336 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardBeginTransaction);
3337 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardEndTransaction);
3338 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardStatus);
3339 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardGetStatusChange);
3343 if (OSXVersion >= 0x10050600)
3345 WINSCARD_LOAD_PROC_EX(g_PCSCModule, g_PCSC, SCardControl, SCardControl132);
3349 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardControl);
3352 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardControl);
3354 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardTransmit);
3355 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardListReaderGroups);
3356 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardListReaders);
3357 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardCancel);
3358 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardGetAttrib);
3359 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardSetAttrib);
3360 g_PCSC.pfnSCardFreeMemory = NULL;
3362 WINSCARD_LOAD_PROC(g_PCSCModule, g_PCSC, SCardFreeMemory);
3365 if (g_PCSC.pfnSCardFreeMemory)
3366 g_SCardAutoAllocate = TRUE;
3368#ifdef DISABLE_PCSC_SCARD_AUTOALLOCATE
3369 g_PCSC.pfnSCardFreeMemory = NULL;
3370 g_SCardAutoAllocate = FALSE;
3373 g_PnP_Notification = FALSE;
This struct contains function pointer to initialize/free objects.