#include <winpr/library.h>
#include <winpr/smartcard.h>
#include <winpr/synch.h>
+#include <winpr/wlog.h>
+
+#include "../log.h"
#include "smartcard.h"
static INIT_ONCE g_Initialized = INIT_ONCE_STATIC_INIT;
static PSCardApiFunctionTable g_SCardApi = NULL;
-#define SCARDAPI_STUB_CALL_LONG(_name, ...) \
- InitOnceExecuteOnce(&g_Initialized, InitializeSCardApiStubs, NULL, NULL); \
- if (!g_SCardApi || !g_SCardApi->pfn##_name) \
- return SCARD_E_NO_SERVICE; \
+#define TAG WINPR_TAG("smartcard")
+
+#define xstr(s) str(s)
+#define str(s) #s
+
+#define SCARDAPI_STUB_CALL_LONG(_name, ...) \
+ InitOnceExecuteOnce(&g_Initialized, InitializeSCardApiStubs, NULL, NULL); \
+ if (!g_SCardApi || !g_SCardApi->pfn##_name) \
+ { \
+ WLog_DBG(TAG, "Missing function pointer g_SCardApi=%p->" xstr(pfn##_name) "=%p", \
+ g_SCardApi, g_SCardApi ? g_SCardApi->pfn##_name : NULL); \
+ return SCARD_E_NO_SERVICE; \
+ } \
return g_SCardApi->pfn##_name(__VA_ARGS__)
#define SCARDAPI_STUB_CALL_HANDLE(_name, ...) \
default:
return "SCARD_E_UNKNOWN";
}
-
- return "SCARD_E_UNKNOWN";
}
WINSCARDAPI const char* WINAPI SCardGetAttributeString(DWORD dwAttrId)
{
case SCARD_ATTR_VENDOR_NAME:
return "SCARD_ATTR_VENDOR_NAME";
- break;
case SCARD_ATTR_VENDOR_IFD_TYPE:
return "SCARD_ATTR_VENDOR_IFD_TYPE";
- break;
case SCARD_ATTR_VENDOR_IFD_VERSION:
return "SCARD_ATTR_VENDOR_IFD_VERSION";
- break;
case SCARD_ATTR_VENDOR_IFD_SERIAL_NO:
return "SCARD_ATTR_VENDOR_IFD_SERIAL_NO";
- break;
case SCARD_ATTR_CHANNEL_ID:
return "SCARD_ATTR_CHANNEL_ID";
- break;
case SCARD_ATTR_PROTOCOL_TYPES:
return "SCARD_ATTR_PROTOCOL_TYPES";
- break;
case SCARD_ATTR_DEFAULT_CLK:
return "SCARD_ATTR_DEFAULT_CLK";
- break;
case SCARD_ATTR_MAX_CLK:
return "SCARD_ATTR_MAX_CLK";
- break;
case SCARD_ATTR_DEFAULT_DATA_RATE:
return "SCARD_ATTR_DEFAULT_DATA_RATE";
- break;
case SCARD_ATTR_MAX_DATA_RATE:
return "SCARD_ATTR_MAX_DATA_RATE";
- break;
case SCARD_ATTR_MAX_IFSD:
return "SCARD_ATTR_MAX_IFSD";
- break;
case SCARD_ATTR_POWER_MGMT_SUPPORT:
return "SCARD_ATTR_POWER_MGMT_SUPPORT";
- break;
case SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE:
return "SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE";
- break;
case SCARD_ATTR_USER_AUTH_INPUT_DEVICE:
return "SCARD_ATTR_USER_AUTH_INPUT_DEVICE";
- break;
case SCARD_ATTR_CHARACTERISTICS:
return "SCARD_ATTR_CHARACTERISTICS";
- break;
case SCARD_ATTR_CURRENT_PROTOCOL_TYPE:
return "SCARD_ATTR_CURRENT_PROTOCOL_TYPE";
- break;
case SCARD_ATTR_CURRENT_CLK:
return "SCARD_ATTR_CURRENT_CLK";
- break;
case SCARD_ATTR_CURRENT_F:
return "SCARD_ATTR_CURRENT_F";
- break;
case SCARD_ATTR_CURRENT_D:
return "SCARD_ATTR_CURRENT_D";
- break;
case SCARD_ATTR_CURRENT_N:
return "SCARD_ATTR_CURRENT_N";
- break;
case SCARD_ATTR_CURRENT_W:
return "SCARD_ATTR_CURRENT_W";
- break;
case SCARD_ATTR_CURRENT_IFSC:
return "SCARD_ATTR_CURRENT_IFSC";
- break;
case SCARD_ATTR_CURRENT_IFSD:
return "SCARD_ATTR_CURRENT_IFSD";
- break;
case SCARD_ATTR_CURRENT_BWT:
return "SCARD_ATTR_CURRENT_BWT";
- break;
case SCARD_ATTR_CURRENT_CWT:
return "SCARD_ATTR_CURRENT_CWT";
- break;
case SCARD_ATTR_CURRENT_EBC_ENCODING:
return "SCARD_ATTR_CURRENT_EBC_ENCODING";
- break;
case SCARD_ATTR_EXTENDED_BWT:
return "SCARD_ATTR_EXTENDED_BWT";
- break;
case SCARD_ATTR_ICC_PRESENCE:
return "SCARD_ATTR_ICC_PRESENCE";
- break;
case SCARD_ATTR_ICC_INTERFACE_STATUS:
return "SCARD_ATTR_ICC_INTERFACE_STATUS";
- break;
case SCARD_ATTR_CURRENT_IO_STATE:
return "SCARD_ATTR_CURRENT_IO_STATE";
- break;
case SCARD_ATTR_ATR_STRING:
return "SCARD_ATTR_ATR_STRING";
- break;
case SCARD_ATTR_ICC_TYPE_PER_ATR:
return "SCARD_ATTR_ICC_TYPE_PER_ATR";
- break;
case SCARD_ATTR_ESC_RESET:
return "SCARD_ATTR_ESC_RESET";
- break;
case SCARD_ATTR_ESC_CANCEL:
return "SCARD_ATTR_ESC_CANCEL";
- break;
case SCARD_ATTR_ESC_AUTHREQUEST:
return "SCARD_ATTR_ESC_AUTHREQUEST";
- break;
case SCARD_ATTR_MAXINPUT:
return "SCARD_ATTR_MAXINPUT";
- break;
case SCARD_ATTR_DEVICE_UNIT:
return "SCARD_ATTR_DEVICE_UNIT";
- break;
case SCARD_ATTR_DEVICE_IN_USE:
return "SCARD_ATTR_DEVICE_IN_USE";
- break;
case SCARD_ATTR_DEVICE_FRIENDLY_NAME_A:
return "SCARD_ATTR_DEVICE_FRIENDLY_NAME_A";
- break;
case SCARD_ATTR_DEVICE_SYSTEM_NAME_A:
return "SCARD_ATTR_DEVICE_SYSTEM_NAME_A";
- break;
case SCARD_ATTR_DEVICE_FRIENDLY_NAME_W:
return "SCARD_ATTR_DEVICE_FRIENDLY_NAME_W";
- break;
case SCARD_ATTR_DEVICE_SYSTEM_NAME_W:
return "SCARD_ATTR_DEVICE_SYSTEM_NAME_W";
- break;
case SCARD_ATTR_SUPRESS_T1_IFS_REQUEST:
return "SCARD_ATTR_SUPRESS_T1_IFS_REQUEST";
- break;
default:
return "SCARD_ATTR_UNKNOWN";
- break;
}
-
- return "SCARD_ATTR_UNKNOWN";
}
WINSCARDAPI const char* WINAPI SCardGetProtocolString(DWORD dwProtocols)
{
case SCARD_SHARE_EXCLUSIVE:
return "SCARD_SHARE_EXCLUSIVE";
- break;
case SCARD_SHARE_SHARED:
return "SCARD_SHARE_SHARED";
- break;
case SCARD_SHARE_DIRECT:
return "SCARD_SHARE_DIRECT";
- break;
default:
return "SCARD_SHARE_UNKNOWN";
- break;
}
-
- return "SCARD_SHARE_UNKNOWN";
}
WINSCARDAPI const char* WINAPI SCardGetDispositionString(DWORD dwDisposition)
{
case SCARD_LEAVE_CARD:
return "SCARD_LEAVE_CARD";
- break;
case SCARD_RESET_CARD:
return "SCARD_RESET_CARD";
- break;
case SCARD_UNPOWER_CARD:
return "SCARD_UNPOWER_CARD";
- break;
default:
return "SCARD_UNKNOWN_CARD";
- break;
}
-
- return "SCARD_UNKNOWN_CARD";
}
WINSCARDAPI const char* WINAPI SCardGetScopeString(DWORD dwScope)
{
case SCARD_SCOPE_USER:
return "SCARD_SCOPE_USER";
- break;
case SCARD_SCOPE_TERMINAL:
return "SCARD_SCOPE_TERMINAL";
- break;
case SCARD_SCOPE_SYSTEM:
return "SCARD_SCOPE_SYSTEM";
- break;
default:
return "SCARD_SCOPE_UNKNOWN";
- break;
}
-
- return "SCARD_SCOPE_UNKNOWN";
}
WINSCARDAPI const char* WINAPI SCardGetCardStateString(DWORD dwCardState)
{
case SCARD_UNKNOWN:
return "SCARD_UNKNOWN";
- break;
case SCARD_ABSENT:
return "SCARD_ABSENT";
- break;
case SCARD_PRESENT:
return "SCARD_PRESENT";
- break;
case SCARD_SWALLOWED:
return "SCARD_SWALLOWED";
- break;
case SCARD_POWERED:
return "SCARD_POWERED";
- break;
case SCARD_NEGOTIABLE:
return "SCARD_NEGOTIABLE";
- break;
case SCARD_SPECIFIC:
return "SCARD_SPECIFIC";
- break;
default:
return "SCARD_UNKNOWN";
- break;
}
-
- return "SCARD_UNKNOWN";
}
WINSCARDAPI char* WINAPI SCardGetReaderStateString(DWORD dwReaderState)
LPSCARDCONTEXT phContext);
static LONG WINAPI PCSC_SCardReleaseContext_Internal(SCARDCONTEXT hContext);
+static LONG PCSC_SCard_LogError(const char* what)
+{
+ WLog_DBG(TAG, "Missing function pointer %s=NULL", what);
+ return SCARD_E_NO_SERVICE;
+}
+
static LONG PCSC_MapErrorCodeToWinSCard(LONG errorCode)
{
/**
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardEstablishContext)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardEstablishContext");
status = (LONG)g_PCSC.pfnSCardEstablishContext(SCARD_SCOPE_SYSTEM, pvReserved1, pvReserved2,
phContext);
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardReleaseContext)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardReleaseContext");
if (!hContext)
{
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardIsValidContext)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardIsValidContext");
status = (LONG)g_PCSC.pfnSCardIsValidContext(hContext);
status = PCSC_MapErrorCodeToWinSCard(status);
return SCARD_E_INVALID_PARAMETER;
if (!g_PCSC.pfnSCardListReaderGroups)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardListReaderGroups");
if (*pcchGroups == SCARD_AUTOALLOCATE)
pcchGroupsAlloc = TRUE;
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardListReaderGroups)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardListReaderGroups");
if (!PCSC_LockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardListReaderGroups)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardListReaderGroups");
if (!PCSC_LockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
return SCARD_E_INVALID_PARAMETER;
if (!g_PCSC.pfnSCardListReaders)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardListReaders");
mszGroups = NULL; /* mszGroups is not supported by pcsc-lite */
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardListReaders)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardListReaders");
if (!hContext)
{
BOOL nullCardContext = FALSE;
if (!g_PCSC.pfnSCardListReaders)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardListReaders");
if (!hContext)
{
PCSC_DWORD pcsc_cReaders = (PCSC_DWORD)cReaders;
if (!g_PCSC.pfnSCardGetStatusChange)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardGetStatusChange");
if (!cReaders)
return SCARD_S_SUCCESS;
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardGetStatusChange)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardGetStatusChange");
if (!PCSC_LockCardContext(hContext))
return SCARD_E_INVALID_HANDLE;
LONG status = SCARD_S_SUCCESS;
if (!g_PCSC.pfnSCardCancel)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardCancel");
status = (LONG)g_PCSC.pfnSCardCancel(hContext);
status = PCSC_MapErrorCodeToWinSCard(status);
PCSC_DWORD pcsc_dwActiveProtocol = 0;
if (!g_PCSC.pfnSCardConnect)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardConnect");
shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE;
PCSC_WaitForCardAccess(hContext, 0, shared);
PCSC_DWORD pcsc_dwActiveProtocol = 0;
if (!g_PCSC.pfnSCardReconnect)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardReconnect");
shared = (dwShareMode == SCARD_SHARE_DIRECT) ? TRUE : FALSE;
PCSC_WaitForCardAccess(0, hCard, shared);
PCSC_DWORD pcsc_dwDisposition = (PCSC_DWORD)dwDisposition;
if (!g_PCSC.pfnSCardDisconnect)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardDisconnect");
status = (LONG)g_PCSC.pfnSCardDisconnect(hCard, pcsc_dwDisposition);
status = PCSC_MapErrorCodeToWinSCard(status);
PCSC_SCARDCONTEXT* pContext = NULL;
if (!g_PCSC.pfnSCardBeginTransaction)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardBeginTransaction");
pCard = PCSC_GetCardHandleData(hCard);
PCSC_DWORD pcsc_dwDisposition = (PCSC_DWORD)dwDisposition;
if (!g_PCSC.pfnSCardEndTransaction)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardEndTransaction");
pCard = PCSC_GetCardHandleData(hCard);
PCSC_DWORD pcsc_cbAtrLen = (PCSC_DWORD)*pcbAtrLen;
if (!g_PCSC.pfnSCardStatus)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardStatus");
pCard = PCSC_GetCardHandleData(hCard);
LPBYTE tATR = NULL;
if (!g_PCSC.pfnSCardStatus)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardStatus");
pCard = PCSC_GetCardHandleData(hCard);
PCSC_DWORD pcsc_cbRecvLength = 0;
if (!g_PCSC.pfnSCardTransmit)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardTransmit");
pCard = PCSC_GetCardHandleData(hCard);
PCSC_DWORD pcsc_BytesReturned = 0;
if (!g_PCSC.pfnSCardControl)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardControl");
pCard = PCSC_GetCardHandleData(hCard);
PCSC_DWORD pcsc_cbAttrLen = 0;
if (!g_PCSC.pfnSCardGetAttrib)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardGetAttrib");
pCard = PCSC_GetCardHandleData(hCard);
PCSC_DWORD pcsc_cbAttrLen = (PCSC_DWORD)cbAttrLen;
if (!g_PCSC.pfnSCardSetAttrib)
- return SCARD_E_NO_SERVICE;
+ return PCSC_SCard_LogError("g_PCSC.pfnSCardSetAttrib");
pCard = PCSC_GetCardHandleData(hCard);