[PATCH] First winscard patch

Vincent Hardy vincent.hardy.be at gmail.com
Tue Sep 28 06:02:06 CDT 2010


www.linuxunderground.be/compteco/winscard_test.zip
(this program identifies your smartcard reader)
---
 dlls/winscard/winscard.c    |  162 ++++++++++++++++++++++++++++++++++++++++---
 dlls/winscard/winscard.spec |    2 +-
 include/winsmcrd.h          |    2 +
 3 files changed, 156 insertions(+), 10 deletions(-)

diff --git a/dlls/winscard/winscard.c b/dlls/winscard/winscard.c
index bbf1d72..decc72c 100644
--- a/dlls/winscard/winscard.c
+++ b/dlls/winscard/winscard.c
@@ -17,16 +17,27 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 #include <stdarg.h>
 #include "windef.h"
 #include "winbase.h"
 #include "wine/debug.h"
+#include "wine/library.h"
 #include "winscard.h"
 #include "winternl.h"
 
+static BOOL PCSCLite_loadlib(void);
+static BOOL PCSCLite_loadfunctions(void);
+
 WINE_DEFAULT_DEBUG_CHANNEL(winscard);
 
+static LONG (*pSCardEstablishContext)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
+static LONG (*pSCardIsValidContext)(SCARDCONTEXT hContext);
+static LONG (*pSCardReleaseContext)(SCARDCONTEXT hContext);
+static LONG (*pSCardListReaders)(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders);
+
 static HMODULE WINSCARD_hModule;
+static void *g_pcscliteHandle = NULL;
 static HANDLE g_startedEvent = NULL;
 
 const SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
@@ -44,6 +55,10 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
         {
             DisableThreadLibraryCalls(hinstDLL);
             WINSCARD_hModule = hinstDLL;
+            
+	    if (PCSCLite_loadlib())
+	        PCSCLite_loadfunctions();
+	    
             /* FIXME: for now, we act as if the pcsc daemon is always started */
             g_startedEvent = CreateEventA(NULL,TRUE,TRUE,NULL);
             break;
@@ -51,6 +66,13 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
         case DLL_PROCESS_DETACH:
         {
             CloseHandle(g_startedEvent);
+
+            /* release PCSC-lite */
+            if (g_pcscliteHandle)
+            {  
+                wine_dlclose(g_pcscliteHandle,NULL,0);  
+                g_pcscliteHandle = NULL;   	    
+            }   
             break;
         }
     }
@@ -58,6 +80,62 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     return TRUE;
 }
 
