winscard: Implement base functions for work with smart cards

serg_admin at rambler.ru serg_admin at rambler.ru
Mon May 2 11:45:33 CDT 2011


From: Sergey Stepanov <serg_admin at rambler.ru>

---
 dlls/winscard/winscard.c    |  143 +++++++++++++++++++++++++++++++++++++++++--
 dlls/winscard/winscard.spec |   10 ++--
 2 files changed, 142 insertions(+), 11 deletions(-)

diff --git a/dlls/winscard/winscard.c b/dlls/winscard/winscard.c
index 412299c..068be0b 100644
--- a/dlls/winscard/winscard.c
+++ b/dlls/winscard/winscard.c
@@ -17,6 +17,8 @@
  */
 
 #include "config.h"
+#include <dlfcn.h>
+#include <wine/library.h>
 #include <stdarg.h>
 #include "windef.h"
 #include "winbase.h"
@@ -28,14 +30,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(winscard);
 
 static HMODULE WINSCARD_hModule;
 static HANDLE g_startedEvent = NULL;
+static void *h_libpcsc;
 
 const SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
 const SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
 const SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
 
+LONG (*_SCardConnect)(SCARDCONTEXT,LPCSTR,DWORD,DWORD,LPSCARDHANDLE,LPDWORD);
+LONG (*_SCardDisconnect)(SCARDHANDLE, DWORD);
+LONG (*_SCardEstablishContext)(DWORD,LPCVOID,LPCVOID,LPSCARDCONTEXT);
+LONG (*_SCardGetStatusChange)(SCARDCONTEXT,DWORD,LPSCARD_READERSTATEA,DWORD);
+LONG (*_SCardListReaders)(SCARDHANDLE, LPCSTR,LPSTR,LPDWORD);
+LONG (*_SCardReleaseContext)(SCARDCONTEXT);
+LONG (*_SCardTransmit)(SCARDHANDLE,LPCSCARD_IO_REQUEST,LPCBYTE,DWORD,LPSCARD_IO_REQUEST,LPBYTE,LPDWORD);
 
 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
 {
+    char error[512];
     TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);
 
     switch (fdwReason)
@@ -46,11 +57,61 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
             WINSCARD_hModule = hinstDLL;
             /* FIXME: for now, we act as if the pcsc daemon is always started */
             g_startedEvent = CreateEventA(NULL,TRUE,TRUE,NULL);
+            /* check exist libpcsclite.so */
+            h_libpcsc = wine_dlopen("libpcsclite.so", RTLD_LAZY, error, 512);
+            if (h_libpcsc == 0)  {
+              FIXME("Can't load library libpcsclite.so: %s\n", error);
+              SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+            }
+            else  {
+        	_SCardConnect = wine_dlsym(h_libpcsc, "SCardConnect", error, 512);
+        	if (!(_SCardConnect))  {
+        	  FIXME("Can't find method SCardConnec: %s\n", error);
+                  SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+        	}
+		_SCardDisconnect = wine_dlsym(h_libpcsc,"SCardDisconnect", error, 512);
+        	if (!(_SCardDisconnect))  {
+        	  FIXME("Can't find method SCardDisconnect: %s\n", error);
+                  SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+        	}
+        	_SCardEstablishContext = wine_dlsym(h_libpcsc,"SCardEstablishContext", error, 512);
+        	if (!(_SCardEstablishContext))  {
+        	  FIXME("Can't find method SCardEstablishContext: %s\n", error);
+                  SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+        	}
+        	_SCardGetStatusChange = wine_dlsym(h_libpcsc,"SCardGetStatusChange", error, 512);
+        	if (!(_SCardGetStatusChange))  {
+        	  FIXME("Can't find method SCardGetStatusChange: %s\n", error);
+                  SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+        	}
+        	_SCardListReaders = wine_dlsym(h_libpcsc,"SCardListReaders", error, 512);
+        	if (!(_SCardListReaders))  {
+        	  FIXME("Can't find method SCardListReaders: %s\n", error);
+                  SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+        	}
+        	_SCardReleaseContext = wine_dlsym(h_libpcsc,"SCardReleaseContext", error, 512);
+        	if (!(_SCardReleaseContext))  {
+        	  FIXME("Can't find method SCardReleaseContext: %s\n", error);
+                  SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+        	}
+        	_SCardTransmit = wine_dlsym(h_libpcsc,"SCardTransmit", error, 512);
+        	if (!(_SCardReleaseContext))  {
+        	  FIXME("Can't find method SCardTransmit: %s\n", error);
+                  SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+        	}
+            }
             break;
         }
         case DLL_PROCESS_DETACH:
         {
             CloseHandle(g_startedEvent);
+            if (h_libpcsc != 0)
+            {
+              if (wine_dlclose(h_libpcsc, error, 512))
+              {
+                TRACE("Wrong unload libpcsclite.so: %s\n", error);
+              }
+            }
             break;
         }
     }
@@ -87,12 +148,53 @@ LONG WINAPI SCardAddReaderToGroupW(SCARDCONTEXT context, LPCWSTR reader, LPCWSTR
     return SCARD_S_SUCCESS;
 }
 
