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