Yes I started with this referenced discussion.

Here is a first patch. With it, Winscard can identify your smartcard reader.

Is it good enough to be sent to wine-patch ?

Here (http://www.linuxunderground.be/compteco/winscard_test.zip) a Windows test program that identifies your smartcard reader.

PS: don't use versions 1.6.0 and 1.6.1 of pcsc-lite (https://alioth.debian.org/tracker/?func=detail&atid=410085&aid=312555&group_id=30105)

--
Vincent

Le 28/09/2010 13:56, Jerome Leclanche a écrit :
The referenced discussion, in case anyone's curious:
http://www.winehq.org/pipermail/wine-devel/2008-August/068462.html


J. Leclanche



On Tue, Sep 28, 2010 at 12:43 PM, Tom Wickline<twickl...@gmail.com>  wrote:
Hello Vincent,

I don't believe anyone is working on winscard.dll at this time. You are more
then
welcome to work on it or any other part of Wine.

A couple years back their was a discussion about winscard.dll so you might
want to search through the wine-dev mailing list. Maybe those old
discussions
can be of some help.

Just some tips,

Make sure you use the same coding style that's already used.
Send as many test as you can.
Keep your patches small and clean.
Send patches here for review and to wine-patches for inclusion.


Welcome to the wonderful world of Wine!

Cheers,
Tom



On Tue, Sep 28, 2010 at 4:49 PM, viny<vincent.hardy...@gmail.com>  wrote:

Hi all,

Is anyone working on winscard.dll ?

If not, may I propose patches ?

I would like to have a working winscard.dll in wine.

--
Vincent






--
Wine is not a conclusion but a process...







>From 5cf45149ef8eb35f87c93a500938c7e55349796e Mon Sep 17 00:00:00 2001
From: Vincent Hardy <vincent.hardy...@gmail.com>
Date: Tue, 28 Sep 2010 13:02:06 +0200
Subject: [PATCH] First winscard patch
Windows test program :
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



Reply via email to