+static BOOL PCSCLite_loadlib(void)
+{
+    char error[256];
+    
+    if (g_pcscliteHandle)
+            return TRUE; /*already loaded*/
+    else
+    {
+        g_pcscliteHandle = wine_dlopen("libpcsclite.so", RTLD_LAZY | RTLD_GLOBAL, error, sizeof(error));
+        if (g_pcscliteHandle)
+            return TRUE;
+        else
+        {  
+            WARN("Failed to open library libpcsclite.so : %s\n", error);
+            return FALSE;
+        }    
+    } 
+}  
+
+static BOOL PCSCLite_loadfunctions(void)
+{
+    char error[256];
+
+#define LOAD_FUNC(name) \
+if ((p##name = wine_dlsym(g_pcscliteHandle,#name, error, sizeof(error) ))); \
+    else WARN( "Failed to load %s: %s\n", #name, error )
+
+    LOAD_FUNC(SCardIsValidContext);
+    LOAD_FUNC(SCardEstablishContext);
+    LOAD_FUNC(SCardReleaseContext);
+    LOAD_FUNC(SCardListReaders);
+
+#undef LOAD_FUNC
+
+    return TRUE;
+}
+
+/*
+ * translate PCSC-lite errors to equivalent MS ones
+ * Actually, the only difference is for SCARD_W_INSERTED_CARD(0x8010006A) and
+ * SCARD_E_UNSUPPORTED_FEATURE (0x8010001F)
+ */
+
+#define PCSCLITE_SCARD_W_INSERTED_CARD         0x8010006A
+#define PCSCLITE_SCARD_E_UNSUPPORTED_FEATURE   0x8010001F
+
+static LONG TranslateToWin32(LONG retval)
+{
+    if (retval == PCSCLITE_SCARD_E_UNSUPPORTED_FEATURE)
+        return SCARD_E_UNSUPPORTED_FEATURE;
+    else if (retval == PCSCLITE_SCARD_W_INSERTED_CARD)
+        return SCARD_F_UNKNOWN_ERROR; /* FIXME: is there a better WIN32 error code */
+    else
+        return retval;
+}
+
 HANDLE WINAPI SCardAccessStartedEvent(void)
 {
     return g_startedEvent;
@@ -90,16 +168,75 @@ LONG WINAPI SCardAddReaderToGroupW(SCARDCONTEXT context, LPCWSTR reader, LPCWSTR
 LONG WINAPI SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
     LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
 {
-    FIXME("(%x,%p,%p,%p) stub\n", dwScope, pvReserved1, pvReserved2, phContext);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return SCARD_F_INTERNAL_ERROR;
+    LONG retval;
+    
+    TRACE(" 0x%08X %p %p %p\n",dwScope, pvReserved1, pvReserved2, phContext);
+    if (!phContext)
+        retval = SCARD_E_INVALID_PARAMETER;
+    else if(!pSCardEstablishContext)
+        retval = SCARD_F_INTERNAL_ERROR;
+    else
+        retval = pSCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext);
+
+    TRACE(" returned 0x%08X\n", retval);
+    return TranslateToWin32(retval);
 }
 
 LONG WINAPI SCardIsValidContext(SCARDCONTEXT context)
 {
-    FIXME("(%lx) stub\n", context);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return SCARD_F_INTERNAL_ERROR;
+    TRACE(" 0x%08X\n", (unsigned int) context);
+    
+    if (!pSCardIsValidContext)
+        return SCARD_F_INTERNAL_ERROR;
+    else
+        return TranslateToWin32(pSCardIsValidContext(context));
+}
+
+LONG WINAPI SCardListReadersA(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
+{
+    LONG retval;
+    LPSTR *pmszReaders;
+    LPSTR szList = NULL;
+    DWORD ListLength = 0;
+
+    TRACE(" 0x%08X %p %p %p\n", (unsigned int) hContext, mszGroups, mszReaders, pcchReaders);
+    
+    if (!pcchReaders)
+        retval = SCARD_E_INVALID_PARAMETER;
+    else if (!pSCardListReaders)
+        retval = SCARD_F_INTERNAL_ERROR;
+    else if (mszReaders && *pcchReaders == SCARD_AUTOALLOCATE)
+    {               
+        /* get list from pcsc-lite */
+        *pmszReaders = (LPSTR*) mszReaders;
+
+        retval = pSCardListReaders(hContext, mszGroups, NULL, &ListLength);
+        if (retval != SCARD_S_SUCCESS && retval != SCARD_E_INSUFFICIENT_BUFFER)
+            goto out;
+
+        szList = HeapAlloc(GetProcessHeap(), 0, ListLength);
+
+        if (!szList)
+        {
+            retval = SCARD_E_NO_MEMORY;
+            goto out;
+        }
+
+        retval = pSCardListReaders(hContext, mszGroups, szList, &ListLength);
+        if (SCARD_S_SUCCESS != retval)
+            HeapFree(GetProcessHeap(), 0, szList);
+        else
+        {
+            *pmszReaders = szList;
+            *pcchReaders = ListLength;
+        }
+    }
+    else
+        retval = pSCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
+
+out:
+    TRACE(" returned 0x%08X\n", retval);
+    return TranslateToWin32(retval);
 }
 
 LONG WINAPI SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr, LPCGUID rgguidInterfaces, DWORD cguidInterfaceCount, LPSTR mszCards, LPDWORD pcchCards)
@@ -111,7 +248,14 @@ LONG WINAPI SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr, LPCGUID rgguid
 
 LONG WINAPI SCardReleaseContext(SCARDCONTEXT context)
 {
-    FIXME("(%lx) stub\n", context);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return SCARD_F_INTERNAL_ERROR;
+    LONG retval;
+    
+    TRACE(" 0x%08X\n", (unsigned int) context);
+    if (!pSCardReleaseContext)
+        retval = SCARD_F_INTERNAL_ERROR;
+    else 
+        retval = pSCardReleaseContext(context);
+
+    TRACE(" returned 0x%08X\n", retval);
+    return TranslateToWin32(retval);
 }
diff --git a/dlls/winscard/winscard.spec b/dlls/winscard/winscard.spec
index 116cb04..f807de5 100644
--- a/dlls/winscard/winscard.spec
+++ b/dlls/winscard/winscard.spec
@@ -40,7 +40,7 @@
 @ stub SCardListInterfacesW
 @ stub SCardListReaderGroupsA
 @ stub SCardListReaderGroupsW
-@ stub SCardListReadersA
+@ stdcall SCardListReadersA(long str str ptr)
 @ stub SCardListReadersW
 @ stub SCardLocateCardsA
 @ stub SCardLocateCardsByATRA
diff --git a/include/winsmcrd.h b/include/winsmcrd.h
index 60fdd3e..ec5857a 100644
--- a/include/winsmcrd.h
+++ b/include/winsmcrd.h
@@ -27,6 +27,8 @@
 #define SCARD_PROTOCOL_DEFAULT          0x80000000
 #define SCARD_PROTOCOL_Tx               (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
 
+#define SCARD_AUTOALLOCATE (DWORD)(-1)
+
 typedef struct _SCARD_IO_REQUEST
 {
     DWORD dwProtocol;
-- 
1.5.2.5


--------------020107090406040705060205--



More information about the wine-devel mailing list