+LONG WINAPI SCardConnectA(SCARDCONTEXT context, LPCSTR szReader, DWORD dwShareMode,
+    DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
+{
+    TRACE("(%lx,%p,%x,%x,%p,%p) stub\n", context, szReader, dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol);
+    if (_SCardConnect)
+      return (*_SCardConnect)(context, szReader, dwShareMode,
+	dwPreferredProtocols, phCard, pdwActiveProtocol);
+    else {
+      SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+      return SCARD_F_INTERNAL_ERROR;
+    }
+}
+
+LONG WINAPI SCardDisconnect(SCARDCONTEXT context, DWORD dwDisposition)
+{
+    TRACE("(%lx,%x) stub\n", context, dwDisposition);
+    if (_SCardDisconnect)
+      return (*_SCardDisconnect)(context, dwDisposition);
+    else {
+      SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+      return SCARD_F_INTERNAL_ERROR;
+    }
+}
+
 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;
+    TRACE("(%x,%p,%p,%p) stub\n", dwScope, pvReserved1, pvReserved2, phContext);
+    if (_SCardEstablishContext)
+      return (*_SCardEstablishContext)(dwScope, pvReserved1,
+         pvReserved2, phContext);
+    else {
+      SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+      return SCARD_F_INTERNAL_ERROR;
+    }
+}
+
+LONG WINAPI SCardGetStatusChangeA(SCARDCONTEXT context, DWORD dwTimeout, 
+    LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders)
+{
+    TRACE("(%lx, %x, %p, %x) stub\n", context, dwTimeout, rgReaderStates, cReaders);
+    if (_SCardGetStatusChange)
+      return (*_SCardGetStatusChange)(context, dwTimeout, rgReaderStates, cReaders);
+    else {
+      SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+      return SCARD_F_INTERNAL_ERROR;
+    }
 }
 
 LONG WINAPI SCardIsValidContext(SCARDCONTEXT context)
@@ -109,14 +211,43 @@ LONG WINAPI SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr, LPCGUID rgguid
     return SCARD_F_INTERNAL_ERROR;
 }
 
+LONG WINAPI SCardListReadersA(SCARDCONTEXT context, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
+{
+    TRACE("(%lx, %p, %p, %p) stub\n", context, mszGroups, mszReaders, pcchReaders);
+    if (_SCardListReaders)
+      return (*_SCardListReaders)(context,mszGroups,mszReaders,pcchReaders);
+    else {
+      SetLastError(ERROR_DLL_MIGHT_BE_INCOMPATIBLE);
+      return SCARD_F_INTERNAL_ERROR;
+    }
+}
+
 LONG WINAPI SCardReleaseContext(SCARDCONTEXT context)
 {
-    FIXME("(%lx) stub\n", context);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return SCARD_F_INTERNAL_ERROR;
+    TRACE("(%lx) stub\n", context);
+    if (_SCardReleaseContext)
+      return (*_SCardReleaseContext)(context);
+    else {
+      SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+      return SCARD_F_INTERNAL_ERROR;
+    }
 }
 
 void WINAPI SCardReleaseStartedEvent(void)
 {
     FIXME("stub\n");
 }
+
+LONG WINAPI SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, 
+  DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
+{
+    TRACE("(%lx %p %p %x %p %p %p) stub\n", hCard, pioSendPci, pbSendBuffer, cbSendLength, 
+                pioRecvPci, pbRecvBuffer, pcbRecvLength);
+    if (_SCardTransmit)
+      return (*_SCardTransmit)(hCard, pioSendPci, pbSendBuffer, cbSendLength, 
+                pioRecvPci, pbRecvBuffer, pcbRecvLength);
+    else {
+      SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+      return SCARD_F_INTERNAL_ERROR;
+    }
+}
\ No newline at end of file
diff --git a/dlls/winscard/winscard.spec b/dlls/winscard/winscard.spec
index 1bd6ef1..e70de30 100644
--- a/dlls/winscard/winscard.spec
+++ b/dlls/winscard/winscard.spec
@@ -7,10 +7,10 @@
 @ stdcall SCardAddReaderToGroupW(long wstr wstr)
 @ stub SCardBeginTransaction
 @ stub SCardCancel
-@ stub SCardConnectA
+@ stdcall SCardConnectA(long ptr long long ptr ptr)
 @ stub SCardConnectW
 @ stub SCardControl
-@ stub SCardDisconnect
+@ stdcall SCardDisconnect(long long)
 @ stub SCardEndTransaction
 @ stdcall SCardEstablishContext(long ptr ptr ptr)
 @ stub SCardForgetCardTypeA
@@ -25,7 +25,7 @@
 @ stub SCardGetCardTypeProviderNameW
 @ stub SCardGetProviderIdA
 @ stub SCardGetProviderIdW
-@ stub SCardGetStatusChangeA
+@ stdcall SCardGetStatusChangeA(long long ptr long)
 @ stub SCardGetStatusChangeW
 @ stub SCardIntroduceCardTypeA
 @ stub SCardIntroduceCardTypeW
@@ -40,7 +40,7 @@
 @ stub SCardListInterfacesW
 @ stub SCardListReaderGroupsA
 @ stub SCardListReaderGroupsW
-@ stub SCardListReadersA
+@ stdcall SCardListReadersA(long ptr ptr ptr)
 @ stub SCardListReadersW
 @ stub SCardLocateCardsA
 @ stub SCardLocateCardsByATRA
@@ -57,7 +57,7 @@
 @ stub SCardState
 @ stub SCardStatusA
 @ stub SCardStatusW
-@ stub SCardTransmit
+@ stdcall SCardTransmit(long ptr ptr long ptr ptr ptr)
 @ extern g_rgSCardRawPci
 @ extern g_rgSCardT0Pci
 @ extern g_rgSCardT1Pci
-- 
1.7.4.4




More information about the wine-patches mailing list