libwinpr-smartcard: dynamically load pcsclite
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 3 Apr 2014 02:08:04 +0000 (22:08 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 3 Apr 2014 02:08:04 +0000 (22:08 -0400)
winpr/include/winpr/smartcard.h
winpr/libwinpr/smartcard/smartcard.c
winpr/libwinpr/smartcard/test/TestSmartCardListReaders.c

index 350203d..175d188 100644 (file)
 #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
 
index 257f4ca..4242296 100644 (file)
@@ -22,6 +22,7 @@
 #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;
 }
 
@@ -229,6 +360,13 @@ WINSCARDAPI LONG WINAPI SCardForgetCardTypeW(SCARDCONTEXT hContext, LPCWSTR szCa
 
 WINSCARDAPI LONG WINAPI SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
 {
+       InitializeSCardStubs();
+
+       if (g_PCSCLite && g_PCSCLite->pfnSCardFreeMemory)
+       {
+               return g_PCSCLite->pfnSCardFreeMemory(hContext, pvMem);
+       }
+
        return 0;
 }
 
@@ -258,6 +396,7 @@ WINSCARDAPI LONG WINAPI SCardLocateCardsByATRA(SCARDCONTEXT hContext,
 {
        return 0;
 }
+
 WINSCARDAPI LONG WINAPI SCardLocateCardsByATRW(SCARDCONTEXT hContext,
                LPSCARD_ATRMASK rgAtrMasks, DWORD cAtrs, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders)
 {
@@ -267,11 +406,21 @@ WINSCARDAPI LONG WINAPI SCardLocateCardsByATRW(SCARDCONTEXT hContext,
 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;
 }
 
@@ -279,38 +428,80 @@ WINSCARDAPI LONG WINAPI SCardConnectA(SCARDCONTEXT hContext,
                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;
 }
 
@@ -324,12 +515,23 @@ WINSCARDAPI LONG WINAPI SCardStatusA(SCARDHANDLE hCard,
                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;
 }
 
@@ -337,6 +539,14 @@ WINSCARDAPI LONG WINAPI SCardTransmit(SCARDHANDLE hCard,
                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;
 }
 
@@ -349,16 +559,39 @@ WINSCARDAPI LONG WINAPI SCardControl(SCARDHANDLE hCard,
                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;
 }
 
index 19dfef6..7f12727 100644 (file)
@@ -4,6 +4,51 @@
 
 int TestSmartCardListReaders(int argc, char* argv[])
 {
+       LONG lStatus;
+       LPTSTR pReader;
+       SCARDCONTEXT hSC;
+       LPTSTR pmszReaders = NULL;
+       DWORD cch = SCARD_AUTOALLOCATE;
+
+       lStatus = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSC);
+
+       if (lStatus != SCARD_S_SUCCESS)
+       {
+               printf("SCardEstablishContext failure: 0x%04X\n", (int) lStatus);
+               return -1;
+       }
+
+       lStatus = SCardListReaders(hSC, NULL, (LPTSTR) &pmszReaders, &cch);
+
+       if (lStatus != SCARD_S_SUCCESS)
+       {
+               if (lStatus == SCARD_E_NO_READERS_AVAILABLE)
+               {
+                       printf("SCARD_E_NO_READERS_AVAILABLE\n");
+               }
+               else
+               {
+                       return -1;
+               }
+       }
+       else
+       {
+               pReader = pmszReaders;
+
+               while (*pReader)
+               {
+                       printf("Reader: %s\n", pReader);
+                       pReader = pReader + strlen((CHAR*) pReader) + 1;
+               }
+
+               lStatus = SCardFreeMemory(hSC, pmszReaders);
+
+               if (lStatus != SCARD_S_SUCCESS)
+                       printf("Failed SCardFreeMemory\n");
+       }
+
+       SCardReleaseContext(hSC);
+
        return 0;
 }