#include <winpr/winpr.h>
#include <winpr/wtypes.h>
-#ifndef _WIN32
+#include <winpr/error.h>
+
+#ifdef _WIN32
+
+#include <winscard.h>
+
+#else
+
+#ifndef SCARD_S_SUCCESS
+#define SCARD_S_SUCCESS NO_ERROR
+#endif
+
+#define SCARD_F_INTERNAL_ERROR ((DWORD)0x80100001L)
+#define SCARD_E_CANCELLED ((DWORD)0x80100002L)
+#define SCARD_E_INVALID_HANDLE ((DWORD)0x80100003L)
+#define SCARD_E_INVALID_PARAMETER ((DWORD)0x80100004L)
+#define SCARD_E_INVALID_TARGET ((DWORD)0x80100005L)
+#define SCARD_E_NO_MEMORY ((DWORD)0x80100006L)
+#define SCARD_F_WAITED_TOO_LONG ((DWORD)0x80100007L)
+#define SCARD_E_INSUFFICIENT_BUFFER ((DWORD)0x80100008L)
+#define SCARD_E_UNKNOWN_READER ((DWORD)0x80100009L)
+#define SCARD_E_TIMEOUT ((DWORD)0x8010000AL)
+#define SCARD_E_SHARING_VIOLATION ((DWORD)0x8010000BL)
+#define SCARD_E_NO_SMARTCARD ((DWORD)0x8010000CL)
+#define SCARD_E_UNKNOWN_CARD ((DWORD)0x8010000DL)
+#define SCARD_E_CANT_DISPOSE ((DWORD)0x8010000EL)
+#define SCARD_E_PROTO_MISMATCH ((DWORD)0x8010000FL)
+#define SCARD_E_NOT_READY ((DWORD)0x80100010L)
+#define SCARD_E_INVALID_VALUE ((DWORD)0x80100011L)
+#define SCARD_E_SYSTEM_CANCELLED ((DWORD)0x80100012L)
+#define SCARD_F_COMM_ERROR ((DWORD)0x80100013L)
+#define SCARD_F_UNKNOWN_ERROR ((DWORD)0x80100014L)
+#define SCARD_E_INVALID_ATR ((DWORD)0x80100015L)
+#define SCARD_E_NOT_TRANSACTED ((DWORD)0x80100016L)
+#define SCARD_E_READER_UNAVAILABLE ((DWORD)0x80100017L)
+#define SCARD_P_SHUTDOWN ((DWORD)0x80100018L)
+#define SCARD_E_PCI_TOO_SMALL ((DWORD)0x80100019L)
+#define SCARD_E_READER_UNSUPPORTED ((DWORD)0x8010001AL)
+#define SCARD_E_DUPLICATE_READER ((DWORD)0x8010001BL)
+#define SCARD_E_CARD_UNSUPPORTED ((DWORD)0x8010001CL)
+#define SCARD_E_NO_SERVICE ((DWORD)0x8010001DL)
+#define SCARD_E_SERVICE_STOPPED ((DWORD)0x8010001EL)
+#define SCARD_E_UNEXPECTED ((DWORD)0x8010001FL)
+#define SCARD_E_ICC_INSTALLATION ((DWORD)0x80100020L)
+#define SCARD_E_ICC_CREATEORDER ((DWORD)0x80100021L)
+#define SCARD_E_UNSUPPORTED_FEATURE ((DWORD)0x80100022L)
+#define SCARD_E_DIR_NOT_FOUND ((DWORD)0x80100023L)
+#define SCARD_E_FILE_NOT_FOUND ((DWORD)0x80100024L)
+#define SCARD_E_NO_DIR ((DWORD)0x80100025L)
+#define SCARD_E_NO_FILE ((DWORD)0x80100026L)
+#define SCARD_E_NO_ACCESS ((DWORD)0x80100027L)
+#define SCARD_E_WRITE_TOO_MANY ((DWORD)0x80100028L)
+#define SCARD_E_BAD_SEEK ((DWORD)0x80100029L)
+#define SCARD_E_INVALID_CHV ((DWORD)0x8010002AL)
+#define SCARD_E_UNKNOWN_RES_MNG ((DWORD)0x8010002BL)
+#define SCARD_E_NO_SUCH_CERTIFICATE ((DWORD)0x8010002CL)
+#define SCARD_E_CERTIFICATE_UNAVAILABLE ((DWORD)0x8010002DL)
+#define SCARD_E_NO_READERS_AVAILABLE ((DWORD)0x8010002EL)
+#define SCARD_E_COMM_DATA_LOST ((DWORD)0x8010002FL)
+#define SCARD_E_NO_KEY_CONTAINER ((DWORD)0x80100030L)
+#define SCARD_E_SERVER_TOO_BUSY ((DWORD)0x80100031L)
+#define SCARD_E_PIN_CACHE_EXPIRED ((DWORD)0x80100032L)
+#define SCARD_E_NO_PIN_CACHE ((DWORD)0x80100033L)
+#define SCARD_E_READ_ONLY_CARD ((DWORD)0x80100034L)
+#define SCARD_W_UNSUPPORTED_CARD ((DWORD)0x80100065L)
+#define SCARD_W_UNRESPONSIVE_CARD ((DWORD)0x80100066L)
+#define SCARD_W_UNPOWERED_CARD ((DWORD)0x80100067L)
+#define SCARD_W_RESET_CARD ((DWORD)0x80100068L)
+#define SCARD_W_REMOVED_CARD ((DWORD)0x80100069L)
+#define SCARD_W_SECURITY_VIOLATION ((DWORD)0x8010006AL)
+#define SCARD_W_WRONG_CHV ((DWORD)0x8010006BL)
+#define SCARD_W_CHV_BLOCKED ((DWORD)0x8010006CL)
+#define SCARD_W_EOF ((DWORD)0x8010006DL)
+#define SCARD_W_CANCELLED_BY_USER ((DWORD)0x8010006EL)
+#define SCARD_W_CARD_NOT_AUTHENTICATED ((DWORD)0x8010006FL)
+#define SCARD_W_CACHE_ITEM_NOT_FOUND ((DWORD)0x80100070L)
+#define SCARD_W_CACHE_ITEM_STALE ((DWORD)0x80100071L)
+#define SCARD_W_CACHE_ITEM_TOO_BIG ((DWORD)0x80100072L)
#define SCARD_ATR_LENGTH 33
#endif
#include <winpr/crt.h>
+#include <winpr/library.h>
#include <winpr/smartcard.h>
#ifndef _WIN32
/**
* libpcsclite.so.1:
*
- * SCardBeginTransaction
- * SCardCancel
+ * SCardEstablishContext
+ * SCardReleaseContext
+ * SCardIsValidContext
* SCardConnect
- * SCardControl
+ * SCardReconnect
* SCardDisconnect
+ * SCardBeginTransaction
* SCardEndTransaction
- * SCardEstablishContext
- * SCardFreeMemory
- * SCardGetAttrib
+ * SCardStatus
* SCardGetStatusChange
- * SCardIsValidContext
+ * SCardControl
+ * SCardTransmit
* SCardListReaderGroups
* SCardListReaders
- * SCardReconnect
- * SCardReleaseContext
+ * SCardFreeMemory
+ * SCardCancel
+ * SCardGetAttrib
* SCardSetAttrib
- * SCardStatus
- * SCardTransmit
+ */
+
+struct _PCSCLiteFunctionTable
+{
+ LONG (* pfnSCardEstablishContext)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
+ LONG (* pfnSCardReleaseContext)(SCARDCONTEXT hContext);
+ LONG (* pfnSCardIsValidContext)(SCARDCONTEXT hContext);
+ LONG (* pfnSCardConnect)(SCARDCONTEXT hContext,
+ LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
+ LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol);
+ LONG (* pfnSCardReconnect)(SCARDHANDLE hCard,
+ DWORD dwShareMode, DWORD dwPreferredProtocols,
+ DWORD dwInitialization, LPDWORD pdwActiveProtocol);
+ LONG (* pfnSCardDisconnect)(SCARDHANDLE hCard, DWORD dwDisposition);
+ LONG (* pfnSCardBeginTransaction)(SCARDHANDLE hCard);
+ LONG (* pfnSCardEndTransaction)(SCARDHANDLE hCard, DWORD dwDisposition);
+ LONG (* pfnSCardStatus)(SCARDHANDLE hCard,
+ LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState,
+ LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen);
+ LONG (* pfnSCardGetStatusChange)(SCARDCONTEXT hContext,
+ DWORD dwTimeout, LPSCARD_READERSTATE rgReaderStates, DWORD cReaders);
+ LONG (* pfnSCardControl)(SCARDHANDLE hCard,
+ DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength,
+ LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned);
+ LONG (* pfnSCardTransmit)(SCARDHANDLE hCard,
+ const SCARD_IO_REQUEST* pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength,
+ SCARD_IO_REQUEST* pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
+ LONG (* pfnSCardListReaderGroups)(SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups);
+ LONG (* pfnSCardListReaders)(SCARDCONTEXT hContext,
+ LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders);
+ LONG (* pfnSCardFreeMemory)(SCARDCONTEXT hContext, LPCVOID pvMem);
+ LONG (* pfnSCardCancel)(SCARDCONTEXT hContext);
+ LONG (* pfnSCardGetAttrib)(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen);
+ LONG (* pfnSCardSetAttrib)(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen);
+};
+typedef struct _PCSCLiteFunctionTable PCSCLiteFunctionTable;
+
+static BOOL g_Initialized = FALSE;
+static HMODULE g_PCSCLiteModule = NULL;
+
+static PCSCLiteFunctionTable* g_PCSCLite = NULL;
+
+void InitializePCSCLite(void)
+{
+ if (g_PCSCLite)
+ return;
+
+ g_PCSCLiteModule = LoadLibraryA("libpcsclite.so.1");
+
+ if (!g_PCSCLiteModule)
+ return;
+
+ g_PCSCLite = calloc(1, sizeof(PCSCLiteFunctionTable));
+
+ if (!g_PCSCLite)
+ return;
+
+ g_PCSCLite->pfnSCardEstablishContext = GetProcAddress(g_PCSCLiteModule, "SCardEstablishContext");
+ g_PCSCLite->pfnSCardReleaseContext = GetProcAddress(g_PCSCLiteModule, "SCardReleaseContext");
+ g_PCSCLite->pfnSCardIsValidContext = GetProcAddress(g_PCSCLiteModule, "SCardIsValidContext");
+ g_PCSCLite->pfnSCardConnect = GetProcAddress(g_PCSCLiteModule, "SCardConnect");
+ g_PCSCLite->pfnSCardReconnect = GetProcAddress(g_PCSCLiteModule, "SCardReconnect");
+ g_PCSCLite->pfnSCardDisconnect = GetProcAddress(g_PCSCLiteModule, "SCardDisconnect");
+ g_PCSCLite->pfnSCardBeginTransaction = GetProcAddress(g_PCSCLiteModule, "SCardBeginTransaction");
+ g_PCSCLite->pfnSCardEndTransaction = GetProcAddress(g_PCSCLiteModule, "SCardEndTransaction");
+ g_PCSCLite->pfnSCardStatus = GetProcAddress(g_PCSCLiteModule, "SCardStatus");
+ g_PCSCLite->pfnSCardGetStatusChange = GetProcAddress(g_PCSCLiteModule, "SCardGetStatusChange");
+ g_PCSCLite->pfnSCardControl = GetProcAddress(g_PCSCLiteModule, "SCardControl");
+ g_PCSCLite->pfnSCardTransmit = GetProcAddress(g_PCSCLiteModule, "SCardTransmit");
+ g_PCSCLite->pfnSCardListReaderGroups = GetProcAddress(g_PCSCLiteModule, "SCardListReaderGroups");
+ g_PCSCLite->pfnSCardListReaders = GetProcAddress(g_PCSCLiteModule, "SCardListReaders");
+ g_PCSCLite->pfnSCardFreeMemory = GetProcAddress(g_PCSCLiteModule, "SCardFreeMemory");
+ g_PCSCLite->pfnSCardCancel = GetProcAddress(g_PCSCLiteModule, "SCardCancel");
+ g_PCSCLite->pfnSCardGetAttrib = GetProcAddress(g_PCSCLiteModule, "SCardGetAttrib");
+ g_PCSCLite->pfnSCardSetAttrib = GetProcAddress(g_PCSCLiteModule, "SCardSetAttrib");
+}
+
+void InitializeSCardStubs(void)
+{
+ if (g_Initialized)
+ return;
+
+ g_Initialized = TRUE;
+
+ InitializePCSCLite();
+}
+
+/**
+ * Standard Windows Smart Card API
*/
WINSCARDAPI LONG WINAPI SCardEstablishContext(DWORD dwScope,
LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardEstablishContext)
+ {
+ return g_PCSCLite->pfnSCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardReleaseContext(SCARDCONTEXT hContext)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardReleaseContext)
+ {
+ return g_PCSCLite->pfnSCardReleaseContext(hContext);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardIsValidContext(SCARDCONTEXT hContext)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardIsValidContext)
+ {
+ return g_PCSCLite->pfnSCardIsValidContext(hContext);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardListReaderGroupsA(SCARDCONTEXT hContext,
LPSTR mszGroups, LPDWORD pcchGroups)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardListReaderGroups)
+ {
+ return g_PCSCLite->pfnSCardListReaderGroups(hContext, mszGroups, pcchGroups);
+ }
+
return 0;
}
+
WINSCARDAPI LONG WINAPI SCardListReaderGroupsW(SCARDCONTEXT hContext,
LPWSTR mszGroups, LPDWORD pcchGroups)
{
+ InitializeSCardStubs();
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardListReadersA(SCARDCONTEXT hContext,
LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardListReaders)
+ {
+ return g_PCSCLite->pfnSCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
+ }
+
return 0;
}
+
WINSCARDAPI LONG WINAPI SCardListReadersW(SCARDCONTEXT hContext,
LPCWSTR mszGroups, LPWSTR mszReaders, LPDWORD pcchReaders)
{
+ InitializeSCardStubs();
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardFreeMemory)
+ {
+ return g_PCSCLite->pfnSCardFreeMemory(hContext, pvMem);
+ }
+
return 0;
}
{
return 0;
}
+
WINSCARDAPI LONG WINAPI SCardLocateCardsByATRW(SCARDCONTEXT hContext,
LPSCARD_ATRMASK rgAtrMasks, DWORD cAtrs, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders)
{
WINSCARDAPI LONG WINAPI SCardGetStatusChangeA(SCARDCONTEXT hContext,
DWORD dwTimeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardGetStatusChange)
+ {
+ return g_PCSCLite->pfnSCardGetStatusChange(hContext, dwTimeout, rgReaderStates, cReaders);
+ }
+
return 0;
}
+
WINSCARDAPI LONG WINAPI SCardGetStatusChangeW(SCARDCONTEXT hContext,
DWORD dwTimeout, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders)
{
+ InitializeSCardStubs();
+
return 0;
}
LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardConnect)
+ {
+ return g_PCSCLite->pfnSCardConnect(hContext, szReader,
+ dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol);
+ }
+
return 0;
}
+
WINSCARDAPI LONG WINAPI SCardConnectW(SCARDCONTEXT hContext,
LPCWSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols,
LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
{
+ InitializeSCardStubs();
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardReconnect(SCARDHANDLE hCard,
DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardReconnect)
+ {
+ return g_PCSCLite->pfnSCardReconnect(hCard, dwShareMode,
+ dwPreferredProtocols, dwInitialization, pdwActiveProtocol);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardDisconnect)
+ {
+ return g_PCSCLite->pfnSCardDisconnect(hCard, dwDisposition);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardBeginTransaction(SCARDHANDLE hCard)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardBeginTransaction)
+ {
+ return g_PCSCLite->pfnSCardBeginTransaction(hCard);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardEndTransaction)
+ {
+ return g_PCSCLite->pfnSCardEndTransaction(hCard, dwDisposition);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardCancelTransaction(SCARDHANDLE hCard)
{
+ InitializeSCardStubs();
+
return 0;
}
LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardStatus)
+ {
+ return g_PCSCLite->pfnSCardStatus(hCard, mszReaderNames, pcchReaderLen,
+ pdwState, pdwProtocol, pbAtr, pcbAtrLen);
+ }
+
return 0;
}
+
WINSCARDAPI LONG WINAPI SCardStatusW(SCARDHANDLE hCard,
LPWSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState,
LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
{
+ InitializeSCardStubs();
+
return 0;
}
LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength,
LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardTransmit)
+ {
+ return g_PCSCLite->pfnSCardTransmit(hCard, pioSendPci, pbSendBuffer,
+ cbSendLength, pioRecvPci, pbRecvBuffer, pcbRecvLength);
+ }
+
return 0;
}
DWORD dwControlCode, LPCVOID lpInBuffer, DWORD cbInBufferSize,
LPVOID lpOutBuffer, DWORD cbOutBufferSize, LPDWORD lpBytesReturned)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardControl)
+ {
+ return g_PCSCLite->pfnSCardControl(hCard,
+ dwControlCode, lpInBuffer, cbInBufferSize,
+ lpOutBuffer, cbOutBufferSize, lpBytesReturned);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardGetAttrib)
+ {
+ return g_PCSCLite->pfnSCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
+ }
+
return 0;
}
WINSCARDAPI LONG WINAPI SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen)
{
+ InitializeSCardStubs();
+
+ if (g_PCSCLite && g_PCSCLite->pfnSCardSetAttrib)
+ {
+ return g_PCSCLite->pfnSCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);
+ }
+
return 0;
}