Winscard support (for smart cards)

Mounir IDRASSI mounir.idrassi at idrix.fr
Sun Apr 29 17:58:53 CDT 2007


Hi all,
We have managed to integrate our winscard source code into the wine source tree, including the configure.ac and Makefine.in files.
As described in the developer's guide, I am attaching with this email the output of the command "git format-patch origin".
Can someone please check if I have done it the right way? If this is ok, should I post it also to the patches mailing list.
For your information, our implementation uses pcsc-lite through wine_dlopen and wine_dlsym, so pcsc-lite is not required at compile time.
We have not included test files as they include the use of smart cards with proprietary applications.
I will try in the near future to include a wine implementation of a graphical tool that can manipulate smart cards using the wine winscard dll.
Thanks for your help.
Cheers,

Mounir IDRASSI
IDRIX - Cryptography and IT Security Experts
http://www.idrix.fr


-------------- next part --------------
>From d0a45c9347a4462b56e6deac0bcf1b37a815f541 Mon Sep 17 00:00:00 2001
From: Mounir IDRASSI <mounir.idrassi at idrix.fr>
Date: Sun, 29 Apr 2007 22:31:09 +0200
Subject: [PATCH] First version of wine implementation of Smart Card API based on pcsc-lite

---
 Makefile.in                 |    2 +
 configure                   |    3 +
 configure.ac                |    1 +
 dlls/Makefile.in            |    5 +
 dlls/winscard/Makefile.in   |   17 +
 dlls/winscard/rsrc.rc       |   33 +
 dlls/winscard/winscard.c    | 1991 +++++++++++++++++++++++++++++++++++++++++++
 dlls/winscard/winscard.spec |   63 ++
 include/Makefile.in         |    3 +
 include/scarderr.h          |  111 +++
 include/winscard.h          |  381 +++++++++
 include/winsmcrd.h          |  207 +++++
 12 files changed, 2817 insertions(+), 0 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 1f8f0c9..fd825a7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -417,6 +417,7 @@ ALL_MAKEFILES = \
 	dlls/winmm/Makefile \
 	dlls/winmm/tests/Makefile \
 	dlls/winnls32/Makefile \
+	dlls/winscard/Makefile \
 	dlls/winspool.drv/Makefile \
 	dlls/winspool.drv/tests/Makefile \
 	dlls/wintab32/Makefile \
@@ -762,6 +763,7 @@ dlls/wininet/tests/Makefile: dlls/wininet/tests/Makefile.in dlls/Maketest.rules
 dlls/winmm/Makefile: dlls/winmm/Makefile.in dlls/Makedll.rules
 dlls/winmm/tests/Makefile: dlls/winmm/tests/Makefile.in dlls/Maketest.rules
 dlls/winnls32/Makefile: dlls/winnls32/Makefile.in dlls/Makedll.rules
+dlls/winscard/Makefile: dlls/winscard/Makefile.in dlls/Makedll.rules
 dlls/winspool.drv/Makefile: dlls/winspool.drv/Makefile.in dlls/Makedll.rules
 dlls/winspool.drv/tests/Makefile: dlls/winspool.drv/tests/Makefile.in dlls/Maketest.rules
 dlls/wintab32/Makefile: dlls/wintab32/Makefile.in dlls/Makedll.rules
diff --git a/configure b/configure
index 71a66ae..1a11b08 100755
--- a/configure
+++ b/configure
@@ -20839,6 +20839,8 @@ ac_config_files="$ac_config_files dlls/winmm/tests/Makefile"
 
 ac_config_files="$ac_config_files dlls/winnls32/Makefile"
 
+ac_config_files="$ac_config_files dlls/winscard/Makefile"
+
 ac_config_files="$ac_config_files dlls/winspool.drv/Makefile"
 
 ac_config_files="$ac_config_files dlls/winspool.drv/tests/Makefile"
@@ -21806,6 +21808,7 @@ do
     "dlls/winmm/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winmm/Makefile" ;;
     "dlls/winmm/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winmm/tests/Makefile" ;;
     "dlls/winnls32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winnls32/Makefile" ;;
+    "dlls/winscard/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winscard/Makefile" ;;    
     "dlls/winspool.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winspool.drv/Makefile" ;;
     "dlls/winspool.drv/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winspool.drv/tests/Makefile" ;;
     "dlls/wintab32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/wintab32/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index ddec5f4..19026c6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1744,6 +1744,7 @@ AC_CONFIG_FILES([dlls/wininet/tests/Makefile])
 AC_CONFIG_FILES([dlls/winmm/Makefile])
 AC_CONFIG_FILES([dlls/winmm/tests/Makefile])
 AC_CONFIG_FILES([dlls/winnls32/Makefile])
+AC_CONFIG_FILES([dlls/winscard/Makefile])
 AC_CONFIG_FILES([dlls/winspool.drv/Makefile])
 AC_CONFIG_FILES([dlls/winspool.drv/tests/Makefile])
 AC_CONFIG_FILES([dlls/wintab32/Makefile])
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index f9707e7..7dbf3c4 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -205,6 +205,7 @@ BASEDIRS = \
 	wininet \
 	winmm \
 	winnls32 \
+	winscard \
 	winspool.drv \
 	wintab32 \
 	wintrust \
@@ -571,6 +572,7 @@ IMPORT_LIBS = \
 	wininet/libwininet.$(IMPLIBEXT) \
 	winmm/libwinmm.$(IMPLIBEXT) \
 	winnls32/libwinnls32.$(IMPLIBEXT) \
+	winscard/libwinscard.$(IMPLIBEXT) \
 	winspool.drv/libwinspool.$(IMPLIBEXT) \
 	wintab32/libwintab32.$(IMPLIBEXT) \
 	wintrust/libwintrust.$(IMPLIBEXT) \
@@ -920,6 +922,9 @@ winmm/libwinmm.$(IMPLIBEXT): winmm/winmm.spec $(WINEBUILD)
 
 winnls32/libwinnls32.$(IMPLIBEXT): winnls32/winnls32.spec $(WINEBUILD)
 	@cd winnls32 && $(MAKE) libwinnls32.$(IMPLIBEXT)
+	
+winscard/libwinscard.$(IMPLIBEXT): winscard/winscard.spec $(WINEBUILD)
+	@cd winscard && $(MAKE) libwinscard.$(IMPLIBEXT)	
 
 winspool.drv/libwinspool.$(IMPLIBEXT): winspool.drv/winspool.drv.spec $(WINEBUILD)
 	@cd winspool.drv && $(MAKE) libwinspool.$(IMPLIBEXT)
diff --git a/dlls/winscard/Makefile.in b/dlls/winscard/Makefile.in
new file mode 100755
index 0000000..7f08a02
--- /dev/null
+++ b/dlls/winscard/Makefile.in
@@ -0,0 +1,17 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = winscard.dll
+IMPORTLIB = libwinscard.$(IMPLIBEXT)
+IMPORTS   = advapi32 kernel32
+
+C_SRCS = \
+	winscard.c
+
+RC_SRCS = \
+	rsrc.rc
+
+ at MAKE_DLL_RULES@
+
+ at DEPENDENCIES@  # everything below this line is overwritten by make depend
diff --git a/dlls/winscard/rsrc.rc b/dlls/winscard/rsrc.rc
new file mode 100644
index 0000000..8226e9d
--- /dev/null
+++ b/dlls/winscard/rsrc.rc
@@ -0,0 +1,33 @@
+/*
+ * Top level resource file for winscard.dll
+ *
+ * Copyright 2007 Mounir IDRASSI  (mounir.idrassi at idrix.fr, for IDRIX)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winver.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#define WINE_FILEDESCRIPTION_STR "Wine Smart Card API"
+#define WINE_FILENAME_STR "winscard.dll"
+#define WINE_FILEVERSION 5,1,2600,2180
+#define WINE_FILEVERSION_STR "5.1.2600.2180"
+
+#include "wine/wine_common_ver.rc"
diff --git a/dlls/winscard/winscard.c b/dlls/winscard/winscard.c
new file mode 100755
index 0000000..4b0ce38
--- /dev/null
+++ b/dlls/winscard/winscard.c
@@ -0,0 +1,1991 @@
+/*
+ * Copyright 2007 Mounir IDRASSI  (mounir.idrassi at idrix.fr, for IDRIX)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+#include <stdarg.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "wine/debug.h"
+#include "wine/library.h"
+#include "wine/unicode.h"
+#include <winscard.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(winscard);
+
+static HMODULE WINSCARD_hModule;
+
+SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
+SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
+SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
+
+
+#define MAX_PCSCLITE_READERNAME			52
+
+/*
+  * pcsc-lite functions pointers
+  */
+typedef LONG (*SCardEstablishContextPtr)(DWORD dwScope,LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
+typedef LONG (*SCardReleaseContextPtr)(SCARDCONTEXT hContext);
+typedef LONG (*SCardIsValidContextPtr)(SCARDCONTEXT hContext);
+typedef LONG (*SCardSetTimeoutPtr)(SCARDCONTEXT hContext, DWORD dwTimeout);
+typedef LONG (*SCardConnectPtr)(SCARDCONTEXT hContext,LPCSTR szReader,DWORD dwShareMode,DWORD dwPreferredProtocols,LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol);
+typedef LONG (*SCardReconnectPtr)(SCARDHANDLE hCard,DWORD dwShareMode,DWORD dwPreferredProtocols,DWORD dwInitialization, LPDWORD pdwActiveProtocol);
+typedef LONG (*SCardDisconnectPtr)(SCARDHANDLE hCard, DWORD dwDisposition);
+typedef LONG (*SCardBeginTransactionPtr)(SCARDHANDLE hCard);
+typedef LONG (*SCardEndTransactionPtr)(SCARDHANDLE hCard, DWORD dwDisposition);
+typedef LONG (*SCardCancelTransactionPtr)(SCARDHANDLE hCard);
+typedef LONG (*SCardStatusPtr)(SCARDHANDLE hCard,LPSTR mszReaderNames, LPDWORD pcchReaderLen,LPDWORD pdwState,LPDWORD pdwProtocol,BYTE* pbAtr,LPDWORD pcbAtrLen);
+typedef LONG (*SCardGetStatusChangePtr)(SCARDCONTEXT hContext,DWORD dwTimeout,LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders);
+typedef LONG (*SCardControlPtr)(SCARDHANDLE hCard, DWORD dwControlCode,	LPCVOID pbSendBuffer, DWORD cbSendLength,LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned);
+typedef LONG (*SCardTransmitPtr)(SCARDHANDLE hCard,LPCSCARD_IO_REQUEST pioSendPci,const BYTE* pbSendBuffer, DWORD cbSendLength,LPSCARD_IO_REQUEST pioRecvPci,BYTE* pbRecvBuffer, LPDWORD pcbRecvLength);
+typedef LONG (*SCardListReaderGroupsPtr)(SCARDCONTEXT hContext,LPSTR mszGroups, LPDWORD pcchGroups);
+typedef LONG (*SCardListReadersPtr)(SCARDCONTEXT hContext,LPCSTR mszGroups,LPSTR mszReaders, LPDWORD pcchReaders);
+typedef LONG (*SCardCancelPtr)(SCARDCONTEXT hContext);
+typedef LONG (*SCardGetAttribPtr)(SCARDHANDLE hCard, DWORD dwAttrId,BYTE* pbAttr, LPDWORD pcbAttrLen);
+typedef LONG (*SCardSetAttribPtr)(SCARDHANDLE hCard, DWORD dwAttrId,const BYTE* pbAttr, DWORD cbAttrLen);  
+		
+SCardEstablishContextPtr 	liteSCardEstablishContext 	= NULL;
+SCardReleaseContextPtr 		liteSCardReleaseContext 	= NULL;
+SCardIsValidContextPtr 		liteSCardIsValidContext 		= NULL;
+SCardSetTimeoutPtr 		liteSCardSetTimeout		= NULL;
+SCardConnectPtr 			liteSCardConnect			= NULL;
+SCardReconnectPtr			liteSCardReconnect			= NULL;
+SCardDisconnectPtr			liteSCardDisconnect		= NULL;		
+SCardBeginTransactionPtr	liteSCardBeginTransaction	= NULL;
+SCardEndTransactionPtr		liteSCardEndTransaction		= NULL;
+SCardCancelTransactionPtr	liteSCardCancelTransaction	= NULL;
+SCardStatusPtr			liteSCardStatus			= NULL;
+SCardGetStatusChangePtr	liteSCardGetStatusChange	= NULL;
+SCardControlPtr			liteSCardControl			= NULL;
+SCardTransmitPtr			liteSCardTransmit			= NULL;
+SCardListReaderGroupsPtr	liteSCardListReaderGroups	= NULL;
+SCardListReadersPtr		liteSCardListReaders		= NULL;
+SCardCancelPtr			liteSCardCancel			= NULL;
+SCardGetAttribPtr			liteSCardGetAttrib			= NULL;
+SCardSetAttribPtr			liteSCardSetAttrib			= NULL;
+
+static void* g_pcscliteHandle = NULL;
+static BOOL InitializePCSCLite();
+
+
+
+
+HANDLE g_startedEvent = NULL;
+
+
+BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);
+
+    switch (fdwReason) {
+        case DLL_PROCESS_ATTACH:
+        {
+		DisableThreadLibraryCalls(hinstDLL);
+		WINSCARD_hModule = hinstDLL;
+		InitializePCSCLite();
+		// FIXME: for now, we act as if the pcsc daemon is always started
+		g_startedEvent = CreateEventA(NULL,TRUE,TRUE,NULL);
+		break;
+        }
+        case DLL_PROCESS_DETACH:
+        {
+		
+		CloseHandle(g_startedEvent);
+		
+		/* release PCSC-lite */
+		if(g_pcscliteHandle)
+		{
+			liteSCardEstablishContext 	= NULL;
+			liteSCardReleaseContext 	= NULL;
+			liteSCardIsValidContext 		= NULL;
+			liteSCardSetTimeout		= NULL;
+			liteSCardConnect			= NULL;
+			liteSCardReconnect			= NULL;
+			liteSCardDisconnect		= NULL;		
+			liteSCardBeginTransaction	= NULL;
+			liteSCardEndTransaction		= NULL;
+			liteSCardCancelTransaction	= NULL;
+			liteSCardStatus			= NULL;
+			liteSCardGetStatusChange	= NULL;
+			liteSCardControl			= NULL;
+			liteSCardTransmit			= NULL;
+			liteSCardListReaderGroups	= NULL;
+			liteSCardListReaders		= NULL;
+			liteSCardCancel			= NULL;
+			liteSCardGetAttrib			= NULL;
+			liteSCardSetAttrib			= NULL;	
+			wine_dlclose(g_pcscliteHandle,NULL,0);	
+			g_pcscliteHandle = NULL;			
+		}
+		break;
+        }
+    }
+
+    return TRUE;
+}
+
+/*
+ *  Initialize pcsc-lite pointers
+ */
+
+static BOOL InitializePCSCLite()
+{
+	BOOL bStatus = FALSE;
+	if(g_pcscliteHandle)
+		bStatus = TRUE; /*already loaded*/
+	else
+	{
+		/* try to load pcsc-lite */
+		char szErr[256];
+		g_pcscliteHandle = wine_dlopen("libpcsclite.so",RTLD_LAZY | RTLD_GLOBAL,szErr,sizeof(szErr));
+		if(!g_pcscliteHandle)
+		{
+			/* error occured*/
+			WARN("loading libpcsclite.so failed.Error = %s \n",szErr);
+		}
+		else
+		{
+			/* loading entry points*/
+			BOOL bSuccess = TRUE;
+			if(bSuccess && !(liteSCardEstablishContext = (SCardEstablishContextPtr) wine_dlsym(g_pcscliteHandle,"SCardEstablishContext",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardEstablishContext from pcsclite library. Error = %s\n",szErr);
+			}
+			
+			if(bSuccess && !(liteSCardReleaseContext = (SCardReleaseContextPtr) wine_dlsym(g_pcscliteHandle,"SCardReleaseContext",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardReleaseContext from pcsclite library. Error = %s\n",szErr);
+			}			
+
+			if(bSuccess && !(liteSCardIsValidContext = (SCardIsValidContextPtr) wine_dlsym(g_pcscliteHandle,"SCardIsValidContext",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardIsValidContext from pcsclite library. Error = %s\n",szErr);
+			}					
+
+			if(bSuccess && !(liteSCardSetTimeout = (SCardSetTimeoutPtr) wine_dlsym(g_pcscliteHandle,"SCardSetTimeout",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardSetTimeout from pcsclite library. Error = %s\n",szErr);
+			}	
+			
+			if(bSuccess && !(liteSCardConnect = (SCardConnectPtr) wine_dlsym(g_pcscliteHandle,"SCardConnect",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardConnect from pcsclite library. Error = %s\n",szErr);
+			}				
+
+			if(bSuccess && !(liteSCardReconnect = (SCardReconnectPtr) wine_dlsym(g_pcscliteHandle,"SCardReconnect",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardReconnect from pcsclite library. Error = %s\n",szErr);
+			}			
+
+			if(bSuccess && !(liteSCardDisconnect = (SCardDisconnectPtr) wine_dlsym(g_pcscliteHandle,"SCardDisconnect",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardDisconnect from pcsclite library. Error = %s\n",szErr);
+			}				
+
+			if(bSuccess && !(liteSCardBeginTransaction = (SCardBeginTransactionPtr) wine_dlsym(g_pcscliteHandle,"SCardBeginTransaction",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardBeginTransaction from pcsclite library. Error = %s\n",szErr);
+			}			
+
+
+			if(bSuccess && !(liteSCardEndTransaction = (SCardEndTransactionPtr) wine_dlsym(g_pcscliteHandle,"SCardEndTransaction",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardEndTransaction from pcsclite library. Error = %s\n",szErr);
+			}			
+
+			if(bSuccess && !(liteSCardCancelTransaction = (SCardCancelTransactionPtr) wine_dlsym(g_pcscliteHandle,"SCardCancelTransaction",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardCancelTransaction from pcsclite library. Error = %s\n",szErr);
+			}
+			
+			if(bSuccess && !(liteSCardStatus = (SCardStatusPtr) wine_dlsym(g_pcscliteHandle,"SCardStatus",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardStatus from pcsclite library. Error = %s\n",szErr);
+			}
+			
+			if(bSuccess && !(liteSCardGetStatusChange = (SCardGetStatusChangePtr) wine_dlsym(g_pcscliteHandle,"SCardGetStatusChange",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardGetStatusChange from pcsclite library. Error = %s\n",szErr);
+			}
+			
+			if(bSuccess && !(liteSCardControl = (SCardControlPtr) wine_dlsym(g_pcscliteHandle,"SCardControl",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardControl from pcsclite library. Error = %s\n",szErr);
+			}			
+			
+			if(bSuccess && !(liteSCardTransmit = (SCardTransmitPtr) wine_dlsym(g_pcscliteHandle,"SCardTransmit",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardTransmit from pcsclite library. Error = %s\n",szErr);
+			}						
+			
+			if(bSuccess && !(liteSCardListReaderGroups = (SCardListReaderGroupsPtr) wine_dlsym(g_pcscliteHandle,"SCardListReaderGroups",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardListReaderGroups from pcsclite library. Error = %s\n",szErr);
+			}		
+			
+			if(bSuccess && !(liteSCardListReaders = (SCardListReadersPtr) wine_dlsym(g_pcscliteHandle,"SCardListReaders",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardListReaders from pcsclite library. Error = %s\n",szErr);
+			}		
+			
+			if(bSuccess && !(liteSCardCancel = (SCardCancelPtr) wine_dlsym(g_pcscliteHandle,"SCardCancel",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardCancel from pcsclite library. Error = %s\n",szErr);
+			}		
+			
+			if(bSuccess && !(liteSCardGetAttrib = (SCardGetAttribPtr) wine_dlsym(g_pcscliteHandle,"SCardGetAttrib",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardGetAttrib from pcsclite library. Error = %s\n",szErr);
+			}		
+			
+			if(bSuccess && !(liteSCardSetAttrib = (SCardSetAttribPtr) wine_dlsym(g_pcscliteHandle,"SCardSetAttrib",szErr,sizeof(szErr))))
+			{
+				bSuccess = FALSE;
+				ERR("Failed to get SCardSetAttrib from pcsclite library. Error = %s\n",szErr);
+			}		
+
+			
+			if(!bSuccess)
+			{
+				/* a entry point is missing. unload the library */
+				wine_dlclose(g_pcscliteHandle,NULL,0);
+				g_pcscliteHandle = NULL;
+			}
+			
+			bStatus = bSuccess;
+			
+		}
+	}
+	
+	return bStatus;
+}
+
+
+static size_t wstrlen(LPCWSTR szwStr)
+{
+	if(!szwStr)
+		return 0;
+	else
+	{
+		size_t result = 0;
+		while(*szwStr++ != (WCHAR) '\0') result++;
+		return result;
+	}
+}
+
+/*
+ * Convert a wide-char multi-string to an ANSI multi-string
+ */
+static LONG ConvertListToANSI(LPCWSTR szListW,LPSTR* pszListA,LPDWORD pdwLength)
+{
+	if(!szListW)
+	{
+		*pszListA = NULL;
+		*pdwLength = 0;
+	}
+	else if(!*szListW) /* empty multi-string case */
+	{
+		*pdwLength = 2;
+		*pszListA = (LPSTR) malloc(2);
+		if(!*pszListA)
+			return SCARD_E_NO_MEMORY;
+		*pszListA[0] = '\0';
+		*pszListA[1] = '\0';
+	}
+	else
+	{
+		
+		LPWSTR ptr = (LPWSTR) szListW;
+		LPSTR szStr = NULL,aptr;
+		DWORD alen = 0,tmp;
+		
+		/* compute the wide-char list length */
+		for(;*ptr;ptr += wstrlen(ptr) + 1)
+		{
+			int aclen = WideCharToMultiByte(CP_ACP,0,ptr,-1,NULL,0,NULL,NULL);
+			if(!aclen)
+				return SCARD_F_INTERNAL_ERROR;
+			alen += aclen;		
+		}
+		
+		alen++; /* add the final null character */
+		
+		/* allocate memory */
+		szStr = (LPSTR) malloc(alen);
+		if(!szStr)
+			return SCARD_F_INTERNAL_ERROR;
+		
+		aptr = szStr;
+		tmp = alen;
+		
+		/* do the conversion */
+		for( ptr = (LPWSTR) szListW;*ptr;ptr += wstrlen(ptr) + 1)
+		{
+			int aclen = WideCharToMultiByte(CP_ACP,0,ptr,-1,aptr,tmp,NULL,NULL);
+			tmp -= aclen;		
+			aptr += aclen;
+		}	
+		
+		*aptr = '\0';
+		
+		*pszListA = szStr;
+		*pdwLength = alen;
+	}
+	
+	return SCARD_S_SUCCESS;
+}
+
+
+
+/*
+ * Convert a ANSII multi-string to a wide-char multi-string
+ */
+static LONG ConvertListToWideChar(LPCSTR szListA,LPWSTR* pszListW,LPDWORD pdwLength)
+{
+	if(!szListA)
+	{
+		*pszListW = NULL;
+		*pdwLength = 0;
+	}
+	else if(!*szListA) /* empty multi-string case */
+	{
+		*pdwLength = 2;
+		*pszListW = (LPWSTR) malloc(2*sizeof(WCHAR));
+		if(!*pszListW)
+			return SCARD_E_NO_MEMORY;
+		*pszListW[0] = '\0';
+		*pszListW[1] = '\0';
+	}
+	else
+	{
+		
+		LPSTR ptr = (LPSTR) szListA;
+		LPWSTR szStr = NULL,wptr;
+		DWORD wlen = 0,tmp;
+		
+		/* compute the wide-char list length */
+		for(;*ptr;ptr += strlen(ptr) + 1)
+		{
+			int wclen = MultiByteToWideChar(CP_ACP,0,ptr,-1,NULL,0);
+			if(!wclen)
+				return SCARD_F_INTERNAL_ERROR;
+			wlen += wclen;		
+		}
+		
+		wlen++; /* add the final null character */
+		
+		/* allocate memory */
+		szStr = (LPWSTR) malloc(wlen*sizeof(WCHAR));
+		if(!szStr)
+			return SCARD_F_INTERNAL_ERROR;
+		
+		wptr = szStr;
+		tmp = wlen;
+		
+		/* do the conversion */
+		for( ptr = (LPSTR) szListA;*ptr;ptr += strlen(ptr) + 1)
+		{
+			int wclen = MultiByteToWideChar(CP_ACP,0,ptr,-1,wptr,tmp);
+			tmp -= wclen;		
+			wptr += wclen;
+		}	
+		
+		*wptr = '\0';
+		
+		*pszListW = szStr;
+		*pdwLength = wlen;
+	}
+	
+	return SCARD_S_SUCCESS;
+}
+
+
+/*
+ * 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 lRet)
+{
+	if(lRet == PCSCLITE_SCARD_E_UNSUPPORTED_FEATURE)
+		return SCARD_E_UNSUPPORTED_FEATURE;
+	else if(lRet == PCSCLITE_SCARD_W_INSERTED_CARD)
+		return SCARD_F_UNKNOWN_ERROR; /* FIXME: is there a better WIN32 error code */
+	else
+		return lRet;
+}
+	
+
+/*
+  * events functions
+  */
+  
+HANDLE WINAPI SCardAccessNewReaderEvent()
+{
+    FIXME("stub\n");
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return NULL;
+}
+
+long WINAPI SCardReleaseAllEvents()
+{
+    FIXME("stub\n");
+
+    return SCARD_S_SUCCESS;
+}
+
+long WINAPI SCardReleaseNewReaderEvent(HANDLE hNewReaderEventHandle)
+{
+    FIXME("stub\n");
+
+    return SCARD_S_SUCCESS;
+}
+
+HANDLE WINAPI SCardAccessStartedEvent()
+{
+	return g_startedEvent;
+}
+
+void WINAPI SCardReleaseStartedEvent(HANDLE hStartedEventHandle)
+{
+	/* do nothing  because we don't implement yet reference couting for the event handle*/
+}
+
+
+LONG WINAPI SCardFreeMemory( SCARDCONTEXT hContext,LPCVOID pvMem)
+{
+	if(pvMem)
+		free((void*) pvMem);
+	return SCARD_S_SUCCESS;
+}
+
+/*
+ *  smar cards database functions. Almost all of them are stubs
+ */
+
+LONG WINAPI SCardListCardsA(
+		SCARDCONTEXT hContext,
+		const BYTE* pbAtr,
+		LPCGUID rgquidInterfaces,
+		DWORD cguidInterfaceCount,
+		LPSTR mszCards,
+		LPDWORD pcchCards)
+{
+	TRACE("0x%08X %p %p %d %p %p - stub\n",(unsigned int) hContext,pbAtr,rgquidInterfaces,cguidInterfaceCount,mszCards,pcchCards);
+	
+	/* we simuate the fact that no cards are enregistred on the system by returning an empty multi-string*/
+	if(!pcchCards)
+		return SCARD_E_INVALID_PARAMETER;
+	else if(!mszCards)
+		*pcchCards = 2;	
+	else
+	{
+		DWORD len = *pcchCards;
+		if(SCARD_AUTOALLOCATE == len)
+		{
+			if(!mszCards)
+				return SCARD_E_INVALID_PARAMETER;
+			else
+			{
+				/* allocate memory */
+				LPSTR* pmszCards = (LPSTR*) mszCards;
+				LPSTR szResult = (LPSTR) malloc(2);
+				if(!szResult)
+					return SCARD_E_NO_MEMORY;
+				szResult[0] = '\0';
+				szResult[1] = '\0';
+				*pcchCards = 2;
+				*pmszCards = szResult;
+			}
+		}
+		else
+		{
+			if(len < 2)
+			{
+				*pcchCards = 2;
+				return SCARD_E_INSUFFICIENT_BUFFER;
+			}
+			else
+			{
+				/* return a empty multi string */
+				mszCards[0] = '\0';
+				mszCards[1] = '\0';
+				*pcchCards = 2;
+			}				
+		}
+	}
+	
+	return SCARD_S_SUCCESS;
+}
+
+LONG WINAPI SCardListCardsW(
+          SCARDCONTEXT hContext,
+          const BYTE* pbAtr,
+          LPCGUID rgquidInterfaces,
+          DWORD cguidInterfaceCount,
+	  LPWSTR mszCards,
+	  LPDWORD pcchCards)
+{
+	TRACE("0x%08X %p %p %d %p %p - stub\n",(unsigned int)hContext,pbAtr,rgquidInterfaces,cguidInterfaceCount,mszCards,pcchCards);
+	
+	/* we simuate the fact that no cards are enregistred on the system by returning an empty multi-string*/	
+	if(!pcchCards)
+		return SCARD_E_INVALID_PARAMETER;
+	else if(!mszCards)
+		*pcchCards = 2;
+	else
+	{
+		DWORD len = *pcchCards;
+		if(SCARD_AUTOALLOCATE == len)
+		{
+			if(!mszCards)
+				return SCARD_E_INVALID_PARAMETER;
+			else
+			{
+				/* allocate memory */
+				LPSTR* pmszCards = (LPSTR*) mszCards;
+				LPSTR szResult = (LPSTR) malloc(2*sizeof(WCHAR));
+				if(!szResult)
+					return SCARD_E_NO_MEMORY;
+				szResult[0] = '\0';
+				szResult[1] = '\0';
+				*pcchCards = 2;
+				*pmszCards = szResult;
+			}
+		}
+		else
+		{
+			if(len < 2)
+			{
+				*pcchCards = 2;
+				return SCARD_E_INSUFFICIENT_BUFFER;
+			}
+			else
+			{
+				/* return a empty multi string */
+				mszCards[0] = '\0';
+				mszCards[1] = '\0';
+				*pcchCards = 2;
+			}				
+		}
+	}
+	
+	return SCARD_S_SUCCESS;	
+}
+	
+LONG WINAPI SCardListInterfacesA(
+		SCARDCONTEXT hContext,
+		LPCSTR szCard,
+		LPGUID pguidInterfaces,
+		LPDWORD pcguidInterfaces)
+{
+	FIXME("0x%08X %s %p %p - stub\n",(unsigned int)hContext,debugstr_a(szCard),pguidInterfaces,pcguidInterfaces);
+	
+	return SCARD_E_UNKNOWN_CARD;
+}
+
+LONG WINAPI SCardListInterfacesW(
+		SCARDCONTEXT hContext,
+		LPCWSTR szCard,
+		LPGUID pguidInterfaces,
+		LPDWORD pcguidInterfaces)
+{	
+	FIXME("0x%08X %s %p %p - stub\n",(unsigned int)hContext,debugstr_w(szCard),pguidInterfaces,pcguidInterfaces);
+	
+	return SCARD_E_UNKNOWN_CARD;	
+}
+  
+LONG WINAPI SCardGetProviderIdA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCard,
+    LPGUID pguidProviderId)
+{
+	FIXME("0x%08X %s %p - stub\n",(unsigned int)hContext,debugstr_a(szCard),pguidProviderId);
+	
+	if(!pguidProviderId)
+		return SCARD_E_INVALID_PARAMETER;
+	
+	return SCARD_E_UNKNOWN_CARD;
+}
+	
+LONG WINAPI SCardGetProviderIdW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCard,
+    LPGUID pguidProviderId)
+{
+	FIXME("0x%08X %s %p - stub\n",(unsigned int)hContext,debugstr_w(szCard),pguidProviderId);
+	
+	if(!pguidProviderId)
+		return SCARD_E_INVALID_PARAMETER;
+	
+	return SCARD_E_UNKNOWN_CARD;	
+}
+	
+LONG WINAPI SCardGetCardTypeProviderNameA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCardName,
+    DWORD dwProviderId,
+    LPSTR szProvider,
+    LPDWORD pcchProvider)
+{
+	FIXME("0x%08X %s 0x%08X %p %p - stub\n",(unsigned int)hContext,debugstr_a(szCardName),dwProviderId,szProvider,pcchProvider);
+	
+	return SCARD_E_UNKNOWN_CARD;
+}
+	
+LONG WINAPI SCardGetCardTypeProviderNameW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCardName,
+    DWORD dwProviderId,
+    LPWSTR szProvider,
+    LPDWORD pcchProvider)
+{
+	FIXME("0x%08X %s 0x%08X %p %p - stub\n",(unsigned int)hContext,debugstr_w(szCardName),dwProviderId,szProvider,pcchProvider);
+	
+	return SCARD_E_UNKNOWN_CARD;	
+}
+
+
+LONG WINAPI SCardIntroduceReaderGroupA(
+    SCARDCONTEXT hContext,
+    LPCSTR szGroupName)
+{
+	FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_a(szGroupName));
+	
+	return SCARD_F_UNKNOWN_ERROR;
+}
+	
+LONG WINAPI SCardIntroduceReaderGroupW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szGroupName)
+{
+	FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_w(szGroupName));
+	
+	return SCARD_F_UNKNOWN_ERROR;	
+}
+
+LONG WINAPI SCardForgetReaderGroupA(
+    SCARDCONTEXT hContext,
+    LPCSTR szGroupName)
+{
+	FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_a(szGroupName));
+	
+	return SCARD_S_SUCCESS;	
+}
+	
+LONG WINAPI SCardForgetReaderGroupW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szGroupName)
+{
+	FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_w(szGroupName));
+	
+	return SCARD_S_SUCCESS;		
+}
+
+
+LONG WINAPI SCardIntroduceReaderA(
+    SCARDCONTEXT hContext,
+    LPCSTR szReaderName,
+    LPCSTR szDeviceName)
+{
+	FIXME("0x%08X %s %s - stub\n",(unsigned int)hContext,debugstr_a(szReaderName),debugstr_a(szDeviceName));
+	
+	return SCARD_F_UNKNOWN_ERROR;
+}
+	
+LONG WINAPI SCardIntroduceReaderW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szReaderName,
+    LPCWSTR szDeviceName)
+{
+	FIXME("0x%08X %s %s - stub\n",(unsigned int)hContext,debugstr_w(szReaderName),debugstr_w(szDeviceName));
+	
+	return SCARD_F_UNKNOWN_ERROR;	
+}
+
+LONG WINAPI SCardForgetReaderA(
+    SCARDCONTEXT hContext,
+    LPCSTR szReaderName)
+{
+	FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_a(szReaderName));
+	
+	return SCARD_S_SUCCESS;		
+}
+
+
+LONG WINAPI SCardForgetReaderW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szReaderName)
+{
+	FIXME("0x%08X %s - stub\n",(unsigned int)hContext,debugstr_w(szReaderName));
+	
+	return SCARD_S_SUCCESS;	
+}
+
+LONG WINAPI SCardAddReaderToGroupA(
+    SCARDCONTEXT hContext,
+    LPCSTR szReaderName,
+    LPCSTR szGroupName)
+{
+	FIXME("0x%08X %s %s - stub\n",(unsigned int) hContext, debugstr_a( szReaderName), debugstr_a(szGroupName));
+	
+	return SCARD_F_UNKNOWN_ERROR;
+}
+	
+LONG WINAPI SCardAddReaderToGroupW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szReaderName,
+    LPCWSTR szGroupName)
+{
+	FIXME("0x%08X %s %s - stub\n",(unsigned int) hContext, debugstr_w( szReaderName), debugstr_w(szGroupName));
+	
+	return SCARD_F_UNKNOWN_ERROR;	
+}
+
+LONG WINAPI SCardRemoveReaderFromGroupA(
+    SCARDCONTEXT hContext,
+    LPCSTR szReaderName,
+    LPCSTR szGroupName)
+{
+	FIXME("0x%08X %s %s - stub\n",(unsigned int) hContext, debugstr_a( szReaderName), debugstr_a(szGroupName));
+	
+	return SCARD_S_SUCCESS;	
+}
+	
+LONG WINAPI SCardRemoveReaderFromGroupW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szReaderName,
+    LPCWSTR szGroupName)
+{
+	FIXME("0x%08X %s %s - stub\n",(unsigned int) hContext, debugstr_w( szReaderName), debugstr_w(szGroupName));
+	
+	return SCARD_S_SUCCESS;		
+}
+
+
+LONG WINAPI SCardIntroduceCardTypeA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCardName,
+    LPCGUID pguidPrimaryProvider,
+    LPCGUID rgguidInterfaces,
+    DWORD dwInterfaceCount,
+    const BYTE* pbAtr,
+    const BYTE* pbAtrMask,
+    DWORD cbAtrLen)
+{
+	FIXME("0x%08X %s %p %p %d %p %p %d - stub\n",(unsigned int) hContext, debugstr_a(szCardName),pguidPrimaryProvider,rgguidInterfaces,dwInterfaceCount,pbAtr,pbAtrMask,cbAtrLen);
+	
+	return SCARD_F_UNKNOWN_ERROR;
+}
+	
+LONG WINAPI SCardIntroduceCardTypeW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCardName,
+    LPCGUID pguidPrimaryProvider,
+    LPCGUID rgguidInterfaces,
+    DWORD dwInterfaceCount,
+    const BYTE* pbAtr,
+    const BYTE* pbAtrMask,
+    DWORD cbAtrLen)
+{
+	FIXME("0x%08X %s %p %p %d %p %p %d - stub\n",(unsigned int) hContext, debugstr_w(szCardName),pguidPrimaryProvider,rgguidInterfaces,dwInterfaceCount,pbAtr,pbAtrMask,cbAtrLen);
+	
+	return SCARD_F_UNKNOWN_ERROR;	
+}
+	
+
+LONG WINAPI SCardSetCardTypeProviderNameA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCardName,
+    DWORD dwProviderId,
+    LPCSTR szProvider)
+{
+	FIXME("0x%08X %s 0x%08X %s - stub\n",(unsigned int) hContext, debugstr_a(szCardName),dwProviderId,debugstr_a(szProvider));
+	
+	return SCARD_F_UNKNOWN_ERROR;
+}
+	
+LONG WINAPI SCardSetCardTypeProviderNameW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCardName,
+    DWORD dwProviderId,
+    LPCWSTR szProvider)
+{
+	FIXME("0x%08X %s 0x%08X %s - stub\n",(unsigned int) hContext, debugstr_w(szCardName),dwProviderId,debugstr_w(szProvider));
+	
+	return SCARD_F_UNKNOWN_ERROR;	
+}
+
+LONG WINAPI SCardForgetCardTypeA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCardName)
+{
+	FIXME("0x%08X %s - stub\n",(unsigned int) hContext, debugstr_a(szCardName));
+	
+	return SCARD_E_UNKNOWN_CARD;
+}
+	
+LONG WINAPI SCardForgetCardTypeW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCardName)
+{
+	FIXME("0x%08X %s - stub\n",(unsigned int) hContext, debugstr_w(szCardName));
+	
+	return SCARD_E_UNKNOWN_CARD;	
+}
+	
+LONG WINAPI SCardLocateCardsA(
+    SCARDCONTEXT hContext,
+    LPCSTR mszCards,
+    LPSCARD_READERSTATEA rgReaderStates,
+    DWORD cReaders)
+{
+	FIXME("0x%08X %s %p %d - stub\n",(unsigned int) hContext, debugstr_a(mszCards),rgReaderStates,cReaders);
+	
+	return SCARD_E_UNKNOWN_CARD;
+}
+	
+LONG WINAPI SCardLocateCardsW(
+    SCARDCONTEXT hContext,
+    LPCWSTR mszCards,
+    LPSCARD_READERSTATEW rgReaderStates,
+    DWORD cReaders)
+{
+	FIXME("0x%08X %s %p %d - stub\n",(unsigned int) hContext, debugstr_w(mszCards),rgReaderStates,cReaders);
+	
+	return SCARD_E_UNKNOWN_CARD;	
+}
+
+LONG WINAPI SCardLocateCardsByATRA(
+    SCARDCONTEXT hContext,
+    LPSCARD_ATRMASK rgAtrMasks,
+    DWORD cAtrs,
+    LPSCARD_READERSTATEA rgReaderStates,
+    DWORD cReaders)
+{
+	FIXME("0x%08X %p %d %p %d - stub\n",(unsigned int) hContext, rgAtrMasks, cAtrs, rgReaderStates,  cReaders);
+	
+	return SCARD_F_UNKNOWN_ERROR;
+}
+	
+LONG WINAPI SCardLocateCardsByATRW(
+    SCARDCONTEXT hContext,
+    LPSCARD_ATRMASK rgAtrMasks,
+    DWORD cAtrs,
+    LPSCARD_READERSTATEW rgReaderStates,
+    DWORD cReaders)
+{
+	FIXME("0x%08X %p %d %p %d - stub\n",(unsigned int) hContext, rgAtrMasks, cAtrs, rgReaderStates,  cReaders);
+	
+	return SCARD_F_UNKNOWN_ERROR;	
+}
+
+LONG WINAPI SCardListReaderGroupsA(
+		SCARDCONTEXT hContext,
+		LPSTR mszGroups, 
+		LPDWORD pcchGroups)
+{	
+	LONG lRet = SCARD_F_UNKNOWN_ERROR;
+	DWORD len ;
+	
+	if(!pcchGroups)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardListReaderGroups)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else if(mszGroups && *pcchGroups == SCARD_AUTOALLOCATE)
+	{
+		LPSTR* pmszGroups = (LPSTR*) mszGroups;
+		LPSTR szList = NULL;
+		len = 0;
+		
+		/* ask for the length */
+		lRet = liteSCardListReaderGroups(hContext,NULL,&len);
+		if(SCARD_S_SUCCESS == lRet)
+		{
+			/* allocate memory for the list */
+			szList = (LPSTR) malloc(len);
+			if(!szList)
+				lRet = SCARD_E_NO_MEMORY;
+			else
+			{
+				/* fill the list */
+				lRet = liteSCardListReaderGroups(hContext,szList,&len);
+				if(SCARD_S_SUCCESS != lRet)
+					free(szList);
+				else
+				{
+					*pmszGroups = szList;
+					*pcchGroups = len;		
+				}
+			}
+		}				
+		
+	}
+	else
+		lRet = liteSCardListReaderGroups(hContext,mszGroups,pcchGroups);
+	
+	return TranslateToWin32(lRet);
+}
+		
+LONG WINAPI SCardListReaderGroupsW(
+		SCARDCONTEXT hContext,
+		LPWSTR mszGroups, 
+		LPDWORD pcchGroups)
+{
+	LONG lRet = SCARD_F_UNKNOWN_ERROR;
+	LPSTR szList = NULL;
+	LPWSTR szListW = NULL;
+	DWORD alen = 0,wlen = 0;
+	
+	if(!pcchGroups)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardListReaderGroups)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+	{
+		if(!mszGroups)
+		{
+			/* asking for length only
+			 * get the length in ANSI and multiply by sizeof(WCHAR)
+			 */
+			alen = 0;
+			lRet = SCardListReaderGroupsA(hContext,NULL,&alen);
+			if(lRet == SCARD_S_SUCCESS || lRet == SCARD_E_INSUFFICIENT_BUFFER)
+			{
+				*pcchGroups = alen ;
+			}
+			goto end_label;
+		}
+		
+		/* get the ASCII list from pcsclite */
+		alen = SCARD_AUTOALLOCATE;
+		lRet = SCardListReaderGroupsA(hContext,(LPSTR) &szList,&alen);
+		if(SCARD_S_SUCCESS != lRet)
+			goto end_label;
+		
+		/* now convert the list to a wide char list */
+		lRet = ConvertListToWideChar(szList,&szListW,&wlen);
+		
+		/* free the ASCII list, we don't need it any more */
+		SCardFreeMemory(hContext,(LPCVOID) szList);
+		
+		if(SCARD_S_SUCCESS != lRet)
+			goto end_label;
+		
+		if(SCARD_AUTOALLOCATE == *pcchGroups)
+		{
+			LPWSTR* pmszGroups = (LPWSTR*) mszGroups;
+			*pmszGroups = szListW;
+			*pcchGroups = wlen;
+			szListW = NULL;
+			lRet = SCARD_S_SUCCESS;			
+		}
+		else
+		{
+			DWORD cchGroups = *pcchGroups;
+			if(cchGroups < wlen)
+			{
+				*pcchGroups = wlen;
+				lRet = SCARD_E_INSUFFICIENT_BUFFER;
+			}
+			else
+			{
+				*pcchGroups = wlen;
+				memcpy(mszGroups,szListW,wlen*sizeof(WCHAR));
+				lRet = SCARD_S_SUCCESS;
+			}
+		}
+	}
+	
+end_label:	
+	if(szListW)
+		free(szListW);
+	return TranslateToWin32(lRet);
+	
+}
+	
+	
+
+LONG WINAPI SCardListReadersA(
+		SCARDCONTEXT hContext,
+		LPCSTR mszGroups,
+		LPSTR mszReaders, 
+		LPDWORD pcchReaders)
+{
+	LONG lRet;
+	if(!pcchReaders)
+		lRet = SCARD_E_INVALID_PARAMETER;	
+	else if(!liteSCardListReaders)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else if(mszReaders && SCARD_AUTOALLOCATE == *pcchReaders)
+	{		
+		/* get list from pcsc-lite */
+		LPSTR* pmszReaders = (LPSTR*) mszReaders;
+		LPSTR szList = NULL;
+		DWORD dwListLength = 0;
+		
+		lRet = liteSCardListReaders(hContext,mszGroups,NULL,&dwListLength);
+		if(SCARD_S_SUCCESS != lRet && lRet != SCARD_E_INSUFFICIENT_BUFFER)
+			goto end_label;
+		
+		szList = (LPSTR) malloc(dwListLength);
+		if(!szList)
+		{
+			lRet = SCARD_E_NO_MEMORY;
+			goto end_label;
+		}
+		
+		lRet = liteSCardListReaders(hContext,mszGroups,szList,&dwListLength);
+		if(SCARD_S_SUCCESS != lRet)
+			free(szList);
+		else
+		{
+			*pmszReaders = szList;
+			*pcchReaders = dwListLength;
+		}
+	}
+	else
+		lRet = liteSCardListReaders(hContext,mszGroups,mszReaders,pcchReaders);
+	
+end_label:	
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardListReadersW(
+		SCARDCONTEXT hContext,
+		LPCWSTR mszGroups,
+		LPWSTR mszReaders, 
+		LPDWORD pcchReaders)
+{
+	LONG lRet;
+	if(!pcchReaders)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardListReaders)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+	{
+		/* call the ANSI version */
+		LPSTR mszGroupsA = NULL;
+		LPSTR mszReadersA = NULL;
+		LPWSTR szListW = NULL;
+		DWORD dwLength ;
+		if(mszGroups)
+		{
+			lRet = ConvertListToANSI(mszGroups,&mszGroupsA,&dwLength);
+			if(SCARD_S_SUCCESS != lRet)
+				goto end_label;
+		}
+		
+		if(!mszReaders)
+		{
+			/* asking for length only
+			 * Assume that number of wide char is the same
+			 * as the number f ANSI characters
+			 */
+			dwLength = 0;
+			lRet = SCardListReadersA(hContext,mszGroupsA,NULL,&dwLength);
+			if(lRet == SCARD_S_SUCCESS || lRet == SCARD_E_INSUFFICIENT_BUFFER)
+			{
+				*pcchReaders = dwLength;
+			}
+			if(mszGroupsA)
+				free(mszGroupsA);
+			goto end_label;
+		}
+		
+		dwLength = SCARD_AUTOALLOCATE;
+		lRet = SCardListReadersA(hContext,mszGroupsA,(LPSTR) &mszReadersA,&dwLength);
+		
+		/* free the ANSI list of groups : no more needed */
+		if(mszGroupsA)
+			free(mszGroupsA);
+		
+		if(SCARD_S_SUCCESS != lRet)
+			goto end_label;
+		
+		/* we now have the list in ANSI. Covert it to wide-char format*/
+		lRet = ConvertListToWideChar(mszReadersA,&szListW,&dwLength);
+		
+		/* ANSI list of readers no more needed */
+		SCardFreeMemory(hContext,(LPCVOID) mszReadersA);
+		
+		if(SCARD_S_SUCCESS != lRet)
+			goto end_label;
+		
+		if(SCARD_AUTOALLOCATE == *pcchReaders)
+		{
+			LPWSTR* pmszReaders = (LPWSTR*) mszReaders;
+			*pmszReaders = szListW;
+			szListW = NULL;
+			*pcchReaders = dwLength;
+		}
+		else
+		{
+			DWORD inputLength = *pcchReaders;
+			if(inputLength < dwLength)
+				lRet = SCARD_E_INSUFFICIENT_BUFFER;
+			else
+				memcpy(mszReaders,szListW,dwLength*sizeof(WCHAR));
+			*pcchReaders = dwLength;
+		}
+		
+		if(szListW)
+			free(szListW);
+	}
+end_label:	
+	return TranslateToWin32(lRet);
+}
+
+/*
+ *  PCS/SC communication functions
+ */
+LONG WINAPI SCardEstablishContext(DWORD dwScope,LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
+{
+	LONG lRet;
+	TRACE(" 0x%08X %p %p %p\n",dwScope,pvReserved1,pvReserved2,phContext);
+	if(!phContext)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardEstablishContext)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+		lRet = liteSCardEstablishContext(dwScope,pvReserved1,pvReserved2,phContext);
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+
+LONG WINAPI SCardReleaseContext(SCARDCONTEXT hContext)
+{
+	LONG lRet;
+	TRACE(" 0x%08X\n", (unsigned int) hContext);
+	if(!liteSCardReleaseContext)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else 
+		lRet = liteSCardReleaseContext(hContext);
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardIsValidContext(SCARDCONTEXT hContext)
+{
+	if(!liteSCardIsValidContext)
+		return SCARD_F_INTERNAL_ERROR;
+	else
+		return TranslateToWin32(liteSCardIsValidContext(hContext));
+}
+
+
+#define PCSCLITE_SCARD_PROTOCOL_RAW	0x00000004
+
+LONG WINAPI SCardConnectA(SCARDCONTEXT hContext,
+						LPCSTR szReader,
+						DWORD dwShareMode,
+						DWORD dwPreferredProtocols,
+						LPSCARDHANDLE phCard, 
+						LPDWORD pdwActiveProtocol)
+{
+	LONG lRet;
+	TRACE(" 0x%08X %s 0x%08X 0x%08X %p %p\n",(unsigned int) hContext,debugstr_a(szReader),dwShareMode,dwPreferredProtocols,phCard,pdwActiveProtocol);
+	if(!szReader || !phCard || !pdwActiveProtocol)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardConnect)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+	{
+		/* the value of SCARD_PROTOCOL_RAW is different between MS implementation and
+		 * pcsc-lite implementation. We must change its value
+		 */
+		if(dwPreferredProtocols & SCARD_PROTOCOL_RAW)
+		{
+			dwPreferredProtocols ^= SCARD_PROTOCOL_RAW;
+			dwPreferredProtocols |= PCSCLITE_SCARD_PROTOCOL_RAW;
+		}
+		
+		lRet = liteSCardConnect(hContext,szReader,dwShareMode,dwPreferredProtocols,phCard,pdwActiveProtocol);
+		if(SCARD_S_SUCCESS == lRet)
+		{
+			/* if PCSCLITE_SCARD_PROTOCOL_RAW is set, put back the MS corresponding value */
+			if(*pdwActiveProtocol & PCSCLITE_SCARD_PROTOCOL_RAW)
+			{
+				*pdwActiveProtocol ^= PCSCLITE_SCARD_PROTOCOL_RAW;
+				*pdwActiveProtocol |= SCARD_PROTOCOL_RAW;
+			}
+			
+		}
+	}
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+						
+LONG WINAPI SCardConnectW(SCARDCONTEXT hContext,
+						LPCWSTR szReader,
+						DWORD dwShareMode,
+						DWORD dwPreferredProtocols,
+						LPSCARDHANDLE phCard, 
+						LPDWORD pdwActiveProtocol)
+{
+	LONG lRet;
+	TRACE(" 0x%08X %s 0x%08X 0x%08X %p %p\n",(unsigned int) hContext,debugstr_w(szReader),dwShareMode,dwPreferredProtocols,phCard,pdwActiveProtocol);	
+	if(!szReader || !phCard || !pdwActiveProtocol)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardConnect)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+	{
+		LPSTR szReaderA = NULL;
+		int dwLen = WideCharToMultiByte(CP_ACP,0,szReader,-1,NULL,0,NULL,NULL);
+		if(!dwLen)
+		{
+			lRet = SCARD_F_UNKNOWN_ERROR;
+			goto end_label;
+		}
+		
+		szReaderA = (LPSTR) malloc(dwLen);
+		if(!szReaderA)
+		{
+			lRet = SCARD_E_NO_MEMORY;
+			goto end_label;
+		}
+		
+		dwLen = WideCharToMultiByte(CP_ACP,0,szReader,-1,szReaderA,dwLen,NULL,NULL);
+		if(!dwLen)
+		{
+			free(szReaderA);
+			lRet = SCARD_F_UNKNOWN_ERROR;
+			goto end_label;
+		}
+		
+		/* the value of SCARD_PROTOCOL_RAW is different between MS implementation and
+		 * pcsc-lite implementation. We must change its value
+		 */
+		if(dwPreferredProtocols & SCARD_PROTOCOL_RAW)
+		{
+			dwPreferredProtocols ^= SCARD_PROTOCOL_RAW;
+			dwPreferredProtocols |= PCSCLITE_SCARD_PROTOCOL_RAW;
+		}
+		
+		lRet = liteSCardConnect(hContext,szReaderA,dwShareMode,dwPreferredProtocols,phCard,pdwActiveProtocol);
+		if(SCARD_S_SUCCESS == lRet)
+		{
+			/* if PCSCLITE_SCARD_PROTOCOL_RAW is set, put back the MS corresponding value */
+			if(*pdwActiveProtocol & PCSCLITE_SCARD_PROTOCOL_RAW)
+			{
+				*pdwActiveProtocol ^= PCSCLITE_SCARD_PROTOCOL_RAW;
+				*pdwActiveProtocol |= SCARD_PROTOCOL_RAW;
+			}			
+		}
+		
+		/* free the allocate ANSI string */
+		free(szReaderA);
+	}		
+end_label:	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);	
+}
+
+LONG WINAPI SCardReconnect(SCARDHANDLE hCard,
+						DWORD dwShareMode,
+						DWORD dwPreferredProtocols,
+						DWORD dwInitialization, 
+						LPDWORD pdwActiveProtocol)
+{
+	LONG lRet;
+	TRACE(" 0x%08X 0x%08X 0x%08X 0x%08X %p\n",(unsigned int) hCard,dwShareMode,dwPreferredProtocols,dwInitialization,pdwActiveProtocol);
+	if(!pdwActiveProtocol)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardReconnect)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+	{
+		/* the value of SCARD_PROTOCOL_RAW is different between MS implementation and
+		 * pcsc-lite implementation. We must change its value
+		 */
+		if(dwPreferredProtocols & SCARD_PROTOCOL_RAW)
+		{
+			dwPreferredProtocols ^= SCARD_PROTOCOL_RAW;
+			dwPreferredProtocols |= PCSCLITE_SCARD_PROTOCOL_RAW;
+		}
+
+		lRet = liteSCardReconnect(hCard,dwShareMode,dwPreferredProtocols,dwInitialization,pdwActiveProtocol);
+		if(SCARD_S_SUCCESS == lRet)
+		{
+			/* if PCSCLITE_SCARD_PROTOCOL_RAW is set, put back the MS corresponding value */
+			if(*pdwActiveProtocol & PCSCLITE_SCARD_PROTOCOL_RAW)
+			{
+				*pdwActiveProtocol ^= PCSCLITE_SCARD_PROTOCOL_RAW;
+				*pdwActiveProtocol |= SCARD_PROTOCOL_RAW;
+			}			
+		}		
+	}
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
+{
+	LONG lRet;
+	TRACE(" 0x%08X 0x%08X\n",(unsigned int) hCard,dwDisposition);
+	if(!liteSCardDisconnect)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+		lRet = liteSCardDisconnect(hCard,dwDisposition);
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardBeginTransaction(SCARDHANDLE hCard)
+{
+	LONG lRet;
+	TRACE(" 0x%08X\n",(unsigned int) hCard);
+	if(!liteSCardBeginTransaction)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+		lRet = liteSCardBeginTransaction(hCard);
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
+{	
+	LONG lRet;
+	TRACE(" 0x%08X 0x%08X\n",(unsigned int) hCard,dwDisposition);
+	if(!liteSCardEndTransaction)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+		lRet = liteSCardEndTransaction(hCard,dwDisposition);
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardCancelTransaction(SCARDHANDLE hCard)
+{
+	LONG lRet;
+	TRACE(" 0x%08X\n",(unsigned int) hCard);
+	if(!liteSCardCancelTransaction)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+		lRet = liteSCardCancelTransaction(hCard);
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardState(
+    SCARDHANDLE hCard,
+    LPDWORD pdwState,
+    LPDWORD pdwProtocol,
+    LPBYTE pbAtr,
+    LPDWORD pcbAtrLen)
+{
+	LONG lRet ;
+	LPSTR szName = NULL;
+	DWORD cchReaderLen = SCARD_AUTOALLOCATE;;
+	TRACE(" 0x%08X %p %p %p %p\n",(unsigned int) hCard,pdwState,pdwProtocol,pbAtr,pcbAtrLen);
+	lRet = SCardStatusA(hCard,(LPSTR) &szName,&cchReaderLen,pdwState,pdwProtocol,pbAtr,pcbAtrLen);
+	
+	/* free szName is allocated by SCardStatusA */
+	if(szName)
+		free((void*) szName);
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);	
+}
+
+LONG WINAPI SCardStatusA(
+		SCARDHANDLE hCard,
+		LPSTR mszReaderNames, 
+		LPDWORD pcchReaderLen,
+		LPDWORD pdwState,
+		LPDWORD pdwProtocol,
+		LPBYTE pbAtr, 
+		LPDWORD pcbAtrLen)
+{
+	LONG lRet;
+	TRACE(" 0x%08X %p %p %p %p %p %p\n",(unsigned int) hCard,mszReaderNames,pcchReaderLen,pdwState,pdwProtocol,pbAtr,pcbAtrLen);
+	if(!pcchReaderLen || !pdwState || !pdwProtocol || !pcbAtrLen)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardStatus)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+	{
+		if(!mszReaderNames || !pbAtr 
+		    || (*pcchReaderLen == SCARD_AUTOALLOCATE) || (*pcbAtrLen == SCARD_AUTOALLOCATE))
+		{
+			/* retreive the information from pcsc-lite */
+			BOOL bHasAutoAllocated = FALSE;
+			DWORD dwNameLen = 0,dwAtrLen=MAX_ATR_SIZE;
+			BYTE atr[MAX_ATR_SIZE];
+			LPSTR szNames = NULL;
+			lRet = liteSCardStatus(hCard,NULL,&dwNameLen,pdwState,pdwProtocol,atr,&dwAtrLen);
+			if(lRet != SCARD_S_SUCCESS && lRet != SCARD_E_INSUFFICIENT_BUFFER)
+				goto end_label;
+			
+			/* case 1: asking for reader names length */
+			if(!mszReaderNames)
+			{
+				lRet = SCARD_S_SUCCESS;
+				*pcchReaderLen = dwNameLen;
+				if(!pbAtr)
+					*pcbAtrLen = dwAtrLen;
+				else if(*pcbAtrLen == SCARD_AUTOALLOCATE)
+				{
+					LPBYTE* ppbAtr = (LPBYTE*) pbAtr;
+					*ppbAtr = (LPBYTE) malloc(dwAtrLen);
+					*pcbAtrLen = dwAtrLen;
+					memcpy(*ppbAtr,atr,dwAtrLen);
+				}
+				else if(*pcbAtrLen < dwAtrLen)
+				{
+					*pcbAtrLen = dwAtrLen;	
+					lRet = SCARD_E_INSUFFICIENT_BUFFER;
+				}
+				else
+				{
+					*pcbAtrLen = dwAtrLen;	
+					memcpy(pbAtr,atr,dwAtrLen);
+				}
+				
+				goto end_label;
+			}
+			
+			/* case 2: reader names pointer provided but its length is unsufficient */
+			if(*pcchReaderLen < dwNameLen)
+			{
+				*pcchReaderLen = dwNameLen;
+				lRet = SCARD_E_INSUFFICIENT_BUFFER;
+				goto end_label;
+			}
+			
+			bHasAutoAllocated = (*pcchReaderLen == SCARD_AUTOALLOCATE)? TRUE : FALSE;
+			if(bHasAutoAllocated)			
+				szNames = (LPSTR) malloc(dwNameLen);
+			else
+				szNames = mszReaderNames;
+			
+			lRet = liteSCardStatus(hCard,szNames,&dwNameLen,pdwState,pdwProtocol,atr,&dwAtrLen);
+			if(lRet != SCARD_S_SUCCESS)
+			{
+				if(bHasAutoAllocated)
+					free(szNames);
+				goto end_label;
+			}
+			
+			*pcchReaderLen = dwNameLen;
+			if(bHasAutoAllocated)
+			{
+				LPSTR* pmszReaderNames = (LPSTR*) mszReaderNames;
+				*pmszReaderNames = szNames;
+				szNames = NULL;
+			}
+				
+			
+			/* now fill the ATR  parameter */
+			if(!pbAtr)
+				*pcbAtrLen = dwAtrLen;
+			else if(*pcbAtrLen == SCARD_AUTOALLOCATE)
+			{
+				LPBYTE* ppbAtr = (LPBYTE*) pbAtr;
+				*ppbAtr = (LPBYTE) malloc(dwAtrLen);
+				*pcbAtrLen = dwAtrLen;
+				memcpy(*ppbAtr,atr,dwAtrLen);
+			}
+			else if(*pcbAtrLen < dwAtrLen)
+			{
+				*pcbAtrLen = dwAtrLen;	
+				lRet = SCARD_E_INSUFFICIENT_BUFFER;
+			}
+			else
+			{
+				*pcbAtrLen = dwAtrLen;	
+				memcpy(pbAtr,atr,dwAtrLen);
+			}
+				
+			if(bHasAutoAllocated && szNames)
+				free(szNames);
+		}
+		else
+			lRet = liteSCardStatus(hCard,mszReaderNames,pcchReaderLen,pdwState,pdwProtocol,pbAtr,pcbAtrLen);
+	}
+	
+end_label:	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+		
+LONG WINAPI SCardStatusW(
+		SCARDHANDLE hCard,
+		LPWSTR mszReaderNames, 
+		LPDWORD pcchReaderLen,
+		LPDWORD pdwState,
+		LPDWORD pdwProtocol,
+		LPBYTE pbAtr, 
+		LPDWORD pcbAtrLen)
+{
+	LONG lRet;
+	TRACE(" 0x%08X %p %p %p %p %p %p\n",(unsigned int) hCard,mszReaderNames,pcchReaderLen,pdwState,pdwProtocol,pbAtr,pcbAtrLen);
+	if(!pcchReaderLen || !pdwState || !pdwProtocol || !pcbAtrLen)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardStatus)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+	{	
+		/* call the ANSI version with SCARD_AUTOALLOCATE */
+		LPSTR mszReaderNamesA = NULL;
+		DWORD dwAnsiNamesLength = SCARD_AUTOALLOCATE;
+		lRet = SCardStatusA(hCard,(LPSTR) &mszReaderNamesA,&dwAnsiNamesLength,pdwState,pdwProtocol,pbAtr,pcbAtrLen);
+		if(lRet == SCARD_S_SUCCESS)
+		{
+			/* convert mszReaderNamesA to a wide char multi-string */
+			LPWSTR mszWideNamesList = NULL;
+			DWORD dwWideNamesLength = 0;
+			lRet = ConvertListToWideChar(mszReaderNamesA,&mszWideNamesList,&dwWideNamesLength);
+			
+			/* no more needed */
+			if(mszReaderNamesA)
+					free(mszReaderNamesA);
+			
+			if(lRet == SCARD_S_SUCCESS)
+			{
+				if(!mszReaderNames)
+					*pcchReaderLen = dwWideNamesLength;
+				else if(*pcchReaderLen == SCARD_AUTOALLOCATE)
+				{
+					LPWSTR* pmszReaderNames = (LPWSTR*) mszReaderNames;
+					*pmszReaderNames = mszWideNamesList;
+					*pcchReaderLen = dwWideNamesLength;
+					mszWideNamesList = NULL;
+				}
+				else if(*pcchReaderLen < dwWideNamesLength)
+				{
+					*pcchReaderLen = dwWideNamesLength;
+					lRet = SCARD_E_INSUFFICIENT_BUFFER;
+				}
+				else
+				{
+					*pcchReaderLen = dwWideNamesLength;
+					memcpy(mszReaderNames,mszWideNamesList,dwWideNamesLength);
+				}
+			}
+			
+			if(mszWideNamesList)
+				free(mszWideNamesList);	
+		}
+	}
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardGetStatusChangeA(
+		SCARDCONTEXT hContext,
+		DWORD dwTimeout,
+		LPSCARD_READERSTATEA rgReaderStates, 
+		DWORD cReaders)
+{
+	LONG lRet;
+	TRACE(" 0x%08X 0x%08X %p 0x%08X\n",(unsigned int) hContext, dwTimeout,rgReaderStates,cReaders);
+	if(!liteSCardGetStatusChange)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else if(!rgReaderStates && cReaders)
+		lRet =  SCARD_E_INVALID_PARAMETER;
+	else if(!cReaders)
+	{
+		if(liteSCardIsValidContext)
+			lRet =  liteSCardIsValidContext(hContext);
+		else
+			lRet = SCARD_S_SUCCESS;
+	}
+	else
+	{
+		/* in pcsclite, dwTimeout = 0 is equivalent to dwTimeout = INFINITE
+		 * In Windows, dwTimeout = 0 means return immediately
+		 * We will simulate an immediate return
+		 */
+		if(dwTimeout == 0)
+		{
+			/* get the current state of readers and compare it with input
+			 * Return SCARD_S_SUCCESS if a change is detected and
+			 * SCARD_E_TIMEOUT otherwide
+			 */
+			
+			DWORD i;
+			LPSCARD_READERSTATEA pStates = (LPSCARD_READERSTATEA) malloc(cReaders * sizeof(SCARD_READERSTATEA));
+			memset(pStates,0,cReaders * sizeof(SCARD_READERSTATEA));
+			for(i=0;i<cReaders;i++)
+				pStates[i].szReader = rgReaderStates[i].szReader;
+			
+			lRet = liteSCardGetStatusChange(hContext,0,pStates,cReaders);
+			if(lRet == SCARD_S_SUCCESS)
+			{
+				BOOL bStateChanges = FALSE;
+				for(i=0;i<cReaders;i++)
+				{
+					DWORD dwState = pStates[i].dwEventState & (~SCARD_STATE_CHANGED);
+					rgReaderStates[i].cbAtr = pStates[i].cbAtr;
+					memcpy(rgReaderStates[i].rgbAtr,pStates[i].rgbAtr,MAX_ATR_SIZE);					
+					
+					if(dwState != rgReaderStates[i].dwCurrentState)
+					{
+						rgReaderStates[i].dwEventState = pStates[i].dwEventState;
+						bStateChanges = TRUE;
+					}
+					else
+						rgReaderStates[i].dwEventState = dwState;
+				}
+				
+				
+				if(!bStateChanges)
+					lRet = SCARD_E_TIMEOUT;
+			}
+			
+			free(pStates);
+		}
+		else
+			lRet = liteSCardGetStatusChange(hContext,dwTimeout,rgReaderStates,cReaders);
+	}
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);	
+}
+		
+LONG WINAPI SCardGetStatusChangeW(
+		SCARDCONTEXT hContext,
+		DWORD dwTimeout,
+		LPSCARD_READERSTATEW rgReaderStates, 
+		DWORD cReaders)
+{
+	LONG lRet;
+	TRACE(" 0x%08X 0x%08X %p 0x%08X\n",(unsigned int) hContext, dwTimeout,rgReaderStates,cReaders);	
+	if(!rgReaderStates && cReaders)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else if(!liteSCardGetStatusChange)
+		lRet =  SCARD_F_INTERNAL_ERROR;
+	else if(!cReaders)
+	{
+		if(liteSCardIsValidContext)
+			lRet = liteSCardIsValidContext(hContext);
+		else
+			lRet = SCARD_S_SUCCESS;
+	}	
+	else
+	{
+		/* create an ANSI array of readers states* */
+		DWORD i;
+		LPSCARD_READERSTATEA rgReaderStatesAnsi = (LPSCARD_READERSTATEA) malloc(cReaders * sizeof(SCARD_READERSTATEA));
+		if(!rgReaderStatesAnsi)
+			return SCARD_E_NO_MEMORY;
+		memset(rgReaderStatesAnsi,0,cReaders * sizeof(SCARD_READERSTATEA));
+		for(i=0;i<cReaders;i++)
+		{
+			int alen = WideCharToMultiByte(CP_ACP,0,rgReaderStates[i].szReader,-1,NULL,0,NULL,NULL);
+			if(!alen)
+				break;
+			rgReaderStatesAnsi[i].szReader = (LPSTR) malloc(alen);
+			WideCharToMultiByte(CP_ACP,0,rgReaderStates[i].szReader,-1,(LPSTR) rgReaderStatesAnsi[i].szReader,alen,NULL,NULL);
+			rgReaderStatesAnsi[i].pvUserData = rgReaderStates[i].pvUserData;
+			rgReaderStatesAnsi[i].dwCurrentState = rgReaderStates[i].dwCurrentState;
+			rgReaderStatesAnsi[i].dwEventState = rgReaderStates[i].dwEventState;
+			rgReaderStatesAnsi[i].cbAtr = rgReaderStates[i].cbAtr;		
+			memcpy(rgReaderStatesAnsi[i].rgbAtr,rgReaderStates[i].rgbAtr,MAX_ATR_SIZE);
+		}
+		
+		if(i < cReaders)
+			lRet = SCARD_F_UNKNOWN_ERROR;
+		else
+		{
+			lRet = SCardGetStatusChangeA(hContext,dwTimeout,rgReaderStatesAnsi,cReaders);
+			if(lRet == SCARD_S_SUCCESS)
+			{
+				/* copy back the information */
+				for(i=0;i<cReaders;i++)
+				{
+					rgReaderStates[i].dwEventState = rgReaderStatesAnsi[i].dwEventState;
+					rgReaderStates[i].cbAtr = rgReaderStatesAnsi[i].cbAtr;		
+					memcpy(rgReaderStates[i].rgbAtr,rgReaderStatesAnsi[i].rgbAtr,MAX_ATR_SIZE);						
+				}	
+			}
+		}
+		/* free memory */
+		for(i=0;i<cReaders;i++)
+		{
+			if(rgReaderStatesAnsi[i].szReader)
+				free((void*) rgReaderStatesAnsi[i].szReader);
+		}
+		free(rgReaderStatesAnsi);	
+	}
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardControl(
+			SCARDHANDLE hCard, 
+			DWORD dwControlCode,
+			LPCVOID pbSendBuffer, 
+			DWORD cbSendLength,
+			LPVOID pbRecvBuffer, 
+			DWORD cbRecvLength, 
+			LPDWORD lpBytesReturned)
+{
+	if(!liteSCardControl)
+		return SCARD_F_INTERNAL_ERROR;
+	else
+		return TranslateToWin32(liteSCardControl(hCard,dwControlCode,pbSendBuffer,cbSendLength,pbRecvBuffer,cbRecvLength,lpBytesReturned));	
+}
+
+LONG WINAPI SCardTransmit(
+		SCARDHANDLE hCard,
+		LPCSCARD_IO_REQUEST pioSendPci,
+		const BYTE* pbSendBuffer, 
+		DWORD cbSendLength,
+		LPSCARD_IO_REQUEST pioRecvPci,
+		LPBYTE pbRecvBuffer, 
+		LPDWORD pcbRecvLength)
+{
+	LONG lRet;
+	if(!liteSCardTransmit)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+	{
+		if(!pioSendPci)
+		{
+			/* In MS PC/SC, pioSendPci can be NULL. But not in pcsc-lite */
+			/* Get the protocol and set the correct value for pioSendPci*/
+			DWORD protocol,dwState;
+			DWORD dwAtrLen,dwNameLen;
+			lRet = SCardStatusA(hCard,NULL,&dwNameLen,&dwState,&protocol,NULL,&dwAtrLen);
+			if(lRet == SCARD_S_SUCCESS)
+			{
+				if(protocol == SCARD_PROTOCOL_T0)
+					pioSendPci = SCARD_PCI_T0;
+				else if(protocol == SCARD_PROTOCOL_T1)
+					pioSendPci = SCARD_PCI_T1;
+				else if(protocol == SCARD_PROTOCOL_RAW)
+					pioSendPci = SCARD_PCI_RAW;
+			}
+		}
+		
+		lRet = liteSCardTransmit(hCard,pioSendPci,pbSendBuffer,cbSendLength,pioRecvPci,pbRecvBuffer,pcbRecvLength);
+	}
+	
+	return TranslateToWin32(lRet);
+}
+		
+LONG WINAPI SCardCancel(SCARDCONTEXT hContext)
+{
+	LONG lRet;
+	TRACE(" 0x%08X \n",(unsigned int) hContext);
+	if(!liteSCardCancel)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else 
+		lRet = liteSCardCancel(hContext);
+	
+	TRACE(" returned 0x%08X\n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardGetAttrib(
+			SCARDHANDLE hCard, 
+			DWORD dwAttrId,
+			LPBYTE pbAttr, 
+			LPDWORD pcbAttrLen)
+{
+	LONG lRet;
+	TRACE(" 0x%08X 0x%08X %p %p \n",(unsigned int) hCard, dwAttrId,pbAttr,pcbAttrLen);
+	if(!liteSCardGetAttrib)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else if(!pcbAttrLen)
+		lRet = SCARD_E_INVALID_PARAMETER;
+	else
+	{
+		LPBYTE ptr = NULL;
+		DWORD dwLength = 0;
+		lRet = liteSCardGetAttrib(hCard,dwAttrId,NULL,&dwLength);
+		if(lRet == SCARD_S_SUCCESS || lRet == SCARD_E_INSUFFICIENT_BUFFER)
+		{
+			if(!pbAttr)
+				*pcbAttrLen = dwLength;
+			else if(*pcbAttrLen < dwLength)
+			{
+				*pcbAttrLen = dwLength;
+				lRet = SCARD_E_INSUFFICIENT_BUFFER;
+			}
+			else
+			{		
+				BOOL bHasAutoAllocate = (*pcbAttrLen == SCARD_AUTOALLOCATE)? TRUE : FALSE;
+				if(bHasAutoAllocate)
+					ptr = (LPBYTE) malloc(dwLength);
+				else
+					ptr = pbAttr;
+				lRet = liteSCardGetAttrib(hCard,dwAttrId,ptr,&dwLength);
+				if(lRet == SCARD_S_SUCCESS)
+				{
+					*pcbAttrLen = dwLength;
+					if(bHasAutoAllocate)
+					{
+						LPBYTE *ppbAttr = (LPBYTE*) pbAttr;
+						*ppbAttr = ptr;
+						ptr = NULL;
+					}	
+				}
+			
+				if(bHasAutoAllocate && ptr)
+					free(ptr);
+			}
+		}
+		
+		if(SCARD_E_UNSUPPORTED_FEATURE == TranslateToWin32(lRet))
+		{
+			/* in case of one of these attributes , do it our selves */
+			if(SCARD_ATTR_ICC_PRESENCE == dwAttrId || SCARD_ATTR_CURRENT_PROTOCOL_TYPE == dwAttrId
+				|| SCARD_ATTR_ATR_STRING == dwAttrId || SCARD_ATTR_DEVICE_FRIENDLY_NAME_A == dwAttrId
+				|| SCARD_ATTR_DEVICE_FRIENDLY_NAME_W == dwAttrId 
+				|| SCARD_ATTR_DEVICE_SYSTEM_NAME_A == dwAttrId
+				|| SCARD_ATTR_DEVICE_SYSTEM_NAME_W == dwAttrId)
+			{
+				DWORD dwState;
+				DWORD dwProtocol;
+				BYTE pbAtr[MAX_ATR_SIZE];
+				DWORD dwAtrLen =MAX_ATR_SIZE;
+				LPVOID pszReaderNames = NULL;
+				DWORD dwNameLength = SCARD_AUTOALLOCATE;
+				LONG status;
+				
+				if(SCARD_ATTR_DEVICE_SYSTEM_NAME_W == dwAttrId 
+					|| SCARD_ATTR_DEVICE_FRIENDLY_NAME_W == dwAttrId)					
+					status = SCardStatusW(hCard,(LPWSTR) &pszReaderNames, &dwNameLength, &dwState,&dwProtocol, pbAtr,&dwAtrLen);
+				else
+					status = SCardStatusA(hCard,(LPSTR) &pszReaderNames, &dwNameLength, &dwState,&dwProtocol, pbAtr,&dwAtrLen);
+				if(SCARD_S_SUCCESS == status)
+				{
+					BYTE pbValue[MAX_ATR_SIZE];
+					DWORD dwValueLen = 0;
+					LPBYTE pValuePtr = &pbValue[0];
+					if(SCARD_ATTR_ICC_PRESENCE == dwAttrId)
+					{
+						dwValueLen = 1;
+						pbValue[0] = 1; /* present by default */
+						if(dwState == SCARD_ABSENT)
+							pbValue[0] = 0;
+						else if(dwState == SCARD_SWALLOWED)
+							pbValue[0] = 2;
+					}
+					else if(SCARD_ATTR_CURRENT_PROTOCOL_TYPE == dwAttrId)
+					{
+						dwValueLen = 4;
+						memcpy(pbValue,&dwProtocol,4);
+					}
+					else if(SCARD_ATTR_DEVICE_FRIENDLY_NAME_A == dwAttrId ||
+						SCARD_ATTR_DEVICE_SYSTEM_NAME_A == dwAttrId)
+					{
+						pValuePtr = (LPBYTE) pszReaderNames;
+						dwValueLen = dwNameLength ;						
+					}
+					else if(SCARD_ATTR_DEVICE_FRIENDLY_NAME_W == dwAttrId ||
+						SCARD_ATTR_DEVICE_SYSTEM_NAME_W == dwAttrId)
+					{
+						pValuePtr = (LPBYTE) pszReaderNames;
+						dwValueLen = dwNameLength * sizeof(WCHAR);
+					}
+					else /* ATR case */
+					{
+						dwValueLen = dwAtrLen;
+						memcpy(pbValue,pbAtr,dwAtrLen);
+					}
+					
+					lRet = SCARD_S_SUCCESS;
+					if(!pbAttr)
+						*pcbAttrLen =dwValueLen;
+					else if(*pcbAttrLen == SCARD_AUTOALLOCATE)
+					{
+						LPBYTE *ppbAttr = (LPBYTE*) pbAttr;
+						*ppbAttr = (LPBYTE) malloc(dwValueLen);
+						memcpy(*ppbAttr,pValuePtr,dwValueLen);
+						*pcbAttrLen = dwValueLen;
+					}
+					else if(*pcbAttrLen < dwValueLen)
+					{
+						*pcbAttrLen = dwValueLen;
+						lRet = SCARD_E_INSUFFICIENT_BUFFER;
+					}
+					else
+					{
+						*pcbAttrLen = dwValueLen;
+						memcpy(pbAttr,pValuePtr,dwValueLen);
+					}
+					
+					free(pszReaderNames);
+				}
+			}
+		}
+	}
+	TRACE(" returned 0x%08X \n",lRet);
+	return TranslateToWin32(lRet);
+}
+
+LONG WINAPI SCardSetAttrib(
+			SCARDHANDLE hCard, 
+			DWORD dwAttrId,
+			const BYTE* pbAttr, 
+			DWORD cbAttrLen)
+{
+	LONG lRet;
+	TRACE(" 0x%08X 0x%08X %p 0x%08X \n",(unsigned int) hCard,dwAttrId,pbAttr,cbAttrLen);
+	if(!liteSCardSetAttrib)
+		lRet = SCARD_F_INTERNAL_ERROR;
+	else
+		lRet = liteSCardSetAttrib(hCard,dwAttrId,pbAttr,cbAttrLen);
+	
+	TRACE(" returned 0x%08X \n",lRet);	
+	return TranslateToWin32(lRet);
+}
+		
+			
diff --git a/dlls/winscard/winscard.spec b/dlls/winscard/winscard.spec
new file mode 100755
index 0000000..2eb0681
--- /dev/null
+++ b/dlls/winscard/winscard.spec
@@ -0,0 +1,63 @@
+@ stub ClassInstall32
+@ stdcall SCardAccessNewReaderEvent()
+@ stdcall SCardReleaseAllEvents()
+@ stdcall SCardReleaseNewReaderEvent()
+@ stdcall SCardAccessStartedEvent()
+@ stdcall SCardAddReaderToGroupA(long str str)
+@ stdcall SCardAddReaderToGroupW(long wstr wstr)
+@ stdcall SCardBeginTransaction(long)
+@ stdcall SCardCancel(long)
+@ stdcall SCardConnectA(long str long long ptr ptr)
+@ stdcall SCardConnectW(long wstr long long ptr ptr)
+@ stdcall SCardControl(long long ptr long ptr long ptr)
+@ stdcall SCardDisconnect(long long)
+@ stdcall SCardEndTransaction(long long)
+@ stdcall SCardEstablishContext(long ptr ptr ptr)
+@ stdcall SCardForgetCardTypeA(long str)
+@ stdcall SCardForgetCardTypeW(long wstr)
+@ stdcall SCardForgetReaderA(long str)
+@ stdcall SCardForgetReaderGroupA(long str)
+@ stdcall SCardForgetReaderGroupW(long wstr)
+@ stdcall SCardForgetReaderW(long wstr)
+@ stdcall SCardFreeMemory(long ptr)
+@ stdcall SCardGetAttrib(long long ptr ptr)
+@ stdcall SCardGetCardTypeProviderNameA(long str long str ptr)
+@ stdcall SCardGetCardTypeProviderNameW(long wstr long wstr ptr)
+@ stdcall SCardGetProviderIdA(long str ptr)
+@ stdcall SCardGetProviderIdW(long wstr ptr)
+@ stdcall SCardGetStatusChangeA(long long ptr long)
+@ stdcall SCardGetStatusChangeW(long long ptr long)
+@ stdcall SCardIntroduceCardTypeA(long str ptr ptr long ptr ptr long)
+@ stdcall SCardIntroduceCardTypeW(long wstr ptr ptr long ptr ptr long)
+@ stdcall SCardIntroduceReaderA(long str str)
+@ stdcall SCardIntroduceReaderGroupA(long str)
+@ stdcall SCardIntroduceReaderGroupW(long wstr)
+@ stdcall SCardIntroduceReaderW(long wstr wstr)
+@ stdcall SCardIsValidContext(long)
+@ stdcall SCardListCardsA(long ptr ptr long str ptr)
+@ stdcall SCardListCardsW(long ptr ptr long wstr ptr)
+@ stdcall SCardListInterfacesA(long str ptr ptr)
+@ stdcall SCardListInterfacesW(long wstr ptr ptr)
+@ stdcall SCardListReaderGroupsA(long str ptr)
+@ stdcall SCardListReaderGroupsW(long wstr ptr)
+@ stdcall SCardListReadersA(long str str ptr)
+@ stdcall SCardListReadersW(long wstr wstr ptr)
+@ stdcall SCardLocateCardsA(long str ptr long)
+@ stdcall SCardLocateCardsByATRA(long ptr long ptr long)
+@ stdcall SCardLocateCardsByATRW(long ptr long ptr long)
+@ stdcall SCardLocateCardsW(long wstr ptr long)
+@ stdcall SCardReconnect(long long long long ptr)
+@ stdcall SCardReleaseContext(long)
+@ stdcall SCardReleaseStartedEvent()
+@ stdcall SCardRemoveReaderFromGroupA(long str str)
+@ stdcall SCardRemoveReaderFromGroupW(long wstr wstr)
+@ stdcall SCardSetAttrib(long long ptr long)
+@ stdcall SCardSetCardTypeProviderNameA(long str long str)
+@ stdcall SCardSetCardTypeProviderNameW(long wstr long wstr)
+@ stdcall SCardState(long ptr ptr ptr ptr)
+@ stdcall SCardStatusA(long str ptr ptr ptr ptr ptr)
+@ stdcall SCardStatusW(long wstr ptr ptr ptr ptr ptr)
+@ stdcall SCardTransmit(long ptr ptr long ptr ptr ptr)
+@ extern g_rgSCardRawPci
+@ extern g_rgSCardT0Pci	
+@ extern g_rgSCardT1Pci
diff --git a/include/Makefile.in b/include/Makefile.in
index 2577872..7dc0cc3 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -293,6 +293,7 @@ SRCDIR_INCLUDES = \
 	rpcndr.h \
 	rpcnterr.h \
 	rpcproxy.h \
+	scarderr.h \
 	schannel.h \
 	schemadef.h \
 	schnlsp.h \
@@ -351,6 +352,8 @@ SRCDIR_INCLUDES = \
 	winreg.h \
 	winres.h \
 	winresrc.h \
+	winscard.h \
+	winsmcrd.h \
 	winsock.h \
 	winsock2.h \
 	winspool.h \
diff --git a/include/scarderr.h b/include/scarderr.h
new file mode 100755
index 0000000..b956b6d
--- /dev/null
+++ b/include/scarderr.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2007 Mounir IDRASSI  (mounir.idrassi at idrix.fr, for IDRIX)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _WINE_SCARDERR_H
+#define _WINE_SCARDERR_H
+
+
+
+#define SCARD_S_SUCCESS				0x00000000
+#define SCARD_F_INTERNAL_ERROR		0x80100001 /**< An internal consistency check failed. */
+#define SCARD_E_CANCELLED			0x80100002 /**< The action was cancelled by an SCardCancel request. */
+#define SCARD_E_INVALID_HANDLE		0x80100003 /**< The supplied handle was invalid. */
+#define SCARD_E_INVALID_PARAMETER	0x80100004 /**< One or more of the supplied parameters could not be properly interpreted. */
+#define SCARD_E_INVALID_TARGET		0x80100005 /**< Registry startup information is missing or invalid. */
+#define SCARD_E_NO_MEMORY			0x80100006 /**< Not enough memory available to complete this command. */
+#define SCARD_F_WAITED_TOO_LONG		0x80100007 /**< An internal consistency timer has expired. */
+#define SCARD_E_INSUFFICIENT_BUFFER	0x80100008 /**< The data buffer to receive returned data is too small for the returned data. */
+#define SCARD_E_UNKNOWN_READER		0x80100009 /**< The specified reader name is not recognized. */
+#define SCARD_E_TIMEOUT				0x8010000A /**< The user-specified timeout value has expired. */
+#define SCARD_E_SHARING_VIOLATION	0x8010000B /**< The smart card cannot be accessed because of other connections outstanding. */
+
+#ifndef SCARD_E_NO_SMARTCARD
+#define SCARD_E_NO_SMARTCARD		0x8010000C /**< The operation requires a Smart Card, but no Smart Card is currently in the device. */
+#endif
+
+#define SCARD_E_UNKNOWN_CARD		0x8010000D /**< The specified smart card name is not recognized. */
+#define SCARD_E_CANT_DISPOSE		0x8010000E /**< The system could not dispose of the media in the requested manner. */
+#define SCARD_E_PROTO_MISMATCH		0x8010000F /**< The requested protocols are incompatible with the protocol currently in use with the smart card. */
+#define SCARD_E_NOT_READY			0x80100010 /**< The reader or smart card is not ready to accept commands. */
+#define SCARD_E_INVALID_VALUE		0x80100011 /**< One or more of the supplied parameters values could not be properly interpreted. */
+#define SCARD_E_SYSTEM_CANCELLED	0x80100012 /**< The action was cancelled by the system, presumably to log off or shut down. */
+#define SCARD_F_COMM_ERROR			0x80100013 /**< An internal communications error has been detected. */
+#define SCARD_F_UNKNOWN_ERROR		0x80100014 /**< An internal error has been detected, but the source is unknown. */
+#define SCARD_E_INVALID_ATR			0x80100015 /**< An ATR obtained from the registry is not a valid ATR string. */
+#define SCARD_E_NOT_TRANSACTED		0x80100016 /**< An attempt was made to end a non-existent transaction. */
+#define SCARD_E_READER_UNAVAILABLE	0x80100017 /**< The specified reader is not currently available for use. */
+#define SCARD_P_SHUTDOWN			0x80100018/**The operation has been aborted to allow the server application to exit.*/
+#define SCARD_E_PCI_TOO_SMALL		0x80100019 /**< The PCI Receive buffer was too small. */
+#define SCARD_E_READER_UNSUPPORTED	0x8010001A /**< The reader driver does not meet minimal requirements for support. */
+#define SCARD_E_DUPLICATE_READER	0x8010001B /**< The reader driver did not produce a unique reader name. */
+#define SCARD_E_CARD_UNSUPPORTED	0x8010001C /**< The smart card does not meet minimal requirements for support. */
+#define SCARD_E_NO_SERVICE			0x8010001D /**< The Smart card resource manager is not running. */
+#define SCARD_E_SERVICE_STOPPED		0x8010001E /**< The Smart card resource manager has shut down. */
+#define SCARD_E_UNEXPECTED			0x8010001F /** An unexpected card error has occurred. */
+#define SCARD_E_ICC_INSTALLATION    0x80100020 /** No Primary Provider can be found for the smart card.*/
+#define SCARD_E_ICC_CREATEORDER   	0x80100021 /** The requested order of object creation is not supported.*/
+#define SCARD_E_UNSUPPORTED_FEATURE	0x80100022 /** This smart card does not support the requested feature.*/
+#define SCARD_E_DIR_NOT_FOUND 		0x80100023 /** The identified directory does not exist in the smart card. */
+#define SCARD_E_FILE_NOT_FOUND   	0x80100024 /**  The identified file does not exist in the smart card.*/
+#define SCARD_E_NO_DIR             	0x80100025 /** The supplied path does not represent a smart card directory.*/
+#define SCARD_E_NO_FILE            	0x80100026 /** The supplied path does not represent a smart card file.*/
+#define SCARD_E_NO_ACCESS     		0x80100027 /** Access is denied to this file.*/
+#define SCARD_E_WRITE_TOO_MANY   	0x80100028 /** The smartcard does not have enough memory to store the information.*/
+#define SCARD_E_BAD_SEEK      		0x80100029 /** There was an error trying to set the smart card file object pointer.*/
+#define SCARD_E_INVALID_CHV       	0x8010002A /** The supplied PIN is incorrect.*/
+#define SCARD_E_UNKNOWN_RES_MNG    	0x8010002B /** An unrecognized error code was returned from a layered component.*/
+
+#ifndef SCARD_E_NO_SUCH_CERTIFICATE
+#define SCARD_E_NO_SUCH_CERTIFICATE 	0x8010002C /** The requested certificate does not exist.*/			
+#endif
+
+#define SCARD_E_CERTIFICATE_UNAVAILABLE 0x8010002D /** The requested certificate could not be obtained.*/
+#define SCARD_E_NO_READERS_AVAILABLE    0x8010002E /**< Cannot find a smart card reader. */
+
+#ifndef SCARD_E_COMM_DATA_LOST
+#define SCARD_E_COMM_DATA_LOST    		0x8010002F /** A communications error with the smart card has been detected.  Retry the operation.*/
+#endif
+
+#define SCARD_E_NO_KEY_CONTAINER  	0x80100030 /** The requested key container does not exist on the smart card. */
+#define SCARD_E_SERVER_TOO_BUSY    	0x80100031 /** The Smart card resource manager is too busy to complete this operation. */
+
+#define SCARD_W_UNSUPPORTED_CARD	0x80100065 /**< The reader cannot communicate with the card, due to ATR string configuration conflicts. */
+#define SCARD_W_UNRESPONSIVE_CARD	0x80100066 /**< The smart card is not responding to a reset. */
+#define SCARD_W_UNPOWERED_CARD		0x80100067 /**< Power has been removed from the smart card, so that further communication is not possible. */
+#define SCARD_W_RESET_CARD			0x80100068 /**< The smart card has been reset, so any shared state information is invalid. */
+#define SCARD_W_REMOVED_CARD		0x80100069 /**< The smart card has been removed, so further communication is not possible. */
+#define SCARD_W_SECURITY_VIOLATION 	0x8010006A /** Access was denied because of a security violation.*/
+
+#ifndef SCARD_W_WRONG_CHV
+#define SCARD_W_WRONG_CHV   		0x8010006B /** The card cannot be accessed because the wrong PIN was presented.*/
+#endif
+
+#ifndef SCARD_W_CHV_BLOCKED
+#define SCARD_W_CHV_BLOCKED   		0x8010006C /**  The card cannot be accessed because the maximum number of PIN entry attempts has been reached.*/
+#endif
+
+#define SCARD_W_EOF              	0x8010006D /**  The end of the smart card file has been reached.*/
+#define SCARD_W_CANCELLED_BY_USER 	0x8010006E /**  The action was cancelled by the user.*/
+
+#ifndef SCARD_W_CARD_NOT_AUTHENTICATED
+#define SCARD_W_CARD_NOT_AUTHENTICATED	0x8010006F /**No PIN was presented to the smart card.*/
+#endif
+
+
+#endif
diff --git a/include/winscard.h b/include/winscard.h
new file mode 100755
index 0000000..bf1fe8a
--- /dev/null
+++ b/include/winscard.h
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2007 Mounir IDRASSI  (mounir.idrassi at idrix.fr, for IDRIX)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+
+#ifndef _WINE_WINSCARD_H
+#define _WINE_WINSCARD_H
+
+#include "winsmcrd.h"
+#include "scarderr.h"
+
+extern SCARD_IO_REQUEST g_rgSCardT0Pci;
+extern SCARD_IO_REQUEST g_rgSCardT1Pci;
+extern SCARD_IO_REQUEST g_rgSCardRawPci;
+
+#define SCARD_PCI_T0	(&g_rgSCardT0Pci)
+#define SCARD_PCI_T1	(&g_rgSCardT1Pci)
+#define SCARD_PCI_RAW	(&g_rgSCardRawPci)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+LONG WINAPI SCardEstablishContext(DWORD dwScope,LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
+
+LONG WINAPI SCardReleaseContext(SCARDCONTEXT hContext);
+
+LONG WINAPI SCardIsValidContext(SCARDCONTEXT hContext);
+
+
+LONG WINAPI SCardListReaderGroupsA(
+		SCARDCONTEXT hContext,
+		LPSTR mszGroups, 
+		LPDWORD pcchGroups);		
+LONG WINAPI SCardListReaderGroupsW(
+		SCARDCONTEXT hContext,
+		LPWSTR mszGroups, 
+		LPDWORD pcchGroups);		
+	
+#define SCardListReaderGroups 	WINELIB_NAME_AW(SCardListReaderGroups)
+	
+
+LONG WINAPI SCardListReadersA(
+		SCARDCONTEXT hContext,
+		LPCSTR mszGroups,
+		LPSTR mszReaders, 
+		LPDWORD pcchReaders);
+LONG WINAPI SCardListReadersW(
+		SCARDCONTEXT hContext,
+		LPCWSTR mszGroups,
+		LPWSTR mszReaders, 
+		LPDWORD pcchReaders);
+		
+#define SCardListReaders 	WINELIB_NAME_AW(SCardListReaders)
+
+LONG WINAPI SCardListCardsA(
+		SCARDCONTEXT hContext,
+		const BYTE* pbAtr,
+		LPCGUID rgquidInterfaces,
+		DWORD cguidInterfaceCount,
+		LPSTR mszCards,
+		LPDWORD pcchCards);
+LONG WINAPI SCardListCardsW(
+          SCARDCONTEXT hContext,
+          const BYTE* pbAtr,
+          LPCGUID rgquidInterfaces,
+          DWORD cguidInterfaceCount,
+		  LPWSTR mszCards,
+		  LPDWORD pcchCards);
+		  
+#define SCardListCards 	WINELIB_NAME_AW(SCardListCards) 
+	
+LONG WINAPI SCardListInterfacesA(
+        SCARDCONTEXT hContext,
+		LPCSTR szCard,
+		LPGUID pguidInterfaces,
+		LPDWORD pcguidInterfaces);
+LONG WINAPI SCardListInterfacesW(
+		SCARDCONTEXT hContext,
+		LPCWSTR szCard,
+		LPGUID pguidInterfaces,
+		LPDWORD pcguidInterfaces);
+
+#define SCardListInterfaces 	WINELIB_NAME_AW(SCardListInterfaces)		
+  
+LONG WINAPI SCardGetProviderIdA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCard,
+    LPGUID pguidProviderId);
+LONG WINAPI SCardGetProviderIdW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCard,
+    LPGUID pguidProviderId);  
+    
+#define SCardGetProviderId 	WINELIB_NAME_AW(SCardGetProviderId)		    
+	
+LONG WINAPI SCardGetCardTypeProviderNameA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCardName,
+    DWORD dwProviderId,
+    LPSTR szProvider,
+    LPDWORD pcchProvider);
+LONG WINAPI SCardGetCardTypeProviderNameW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCardName,
+    DWORD dwProviderId,
+    LPWSTR szProvider,
+    LPDWORD pcchProvider);	
+    
+#define SCardGetCardTypeProviderName 	WINELIB_NAME_AW(SCardGetCardTypeProviderName)		        
+	
+//
+// Database functions
+//
+
+LONG WINAPI SCardIntroduceReaderGroupA(
+    SCARDCONTEXT hContext,
+    LPCSTR szGroupName);	
+LONG WINAPI SCardIntroduceReaderGroupW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szGroupName);
+    
+#define SCardIntroduceReaderGroup 	WINELIB_NAME_AW(SCardIntroduceReaderGroup)		            
+
+LONG WINAPI SCardForgetReaderGroupA(
+    SCARDCONTEXT hContext,
+    LPCSTR szGroupName);	
+LONG WINAPI SCardForgetReaderGroupW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szGroupName);
+    
+#define SCardForgetReaderGroup 	WINELIB_NAME_AW(SCardForgetReaderGroup)
+
+
+LONG WINAPI SCardIntroduceReaderA(
+    SCARDCONTEXT hContext,
+    LPCSTR szReaderName,
+    LPCSTR szDeviceName);
+LONG WINAPI SCardIntroduceReaderW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szReaderName,
+    LPCWSTR szDeviceName);
+    
+#define SCardIntroduceReader 	WINELIB_NAME_AW(SCardIntroduceReader)		                    
+
+LONG WINAPI SCardForgetReaderA(
+    SCARDCONTEXT hContext,
+    LPCSTR szReaderName);
+LONG WINAPI SCardForgetReaderW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szReaderName);
+    
+#define SCardForgetReader 	WINELIB_NAME_AW(SCardForgetReader)		                        
+
+LONG WINAPI SCardAddReaderToGroupA(
+    SCARDCONTEXT hContext,
+    LPCSTR szReaderName,
+    LPCSTR szGroupName);	
+LONG WINAPI SCardAddReaderToGroupW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szReaderName,
+    LPCWSTR szGroupName);
+    
+#define SCardAddReaderToGroup 	WINELIB_NAME_AW(SCardAddReaderToGroup)		                            
+
+LONG WINAPI SCardRemoveReaderFromGroupA(
+    SCARDCONTEXT hContext,
+    LPCSTR szReaderName,
+    LPCSTR szGroupName);	
+LONG WINAPI SCardRemoveReaderFromGroupW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szReaderName,
+    LPCWSTR szGroupName);
+
+#define SCardRemoveReaderFromGroup 	WINELIB_NAME_AW(SCardRemoveReaderFromGroup)		                            
+
+LONG WINAPI SCardIntroduceCardTypeA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCardName,
+    LPCGUID pguidPrimaryProvider,
+    LPCGUID rgguidInterfaces,
+    DWORD dwInterfaceCount,
+    const BYTE* pbAtr,
+    const BYTE* pbAtrMask,
+    DWORD cbAtrLen);	
+LONG WINAPI SCardIntroduceCardTypeW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCardName,
+    LPCGUID pguidPrimaryProvider,
+    LPCGUID rgguidInterfaces,
+    DWORD dwInterfaceCount,
+    const BYTE* pbAtr,
+    const BYTE* pbAtrMask,
+    DWORD cbAtrLen);	
+	
+#define SCardIntroduceCardType 	WINELIB_NAME_AW(SCardIntroduceCardType)		                            	
+
+LONG WINAPI SCardSetCardTypeProviderNameA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCardName,
+    DWORD dwProviderId,
+    LPCSTR szProvider);	
+LONG WINAPI SCardSetCardTypeProviderNameW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCardName,
+    DWORD dwProviderId,
+    LPCWSTR szProvider);
+
+#define SCardSetCardTypeProviderName 	WINELIB_NAME_AW(SCardSetCardTypeProviderName)		                            	
+
+LONG WINAPI SCardForgetCardTypeA(
+    SCARDCONTEXT hContext,
+    LPCSTR szCardName);	
+LONG WINAPI SCardForgetCardTypeW(
+    SCARDCONTEXT hContext,
+    LPCWSTR szCardName);
+	
+#define SCardForgetCardType 	WINELIB_NAME_AW(SCardForgetCardType)		                            	
+
+LONG WINAPI SCardLocateCardsA(
+    SCARDCONTEXT hContext,
+    LPCSTR mszCards,
+    LPSCARD_READERSTATEA rgReaderStates,
+    DWORD cReaders);	
+LONG WINAPI SCardLocateCardsW(
+    SCARDCONTEXT hContext,
+    LPCWSTR mszCards,
+    LPSCARD_READERSTATEW rgReaderStates,
+    DWORD cReaders);
+
+#define SCardLocateCards 	WINELIB_NAME_AW(SCardLocateCards)		                            	
+
+LONG WINAPI SCardLocateCardsByATRA(
+    SCARDCONTEXT hContext,
+    LPSCARD_ATRMASK rgAtrMasks,
+    DWORD cAtrs,
+    LPSCARD_READERSTATEA rgReaderStates,
+    DWORD cReaders);	
+LONG WINAPI SCardLocateCardsByATRW(
+    SCARDCONTEXT hContext,
+    LPSCARD_ATRMASK rgAtrMasks,
+    DWORD cAtrs,
+    LPSCARD_READERSTATEW rgReaderStates,
+    DWORD cReaders);	
+	
+#define SCardLocateCardsByATR 	WINELIB_NAME_AW(SCardLocateCardsByATR)		                            		
+	
+/*
+  * Service Manager Support Routines
+  */
+
+LONG WINAPI SCardFreeMemory( SCARDCONTEXT hContext,LPCVOID pvMem);
+
+HANDLE WINAPI SCardAccessStartedEvent(void);
+
+void WINAPI SCardReleaseStartedEvent(HANDLE hStartedEventHandle);
+	
+
+LONG WINAPI SCardConnectA(SCARDCONTEXT hContext,
+						LPCSTR szReader,
+						DWORD dwShareMode,
+						DWORD dwPreferredProtocols,
+						LPSCARDHANDLE phCard, 
+						LPDWORD pdwActiveProtocol);						
+LONG WINAPI SCardConnectW(SCARDCONTEXT hContext,
+						LPCWSTR szReader,
+						DWORD dwShareMode,
+						DWORD dwPreferredProtocols,
+						LPSCARDHANDLE phCard, 
+						LPDWORD pdwActiveProtocol);						
+
+#define SCardConnect 	WINELIB_NAME_AW(SCardConnect)		                            		
+
+LONG WINAPI SCardReconnect(SCARDHANDLE hCard,
+						DWORD dwShareMode,
+						DWORD dwPreferredProtocols,
+						DWORD dwInitialization, 
+						LPDWORD pdwActiveProtocol);
+
+LONG WINAPI SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition);
+
+LONG WINAPI SCardBeginTransaction(SCARDHANDLE hCard);
+
+LONG WINAPI SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition);
+
+LONG WINAPI SCardCancelTransaction(SCARDHANDLE hCard);
+
+LONG WINAPI SCardState(
+    SCARDHANDLE hCard,
+    LPDWORD pdwState,
+    LPDWORD pdwProtocol,
+    LPBYTE pbAtr,
+    LPDWORD pcbAtrLen);
+
+LONG WINAPI SCardStatusA(
+		SCARDHANDLE hCard,
+		LPSTR mszReaderNames, 
+		LPDWORD pcchReaderLen,
+		LPDWORD pdwState,
+		LPDWORD pdwProtocol,
+		LPBYTE pbAtr, 
+		LPDWORD pcbAtrLen);		
+LONG WINAPI SCardStatusW(
+		SCARDHANDLE hCard,
+		LPWSTR mszReaderNames, 
+		LPDWORD pcchReaderLen,
+		LPDWORD pdwState,
+		LPDWORD pdwProtocol,
+		LPBYTE pbAtr, 
+		LPDWORD pcbAtrLen);	
+
+#define SCardStatus 	WINELIB_NAME_AW(SCardStatus)		                            		
+
+LONG WINAPI SCardGetStatusChangeA(
+		SCARDCONTEXT hContext,
+		DWORD dwTimeout,
+		LPSCARD_READERSTATEA rgReaderStates, 
+		DWORD cReaders);		
+LONG WINAPI SCardGetStatusChangeW(
+		SCARDCONTEXT hContext,
+		DWORD dwTimeout,
+		LPSCARD_READERSTATEW rgReaderStates, 
+		DWORD cReaders);		
+
+#define SCardGetStatusChange 	WINELIB_NAME_AW(SCardGetStatusChange)		                            		
+
+LONG WINAPI SCardControl(
+			SCARDHANDLE hCard, 
+			DWORD dwControlCode,
+			LPCVOID pbSendBuffer, 
+			DWORD cbSendLength,
+			LPVOID pbRecvBuffer, 
+			DWORD cbRecvLength, 
+			LPDWORD lpBytesReturned);
+
+LONG WINAPI SCardTransmit(
+		SCARDHANDLE hCard,
+		LPCSCARD_IO_REQUEST pioSendPci,
+		const BYTE* pbSendBuffer, 
+		DWORD cbSendLength,
+		LPSCARD_IO_REQUEST pioRecvPci,
+		LPBYTE pbRecvBuffer, 
+		LPDWORD pcbRecvLength);
+		
+LONG WINAPI SCardCancel(SCARDCONTEXT hContext);
+
+LONG WINAPI SCardGetAttrib(
+			SCARDHANDLE hCard, 
+			DWORD dwAttrId,
+			LPBYTE pbAttr, 
+			LPDWORD pcbAttrLen);
+
+LONG WINAPI SCardSetAttrib(
+			SCARDHANDLE hCard, 
+			DWORD dwAttrId,
+			const BYTE* pbAttr, 
+			DWORD cbAttrLen);
+	
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/winsmcrd.h b/include/winsmcrd.h
new file mode 100755
index 0000000..ccef4a3
--- /dev/null
+++ b/include/winsmcrd.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2007 Mounir IDRASSI  (mounir.idrassi at idrix.fr, for IDRIX)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#ifndef _WINE_WINSCMCRD_H
+#define _WINE_WINSCMCRD_H
+
+
+#define MAX_ATR_SIZE			36	/**< Maximum ATR size */
+
+#ifndef SCARD_ATR_LENGTH
+#define SCARD_ATR_LENGTH		MAX_ATR_SIZE	/**< Maximum ATR size */
+#endif
+
+
+#define SCARD_PROTOCOL_UNDEFINED    0x00000000  // There is no active protocol.
+#define SCARD_PROTOCOL_T0           0x00000001  // T=0 is the active protocol.
+#define SCARD_PROTOCOL_T1           0x00000002  // T=1 is the active protocol.
+#define SCARD_PROTOCOL_RAW          0x00010000  // Raw is the active protocol.
+#define SCARD_PROTOCOL_Tx           (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
+
+#define SCARD_AUTOALLOCATE (DWORD)(-1)
+
+#define SCARD_SCOPE_USER		0x0000	/**< Scope in user space */
+#define SCARD_SCOPE_TERMINAL		0x0001	/**< Scope in terminal */
+#define SCARD_SCOPE_SYSTEM		0x0002	/**< Scope in system */
+
+#define SCARD_STATE_UNAWARE		0x0000	/**< App wants status */
+#define SCARD_STATE_IGNORE		0x0001	/**< Ignore this reader */
+#define SCARD_STATE_CHANGED		0x0002	/**< State has changed */
+#define SCARD_STATE_UNKNOWN		0x0004	/**< Reader unknown */
+#define SCARD_STATE_UNAVAILABLE		0x0008	/**< Status unavailable */
+#define SCARD_STATE_EMPTY		0x0010	/**< Card removed */
+#define SCARD_STATE_PRESENT		0x0020	/**< Card inserted */
+#define SCARD_STATE_ATRMATCH		0x0040	/**< ATR matches card */
+#define SCARD_STATE_EXCLUSIVE		0x0080	/**< Exclusive Mode */
+#define SCARD_STATE_INUSE		0x0100	/**< Shared Mode */
+#define SCARD_STATE_MUTE		0x0200	/**< Unresponsive card */
+#define SCARD_STATE_UNPOWERED		0x0400	/**< Unpowered card */
+
+
+
+#define SCARD_SHARE_EXCLUSIVE		0x0001	/**< Exclusive mode only */
+#define SCARD_SHARE_SHARED		0x0002	/**< Shared mode only */
+#define SCARD_SHARE_DIRECT		0x0003	/**< Raw mode only */
+
+#define SCARD_LEAVE_CARD		0x0000	/**< Do nothing on close */
+#define SCARD_RESET_CARD		0x0001	/**< Reset on close */
+#define SCARD_UNPOWER_CARD		0x0002	/**< Power down on close */
+#define SCARD_EJECT_CARD		0x0003	/**< Eject on close */
+
+#define SCARD_UNKNOWN			0x0001	/**< Unknown state */
+#define SCARD_ABSENT			0x0002	/**< Card is absent */
+#define SCARD_PRESENT			0x0004	/**< Card is present */
+#define SCARD_SWALLOWED			0x0008	/**< Card not powered */
+#define SCARD_POWERED			0x0010	/**< Card is powered */
+#define SCARD_NEGOTIABLE		0x0020	/**< Ready for PTS */
+#define SCARD_SPECIFIC			0x0040	/**< PTS has been set */
+
+/*
+ * Tags for requesting card and reader attributes
+ */
+
+#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag)))
+
+#define SCARD_CLASS_VENDOR_INFO     1   /**< Vendor information definitions */
+#define SCARD_CLASS_COMMUNICATIONS  2   /**< Communication definitions */
+#define SCARD_CLASS_PROTOCOL        3   /**< Protocol definitions */
+#define SCARD_CLASS_POWER_MGMT      4   /**< Power Management definitions */
+#define SCARD_CLASS_SECURITY        5   /**< Security Assurance definitions */
+#define SCARD_CLASS_MECHANICAL      6   /**< Mechanical characteristic definitions */
+#define SCARD_CLASS_VENDOR_DEFINED  7   /**< Vendor specific definitions */
+#define SCARD_CLASS_IFD_PROTOCOL    8   /**< Interface Device Protocol options */
+#define SCARD_CLASS_ICC_STATE       9   /**< ICC State specific definitions */
+#define SCARD_CLASS_SYSTEM     0x7fff   /**< System-specific definitions */
+
+#define SCARD_ATTR_VENDOR_NAME SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0100)
+#define SCARD_ATTR_VENDOR_IFD_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0101)
+#define SCARD_ATTR_VENDOR_IFD_VERSION SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0102)
+#define SCARD_ATTR_VENDOR_IFD_SERIAL_NO SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_INFO, 0x0103)
+#define SCARD_ATTR_CHANNEL_ID SCARD_ATTR_VALUE(SCARD_CLASS_COMMUNICATIONS, 0x0110)
+#define SCARD_ATTR_ASYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0120)
+#define SCARD_ATTR_DEFAULT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0121)
+#define SCARD_ATTR_MAX_CLK SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0122)
+#define SCARD_ATTR_DEFAULT_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0123)
+#define SCARD_ATTR_MAX_DATA_RATE SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0124)
+#define SCARD_ATTR_MAX_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0125)
+#define SCARD_ATTR_SYNC_PROTOCOL_TYPES SCARD_ATTR_VALUE(SCARD_CLASS_PROTOCOL, 0x0126)
+#define SCARD_ATTR_POWER_MGMT_SUPPORT SCARD_ATTR_VALUE(SCARD_CLASS_POWER_MGMT, 0x0131)
+#define SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0140)
+#define SCARD_ATTR_USER_AUTH_INPUT_DEVICE SCARD_ATTR_VALUE(SCARD_CLASS_SECURITY, 0x0142)
+#define SCARD_ATTR_CHARACTERISTICS SCARD_ATTR_VALUE(SCARD_CLASS_MECHANICAL, 0x0150)
+
+#define SCARD_ATTR_CURRENT_PROTOCOL_TYPE SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0201)
+#define SCARD_ATTR_CURRENT_CLK SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0202)
+#define SCARD_ATTR_CURRENT_F SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0203)
+#define SCARD_ATTR_CURRENT_D SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0204)
+#define SCARD_ATTR_CURRENT_N SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0205)
+#define SCARD_ATTR_CURRENT_W SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0206)
+#define SCARD_ATTR_CURRENT_IFSC SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0207)
+#define SCARD_ATTR_CURRENT_IFSD SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0208)
+#define SCARD_ATTR_CURRENT_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x0209)
+#define SCARD_ATTR_CURRENT_CWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020a)
+#define SCARD_ATTR_CURRENT_EBC_ENCODING SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020b)
+#define SCARD_ATTR_EXTENDED_BWT SCARD_ATTR_VALUE(SCARD_CLASS_IFD_PROTOCOL, 0x020c)
+
+#define SCARD_ATTR_ICC_PRESENCE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0300)
+#define SCARD_ATTR_ICC_INTERFACE_STATUS SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0301)
+#define SCARD_ATTR_CURRENT_IO_STATE SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0302)
+#define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303)
+#define SCARD_ATTR_ICC_TYPE_PER_ATR SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0304)
+
+#define SCARD_ATTR_ESC_RESET SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA000)
+#define SCARD_ATTR_ESC_CANCEL SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA003)
+#define SCARD_ATTR_ESC_AUTHREQUEST SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA005)
+#define SCARD_ATTR_MAXINPUT SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA007)
+
+#define SCARD_ATTR_DEVICE_UNIT SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0001)
+#define SCARD_ATTR_DEVICE_IN_USE SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0002)
+#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003)
+#define SCARD_ATTR_DEVICE_SYSTEM_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0004)
+#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0005)
+#define SCARD_ATTR_DEVICE_SYSTEM_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0006)
+#define SCARD_ATTR_SUPRESS_T1_IFS_REQUEST SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0007)
+
+
+#define SCARD_ATTR_DEVICE_FRIENDLY_NAME 	WINELIB_NAME_AW(SCARD_ATTR_DEVICE_FRIENDLY_NAME_)
+#define SCARD_ATTR_DEVICE_SYSTEM_NAME 		WINELIB_NAME_AW(SCARD_ATTR_DEVICE_SYSTEM_NAME_)
+
+typedef long SCARDCONTEXT;
+typedef SCARDCONTEXT *PSCARDCONTEXT;
+typedef SCARDCONTEXT *LPSCARDCONTEXT;
+typedef long SCARDHANDLE;
+typedef SCARDHANDLE *PSCARDHANDLE;
+typedef SCARDHANDLE *LPSCARDHANDLE;
+
+typedef struct
+{
+	LPCSTR szReader;
+	void *pvUserData;
+	unsigned long dwCurrentState;
+	unsigned long dwEventState;
+	unsigned long cbAtr;
+	unsigned char rgbAtr[MAX_ATR_SIZE];
+}
+SCARD_READERSTATEA;
+
+typedef struct
+{
+	LPCWSTR szReader;
+	void *pvUserData;
+	unsigned long dwCurrentState;
+	unsigned long dwEventState;
+	unsigned long cbAtr;
+	unsigned char rgbAtr[MAX_ATR_SIZE];
+}
+SCARD_READERSTATEW;
+
+typedef SCARD_READERSTATEA  *PSCARD_READERSTATEA,	*LPSCARD_READERSTATEA;
+
+typedef SCARD_READERSTATEW  *PSCARD_READERSTATEW,	*LPSCARD_READERSTATEW;
+
+DECL_WINELIB_TYPE_AW(SCARD_READERSTATE)
+DECL_WINELIB_TYPE_AW(PSCARD_READERSTATE)
+DECL_WINELIB_TYPE_AW(LPSCARD_READERSTATE)
+	
+// Backwards compatibility macros
+#define SCARD_READERSTATE_A SCARD_READERSTATEA
+#define SCARD_READERSTATE_W SCARD_READERSTATEW
+#define PSCARD_READERSTATE_A PSCARD_READERSTATEA
+#define PSCARD_READERSTATE_W PSCARD_READERSTATEW
+#define LPSCARD_READERSTATE_A LPSCARD_READERSTATEA
+#define LPSCARD_READERSTATE_W LPSCARD_READERSTATEW
+	
+typedef struct _SCARD_IO_REQUEST
+{
+	unsigned long dwProtocol;	/* Protocol identifier */
+	unsigned long cbPciLength;	/* Protocol Control Inf Length */
+}
+SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
+
+typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST;
+
+typedef struct _SCARD_ATRMASK {
+    DWORD       cbAtr;          // Number of bytes in the ATR and the mask.
+    BYTE        rgbAtr[36];     // Atr of card (extra alignment bytes)
+    BYTE        rgbMask[36];    // Mask for the Atr (extra alignment bytes)
+} SCARD_ATRMASK, *PSCARD_ATRMASK, *LPSCARD_ATRMASK;
+
+
+#endif
+
-- 
1.4.4.2


More information about the wine-devel mailing list