Commit 8490c43f authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

winscard: Implement SCardEstablish/ReleaseContext() on top of libpcsclite.

parent 21059660
...@@ -700,6 +700,7 @@ DBUS_LIBS ...@@ -700,6 +700,7 @@ DBUS_LIBS
DBUS_CFLAGS DBUS_CFLAGS
INOTIFY_LIBS INOTIFY_LIBS
INOTIFY_CFLAGS INOTIFY_CFLAGS
PCSCLITE_LIBS
PCAP_LIBS PCAP_LIBS
X_EXTRA_LIBS X_EXTRA_LIBS
X_LIBS X_LIBS
...@@ -928,6 +929,7 @@ with_opengl ...@@ -928,6 +929,7 @@ with_opengl
with_osmesa with_osmesa
with_oss with_oss
with_pcap with_pcap
with_pcsclite
with_pthread with_pthread
with_pulse with_pulse
with_sane with_sane
...@@ -2445,6 +2447,7 @@ Optional Packages: ...@@ -2445,6 +2447,7 @@ Optional Packages:
--without-osmesa do not use the OSMesa library --without-osmesa do not use the OSMesa library
--without-oss do not use the OSS sound support --without-oss do not use the OSS sound support
--without-pcap do not use the Packet Capture library --without-pcap do not use the Packet Capture library
--without-pcsclite do not use PCSC lite
--without-pthread do not use the pthread library --without-pthread do not use the pthread library
--without-pulse do not use PulseAudio sound support --without-pulse do not use PulseAudio sound support
--without-sane do not use SANE (scanner support) --without-sane do not use SANE (scanner support)
...@@ -4308,6 +4311,13 @@ then : ...@@ -4308,6 +4311,13 @@ then :
fi fi
# Check whether --with-pcsclite was given.
if test ${with_pcsclite+y}
then :
withval=$with_pcsclite;
fi
# Check whether --with-pthread was given. # Check whether --with-pthread was given.
if test ${with_pthread+y} if test ${with_pthread+y}
then : then :
...@@ -5864,11 +5874,11 @@ if test x$ac_prog_cxx_stdcxx = xno ...@@ -5864,11 +5874,11 @@ if test x$ac_prog_cxx_stdcxx = xno
then : then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5
printf %s "checking for $CXX option to enable C++11 features... " >&6; } printf %s "checking for $CXX option to enable C++11 features... " >&6; }
if test ${ac_cv_prog_cxx_11+y} if test ${ac_cv_prog_cxx_cxx11+y}
then : then :
printf %s "(cached) " >&6 printf %s "(cached) " >&6
else $as_nop else $as_nop
ac_cv_prog_cxx_11=no ac_cv_prog_cxx_cxx11=no
ac_save_CXX=$CXX ac_save_CXX=$CXX
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
...@@ -5910,11 +5920,11 @@ if test x$ac_prog_cxx_stdcxx = xno ...@@ -5910,11 +5920,11 @@ if test x$ac_prog_cxx_stdcxx = xno
then : then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5
printf %s "checking for $CXX option to enable C++98 features... " >&6; } printf %s "checking for $CXX option to enable C++98 features... " >&6; }
if test ${ac_cv_prog_cxx_98+y} if test ${ac_cv_prog_cxx_cxx98+y}
then : then :
printf %s "(cached) " >&6 printf %s "(cached) " >&6
else $as_nop else $as_nop
ac_cv_prog_cxx_98=no ac_cv_prog_cxx_cxx98=no
ac_save_CXX=$CXX ac_save_CXX=$CXX
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
...@@ -15761,6 +15771,61 @@ esac ...@@ -15761,6 +15771,61 @@ esac
enable_wpcap=${enable_wpcap:-no} enable_wpcap=${enable_wpcap:-no}
fi fi
if test "x$with_pcsclite" != "xno"
then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SCardEstablishContext in -lpcsclite" >&5
printf %s "checking for SCardEstablishContext in -lpcsclite... " >&6; }
if test ${ac_cv_lib_pcsclite_SCardEstablishContext+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_check_lib_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. */
char SCardEstablishContext ();
int
main (void)
{
return SCardEstablishContext ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_pcsclite_SCardEstablishContext=yes
else $as_nop
ac_cv_lib_pcsclite_SCardEstablishContext=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcsclite_SCardEstablishContext" >&5
printf "%s\n" "$ac_cv_lib_pcsclite_SCardEstablishContext" >&6; }
if test "x$ac_cv_lib_pcsclite_SCardEstablishContext" = xyes
then :
PCSCLITE_LIBS="-lpcsclite"
fi
fi
if test "x$ac_cv_lib_pcsclite_SCardEstablishContext" != xyes
then :
case "x$with_pcsclite" in
x) as_fn_append wine_notices "|libpcsclite not found, smart cards won't be supported." ;;
xno) ;;
*) as_fn_error $? "libpcsclite not found, smart cards won't be supported.
This is an error since --with-pcsclite was requested." "$LINENO" 5 ;;
esac
enable_winscard=${enable_winscard:-no}
fi
if test "x$with_inotify" != "xno" if test "x$with_inotify" != "xno"
then then
rm -f conftest.err rm -f conftest.err
...@@ -23087,6 +23152,7 @@ X_PRE_LIBS = $X_PRE_LIBS ...@@ -23087,6 +23152,7 @@ X_PRE_LIBS = $X_PRE_LIBS
X_LIBS = $X_LIBS X_LIBS = $X_LIBS
X_EXTRA_LIBS = $X_EXTRA_LIBS X_EXTRA_LIBS = $X_EXTRA_LIBS
PCAP_LIBS = $PCAP_LIBS PCAP_LIBS = $PCAP_LIBS
PCSCLITE_LIBS = $PCSCLITE_LIBS
INOTIFY_CFLAGS = $INOTIFY_CFLAGS INOTIFY_CFLAGS = $INOTIFY_CFLAGS
INOTIFY_LIBS = $INOTIFY_LIBS INOTIFY_LIBS = $INOTIFY_LIBS
DBUS_CFLAGS = $DBUS_CFLAGS DBUS_CFLAGS = $DBUS_CFLAGS
......
...@@ -50,6 +50,7 @@ AC_ARG_WITH(osmesa, AS_HELP_STRING([--without-osmesa],[do not use the OSMesa ...@@ -50,6 +50,7 @@ AC_ARG_WITH(osmesa, AS_HELP_STRING([--without-osmesa],[do not use the OSMesa
AC_ARG_WITH(oss, AS_HELP_STRING([--without-oss],[do not use the OSS sound support])) AC_ARG_WITH(oss, AS_HELP_STRING([--without-oss],[do not use the OSS sound support]))
AC_ARG_WITH(pcap, AS_HELP_STRING([--without-pcap],[do not use the Packet Capture library]), AC_ARG_WITH(pcap, AS_HELP_STRING([--without-pcap],[do not use the Packet Capture library]),
[if test "x$withval" = "xno"; then ac_cv_header_pcap_pcap_h=no; fi]) [if test "x$withval" = "xno"; then ac_cv_header_pcap_pcap_h=no; fi])
AC_ARG_WITH(pcsclite, AS_HELP_STRING([--without-pcsclite],[do not use PCSC lite]))
AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthread library]), AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthread library]),
[if test "x$withval" = "xno"; then ac_cv_header_pthread_h=no; fi]) [if test "x$withval" = "xno"; then ac_cv_header_pthread_h=no; fi])
AC_ARG_WITH(pulse, AS_HELP_STRING([--without-pulse],[do not use PulseAudio sound support])) AC_ARG_WITH(pulse, AS_HELP_STRING([--without-pulse],[do not use PulseAudio sound support]))
...@@ -1377,6 +1378,15 @@ WINE_NOTICE_WITH(pcap,[test "x$ac_cv_lib_pcap_pcap_init" != xyes], ...@@ -1377,6 +1378,15 @@ WINE_NOTICE_WITH(pcap,[test "x$ac_cv_lib_pcap_pcap_init" != xyes],
[pcap ${notice_platform}development files not found, wpcap won't be supported.], [pcap ${notice_platform}development files not found, wpcap won't be supported.],
[enable_wpcap]) [enable_wpcap])
dnl **** Check for libpcsclite ****
if test "x$with_pcsclite" != "xno"
then
AC_CHECK_LIB(pcsclite,SCardEstablishContext,[AC_SUBST(PCSCLITE_LIBS,["-lpcsclite"])])
fi
WINE_NOTICE_WITH(pcsclite,[test "x$ac_cv_lib_pcsclite_SCardEstablishContext" != xyes],
[libpcsclite not found, smart cards won't be supported.],
[enable_winscard])
dnl **** Check for inotify **** dnl **** Check for inotify ****
if test "x$with_inotify" != "xno" if test "x$with_inotify" != "xno"
then then
......
MODULE = winscard.dll MODULE = winscard.dll
IMPORTLIB = winscard IMPORTLIB = winscard
UNIXLIB = winscard.so
UNIX_LIBS = $(PCSCLITE_LIBS)
C_SRCS = \ C_SRCS = \
unixlib.c \
winscard.c winscard.c
RC_SRCS = \ RC_SRCS = \
......
/*
* Copyright 2022 Hans Leidekker for CodeWeavers
*
* 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
*/
#if 0
#pragma makedep unix
#endif
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winternl.h"
#include "winbase.h"
#include "wine/debug.h"
#include "wine/unixlib.h"
#include "unixlib.h"
LONG SCardEstablishContext( UINT64, const void *, const void *, UINT64 * );
LONG SCardReleaseContext( UINT64 );
static NTSTATUS scard_establish_context( void *args )
{
struct scard_establish_context_params *params = args;
return SCardEstablishContext( params->scope, NULL, NULL, params->handle );
}
static NTSTATUS scard_release_context( void *args )
{
struct scard_release_context_params *params = args;
return SCardReleaseContext( params->handle );
}
const unixlib_entry_t __wine_unix_call_funcs[] =
{
scard_establish_context,
scard_release_context,
};
/*
* Copyright 2022 Hans Leidekker for CodeWeavers
*
* 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
*/
/* pcsclite defines DWORD as unsigned long on 64-bit (except on macOS),
* so use UINT64 instead. */
struct scard_establish_context_params
{
UINT64 scope;
UINT64 *handle;
};
struct scard_release_context_params
{
UINT64 handle;
};
enum winscard_funcs
{
unix_scard_establish_context,
unix_scard_release_context,
};
/* /*
* Copyright 2007 Mounir IDRASSI (mounir.idrassi@idrix.fr, for IDRIX) * Copyright 2007 Mounir IDRASSI (mounir.idrassi@idrix.fr, for IDRIX)
* Copyright 2022 Hans Leidekker for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -19,39 +20,23 @@ ...@@ -19,39 +20,23 @@
#include <stdarg.h> #include <stdarg.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "wine/debug.h"
#include "winscard.h" #include "winscard.h"
#include "winternl.h" #include "winternl.h"
#include "wine/debug.h"
#include "wine/unixlib.h"
#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(winscard); WINE_DEFAULT_DEBUG_CHANNEL(winscard);
static HANDLE g_startedEvent = NULL; #define UNIX_CALL( func, params ) WINE_UNIX_CALL( unix_ ## func, params )
static HANDLE g_startedEvent;
const SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 }; const SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
const SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 }; const SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
const SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 }; const SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
/* 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:
if (lpvReserved) break;
CloseHandle(g_startedEvent);
break;
}
return TRUE;
}
HANDLE WINAPI SCardAccessStartedEvent(void) HANDLE WINAPI SCardAccessStartedEvent(void)
{ {
return g_startedEvent; return g_startedEvent;
...@@ -81,12 +66,32 @@ LONG WINAPI SCardAddReaderToGroupW(SCARDCONTEXT context, LPCWSTR reader, LPCWSTR ...@@ -81,12 +66,32 @@ LONG WINAPI SCardAddReaderToGroupW(SCARDCONTEXT context, LPCWSTR reader, LPCWSTR
return SCARD_S_SUCCESS; return SCARD_S_SUCCESS;
} }
LONG WINAPI SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, #define CONTEXT_MAGIC (('C' << 24) | ('T' << 16) | ('X' << 8) | '0')
LPCVOID pvReserved2, LPSCARDCONTEXT phContext) struct handle
{ {
FIXME("(%lx,%p,%p,%p) stub\n", dwScope, pvReserved1, pvReserved2, phContext); DWORD magic;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); UINT64 unix_handle;
return SCARD_F_INTERNAL_ERROR; };
LONG WINAPI SCardEstablishContext( DWORD scope, const void *reserved1, const void *reserved2, SCARDCONTEXT *context )
{
struct scard_establish_context_params params;
struct handle *handle;
LONG ret;
TRACE( "%#lx, %p, %p, %p\n", scope, reserved1, reserved2, context );
if (!context) return SCARD_E_INVALID_PARAMETER;
if (!(handle = malloc( sizeof(*handle) ))) return SCARD_E_NO_MEMORY;
handle->magic = CONTEXT_MAGIC;
params.scope = scope;
params.handle = &handle->unix_handle;
if (!(ret = UNIX_CALL( scard_establish_context, &params ))) *context = (SCARDCONTEXT)handle;
else free( handle );
TRACE( "returning %#lx\n", ret );
return ret;
} }
LONG WINAPI SCardIsValidContext(SCARDCONTEXT context) LONG WINAPI SCardIsValidContext(SCARDCONTEXT context)
...@@ -103,11 +108,23 @@ LONG WINAPI SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr, LPCGUID rgguid ...@@ -103,11 +108,23 @@ LONG WINAPI SCardListCardsA(SCARDCONTEXT hContext, LPCBYTE pbAtr, LPCGUID rgguid
return SCARD_F_INTERNAL_ERROR; return SCARD_F_INTERNAL_ERROR;
} }
LONG WINAPI SCardReleaseContext(SCARDCONTEXT context) LONG WINAPI SCardReleaseContext( SCARDCONTEXT context )
{ {
FIXME("(%Ix) stub\n", context); struct handle *handle = (struct handle *)context;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); struct scard_release_context_params params;
return SCARD_F_INTERNAL_ERROR; LONG ret;
TRACE( "%Ix\n", context );
if (!handle || handle->magic != CONTEXT_MAGIC) return ERROR_INVALID_HANDLE;
params.handle = handle->unix_handle;
ret = UNIX_CALL( scard_release_context, &params );
handle->magic = 0;
free( handle );
TRACE( "returning %#lx\n", ret );
return ret;
} }
LONG WINAPI SCardStatusA(SCARDHANDLE context, LPSTR szReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) LONG WINAPI SCardStatusA(SCARDHANDLE context, LPSTR szReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
...@@ -147,3 +164,25 @@ LONG WINAPI SCardCancel(SCARDCONTEXT context) ...@@ -147,3 +164,25 @@ LONG WINAPI SCardCancel(SCARDCONTEXT context)
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return SCARD_F_INTERNAL_ERROR; return SCARD_F_INTERNAL_ERROR;
} }
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, void *reserved )
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls( hinst );
if (__wine_init_unix_call()) ERR( "no pcsclite support, expect problems\n" );
/* FIXME: for now, we act as if the pcsc daemon is always started */
g_startedEvent = CreateEventW( NULL, TRUE, TRUE, NULL );
break;
case DLL_PROCESS_DETACH:
if (reserved) break;
CloseHandle( g_startedEvent );
g_startedEvent = NULL;
break;
}
return TRUE;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment