[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