Created
December 17, 2011 09:28
-
-
Save roman-yepishev/1489786 to your computer and use it in GitHub Desktop.
Patch for wine1.3-1.3.28 (Ubuntu Oneiric) winscard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Description: Partial but functional implementation of winscard | |
## Author: Vincent Hardy [email protected] | |
## Origin: http://www.winehq.org/pipermail/wine-devel/2011-September/092627.html | |
Index: wine1.3-1.3.28/configure | |
=================================================================== | |
--- wine1.3-1.3.28.orig/configure 2011-09-09 20:43:48.000000000 +0300 | |
+++ wine1.3-1.3.28/configure 2011-12-18 16:31:46.000000000 +0200 | |
@@ -11767,6 +11767,60 @@ | |
fi | |
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -lpcsclite" >&5 | |
+$as_echo_n "checking for -lpcsclite... " >&6; } | |
+if ${ac_cv_lib_soname_pcsclite+:} false; then : | |
+ $as_echo_n "(cached) " >&6 | |
+else | |
+ ac_check_soname_save_LIBS=$LIBS | |
+LIBS="-lpcsclite $LIBS" | |
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
+/* end confdefs.h. */ | |
+ | |
+/* Override any GCC internal prototype to avoid an error. | |
+ Use char because int might match the return type of a GCC | |
+ builtin and then its argument prototype would still apply. */ | |
+#ifdef __cplusplus | |
+extern "C" | |
+#endif | |
+char SCardEstablishContext (); | |
+int | |
+main () | |
+{ | |
+return SCardEstablishContext (); | |
+ ; | |
+ return 0; | |
+} | |
+_ACEOF | |
+if ac_fn_c_try_link "$LINENO"; then : | |
+ case "$LIBEXT" in | |
+ dll) ac_cv_lib_soname_pcsclite=`$ac_cv_path_LDD conftest.exe | grep "pcsclite" | sed -e "s/dll.*/dll/"';2,$d'` ;; | |
+ dylib) ac_cv_lib_soname_pcsclite=`otool -L conftest$ac_exeext | grep "libpcsclite\\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*\/\(libpcsclite\.[0-9A-Za-z.]*dylib\).*$/\1/"';2,$d'` ;; | |
+ *) ac_cv_lib_soname_pcsclite=`$ac_cv_path_LDD conftest$ac_exeext | grep "libpcsclite\\.$LIBEXT" | sed -e "s/^.*\(libpcsclite\.$LIBEXT[^ ]*\).*$/\1/"';2,$d'` ;; | |
+ esac | |
+fi | |
+rm -f core conftest.err conftest.$ac_objext \ | |
+ conftest$ac_exeext conftest.$ac_ext | |
+ LIBS=$ac_check_soname_save_LIBS | |
+fi | |
+if test "x$ac_cv_lib_soname_pcsclite" = "x"; then : | |
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 | |
+$as_echo "not found" >&6; } | |
+ cat >>confdefs.h <<_ACEOF | |
+#define SONAME_LIBPCSCLITE "libpcsclite.$LIBEXT" | |
+_ACEOF | |
+ | |
+else | |
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_soname_pcsclite" >&5 | |
+$as_echo "$ac_cv_lib_soname_pcsclite" >&6; } | |
+ | |
+cat >>confdefs.h <<_ACEOF | |
+#define SONAME_LIBPCSCLITE "$ac_cv_lib_soname_pcsclite" | |
+_ACEOF | |
+ | |
+ | |
+fi | |
+ | |
test -n "$ALSALIBS" || enable_winealsa_drv=${enable_winealsa_drv:-no} | |
test -n "$COREAUDIO" || enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no} | |
test "x$ac_cv_member_oss_sysinfo_numaudioengines" = xyes || enable_wineoss_drv=${enable_wineoss_drv:-no} | |
Index: wine1.3-1.3.28/configure.ac | |
=================================================================== | |
--- wine1.3-1.3.28.orig/configure.ac 2011-09-09 20:43:48.000000000 +0300 | |
+++ wine1.3-1.3.28/configure.ac 2011-12-18 16:31:46.000000000 +0200 | |
@@ -1643,6 +1643,9 @@ | |
dnl **** Check for libodbc **** | |
WINE_CHECK_SONAME(odbc,SQLConnect,,[AC_DEFINE_UNQUOTED(SONAME_LIBODBC,["libodbc.$LIBEXT"])]) | |
+dnl **** Check for libpcsclite **** | |
+WINE_CHECK_SONAME(pcsclite,SCardEstablishContext,,[AC_DEFINE_UNQUOTED(SONAME_LIBPCSCLITE,["libpcsclite.$LIBEXT"])]) | |
+ | |
dnl **** Disable unsupported winmm drivers **** | |
test -n "$ALSALIBS" || enable_winealsa_drv=${enable_winealsa_drv:-no} | |
test -n "$COREAUDIO" || enable_winecoreaudio_drv=${enable_winecoreaudio_drv:-no} | |
Index: wine1.3-1.3.28/dlls/winscard/winscard.c | |
=================================================================== | |
--- wine1.3-1.3.28.orig/dlls/winscard/winscard.c 2011-09-09 20:43:48.000000000 +0300 | |
+++ wine1.3-1.3.28/dlls/winscard/winscard.c 2011-12-18 16:47:37.032350762 +0200 | |
@@ -17,16 +17,37 @@ | |
*/ | |
#include "config.h" | |
+#include "wine/port.h" | |
#include <stdarg.h> | |
#include "windef.h" | |
#include "winbase.h" | |
#include "wine/debug.h" | |
+#include "wine/library.h" | |
#include "winscard.h" | |
#include "winternl.h" | |
+static BOOL PCSCLite_loadlib(void); | |
+static void PCSCLite_loadfunctions(void); | |
+ | |
WINE_DEFAULT_DEBUG_CHANNEL(winscard); | |
+static LONG (*pSCardEstablishContext)(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext); | |
+static LONG (*pSCardIsValidContext)(SCARDCONTEXT hContext); | |
+static LONG (*pSCardReleaseContext)(SCARDCONTEXT hContext); | |
+static LONG (*pSCardListReaders)(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders); | |
+static LONG (*pSCardCancel)(SCARDCONTEXT hContext); | |
+static LONG (*pSCardGetStatusChange)(SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders); | |
+static LONG (*pSCardStatus)(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, BYTE* pbAtr, LPDWORD pcbAtrLen); | |
+static LONG (*pSCardGetAttrib)(SCARDHANDLE hCard, DWORD dwAttrId, BYTE* pbAttr, LPDWORD pcbAttrLen); | |
+static LONG (*pSCardConnect)(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol); | |
+static LONG (*pSCardDisconnect)(SCARDHANDLE hCard, DWORD dwDisposition); | |
+static LONG (*pSCardReconnect)(SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol); | |
+static LONG (*pSCardBeginTransaction)(SCARDHANDLE hCard); | |
+static LONG (*pSCardTransmit)(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, const BYTE* pbSendBuffer, DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, BYTE* pbRecvBuffer, LPDWORD pcbRecvLength); | |
+static LONG (*pSCardEndTransaction)(SCARDHANDLE hCard, DWORD disposition); | |
+ | |
static HMODULE WINSCARD_hModule; | |
+static void *g_pcscliteHandle; | |
static HANDLE g_startedEvent = NULL; | |
const SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 }; | |
@@ -44,6 +65,10 @@ | |
{ | |
DisableThreadLibraryCalls(hinstDLL); | |
WINSCARD_hModule = hinstDLL; | |
+ | |
+ if (PCSCLite_loadlib()) | |
+ PCSCLite_loadfunctions(); | |
+ | |
/* FIXME: for now, we act as if the pcsc daemon is always started */ | |
g_startedEvent = CreateEventA(NULL,TRUE,TRUE,NULL); | |
break; | |
@@ -51,6 +76,10 @@ | |
case DLL_PROCESS_DETACH: | |
{ | |
CloseHandle(g_startedEvent); | |
+ | |
+ if (g_pcscliteHandle) | |
+ wine_dlclose(g_pcscliteHandle, NULL, 0); | |
+ | |
break; | |
} | |
} | |
@@ -58,6 +87,65 @@ | |
return TRUE; | |
} | |
+static BOOL PCSCLite_loadlib(void) | |
+{ | |
+ char error[256]; | |
+ | |
+ g_pcscliteHandle = wine_dlopen(SONAME_LIBPCSCLITE, RTLD_LAZY | RTLD_GLOBAL, error, sizeof(error)); | |
+ if (g_pcscliteHandle) | |
+ return TRUE; | |
+ else | |
+ { | |
+ WARN("Failed to open library %s : %s\n", debugstr_a(SONAME_LIBPCSCLITE), error); | |
+ return FALSE; | |
+ } | |
+} | |
+ | |
+static void PCSCLite_loadfunctions(void) | |
+{ | |
+ char error[256]; | |
+ | |
+#define LOAD_FUNC(name) \ | |
+ if ((p##name = wine_dlsym(g_pcscliteHandle,#name, error, sizeof(error) ))); \ | |
+ else WARN( "Failed to load %s: %s\n", #name, error ) | |
+ | |
+ LOAD_FUNC(SCardIsValidContext); | |
+ LOAD_FUNC(SCardEstablishContext); | |
+ LOAD_FUNC(SCardReleaseContext); | |
+ LOAD_FUNC(SCardListReaders); | |
+ LOAD_FUNC(SCardCancel); | |
+ LOAD_FUNC(SCardGetStatusChange); | |
+ LOAD_FUNC(SCardStatus); | |
+ LOAD_FUNC(SCardGetAttrib); | |
+ LOAD_FUNC(SCardConnect); | |
+ LOAD_FUNC(SCardDisconnect); | |
+ LOAD_FUNC(SCardReconnect); | |
+ LOAD_FUNC(SCardBeginTransaction); | |
+ LOAD_FUNC(SCardTransmit); | |
+ LOAD_FUNC(SCardEndTransaction); | |
+ | |
+#undef LOAD_FUNC | |
+} | |
+ | |
+/* | |
+ * translate PCSC-lite errors to equivalent MS ones | |
+ * Actually, the only difference is for SCARD_W_INSERTED_CARD(0x8010006A) and | |
+ * SCARD_E_UNSUPPORTED_FEATURE (0x8010001F) | |
+ */ | |
+ | |
+#define PCSCLITE_SCARD_W_INSERTED_CARD 0x8010006A | |
+#define PCSCLITE_SCARD_E_UNSUPPORTED_FEATURE 0x8010001F | |
+ | |
+static LONG TranslateToWin32(LONG retval) | |
+{ | |
+ if (retval == PCSCLITE_SCARD_E_UNSUPPORTED_FEATURE) | |
+ return SCARD_E_UNSUPPORTED_FEATURE; | |
+ else if (retval == PCSCLITE_SCARD_W_INSERTED_CARD) | |
+ return SCARD_F_UNKNOWN_ERROR; /* FIXME : is there a better WIN32 error code */ | |
+ else | |
+ return retval; | |
+} | |
+ | |
HANDLE WINAPI SCardAccessStartedEvent(void) | |
{ | |
return g_startedEvent; | |
@@ -90,14 +178,271 @@ | |
LONG WINAPI SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, | |
LPCVOID pvReserved2, LPSCARDCONTEXT phContext) | |
{ | |
- FIXME("(%x,%p,%p,%p) stub\n", dwScope, pvReserved1, pvReserved2, phContext); | |
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
- return SCARD_F_INTERNAL_ERROR; | |
+ LONG retval; | |
+ | |
+ TRACE(" %x %p %p %p\n", dwScope, pvReserved1, pvReserved2, phContext); | |
+ if (!phContext) | |
+ retval = SCARD_E_INVALID_PARAMETER; | |
+ else if (!pSCardEstablishContext) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ retval = pSCardEstablishContext(dwScope, pvReserved1, pvReserved2, phContext); | |
+ | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ | |
+ return TranslateToWin32(retval); | |
} | |
LONG WINAPI SCardIsValidContext(SCARDCONTEXT context) | |
{ | |
- FIXME("(%lx) stub\n", context); | |
+ TRACE(" %lx\n", context); | |
+ | |
+ if (!pSCardIsValidContext) | |
+ return SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ return TranslateToWin32(pSCardIsValidContext(context)); | |
+} | |
+ | |
+LONG WINAPI SCardListReadersA(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) | |
+{ | |
+ LONG retval; | |
+ LPSTR* pmszReaders; | |
+ LPSTR szList = NULL; | |
+ DWORD ListLength = 0; | |
+ | |
+ TRACE(" %lx %p %p %p\n", hContext, mszGroups, mszReaders, pcchReaders); | |
+ | |
+ if (!pcchReaders) | |
+ retval = SCARD_E_INVALID_PARAMETER; | |
+ else if (!pSCardListReaders) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else if (mszReaders && *pcchReaders == SCARD_AUTOALLOCATE) | |
+ { | |
+ /* get list from pcsc-lite */ | |
+ pmszReaders = (LPSTR*) mszReaders; | |
+ | |
+ retval = pSCardListReaders(hContext, mszGroups, NULL, &ListLength); | |
+ if (retval != SCARD_S_SUCCESS && retval != SCARD_E_INSUFFICIENT_BUFFER) | |
+ goto out; | |
+ | |
+ szList = HeapAlloc(GetProcessHeap(), 0, ListLength); | |
+ | |
+ if (!szList) | |
+ { | |
+ retval = SCARD_E_NO_MEMORY; | |
+ goto out; | |
+ } | |
+ | |
+ retval = pSCardListReaders(hContext, mszGroups, szList, &ListLength); | |
+ if (SCARD_S_SUCCESS != retval) | |
+ HeapFree(GetProcessHeap(), 0, szList); | |
+ else | |
+ { | |
+ *pmszReaders = szList; | |
+ *pcchReaders = ListLength; | |
+ } | |
+ } | |
+ else | |
+ retval = pSCardListReaders(hContext, mszGroups, mszReaders, pcchReaders); | |
+ | |
+out: | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardGetStatusChangeA(SCARDCONTEXT hContext, DWORD Timeout, LPSCARD_READERSTATEA rgReaderStates, DWORD cReaders) | |
+{ | |
+ LONG retval; | |
+ LPSCARD_READERSTATEA pStates; | |
+ DWORD State; | |
+ BOOL StateChanges; | |
+ DWORD i; | |
+ | |
+ TRACE(" %lx %x %p %x\n", hContext, Timeout, rgReaderStates, cReaders); | |
+ | |
+ if (!pSCardGetStatusChange) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else if (!rgReaderStates && cReaders) | |
+ retval = SCARD_E_INVALID_PARAMETER; | |
+ else if (!cReaders) | |
+ { | |
+ if (pSCardIsValidContext) | |
+ retval = pSCardIsValidContext(hContext); | |
+ else | |
+ retval = 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 (Timeout == 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 otherwise | |
+ */ | |
+ | |
+ pStates = HeapAlloc(GetProcessHeap(), 0, cReaders * sizeof(SCARD_READERSTATEA)); | |
+ | |
+ memset(pStates, 0, cReaders * sizeof(SCARD_READERSTATEA)); | |
+ for (i = 0; i < cReaders; i++) | |
+ pStates[i].szReader = rgReaderStates[i].szReader; | |
+ | |
+ retval = pSCardGetStatusChange(hContext, 0, pStates, cReaders); | |
+ if (retval == SCARD_S_SUCCESS) | |
+ { | |
+ StateChanges = FALSE; | |
+ for (i = 0; i < cReaders; i++) | |
+ { | |
+ State = pStates[i].dwEventState & (~SCARD_STATE_CHANGED); | |
+ rgReaderStates[i].cbAtr = pStates[i].cbAtr; | |
+ memcpy(rgReaderStates[i].rgbAtr, pStates[i].rgbAtr, MAX_ATR_SIZE); | |
+ | |
+ if (State != rgReaderStates[i].dwCurrentState) | |
+ { | |
+ rgReaderStates[i].dwEventState = pStates[i].dwEventState; | |
+ StateChanges = TRUE; | |
+ } | |
+ else | |
+ rgReaderStates[i].dwEventState = State; | |
+ } | |
+ if (!StateChanges) | |
+ retval = SCARD_E_TIMEOUT; | |
+ } | |
+ | |
+ HeapFree(GetProcessHeap(), 0, pStates); | |
+ } | |
+ else | |
+ retval = pSCardGetStatusChange(hContext, Timeout, rgReaderStates, cReaders); | |
+ } | |
+ | |
+ TRACE(" returned 0x%08x\n",retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardStatusA(SCARDHANDLE hCard, LPSTR mszReaderNames, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) | |
+{ | |
+ LONG retval; | |
+ BOOL HasAutoAllocated = FALSE; | |
+ DWORD dwNameLen = 0, dwAtrLen = MAX_ATR_SIZE; | |
+ BYTE atr[MAX_ATR_SIZE]; | |
+ LPSTR szNames = NULL; | |
+ LPBYTE* ppbAtr; | |
+ LPSTR* pmszReaderNames; | |
+ | |
+ TRACE(" %lx %p %p %p %p %p %p\n", hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen); | |
+ | |
+ if (!pcchReaderLen || !pdwState || !pdwProtocol || !pcbAtrLen) | |
+ retval = SCARD_E_INVALID_PARAMETER; | |
+ else if (!pSCardStatus) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ { | |
+ if (!mszReaderNames || !pbAtr || (*pcchReaderLen == SCARD_AUTOALLOCATE) || (*pcbAtrLen == SCARD_AUTOALLOCATE)) | |
+ { | |
+ TRACE("Retrieve the information from pcsc-lite\n"); | |
+ retval = pSCardStatus(hCard, NULL, &dwNameLen, pdwState, pdwProtocol, atr, &dwAtrLen); | |
+ if (retval != SCARD_S_SUCCESS && retval != SCARD_E_INSUFFICIENT_BUFFER) | |
+ goto out; | |
+ | |
+ /* case 1: asking for reader names length */ | |
+ if (!mszReaderNames) | |
+ { | |
+ TRACE("Asking for reader names length\n"); | |
+ retval = SCARD_S_SUCCESS; | |
+ *pcchReaderLen = dwNameLen; | |
+ if (!pbAtr) | |
+ *pcbAtrLen = dwAtrLen; | |
+ else if (*pcbAtrLen == SCARD_AUTOALLOCATE) | |
+ { | |
+ ppbAtr = (LPBYTE*) pbAtr; | |
+ *ppbAtr = HeapAlloc(GetProcessHeap(), 0, dwAtrLen); | |
+ *pcbAtrLen = dwAtrLen; | |
+ memcpy(*ppbAtr, atr, dwAtrLen); | |
+ } | |
+ else if (*pcbAtrLen < dwAtrLen) | |
+ { | |
+ *pcbAtrLen = dwAtrLen; | |
+ retval = SCARD_E_INSUFFICIENT_BUFFER; | |
+ } | |
+ else | |
+ { | |
+ *pcbAtrLen = dwAtrLen; | |
+ memcpy(pbAtr, atr, dwAtrLen); | |
+ } | |
+ goto out; | |
+ } | |
+ | |
+ /* case 2: reader names pointer provided but its length is unsufficient */ | |
+ if (*pcchReaderLen < dwNameLen) | |
+ { | |
+ *pcchReaderLen = dwNameLen; | |
+ retval = SCARD_E_INSUFFICIENT_BUFFER; | |
+ goto out; | |
+ } | |
+ | |
+ HasAutoAllocated = (*pcchReaderLen == SCARD_AUTOALLOCATE)? TRUE : FALSE; | |
+ if (HasAutoAllocated) | |
+ szNames = HeapAlloc(GetProcessHeap(), 0, dwNameLen); | |
+ else | |
+ szNames = mszReaderNames; | |
+ | |
+ retval = pSCardStatus(hCard, szNames, &dwNameLen, pdwState, pdwProtocol, atr, &dwAtrLen); | |
+ if (retval != SCARD_S_SUCCESS) | |
+ { | |
+ if (HasAutoAllocated) | |
+ HeapFree(GetProcessHeap(), 0, szNames); | |
+ goto out; | |
+ } | |
+ | |
+ *pcchReaderLen = dwNameLen; | |
+ if (HasAutoAllocated) | |
+ { | |
+ pmszReaderNames = (LPSTR*) mszReaderNames; | |
+ *pmszReaderNames = szNames; | |
+ szNames = NULL; | |
+ } | |
+ | |
+ TRACE("Fill the ATR parameter\n"); | |
+ | |
+ if (!pbAtr) | |
+ *pcbAtrLen = dwAtrLen; | |
+ else if (*pcbAtrLen == SCARD_AUTOALLOCATE) | |
+ { | |
+ ppbAtr = (LPBYTE*) pbAtr; | |
+ *ppbAtr = HeapAlloc(GetProcessHeap(), 0, dwAtrLen); | |
+ *pcbAtrLen = dwAtrLen; | |
+ memcpy(*ppbAtr, atr, dwAtrLen); | |
+ } | |
+ else if (*pcbAtrLen < dwAtrLen) | |
+ { | |
+ *pcbAtrLen = dwAtrLen; | |
+ retval = SCARD_E_INSUFFICIENT_BUFFER; | |
+ } | |
+ else | |
+ { | |
+ *pcbAtrLen = dwAtrLen; | |
+ memcpy(pbAtr, atr, dwAtrLen); | |
+ } | |
+ | |
+ if (HasAutoAllocated && szNames) | |
+ HeapFree(GetProcessHeap(), 0, szNames); | |
+ } | |
+ else | |
+ retval = pSCardStatus(hCard, mszReaderNames, pcchReaderLen, pdwState, pdwProtocol, pbAtr, pcbAtrLen); | |
+ } | |
+ | |
+out: | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) | |
+{ | |
+ FIXME(": stub\n"); | |
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
return SCARD_F_INTERNAL_ERROR; | |
} | |
@@ -111,9 +456,173 @@ | |
LONG WINAPI SCardReleaseContext(SCARDCONTEXT context) | |
{ | |
- FIXME("(%lx) stub\n", context); | |
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED); | |
- return SCARD_F_INTERNAL_ERROR; | |
+ LONG retval; | |
+ | |
+ TRACE(" %lx\n", context); | |
+ if (!pSCardReleaseContext) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ retval = pSCardReleaseContext(context); | |
+ | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+ | |
+#define PCSCLITE_SCARD_PROTOCOL_RAW 0x00000004 | |
+ | |
+LONG WINAPI SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) | |
+{ | |
+ LONG retval; | |
+ | |
+ TRACE(" %lx %s 0x%08X 0x%08X %p %p\n", hContext, debugstr_a(szReader), dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol); | |
+ | |
+ if (!szReader || !phCard || !pdwActiveProtocol) | |
+ retval = SCARD_E_INVALID_PARAMETER; | |
+ else if (!pSCardConnect) | |
+ retval = 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; | |
+ } | |
+ | |
+ retval = pSCardConnect(hContext, szReader, dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol); | |
+ if (retval == SCARD_S_SUCCESS) | |
+ { | |
+ /* 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", retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) | |
+{ | |
+ LONG retval; | |
+ | |
+ TRACE(" %lx 0x%08x\n", hCard, dwDisposition); | |
+ | |
+ if (!pSCardDisconnect) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ retval = pSCardDisconnect(hCard, dwDisposition); | |
+ | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol) | |
+{ | |
+ LONG retval; | |
+ | |
+ TRACE(" %lx 0x%08X 0x%08X 0x%08X %p\n", hCard, dwShareMode, dwPreferredProtocols, dwInitialization, pdwActiveProtocol); | |
+ | |
+ if (!pSCardReconnect) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ retval = pSCardReconnect(hCard, dwShareMode, dwPreferredProtocols, dwInitialization, pdwActiveProtocol); | |
+ | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardBeginTransaction(SCARDHANDLE hCard) | |
+{ | |
+ LONG retval; | |
+ | |
+ TRACE(" %lx\n", hCard); | |
+ | |
+ if (!pSCardBeginTransaction) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ retval = pSCardBeginTransaction(hCard); | |
+ | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardTransmit(SCARDHANDLE hCard, | |
+ LPCSCARD_IO_REQUEST pioSendPci, | |
+ const BYTE* pbSendBuffer, | |
+ DWORD cbSendLength, | |
+ LPSCARD_IO_REQUEST pioRecvPci, | |
+ LPBYTE pbRecvBuffer, | |
+ LPDWORD pcbRecvLength) | |
+{ | |
+ LONG retval; | |
+ DWORD protocol, State; | |
+ DWORD AtrLen, NameLen; | |
+ | |
+ TRACE(" %lx\n", hCard); | |
+ | |
+ if (!pSCardTransmit) | |
+ retval = 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*/ | |
+ TRACE(" Get card protocol\n"); | |
+ | |
+ retval = SCardStatusA(hCard, NULL, &NameLen, &State, &protocol, NULL, &AtrLen); | |
+ if (retval == 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; | |
+ } | |
+ } | |
+ | |
+ retval = pSCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength, pioRecvPci, pbRecvBuffer, pcbRecvLength); | |
+ } | |
+ | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardCancel(SCARDCONTEXT hContext) | |
+{ | |
+ LONG retval; | |
+ | |
+ TRACE(" %lx\n", hContext); | |
+ if (!pSCardCancel) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ retval = pSCardCancel(hContext); | |
+ | |
+ TRACE(" returned 0x%08x\n",retval); | |
+ return TranslateToWin32(retval); | |
+} | |
+ | |
+LONG WINAPI SCardEndTransaction(SCARDHANDLE hCard, DWORD disposition) | |
+{ | |
+ LONG retval; | |
+ | |
+ TRACE(" %lx 0x%08x\n", hCard, disposition); | |
+ | |
+ if (!pSCardEndTransaction) | |
+ retval = SCARD_F_INTERNAL_ERROR; | |
+ else | |
+ retval = pSCardEndTransaction(hCard, disposition); | |
+ | |
+ TRACE(" returned 0x%08x\n", retval); | |
+ return TranslateToWin32(retval); | |
} | |
void WINAPI SCardReleaseStartedEvent(void) | |
Index: wine1.3-1.3.28/dlls/winscard/winscard.spec | |
=================================================================== | |
--- wine1.3-1.3.28.orig/dlls/winscard/winscard.spec 2011-09-09 20:43:48.000000000 +0300 | |
+++ wine1.3-1.3.28/dlls/winscard/winscard.spec 2011-12-18 16:34:55.331945435 +0200 | |
@@ -5,13 +5,14 @@ | |
@ stdcall SCardAccessStartedEvent() | |
@ stdcall SCardAddReaderToGroupA(long str str) | |
@ stdcall SCardAddReaderToGroupW(long wstr wstr) | |
-@ stub SCardBeginTransaction | |
-@ stub SCardCancel | |
-@ stub SCardConnectA | |
+@ stdcall SCardBeginTransaction(long) | |
+@ stdcall SCardCancel(long) | |
+@ stdcall SCardConnectA(long str long long ptr ptr) | |
@ stub SCardConnectW | |
@ stub SCardControl | |
-@ stub SCardDisconnect | |
-@ stub SCardEndTransaction | |
+@ stdcall SCardDisconnect(long long) | |
+@ stdcall SCardReconnect(long long long long ptr) | |
+@ stdcall SCardEndTransaction(long long) | |
@ stdcall SCardEstablishContext(long ptr ptr ptr) | |
@ stub SCardForgetCardTypeA | |
@ stub SCardForgetCardTypeW | |
@@ -20,12 +21,12 @@ | |
@ stub SCardForgetReaderGroupW | |
@ stub SCardForgetReaderW | |
@ stub SCardFreeMemory | |
-@ stub SCardGetAttrib | |
+@ stdcall SCardGetAttrib(long long ptr ptr) | |
@ stub SCardGetCardTypeProviderNameA | |
@ stub SCardGetCardTypeProviderNameW | |
@ stub SCardGetProviderIdA | |
@ stub SCardGetProviderIdW | |
-@ stub SCardGetStatusChangeA | |
+@ stdcall SCardGetStatusChangeA(long long ptr long) | |
@ stub SCardGetStatusChangeW | |
@ stub SCardIntroduceCardTypeA | |
@ stub SCardIntroduceCardTypeW | |
@@ -40,13 +41,12 @@ | |
@ stub SCardListInterfacesW | |
@ stub SCardListReaderGroupsA | |
@ stub SCardListReaderGroupsW | |
-@ stub SCardListReadersA | |
+@ stdcall SCardListReadersA(long str str ptr) | |
@ stub SCardListReadersW | |
@ stub SCardLocateCardsA | |
@ stub SCardLocateCardsByATRA | |
@ stub SCardLocateCardsByATRW | |
@ stub SCardLocateCardsW | |
-@ stub SCardReconnect | |
@ stdcall SCardReleaseContext(long) | |
@ stdcall SCardReleaseStartedEvent() | |
@ stub SCardRemoveReaderFromGroupA | |
@@ -55,9 +55,9 @@ | |
@ stub SCardSetCardTypeProviderNameA | |
@ stub SCardSetCardTypeProviderNameW | |
@ stub SCardState | |
-@ stub SCardStatusA | |
+@ stdcall SCardStatusA(long str ptr ptr ptr ptr ptr) | |
@ stub SCardStatusW | |
-@ stub SCardTransmit | |
+@ stdcall SCardTransmit(long ptr ptr long ptr ptr ptr) | |
@ extern g_rgSCardRawPci | |
@ extern g_rgSCardT0Pci | |
@ extern g_rgSCardT1Pci | |
Index: wine1.3-1.3.28/include/config.h.in | |
=================================================================== | |
--- wine1.3-1.3.28.orig/include/config.h.in 2011-09-09 20:43:48.000000000 +0300 | |
+++ wine1.3-1.3.28/include/config.h.in 2011-12-18 16:31:46.000000000 +0200 | |
@@ -1289,6 +1289,9 @@ | |
/* Define to the soname of the libXxf86vm library. */ | |
#undef SONAME_LIBXXF86VM | |
+/* Define to the soname of the libpcsclite library. */ | |
+#undef SONAME_LIBPCSCLITE | |
+ | |
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */ | |
#undef STAT_MACROS_BROKEN | |
Index: wine1.3-1.3.28/include/winscard.h | |
=================================================================== | |
--- wine1.3-1.3.28.orig/include/winscard.h 2011-09-09 20:43:48.000000000 +0300 | |
+++ wine1.3-1.3.28/include/winscard.h 2011-12-18 16:31:46.000000000 +0200 | |
@@ -61,6 +61,9 @@ | |
DECL_WINELIB_TYPE_AW(PSCARD_READERSTATE) | |
DECL_WINELIB_TYPE_AW(LPSCARD_READERSTATE) | |
+#define SCARD_PCI_T0 (&g_rgSCardT0Pci) | |
+#define SCARD_PCI_T1 (&g_rgSCardT1Pci) | |
+#define SCARD_PCI_RAW (&g_rgSCardRawPci) | |
#ifdef __cplusplus | |
extern "C" { | |
Index: wine1.3-1.3.28/include/winsmcrd.h | |
=================================================================== | |
--- wine1.3-1.3.28.orig/include/winsmcrd.h 2011-09-09 20:43:48.000000000 +0300 | |
+++ wine1.3-1.3.28/include/winsmcrd.h 2011-12-18 16:31:46.000000000 +0200 | |
@@ -27,6 +27,12 @@ | |
#define SCARD_PROTOCOL_DEFAULT 0x80000000 | |
#define SCARD_PROTOCOL_Tx (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) | |
+#define MAX_ATR_SIZE 36 /**< Maximum ATR size */ | |
+ | |
+#define SCARD_AUTOALLOCATE (DWORD)(-1) | |
+ | |
+#define SCARD_STATE_CHANGED 0x0002 /**< State has changed */ | |
+ | |
typedef struct _SCARD_IO_REQUEST | |
{ | |
DWORD dwProtocol; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment