Skip to content

Instantly share code, notes, and snippets.

@roman-yepishev
Created December 17, 2011 09:28
Show Gist options
  • Save roman-yepishev/1489786 to your computer and use it in GitHub Desktop.
Save roman-yepishev/1489786 to your computer and use it in GitHub Desktop.
Patch for wine1.3-1.3.28 (Ubuntu Oneiric) winscard
## 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