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
From d0a45c9347a4462b56e6deac0bcf1b37a815f541 Mon Sep 17 00:00:00 2001
From: Mounir IDRASSI mounir.idrassi@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 + +@MAKE_DLL_RULES@ + +@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@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@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@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@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@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 +