New upstream version 1.9.1
This commit is contained in:
parent
f9c7c07a4d
commit
a8f556e1c1
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
1.9.1: Ludovic Rousseau
|
||||||
|
16 February 2021
|
||||||
|
- Do not (possibly) lock a reader if allocating hCard fails
|
||||||
|
- Fix a hang in SCardTransmit()
|
||||||
|
- Do not report an error if the wrong interface is used by the driver
|
||||||
|
- Update reader state when a card is removed during an exchange
|
||||||
|
- readerfactory: Make sure a freed Reader Context is not accessed
|
||||||
|
- PHSetProtocol(): supports T=0&1 cards on T=0 reader
|
||||||
|
- hotplug-libusb:
|
||||||
|
. support CCIDCLASSDRIVER
|
||||||
|
. add interface name to reader name
|
||||||
|
. remove obsolete libhal scheme
|
||||||
|
- Some other minor improvements
|
||||||
|
|
||||||
|
|
||||||
1.9.0: Ludovic Rousseau
|
1.9.0: Ludovic Rousseau
|
||||||
14 June 2020
|
14 June 2020
|
||||||
- SCardEndTransaction(): greatly improve performances (x300)
|
- SCardEndTransaction(): greatly improve performances (x300)
|
||||||
|
|
893
ChangeLog.git
893
ChangeLog.git
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||||
|
@ -164,7 +164,7 @@ DIST_SUBDIRS = $(SUBDIRS)
|
||||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
|
||||||
$(top_srcdir)/src/PCSC/pcsclite.h.in AUTHORS COPYING ChangeLog \
|
$(top_srcdir)/src/PCSC/pcsclite.h.in AUTHORS COPYING ChangeLog \
|
||||||
INSTALL NEWS README TODO ar-lib compile config.guess \
|
INSTALL NEWS README TODO ar-lib compile config.guess \
|
||||||
config.sub install-sh ltmain.sh missing ylwrap
|
config.sub depcomp install-sh ltmain.sh missing ylwrap
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
distdir = $(PACKAGE)-$(VERSION)
|
distdir = $(PACKAGE)-$(VERSION)
|
||||||
top_distdir = $(distdir)
|
top_distdir = $(distdir)
|
||||||
|
@ -203,6 +203,8 @@ am__relativize = \
|
||||||
GZIP_ENV = --best
|
GZIP_ENV = --best
|
||||||
DIST_ARCHIVES = $(distdir).tar.bz2
|
DIST_ARCHIVES = $(distdir).tar.bz2
|
||||||
DIST_TARGETS = dist-bzip2
|
DIST_TARGETS = dist-bzip2
|
||||||
|
# Exists only to be overridden by the user if desired.
|
||||||
|
AM_DISTCHECK_DVI_TARGET = dvi
|
||||||
distuninstallcheck_listfiles = find . -type f -print
|
distuninstallcheck_listfiles = find . -type f -print
|
||||||
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
|
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
|
||||||
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
|
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
|
||||||
|
@ -689,7 +691,7 @@ distcheck: dist
|
||||||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||||
--srcdir=../.. --prefix="$$dc_install_base" \
|
--srcdir=../.. --prefix="$$dc_install_base" \
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
|
# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||||
[am__api_version='1.16'
|
[am__api_version='1.16'
|
||||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||||
dnl require some minimum version. Point them to the right macro.
|
dnl require some minimum version. Point them to the right macro.
|
||||||
m4_if([$1], [1.16.2], [],
|
m4_if([$1], [1.16.3], [],
|
||||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
|
||||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||||
[AM_AUTOMAKE_VERSION([1.16.2])dnl
|
[AM_AUTOMAKE_VERSION([1.16.3])dnl
|
||||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||||
|
@ -1093,12 +1093,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||||
if test x"${MISSING+set}" != xset; then
|
if test x"${MISSING+set}" != xset; then
|
||||||
case $am_aux_dir in
|
MISSING="\${SHELL} '$am_aux_dir/missing'"
|
||||||
*\ * | *\ *)
|
|
||||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
|
||||||
*)
|
|
||||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
|
||||||
esac
|
|
||||||
fi
|
fi
|
||||||
# Use eval to expand $SHELL
|
# Use eval to expand $SHELL
|
||||||
if eval "$MISSING --is-lightweight"; then
|
if eval "$MISSING --is-lightweight"; then
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.69 for pcsc-lite 1.9.0.
|
# Generated by GNU Autoconf 2.69 for pcsc-lite 1.9.1.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||||
|
@ -587,8 +587,8 @@ MAKEFLAGS=
|
||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='pcsc-lite'
|
PACKAGE_NAME='pcsc-lite'
|
||||||
PACKAGE_TARNAME='pcsc-lite'
|
PACKAGE_TARNAME='pcsc-lite'
|
||||||
PACKAGE_VERSION='1.9.0'
|
PACKAGE_VERSION='1.9.1'
|
||||||
PACKAGE_STRING='pcsc-lite 1.9.0'
|
PACKAGE_STRING='pcsc-lite 1.9.1'
|
||||||
PACKAGE_BUGREPORT=''
|
PACKAGE_BUGREPORT=''
|
||||||
PACKAGE_URL=''
|
PACKAGE_URL=''
|
||||||
|
|
||||||
|
@ -1395,7 +1395,7 @@ if test "$ac_init_help" = "long"; then
|
||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures pcsc-lite 1.9.0 to adapt to many kinds of systems.
|
\`configure' configures pcsc-lite 1.9.1 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
|
@ -1466,7 +1466,7 @@ fi
|
||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of pcsc-lite 1.9.0:";;
|
short | recursive ) echo "Configuration of pcsc-lite 1.9.1:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
|
@ -1618,7 +1618,7 @@ fi
|
||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
pcsc-lite configure 1.9.0
|
pcsc-lite configure 1.9.1
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
@ -2094,7 +2094,7 @@ cat >config.log <<_ACEOF
|
||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by pcsc-lite $as_me 1.9.0, which was
|
It was created by pcsc-lite $as_me 1.9.1, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
|
@ -2648,12 +2648,7 @@ program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
|
||||||
am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||||
|
|
||||||
if test x"${MISSING+set}" != xset; then
|
if test x"${MISSING+set}" != xset; then
|
||||||
case $am_aux_dir in
|
MISSING="\${SHELL} '$am_aux_dir/missing'"
|
||||||
*\ * | *\ *)
|
|
||||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
|
||||||
*)
|
|
||||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
|
||||||
esac
|
|
||||||
fi
|
fi
|
||||||
# Use eval to expand $SHELL
|
# Use eval to expand $SHELL
|
||||||
if eval "$MISSING --is-lightweight"; then
|
if eval "$MISSING --is-lightweight"; then
|
||||||
|
@ -2958,7 +2953,7 @@ fi
|
||||||
|
|
||||||
# Define the identity of the package.
|
# Define the identity of the package.
|
||||||
PACKAGE='pcsc-lite'
|
PACKAGE='pcsc-lite'
|
||||||
VERSION='1.9.0'
|
VERSION='1.9.1'
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
@ -16197,7 +16192,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by pcsc-lite $as_me 1.9.0, which was
|
This file was extended by pcsc-lite $as_me 1.9.1, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
|
@ -16263,7 +16258,7 @@ _ACEOF
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
pcsc-lite config.status 1.9.0
|
pcsc-lite config.status 1.9.1
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
AC_PREREQ([2.69])
|
AC_PREREQ([2.69])
|
||||||
|
|
||||||
AC_INIT([pcsc-lite],[1.9.0])
|
AC_INIT([pcsc-lite],[1.9.1])
|
||||||
AC_CONFIG_SRCDIR(src/pcscdaemon.c)
|
AC_CONFIG_SRCDIR(src/pcscdaemon.c)
|
||||||
AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip)
|
AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip)
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
SUBDIRS = . example
|
SUBDIRS = . example
|
||||||
|
|
||||||
doc_DATA = \
|
doc_DATA = \
|
||||||
README.DAEMON README.polkit
|
README.polkit
|
||||||
|
|
||||||
man_MANS = pcscd.8 reader.conf.5
|
man_MANS = pcscd.8 reader.conf.5
|
||||||
man_in = pcscd.8.in reader.conf.5.in
|
man_in = pcscd.8.in reader.conf.5.in
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||||
|
@ -375,7 +375,7 @@ usbdropdir = @usbdropdir@
|
||||||
usbdropdir_exp = @usbdropdir_exp@
|
usbdropdir_exp = @usbdropdir_exp@
|
||||||
SUBDIRS = . example
|
SUBDIRS = . example
|
||||||
doc_DATA = \
|
doc_DATA = \
|
||||||
README.DAEMON README.polkit
|
README.polkit
|
||||||
|
|
||||||
man_MANS = pcscd.8 reader.conf.5
|
man_MANS = pcscd.8 reader.conf.5
|
||||||
man_in = pcscd.8.in reader.conf.5.in
|
man_in = pcscd.8.in reader.conf.5.in
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
To install pcsc-lite as a daemon that is automatically started up at
|
|
||||||
boot you must use the following command in one of your rc files or add an
|
|
||||||
entry to your rc.d/init.d/ directory for Redhat/Mandrake users.
|
|
||||||
|
|
||||||
nohup /usr/local/pcsc/bin/pcscd </dev/null >> /var/log/pcscd.log 2>&1 &
|
|
||||||
|
|
||||||
|
|
||||||
If you installed using ./configure --enable-daemon then just use:
|
|
||||||
|
|
||||||
pcscd
|
|
||||||
|
|
||||||
Mac OS X Users may create a Startup by doing the following:
|
|
||||||
Copy the files SmartcardServices and StartupParameters.plist from the
|
|
||||||
/etc directory to /System/Library/StartupItems/SmartcardServices.
|
|
||||||
( You will have to create the SmartcardServices directory )
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
PROGRAM=libtool
|
PROGRAM=libtool
|
||||||
PACKAGE=libtool
|
PACKAGE=libtool
|
||||||
VERSION="2.4.6 Debian-2.4.6-14"
|
VERSION="2.4.6 Debian-2.4.6-15"
|
||||||
package_revision=2.4.6
|
package_revision=2.4.6
|
||||||
|
|
||||||
|
|
||||||
|
@ -2141,7 +2141,7 @@ include the following information:
|
||||||
compiler: $LTCC
|
compiler: $LTCC
|
||||||
compiler flags: $LTCFLAGS
|
compiler flags: $LTCFLAGS
|
||||||
linker: $LD (gnu? $with_gnu_ld)
|
linker: $LD (gnu? $with_gnu_ld)
|
||||||
version: $progname $scriptversion Debian-2.4.6-14
|
version: $progname $scriptversion Debian-2.4.6-15
|
||||||
automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
|
automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
|
||||||
autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
|
autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||||
|
|
|
@ -279,7 +279,7 @@ extern const SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci, g_rgSCardRawPci;
|
||||||
#define INFINITE 0xFFFFFFFF /**< Infinite timeout */
|
#define INFINITE 0xFFFFFFFF /**< Infinite timeout */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PCSCLITE_VERSION_NUMBER "1.9.0" /**< Current version */
|
#define PCSCLITE_VERSION_NUMBER "1.9.1" /**< Current version */
|
||||||
/** Maximum readers context (a slot is count as a reader) */
|
/** Maximum readers context (a slot is count as a reader) */
|
||||||
#define PCSCLITE_MAX_READERS_CONTEXTS 16
|
#define PCSCLITE_MAX_READERS_CONTEXTS 16
|
||||||
|
|
||||||
|
|
|
@ -75,15 +75,15 @@ short ATRDecodeAtr(int *availableProtocols, int *currentProtocol,
|
||||||
LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
|
LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dwLength < 2)
|
|
||||||
return 0; /** @retval 0 Atr must have TS and T0 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Zero out the bitmasks
|
* Zero out the bitmasks
|
||||||
*/
|
*/
|
||||||
*availableProtocols = SCARD_PROTOCOL_UNDEFINED;
|
*availableProtocols = SCARD_PROTOCOL_UNDEFINED;
|
||||||
*currentProtocol = SCARD_PROTOCOL_UNDEFINED;
|
*currentProtocol = SCARD_PROTOCOL_UNDEFINED;
|
||||||
|
|
||||||
|
if (dwLength < 2)
|
||||||
|
return 0; /** @retval 0 Atr must have TS and T0 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode the TS byte
|
* Decode the TS byte
|
||||||
*/
|
*/
|
||||||
|
@ -218,8 +218,8 @@ short ATRDecodeAtr(int *availableProtocols, int *currentProtocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ATR_DEBUG
|
#ifdef ATR_DEBUG
|
||||||
Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
|
Log3(PCSC_LOG_DEBUG, "CurrentProtocol: T=%d, AvailableProtocols: %d",
|
||||||
*currentProtocol, *availableProtocols);
|
*currentProtocol - SCARD_PROTOCOL_T0, *availableProtocols);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 1; /** @retval 1 Success */
|
return 1; /** @retval 1 Success */
|
||||||
|
|
|
@ -39,6 +39,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef __atrhandler_h__
|
#ifndef __atrhandler_h__
|
||||||
#define __atrhandler_h__
|
#define __atrhandler_h__
|
||||||
|
|
||||||
|
#include "wintypes.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decodes the ATR
|
* Decodes the ATR
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,6 +35,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef __configfile_h__
|
#ifndef __configfile_h__
|
||||||
#define __configfile_h__
|
#define __configfile_h__
|
||||||
|
|
||||||
|
#include "readerfactory.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef __dyn_generic_h__
|
#ifndef __dyn_generic_h__
|
||||||
#define __dyn_generic_h__
|
#define __dyn_generic_h__
|
||||||
|
|
||||||
|
#include "wintypes.h"
|
||||||
|
|
||||||
LONG DYN_LoadLibrary(void **, char *);
|
LONG DYN_LoadLibrary(void **, char *);
|
||||||
LONG DYN_CloseLibrary(void **);
|
LONG DYN_CloseLibrary(void **);
|
||||||
LONG DYN_GetAddress(void *, /*@out@*/ void **, const char *, int);
|
LONG DYN_GetAddress(void *, /*@out@*/ void **, const char *, int);
|
||||||
|
|
|
@ -104,7 +104,7 @@ LONG EHUnregisterClientForEvent(int32_t filedes)
|
||||||
{
|
{
|
||||||
LONG rv = EHTryToUnregisterClientForEvent(filedes);
|
LONG rv = EHTryToUnregisterClientForEvent(filedes);
|
||||||
|
|
||||||
if (rv < 0)
|
if (rv != SCARD_S_SUCCESS)
|
||||||
Log2(PCSC_LOG_ERROR, "Can't remove client: %d", filedes);
|
Log2(PCSC_LOG_ERROR, "Can't remove client: %d", filedes);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -41,6 +41,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "pcsclite.h"
|
||||||
|
#include "readerfactory.h"
|
||||||
|
#include "wintypes.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define an exported public reader state structure so each
|
* Define an exported public reader state structure so each
|
||||||
* application gets instant notification of changes in state.
|
* application gets instant notification of changes in state.
|
||||||
|
|
|
@ -38,6 +38,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef __hotplug_h__
|
#ifndef __hotplug_h__
|
||||||
#define __hotplug_h__
|
#define __hotplug_h__
|
||||||
|
|
||||||
|
#include "wintypes.h"
|
||||||
|
|
||||||
#ifndef PCSCLITE_HP_DROPDIR
|
#ifndef PCSCLITE_HP_DROPDIR
|
||||||
#define PCSCLITE_HP_DROPDIR "/usr/local/pcsc/drivers/"
|
#define PCSCLITE_HP_DROPDIR "/usr/local/pcsc/drivers/"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -78,6 +78,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
|
|
||||||
|
extern char Add_Interface_In_Name;
|
||||||
extern char Add_Serial_In_Name;
|
extern char Add_Serial_In_Name;
|
||||||
|
|
||||||
/* we use the default libusb context */
|
/* we use the default libusb context */
|
||||||
|
@ -106,6 +107,7 @@ static struct _driverTracker
|
||||||
char *libraryPath;
|
char *libraryPath;
|
||||||
char *readerName;
|
char *readerName;
|
||||||
int ifdCapabilities;
|
int ifdCapabilities;
|
||||||
|
char *CFBundleName;
|
||||||
} *driverTracker = NULL;
|
} *driverTracker = NULL;
|
||||||
#define DRIVER_TRACKER_SIZE_STEP 8
|
#define DRIVER_TRACKER_SIZE_STEP 8
|
||||||
|
|
||||||
|
@ -121,8 +123,10 @@ static struct _readerTracker
|
||||||
|
|
||||||
static LONG HPAddHotPluggable(struct libusb_device *dev,
|
static LONG HPAddHotPluggable(struct libusb_device *dev,
|
||||||
struct libusb_device_descriptor desc,
|
struct libusb_device_descriptor desc,
|
||||||
const char bus_device[], int interface,
|
const char bus_device[],
|
||||||
struct _driverTracker *driver);
|
const struct libusb_interface *idesc,
|
||||||
|
struct _driverTracker *driver,
|
||||||
|
struct _driverTracker *classdriver);
|
||||||
static LONG HPRemoveHotPluggable(int reader_index);
|
static LONG HPRemoveHotPluggable(int reader_index);
|
||||||
|
|
||||||
static LONG HPReadBundleValues(void)
|
static LONG HPReadBundleValues(void)
|
||||||
|
@ -170,6 +174,7 @@ static LONG HPReadBundleValues(void)
|
||||||
list_t *manuIDs, *productIDs, *readerNames;
|
list_t *manuIDs, *productIDs, *readerNames;
|
||||||
char *libraryPath;
|
char *libraryPath;
|
||||||
int ifdCapabilities;
|
int ifdCapabilities;
|
||||||
|
char *CFBundleName;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The bundle exists - let's form a full path name and get the
|
* The bundle exists - let's form a full path name and get the
|
||||||
|
@ -200,6 +205,14 @@ static LONG HPReadBundleValues(void)
|
||||||
GET_KEY(PCSCLITE_HP_PRODKEY_NAME, &productIDs)
|
GET_KEY(PCSCLITE_HP_PRODKEY_NAME, &productIDs)
|
||||||
GET_KEY(PCSCLITE_HP_NAMEKEY_NAME, &readerNames)
|
GET_KEY(PCSCLITE_HP_NAMEKEY_NAME, &readerNames)
|
||||||
|
|
||||||
|
/* Get CFBundleName */
|
||||||
|
rv = LTPBundleFindValueWithKey(&plist, PCSCLITE_HP_CFBUNDLE_NAME,
|
||||||
|
&values);
|
||||||
|
if (rv)
|
||||||
|
CFBundleName = NULL;
|
||||||
|
else
|
||||||
|
CFBundleName = strdup(list_get_at(values, 0));
|
||||||
|
|
||||||
/* while we find a nth ifdVendorID in Info.plist */
|
/* while we find a nth ifdVendorID in Info.plist */
|
||||||
for (alias=0; alias<list_size(manuIDs); alias++)
|
for (alias=0; alias<list_size(manuIDs); alias++)
|
||||||
{
|
{
|
||||||
|
@ -218,6 +231,7 @@ static LONG HPReadBundleValues(void)
|
||||||
driverTracker[listCount].bundleName = strdup(currFP->d_name);
|
driverTracker[listCount].bundleName = strdup(currFP->d_name);
|
||||||
driverTracker[listCount].libraryPath = strdup(fullLibPath);
|
driverTracker[listCount].libraryPath = strdup(fullLibPath);
|
||||||
driverTracker[listCount].ifdCapabilities = ifdCapabilities;
|
driverTracker[listCount].ifdCapabilities = ifdCapabilities;
|
||||||
|
driverTracker[listCount].CFBundleName = CFBundleName;
|
||||||
|
|
||||||
#ifdef DEBUG_HOTPLUG
|
#ifdef DEBUG_HOTPLUG
|
||||||
Log2(PCSC_LOG_INFO, "Found driver for: %s",
|
Log2(PCSC_LOG_INFO, "Found driver for: %s",
|
||||||
|
@ -255,6 +269,7 @@ static LONG HPReadBundleValues(void)
|
||||||
driverTracker[i].libraryPath = NULL;
|
driverTracker[i].libraryPath = NULL;
|
||||||
driverTracker[i].readerName = NULL;
|
driverTracker[i].readerName = NULL;
|
||||||
driverTracker[i].ifdCapabilities = 0;
|
driverTracker[i].ifdCapabilities = 0;
|
||||||
|
driverTracker[i].CFBundleName = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,6 +293,44 @@ static LONG HPReadBundleValues(void)
|
||||||
return driverSize;
|
return driverSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct _driverTracker *get_driver(unsigned int idVendor,
|
||||||
|
unsigned int idProduct, struct _driverTracker **classdriver)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static struct _driverTracker *driver;
|
||||||
|
|
||||||
|
#ifdef DEBUG_HOTPLUG
|
||||||
|
Log3(PCSC_LOG_DEBUG,
|
||||||
|
"Looking for a driver for VID: 0x%04X, PID: 0x%04X",
|
||||||
|
idVendor, idProduct);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*classdriver = NULL;
|
||||||
|
driver = NULL;
|
||||||
|
/* check if the device is supported by one driver */
|
||||||
|
for (i=0; i<driverSize; i++)
|
||||||
|
{
|
||||||
|
if (driverTracker[i].libraryPath != NULL &&
|
||||||
|
idVendor == driverTracker[i].manuID &&
|
||||||
|
idProduct == driverTracker[i].productID)
|
||||||
|
{
|
||||||
|
if ((driverTracker[i].CFBundleName != NULL)
|
||||||
|
&& (0 == strcmp(driverTracker[i].CFBundleName, "CCIDCLASSDRIVER")))
|
||||||
|
*classdriver = &driverTracker[i];
|
||||||
|
else
|
||||||
|
/* it is not a CCID Class driver */
|
||||||
|
driver = &driverTracker[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we found a specific driver */
|
||||||
|
if (driver)
|
||||||
|
return driver;
|
||||||
|
|
||||||
|
/* else return the Class driver (if any) */
|
||||||
|
return *classdriver;
|
||||||
|
}
|
||||||
|
|
||||||
static void HPRescanUsbBus(void)
|
static void HPRescanUsbBus(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -292,7 +345,8 @@ static void HPRescanUsbBus(void)
|
||||||
cnt = libusb_get_device_list(ctx, &devs);
|
cnt = libusb_get_device_list(ctx, &devs);
|
||||||
if (cnt < 0)
|
if (cnt < 0)
|
||||||
{
|
{
|
||||||
Log1(PCSC_LOG_CRITICAL, "libusb_get_device_list() failed\n");
|
Log2(PCSC_LOG_CRITICAL, "libusb_get_device_list() failed: %s",
|
||||||
|
libusb_error_name(cnt));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,78 +358,76 @@ static void HPRescanUsbBus(void)
|
||||||
struct libusb_config_descriptor *config_desc;
|
struct libusb_config_descriptor *config_desc;
|
||||||
uint8_t bus_number = libusb_get_bus_number(dev);
|
uint8_t bus_number = libusb_get_bus_number(dev);
|
||||||
uint8_t device_address = libusb_get_device_address(dev);
|
uint8_t device_address = libusb_get_device_address(dev);
|
||||||
|
struct _driverTracker *driver, *classdriver;
|
||||||
|
int interface;
|
||||||
|
|
||||||
int r = libusb_get_device_descriptor(dev, &desc);
|
int r = libusb_get_device_descriptor(dev, &desc);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
Log3(PCSC_LOG_ERROR, "failed to get device descriptor for %d/%d",
|
Log4(PCSC_LOG_ERROR,
|
||||||
bus_number, device_address);
|
"failed to get device descriptor for %d/%d: %s",
|
||||||
|
bus_number, device_address, libusb_error_name(r));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = libusb_get_active_config_descriptor(dev, &config_desc);
|
r = libusb_get_active_config_descriptor(dev, &config_desc);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
Log3(PCSC_LOG_ERROR, "failed to get device config for %d/%d",
|
Log4(PCSC_LOG_ERROR, "failed to get device config for %d/%d: %s",
|
||||||
bus_number, device_address);
|
bus_number, device_address, libusb_error_name(r));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if the device is supported by one driver */
|
driver = get_driver(desc.idVendor, desc.idProduct, &classdriver);
|
||||||
for (i=0; i<driverSize; i++)
|
if (NULL == driver)
|
||||||
{
|
{
|
||||||
if (driverTracker[i].libraryPath != NULL &&
|
/* not a smart card reader */
|
||||||
desc.idVendor == driverTracker[i].manuID &&
|
#ifdef DEBUG_HOTPLUG
|
||||||
desc.idProduct == driverTracker[i].productID)
|
Log3(PCSC_LOG_DEBUG, "%d/%d is not a supported smart card reader",
|
||||||
|
bus_number, device_address);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_HOTPLUG
|
||||||
|
Log3(PCSC_LOG_DEBUG, "Found matching USB device: %d:%d",
|
||||||
|
bus_number, device_address);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (interface = 0; interface < config_desc->bNumInterfaces;
|
||||||
|
interface++)
|
||||||
|
{
|
||||||
|
int newreader;
|
||||||
|
|
||||||
|
/* A known device has been found */
|
||||||
|
snprintf(bus_device, BUS_DEVICE_STRSIZE, "%d:%d:%d",
|
||||||
|
bus_number, device_address, interface);
|
||||||
|
bus_device[BUS_DEVICE_STRSIZE - 1] = '\0';
|
||||||
|
newreader = TRUE;
|
||||||
|
|
||||||
|
/* Check if the reader is a new one */
|
||||||
|
for (j=0; j<PCSCLITE_MAX_READERS_CONTEXTS; j++)
|
||||||
{
|
{
|
||||||
int interface;
|
if (strncmp(readerTracker[j].bus_device,
|
||||||
|
|
||||||
#ifdef DEBUG_HOTPLUG
|
|
||||||
Log3(PCSC_LOG_DEBUG, "Found matching USB device: %d:%d",
|
|
||||||
bus_number, device_address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (interface = 0; interface < config_desc->bNumInterfaces;
|
|
||||||
interface++)
|
|
||||||
{
|
|
||||||
int newreader;
|
|
||||||
|
|
||||||
/* A known device has been found */
|
|
||||||
snprintf(bus_device, BUS_DEVICE_STRSIZE, "%d:%d:%d",
|
|
||||||
bus_number, device_address, interface);
|
|
||||||
bus_device[BUS_DEVICE_STRSIZE - 1] = '\0';
|
|
||||||
newreader = TRUE;
|
|
||||||
|
|
||||||
/* Check if the reader is a new one */
|
|
||||||
for (j=0; j<PCSCLITE_MAX_READERS_CONTEXTS; j++)
|
|
||||||
{
|
|
||||||
if (strncmp(readerTracker[j].bus_device,
|
|
||||||
bus_device, BUS_DEVICE_STRSIZE) == 0)
|
bus_device, BUS_DEVICE_STRSIZE) == 0)
|
||||||
{
|
{
|
||||||
/* The reader is already known */
|
/* The reader is already known */
|
||||||
readerTracker[j].status = READER_PRESENT;
|
readerTracker[j].status = READER_PRESENT;
|
||||||
newreader = FALSE;
|
newreader = FALSE;
|
||||||
#ifdef DEBUG_HOTPLUG
|
#ifdef DEBUG_HOTPLUG
|
||||||
Log2(PCSC_LOG_DEBUG, "Refresh USB device: %s",
|
Log2(PCSC_LOG_DEBUG, "Refresh USB device: %s",
|
||||||
bus_device);
|
bus_device);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New reader found */
|
|
||||||
if (newreader)
|
|
||||||
{
|
|
||||||
if (config_desc->bNumInterfaces > 1)
|
|
||||||
HPAddHotPluggable(dev, desc, bus_device,
|
|
||||||
interface, &driverTracker[i]);
|
|
||||||
else
|
|
||||||
HPAddHotPluggable(dev, desc, bus_device,
|
|
||||||
-1, &driverTracker[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* New reader found */
|
||||||
|
if (newreader)
|
||||||
|
HPAddHotPluggable(dev, desc, bus_device,
|
||||||
|
&config_desc->interface[interface], driver, classdriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_free_config_descriptor(config_desc);
|
libusb_free_config_descriptor(config_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,6 +451,7 @@ static void HPRescanUsbBus(void)
|
||||||
free(driverTracker[i].bundleName);
|
free(driverTracker[i].bundleName);
|
||||||
free(driverTracker[i].libraryPath);
|
free(driverTracker[i].libraryPath);
|
||||||
free(driverTracker[i].readerName);
|
free(driverTracker[i].readerName);
|
||||||
|
free(driverTracker[i].CFBundleName);
|
||||||
}
|
}
|
||||||
free(driverTracker);
|
free(driverTracker);
|
||||||
|
|
||||||
|
@ -410,7 +463,7 @@ static void HPRescanUsbBus(void)
|
||||||
libusb_free_device_list(devs, 1);
|
libusb_free_device_list(devs, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HPEstablishUSBNotifications(int pipefd[2])
|
static void * HPEstablishUSBNotifications(int pipefd[2])
|
||||||
{
|
{
|
||||||
int i, do_polling;
|
int i, do_polling;
|
||||||
int r;
|
int r;
|
||||||
|
@ -419,17 +472,21 @@ static void HPEstablishUSBNotifications(int pipefd[2])
|
||||||
r = libusb_init(ctx);
|
r = libusb_init(ctx);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
Log2(PCSC_LOG_CRITICAL, "libusb_init failed: %d", r);
|
Log2(PCSC_LOG_CRITICAL, "libusb_init failed: %s", libusb_error_name(r));
|
||||||
/* emergency exit */
|
/* emergency exit */
|
||||||
kill(getpid(), SIGTERM);
|
kill(getpid(), SIGTERM);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* scan the USB bus for devices at startup */
|
/* scan the USB bus for devices at startup */
|
||||||
HPRescanUsbBus();
|
HPRescanUsbBus();
|
||||||
|
|
||||||
/* signal that the initially connected readers are now visible */
|
/* signal that the initially connected readers are now visible */
|
||||||
write(pipefd[1], &c, 1);
|
if (write(pipefd[1], &c, 1) == -1)
|
||||||
|
{
|
||||||
|
Log2(PCSC_LOG_ERROR, "write: %s", strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* if at least one driver do not have IFD_GENERATE_HOTPLUG */
|
/* if at least one driver do not have IFD_GENERATE_HOTPLUG */
|
||||||
do_polling = FALSE;
|
do_polling = FALSE;
|
||||||
|
@ -464,7 +521,11 @@ static void HPEstablishUSBNotifications(int pipefd[2])
|
||||||
{
|
{
|
||||||
char dummy;
|
char dummy;
|
||||||
|
|
||||||
pipe(rescan_pipe);
|
if (pipe(rescan_pipe) == -1)
|
||||||
|
{
|
||||||
|
Log2(PCSC_LOG_ERROR, "pipe: %s", strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
while (read(rescan_pipe[0], &dummy, sizeof(dummy)) > 0)
|
while (read(rescan_pipe[0], &dummy, sizeof(dummy)) > 0)
|
||||||
{
|
{
|
||||||
Log1(PCSC_LOG_INFO, "Reload serial configuration");
|
Log1(PCSC_LOG_INFO, "Reload serial configuration");
|
||||||
|
@ -477,6 +538,8 @@ static void HPEstablishUSBNotifications(int pipefd[2])
|
||||||
close(rescan_pipe[0]);
|
close(rescan_pipe[0]);
|
||||||
rescan_pipe[0] = -1;
|
rescan_pipe[0] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG HPSearchHotPluggables(void)
|
LONG HPSearchHotPluggables(void)
|
||||||
|
@ -505,7 +568,11 @@ LONG HPSearchHotPluggables(void)
|
||||||
(PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, pipefd);
|
(PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, pipefd);
|
||||||
|
|
||||||
/* Wait for initial readers to setup */
|
/* Wait for initial readers to setup */
|
||||||
read(pipefd[0], &c, 1);
|
if (read(pipefd[0], &c, 1) == -1)
|
||||||
|
{
|
||||||
|
Log2(PCSC_LOG_ERROR, "read: %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
/* cleanup pipe fd */
|
/* cleanup pipe fd */
|
||||||
close(pipefd[0]);
|
close(pipefd[0]);
|
||||||
|
@ -529,21 +596,20 @@ LONG HPStopHotPluggables(void)
|
||||||
|
|
||||||
static LONG HPAddHotPluggable(struct libusb_device *dev,
|
static LONG HPAddHotPluggable(struct libusb_device *dev,
|
||||||
struct libusb_device_descriptor desc,
|
struct libusb_device_descriptor desc,
|
||||||
const char bus_device[], int interface,
|
const char bus_device[],
|
||||||
struct _driverTracker *driver)
|
const struct libusb_interface *idesc,
|
||||||
|
struct _driverTracker *driver,
|
||||||
|
struct _driverTracker *classdriver)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
uint8_t iInterface = 0;
|
||||||
|
uint8_t iSerialNumber = 0;
|
||||||
char deviceName[MAX_DEVICENAME];
|
char deviceName[MAX_DEVICENAME];
|
||||||
|
|
||||||
Log2(PCSC_LOG_INFO, "Adding USB device: %s", bus_device);
|
Log2(PCSC_LOG_INFO, "Adding USB device: %s", bus_device);
|
||||||
|
|
||||||
if (interface >= 0)
|
snprintf(deviceName, sizeof(deviceName), "usb:%04x/%04x:libusb-1.0:%s",
|
||||||
snprintf(deviceName, sizeof(deviceName), "usb:%04x/%04x:libhal:/org/freedesktop/Hal/devices/usb_device_%04x_%04x_serialnotneeded_if%d",
|
desc.idVendor, desc.idProduct, bus_device);
|
||||||
desc.idVendor, desc.idProduct, desc.idVendor, desc.idProduct,
|
|
||||||
interface);
|
|
||||||
else
|
|
||||||
snprintf(deviceName, sizeof(deviceName), "usb:%04x/%04x:libusb-1.0:%s",
|
|
||||||
desc.idVendor, desc.idProduct, bus_device);
|
|
||||||
|
|
||||||
deviceName[sizeof(deviceName) -1] = '\0';
|
deviceName[sizeof(deviceName) -1] = '\0';
|
||||||
|
|
||||||
|
@ -567,8 +633,15 @@ static LONG HPAddHotPluggable(struct libusb_device *dev,
|
||||||
strncpy(readerTracker[i].bus_device, bus_device,
|
strncpy(readerTracker[i].bus_device, bus_device,
|
||||||
sizeof(readerTracker[i].bus_device));
|
sizeof(readerTracker[i].bus_device));
|
||||||
readerTracker[i].bus_device[sizeof(readerTracker[i].bus_device) - 1] = '\0';
|
readerTracker[i].bus_device[sizeof(readerTracker[i].bus_device) - 1] = '\0';
|
||||||
|
readerTracker[i].fullName = NULL;
|
||||||
|
|
||||||
if (Add_Serial_In_Name && desc.iSerialNumber)
|
if (Add_Interface_In_Name && idesc->num_altsetting > 0)
|
||||||
|
iInterface = idesc->altsetting[0].iInterface;
|
||||||
|
|
||||||
|
if (Add_Serial_In_Name)
|
||||||
|
iSerialNumber = desc.iSerialNumber;
|
||||||
|
|
||||||
|
if (iSerialNumber != 0 || iInterface != 0)
|
||||||
{
|
{
|
||||||
libusb_device_handle *device;
|
libusb_device_handle *device;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -576,45 +649,104 @@ static LONG HPAddHotPluggable(struct libusb_device *dev,
|
||||||
ret = libusb_open(dev, &device);
|
ret = libusb_open(dev, &device);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
Log2(PCSC_LOG_ERROR, "libusb_open failed: %d", ret);
|
Log2(PCSC_LOG_ERROR, "libusb_open failed: %s",
|
||||||
|
libusb_error_name(ret));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
unsigned char interfaceName[MAX_READERNAME];
|
||||||
unsigned char serialNumber[MAX_READERNAME];
|
unsigned char serialNumber[MAX_READERNAME];
|
||||||
|
char fullname[MAX_READERNAME * 3];
|
||||||
|
fullname[0] = '\0';
|
||||||
|
int ret_interface = 0;
|
||||||
|
int ret_serial = 0;
|
||||||
|
|
||||||
|
if (iInterface)
|
||||||
|
{
|
||||||
|
ret_interface = libusb_get_string_descriptor_ascii(device,
|
||||||
|
iInterface, interfaceName, sizeof interfaceName);
|
||||||
|
if (ret_interface < 0)
|
||||||
|
{
|
||||||
|
Log2(PCSC_LOG_ERROR,
|
||||||
|
"libusb_get_string_descriptor_ascii failed: %s",
|
||||||
|
libusb_error_name(ret_interface));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iSerialNumber)
|
||||||
|
{
|
||||||
|
ret_serial = libusb_get_string_descriptor_ascii(device,
|
||||||
|
iSerialNumber, serialNumber, sizeof serialNumber);
|
||||||
|
if (ret_serial < 0)
|
||||||
|
{
|
||||||
|
Log2(PCSC_LOG_ERROR,
|
||||||
|
"libusb_get_string_descriptor_ascii failed: %s",
|
||||||
|
libusb_error_name(ret_serial));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = libusb_get_string_descriptor_ascii(device, desc.iSerialNumber,
|
|
||||||
serialNumber, MAX_READERNAME);
|
|
||||||
libusb_close(device);
|
libusb_close(device);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret_interface > 0 && ret_serial > 0)
|
||||||
{
|
{
|
||||||
Log2(PCSC_LOG_ERROR,
|
snprintf(fullname, sizeof(fullname), "%s [%s] (%s)",
|
||||||
"libusb_get_string_descriptor_ascii failed: %d", ret);
|
driver->readerName, interfaceName, serialNumber);
|
||||||
readerTracker[i].fullName = strdup(driver->readerName);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char fullname[MAX_READERNAME];
|
if (ret_interface > 0)
|
||||||
|
{
|
||||||
snprintf(fullname, sizeof(fullname), "%s (%s)",
|
snprintf(fullname, sizeof(fullname), "%s [%s]",
|
||||||
driver->readerName, serialNumber);
|
driver->readerName, interfaceName);
|
||||||
readerTracker[i].fullName = strdup(fullname);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ret_serial > 0)
|
||||||
|
{
|
||||||
|
snprintf(fullname, sizeof(fullname), "%s (%s)",
|
||||||
|
driver->readerName, serialNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fullname[0] != '\0')
|
||||||
|
readerTracker[i].fullName = strdup(fullname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (readerTracker[i].fullName == NULL)
|
||||||
readerTracker[i].fullName = strdup(driver->readerName);
|
readerTracker[i].fullName = strdup(driver->readerName);
|
||||||
|
|
||||||
if (RFAddReader(readerTracker[i].fullName, PCSCLITE_HP_BASE_PORT + i,
|
LONG ret;
|
||||||
driver->libraryPath, deviceName) == SCARD_S_SUCCESS)
|
ret = RFAddReader(readerTracker[i].fullName, PCSCLITE_HP_BASE_PORT + i,
|
||||||
readerTracker[i].status = READER_PRESENT;
|
driver->libraryPath, deviceName);
|
||||||
else
|
/* success by default */
|
||||||
|
readerTracker[i].status = READER_PRESENT;
|
||||||
|
if ((SCARD_S_SUCCESS != ret) && (SCARD_E_UNKNOWN_READER != ret))
|
||||||
{
|
{
|
||||||
readerTracker[i].status = READER_FAILED;
|
Log2(PCSC_LOG_ERROR, "Failed adding USB device: %s",
|
||||||
|
driver->readerName);
|
||||||
|
|
||||||
(void)CheckForOpenCT();
|
if (classdriver && driver != classdriver)
|
||||||
|
{
|
||||||
|
/* the reader can also be used by the a class driver */
|
||||||
|
ret = RFAddReader(readerTracker[i].fullName,
|
||||||
|
PCSCLITE_HP_BASE_PORT + i,
|
||||||
|
classdriver->libraryPath, deviceName);
|
||||||
|
if ((SCARD_S_SUCCESS != ret) && (SCARD_E_UNKNOWN_READER != ret))
|
||||||
|
{
|
||||||
|
Log2(PCSC_LOG_ERROR, "Failed adding USB device: %s",
|
||||||
|
driver->readerName);
|
||||||
|
readerTracker[i].status = READER_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
readerTracker[i].status = READER_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (READER_FAILED == readerTracker[i].status)
|
||||||
|
(void)CheckForOpenCT();
|
||||||
|
|
||||||
pthread_mutex_unlock(&usbNotifierMutex);
|
pthread_mutex_unlock(&usbNotifierMutex);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -654,7 +786,8 @@ void HPReCheckSerialReaders(void)
|
||||||
if (rescan_pipe[1] >= 0)
|
if (rescan_pipe[1] >= 0)
|
||||||
{
|
{
|
||||||
char dummy = 0;
|
char dummy = 0;
|
||||||
write(rescan_pipe[1], &dummy, sizeof(dummy));
|
if (write(rescan_pipe[1], &dummy, sizeof(dummy)) == -1)
|
||||||
|
Log2(PCSC_LOG_ERROR, "write: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,7 @@ static void HPEstablishUSBNotifications(void)
|
||||||
int deviceNumber;
|
int deviceNumber;
|
||||||
int suspectDeviceNumber;
|
int suspectDeviceNumber;
|
||||||
char dirpath[FILENAME_MAX];
|
char dirpath[FILENAME_MAX];
|
||||||
char filename[FILENAME_MAX];
|
char filename[FILENAME_MAX * 2];
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
struct usb_device_descriptor usbDescriptor;
|
struct usb_device_descriptor usbDescriptor;
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* Set the protocol type selection (PTS).
|
* Set the protocol type selection (PTS).
|
||||||
* This function sets the appropriate protocol to be used on the card.
|
* This function sets the appropriate protocol to be used on the card.
|
||||||
*/
|
*/
|
||||||
LONG IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol, UCHAR ucFlags,
|
RESPONSECODE IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol,
|
||||||
UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
|
UCHAR ucFlags, UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
|
||||||
{
|
{
|
||||||
RESPONSECODE rv;
|
RESPONSECODE rv;
|
||||||
|
|
||||||
|
@ -102,9 +102,9 @@ LONG IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol, UCHAR ucFlags,
|
||||||
/**
|
/**
|
||||||
* Open a communication channel to the IFD.
|
* Open a communication channel to the IFD.
|
||||||
*/
|
*/
|
||||||
LONG IFDOpenIFD(READER_CONTEXT * rContext)
|
RESPONSECODE IFDOpenIFD(READER_CONTEXT * rContext)
|
||||||
{
|
{
|
||||||
RESPONSECODE rv = 0;
|
RESPONSECODE rv = IFD_SUCCESS;
|
||||||
|
|
||||||
#ifndef PCSCLITE_STATIC_DRIVER
|
#ifndef PCSCLITE_STATIC_DRIVER
|
||||||
RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
|
RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
|
||||||
|
@ -160,7 +160,7 @@ LONG IFDOpenIFD(READER_CONTEXT * rContext)
|
||||||
/**
|
/**
|
||||||
* Close a communication channel to the IFD.
|
* Close a communication channel to the IFD.
|
||||||
*/
|
*/
|
||||||
LONG IFDCloseIFD(READER_CONTEXT * rContext)
|
RESPONSECODE IFDCloseIFD(READER_CONTEXT * rContext)
|
||||||
{
|
{
|
||||||
RESPONSECODE rv;
|
RESPONSECODE rv;
|
||||||
int repeat;
|
int repeat;
|
||||||
|
@ -201,7 +201,7 @@ again:
|
||||||
/**
|
/**
|
||||||
* Set capabilities in the reader.
|
* Set capabilities in the reader.
|
||||||
*/
|
*/
|
||||||
LONG IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
RESPONSECODE IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
||||||
DWORD dwLength, PUCHAR pucValue)
|
DWORD dwLength, PUCHAR pucValue)
|
||||||
{
|
{
|
||||||
RESPONSECODE rv;
|
RESPONSECODE rv;
|
||||||
|
@ -232,7 +232,7 @@ LONG IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
||||||
* Other functions int this file will call
|
* Other functions int this file will call
|
||||||
* the driver directly to not cause a deadlock.
|
* the driver directly to not cause a deadlock.
|
||||||
*/
|
*/
|
||||||
LONG IFDGetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
RESPONSECODE IFDGetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
||||||
PDWORD pdwLength, PUCHAR pucValue)
|
PDWORD pdwLength, PUCHAR pucValue)
|
||||||
{
|
{
|
||||||
RESPONSECODE rv;
|
RESPONSECODE rv;
|
||||||
|
@ -262,7 +262,7 @@ LONG IFDGetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
||||||
/**
|
/**
|
||||||
* Power up/down or reset's an ICC located in the IFD.
|
* Power up/down or reset's an ICC located in the IFD.
|
||||||
*/
|
*/
|
||||||
LONG IFDPowerICC(READER_CONTEXT * rContext, DWORD dwAction,
|
RESPONSECODE IFDPowerICC(READER_CONTEXT * rContext, DWORD dwAction,
|
||||||
PUCHAR pucAtr, PDWORD pdwAtrLen)
|
PUCHAR pucAtr, PDWORD pdwAtrLen)
|
||||||
{
|
{
|
||||||
RESPONSECODE rv;
|
RESPONSECODE rv;
|
||||||
|
@ -548,6 +548,9 @@ LONG IFDTransmit(READER_CONTEXT * rContext, SCARD_IO_HEADER pioTxPci,
|
||||||
return SCARD_E_READER_UNAVAILABLE;
|
return SCARD_E_READER_UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rv == IFD_ICC_NOT_PRESENT)
|
||||||
|
return SCARD_E_NO_SMARTCARD;
|
||||||
|
|
||||||
return SCARD_E_NOT_TRANSACTED;
|
return SCARD_E_NOT_TRANSACTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,13 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef __ifdwrapper_h__
|
#ifndef __ifdwrapper_h__
|
||||||
#define __ifdwrapper_h__
|
#define __ifdwrapper_h__
|
||||||
|
|
||||||
LONG IFDOpenIFD(READER_CONTEXT *);
|
#include "ifdhandler.h"
|
||||||
LONG IFDCloseIFD(READER_CONTEXT *);
|
#include "readerfactory.h"
|
||||||
LONG IFDPowerICC(READER_CONTEXT *, DWORD, PUCHAR, /*@out@*/ PDWORD);
|
#include "wintypes.h"
|
||||||
|
|
||||||
|
RESPONSECODE IFDOpenIFD(READER_CONTEXT *);
|
||||||
|
RESPONSECODE IFDCloseIFD(READER_CONTEXT *);
|
||||||
|
RESPONSECODE IFDPowerICC(READER_CONTEXT *, DWORD, PUCHAR, /*@out@*/ PDWORD);
|
||||||
LONG IFDStatusICC(READER_CONTEXT *, /*@out@*/ PDWORD);
|
LONG IFDStatusICC(READER_CONTEXT *, /*@out@*/ PDWORD);
|
||||||
LONG IFDControl_v2(READER_CONTEXT *, PUCHAR, DWORD, /*@out@*/ PUCHAR,
|
LONG IFDControl_v2(READER_CONTEXT *, PUCHAR, DWORD, /*@out@*/ PUCHAR,
|
||||||
PDWORD);
|
PDWORD);
|
||||||
|
@ -49,8 +53,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
DWORD, LPDWORD);
|
DWORD, LPDWORD);
|
||||||
LONG IFDTransmit(READER_CONTEXT *, SCARD_IO_HEADER,
|
LONG IFDTransmit(READER_CONTEXT *, SCARD_IO_HEADER,
|
||||||
PUCHAR, DWORD, /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER);
|
PUCHAR, DWORD, /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER);
|
||||||
LONG IFDSetPTS(READER_CONTEXT *, DWORD, UCHAR, UCHAR, UCHAR, UCHAR);
|
RESPONSECODE IFDSetPTS(READER_CONTEXT *, DWORD, UCHAR, UCHAR, UCHAR, UCHAR);
|
||||||
LONG IFDSetCapabilities(READER_CONTEXT *, DWORD, DWORD, PUCHAR);
|
RESPONSECODE IFDSetCapabilities(READER_CONTEXT *, DWORD, DWORD, PUCHAR);
|
||||||
LONG IFDGetCapabilities(READER_CONTEXT *, DWORD, PDWORD, /*@out@*/ PUCHAR);
|
RESPONSECODE IFDGetCapabilities(READER_CONTEXT *, DWORD, PDWORD, /*@out@*/ PUCHAR);
|
||||||
|
|
||||||
#endif /* __ifdwrapper_h__ */
|
#endif /* __ifdwrapper_h__ */
|
||||||
|
|
|
@ -42,14 +42,14 @@
|
||||||
#define SCARD_INSERTED 0x0002 /**< Card was inserted */
|
#define SCARD_INSERTED 0x0002 /**< Card was inserted */
|
||||||
#define SCARD_REMOVED 0x0004 /**< Card was removed */
|
#define SCARD_REMOVED 0x0004 /**< Card was removed */
|
||||||
|
|
||||||
#define PCSCLITE_CONFIG_DIR "/usr/local/etc/reader.conf.d"
|
#define PCSCLITE_CONFIG_DIR "/etc/reader.conf.d"
|
||||||
|
|
||||||
#define PCSCLITE_IPC_DIR USE_IPCDIR
|
#define PCSCLITE_IPC_DIR USE_IPCDIR
|
||||||
#define PCSCLITE_RUN_PID PCSCLITE_IPC_DIR "/pcscd.pid"
|
#define PCSCLITE_RUN_PID PCSCLITE_IPC_DIR "/pcscd.pid"
|
||||||
|
|
||||||
#define PCSCLITE_CSOCK_NAME PCSCLITE_IPC_DIR "/pcscd.comm"
|
#define PCSCLITE_CSOCK_NAME PCSCLITE_IPC_DIR "/pcscd.comm"
|
||||||
|
|
||||||
#define PCSCLITE_VERSION_NUMBER "1.9.0" /**< Current version */
|
#define PCSCLITE_VERSION_NUMBER "1.9.1" /**< Current version */
|
||||||
#define PCSCLITE_STATUS_POLL_RATE 400000 /**< Status polling rate */
|
#define PCSCLITE_STATUS_POLL_RATE 400000 /**< Status polling rate */
|
||||||
#define PCSCLITE_LOCK_POLL_RATE 100000 /**< Lock polling rate */
|
#define PCSCLITE_LOCK_POLL_RATE 100000 /**< Lock polling rate */
|
||||||
|
|
||||||
|
|
|
@ -839,7 +839,7 @@ static void print_version(void)
|
||||||
printf("Copyright (C) 1999-2002 by David Corcoran <corcoran@musclecard.com>.\n");
|
printf("Copyright (C) 1999-2002 by David Corcoran <corcoran@musclecard.com>.\n");
|
||||||
printf("Copyright (C) 2001-2018 by Ludovic Rousseau <ludovic.rousseau@free.fr>.\n");
|
printf("Copyright (C) 2001-2018 by Ludovic Rousseau <ludovic.rousseau@free.fr>.\n");
|
||||||
printf("Copyright (C) 2003-2004 by Damien Sauveron <sauveron@labri.fr>.\n");
|
printf("Copyright (C) 2003-2004 by Damien Sauveron <sauveron@labri.fr>.\n");
|
||||||
printf("Report bugs to <pcsclite-muscle@lists.alioth.debian.org>.\n");
|
printf("Report bugs to <pcsclite-muscle@lists.infradead.org>.\n");
|
||||||
|
|
||||||
printf ("Enabled features:%s\n", PCSCLITE_FEATURES);
|
printf ("Enabled features:%s\n", PCSCLITE_FEATURES);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ DWORD PHSetProtocol(struct ReaderContext * rContext,
|
||||||
UCHAR ucChosen;
|
UCHAR ucChosen;
|
||||||
|
|
||||||
/* App has specified no protocol */
|
/* App has specified no protocol */
|
||||||
if (dwPreferred == 0)
|
if (dwPreferred == SCARD_PROTOCOL_UNDEFINED)
|
||||||
return SET_PROTOCOL_WRONG_ARGUMENT;
|
return SET_PROTOCOL_WRONG_ARGUMENT;
|
||||||
|
|
||||||
/* requested protocol is not available */
|
/* requested protocol is not available */
|
||||||
|
@ -108,27 +108,38 @@ DWORD PHSetProtocol(struct ReaderContext * rContext,
|
||||||
(SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1));
|
(SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1));
|
||||||
rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00);
|
rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00);
|
||||||
|
|
||||||
if (IFD_SUCCESS == rv)
|
switch(rv)
|
||||||
protocol = ucChosen;
|
{
|
||||||
else
|
case IFD_SUCCESS:
|
||||||
if (IFD_NOT_SUPPORTED == rv)
|
protocol = ucChosen;
|
||||||
Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d",
|
break;
|
||||||
(SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
|
|
||||||
else
|
case IFD_NOT_SUPPORTED:
|
||||||
if (IFD_PROTOCOL_NOT_SUPPORTED == rv)
|
case IFD_PROTOCOL_NOT_SUPPORTED:
|
||||||
Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d",
|
case IFD_ERROR_NOT_SUPPORTED:
|
||||||
|
if (protocol != dwPreferred)
|
||||||
|
{
|
||||||
|
Log3(PCSC_LOG_INFO,
|
||||||
|
"Set PTS failed (%ld). Using T=%d", rv,
|
||||||
(SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
|
(SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log3(PCSC_LOG_INFO, "PTS failed (%ld), using T=%d", rv,
|
/* no other protocol to use */
|
||||||
(SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
|
Log2(PCSC_LOG_INFO, "PTS protocol failed (%ld)", rv);
|
||||||
|
protocol = SET_PROTOCOL_PPS_FAILED;
|
||||||
/* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14
|
|
||||||
* - If the PPS exchange is unsuccessful, then the interface device
|
|
||||||
* shall either reset or reject the card.
|
|
||||||
*/
|
|
||||||
return SET_PROTOCOL_PPS_FAILED;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log2(PCSC_LOG_INFO, "Set PTS failed (%ld)", rv);
|
||||||
|
|
||||||
|
/* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14
|
||||||
|
* - If the PPS exchange is unsuccessful, then the interface
|
||||||
|
* device shall either reset or reject the card.
|
||||||
|
*/
|
||||||
|
protocol = SET_PROTOCOL_PPS_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
return protocol;
|
return protocol;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef __prothandler_h__
|
#ifndef __prothandler_h__
|
||||||
#define __prothandler_h__
|
#define __prothandler_h__
|
||||||
|
|
||||||
|
#include "readerfactory.h"
|
||||||
|
#include "wintypes.h"
|
||||||
|
|
||||||
DWORD PHSetProtocol(struct ReaderContext *, DWORD, UCHAR, UCHAR);
|
DWORD PHSetProtocol(struct ReaderContext *, DWORD, UCHAR, UCHAR);
|
||||||
|
|
||||||
#define SET_PROTOCOL_WRONG_ARGUMENT -1
|
#define SET_PROTOCOL_WRONG_ARGUMENT -1
|
||||||
|
|
|
@ -372,8 +372,12 @@ LONG RFAddReader(const char *readerNameLong, int port, const char *library,
|
||||||
rv = RFInitializeReader(sReadersContexts[dwContext]);
|
rv = RFInitializeReader(sReadersContexts[dwContext]);
|
||||||
if (rv != SCARD_S_SUCCESS)
|
if (rv != SCARD_S_SUCCESS)
|
||||||
{
|
{
|
||||||
|
int log_level = PCSC_LOG_ERROR;
|
||||||
|
if (SCARD_E_UNKNOWN_READER == rv)
|
||||||
|
log_level = PCSC_LOG_INFO;
|
||||||
|
|
||||||
/* Cannot connect to reader. Exit gracefully */
|
/* Cannot connect to reader. Exit gracefully */
|
||||||
Log2(PCSC_LOG_ERROR, "%s init failed.", readerName);
|
Log2(log_level, "%s init failed.", readerName);
|
||||||
(void)RFRemoveReader(readerName, port);
|
(void)RFRemoveReader(readerName, port);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -595,7 +599,7 @@ LONG RFRemoveReader(const char *readerName, int port)
|
||||||
|
|
||||||
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
|
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
|
||||||
{
|
{
|
||||||
if (sReadersContexts[i]->vHandle != 0)
|
if (sReadersContexts[i] && (sReadersContexts[i]->vHandle != 0))
|
||||||
{
|
{
|
||||||
strncpy(lpcStripReader,
|
strncpy(lpcStripReader,
|
||||||
sReadersContexts[i]->readerState->readerName,
|
sReadersContexts[i]->readerState->readerName,
|
||||||
|
@ -1068,7 +1072,8 @@ LONG RFUnlockAllSharing(SCARDHANDLE hCard, READER_CONTEXT * rContext)
|
||||||
|
|
||||||
LONG RFInitializeReader(READER_CONTEXT * rContext)
|
LONG RFInitializeReader(READER_CONTEXT * rContext)
|
||||||
{
|
{
|
||||||
LONG rv;
|
LONG rv = SCARD_S_SUCCESS;
|
||||||
|
RESPONSECODE rvd;
|
||||||
|
|
||||||
/* Spawn the event handler thread */
|
/* Spawn the event handler thread */
|
||||||
Log3(PCSC_LOG_INFO, "Attempting startup of %s using %s",
|
Log3(PCSC_LOG_INFO, "Attempting startup of %s using %s",
|
||||||
|
@ -1098,26 +1103,29 @@ LONG RFInitializeReader(READER_CONTEXT * rContext)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* tries to open the port */
|
/* tries to open the port */
|
||||||
rv = IFDOpenIFD(rContext);
|
rvd = IFDOpenIFD(rContext);
|
||||||
|
|
||||||
if (rv != IFD_SUCCESS)
|
if (rvd != IFD_SUCCESS)
|
||||||
{
|
{
|
||||||
Log3(PCSC_LOG_CRITICAL, "Open Port 0x%X Failed (%s)",
|
int log_level = PCSC_LOG_CRITICAL;
|
||||||
|
rv = SCARD_E_INVALID_TARGET;
|
||||||
|
|
||||||
|
if (IFD_NO_SUCH_DEVICE == rvd)
|
||||||
|
{
|
||||||
|
/* wrong interface on a composite device? */
|
||||||
|
log_level = PCSC_LOG_INFO;
|
||||||
|
rv = SCARD_E_UNKNOWN_READER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log3(log_level, "Open Port 0x%X Failed (%s)",
|
||||||
rContext->port, rContext->device);
|
rContext->port, rContext->device);
|
||||||
|
|
||||||
|
/* IFDOpenIFD() failed */
|
||||||
/* the reader was not started correctly */
|
/* the reader was not started correctly */
|
||||||
rContext->slot = -1;
|
rContext->slot = -1;
|
||||||
|
|
||||||
/* IFDOpenIFD() failed */
|
|
||||||
rContext->slot = -1;
|
|
||||||
|
|
||||||
if (IFD_NO_SUCH_DEVICE == rv)
|
|
||||||
return SCARD_E_UNKNOWN_READER;
|
|
||||||
else
|
|
||||||
return SCARD_E_INVALID_TARGET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SCARD_S_SUCCESS;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFUnInitializeReader(READER_CONTEXT * rContext)
|
void RFUnInitializeReader(READER_CONTEXT * rContext)
|
||||||
|
@ -1373,6 +1381,8 @@ void RFCleanupReaders(void)
|
||||||
Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08lX", rv);
|
Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08lX", rv);
|
||||||
|
|
||||||
free(sReadersContexts[i]);
|
free(sReadersContexts[i]);
|
||||||
|
|
||||||
|
sReadersContexts[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
# @configure_input@
|
# @configure_input@
|
||||||
|
|
||||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||||
|
|
|
@ -91,6 +91,8 @@ static const char * internal_stringify_error(void)
|
||||||
return "No spy pcsc_stringify_error() function";
|
return "No spy pcsc_stringify_error() function";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||||
/* contains pointers to real functions */
|
/* contains pointers to real functions */
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
|
@ -135,6 +137,7 @@ static struct
|
||||||
.SCardSetAttrib = (p_SCardSetAttrib(*))internal_error,
|
.SCardSetAttrib = (p_SCardSetAttrib(*))internal_error,
|
||||||
.pcsc_stringify_error = (p_pcsc_stringify_error(*))internal_stringify_error
|
.pcsc_stringify_error = (p_pcsc_stringify_error(*))internal_stringify_error
|
||||||
};
|
};
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
#define LOG log_line("%s:%d", __FILE__, __LINE__)
|
#define LOG log_line("%s:%d", __FILE__, __LINE__)
|
||||||
|
|
||||||
|
|
|
@ -600,7 +600,7 @@ LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
|
||||||
/*
|
/*
|
||||||
* Set up the status bit masks on readerState
|
* Set up the status bit masks on readerState
|
||||||
*/
|
*/
|
||||||
if (rv == SCARD_S_SUCCESS)
|
if (rv == IFD_SUCCESS)
|
||||||
{
|
{
|
||||||
rContext->readerState->cardAtrLength = dwAtrLen;
|
rContext->readerState->cardAtrLength = dwAtrLen;
|
||||||
rContext->readerState->readerState =
|
rContext->readerState->readerState =
|
||||||
|
@ -907,7 +907,7 @@ LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||||
/* the protocol is unset after a power on */
|
/* the protocol is unset after a power on */
|
||||||
rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
|
rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
|
||||||
|
|
||||||
if (rv == SCARD_S_SUCCESS)
|
if (rv == IFD_SUCCESS)
|
||||||
{
|
{
|
||||||
if (SCARD_UNPOWER_CARD == dwDisposition)
|
if (SCARD_UNPOWER_CARD == dwDisposition)
|
||||||
rContext->readerState->readerState = SCARD_PRESENT;
|
rContext->readerState->readerState = SCARD_PRESENT;
|
||||||
|
@ -1156,7 +1156,7 @@ LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||||
/*
|
/*
|
||||||
* Set up the status bit masks on readerState
|
* Set up the status bit masks on readerState
|
||||||
*/
|
*/
|
||||||
if (rv == SCARD_S_SUCCESS)
|
if (rv == IFD_SUCCESS)
|
||||||
{
|
{
|
||||||
rContext->readerState->cardAtrLength = dwAtrLen;
|
rContext->readerState->cardAtrLength = dwAtrLen;
|
||||||
rContext->readerState->readerState =
|
rContext->readerState->readerState =
|
||||||
|
@ -1580,7 +1580,7 @@ LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned long prot = rContext->readerState->cardProtocol;
|
unsigned long prot = rContext->readerState->cardProtocol;
|
||||||
|
|
||||||
for (i = 0 ; prot != 1 ; i++)
|
for (i = 0 ; prot != 1 && i < 16; i++)
|
||||||
prot >>= 1;
|
prot >>= 1;
|
||||||
|
|
||||||
sSendPci.Protocol = i;
|
sSendPci.Protocol = i;
|
||||||
|
@ -1618,6 +1618,14 @@ LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
||||||
{
|
{
|
||||||
*pcbRecvLength = 0;
|
*pcbRecvLength = 0;
|
||||||
Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv);
|
Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv);
|
||||||
|
|
||||||
|
if (SCARD_E_NO_SMARTCARD == rv)
|
||||||
|
{
|
||||||
|
rContext->readerState->cardAtrLength = 0;
|
||||||
|
rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
|
||||||
|
rContext->readerState->readerState = SCARD_ABSENT;
|
||||||
|
}
|
||||||
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "pcsclite.h"
|
||||||
|
#include "wintypes.h"
|
||||||
|
|
||||||
/** Major version of the current message protocol */
|
/** Major version of the current message protocol */
|
||||||
#define PROTOCOL_VERSION_MAJOR 4
|
#define PROTOCOL_VERSION_MAJOR 4
|
||||||
/** Minor version of the current message protocol */
|
/** Minor version of the current message protocol */
|
||||||
|
|
|
@ -507,9 +507,15 @@ static void * ContextThread(LPVOID newContext)
|
||||||
coStr.dwActiveProtocol = dwActiveProtocol;
|
coStr.dwActiveProtocol = dwActiveProtocol;
|
||||||
|
|
||||||
if (coStr.rv == SCARD_S_SUCCESS)
|
if (coStr.rv == SCARD_S_SUCCESS)
|
||||||
|
{
|
||||||
coStr.rv = MSGAddHandle(coStr.hContext, coStr.hCard,
|
coStr.rv = MSGAddHandle(coStr.hContext, coStr.hCard,
|
||||||
threadContext);
|
threadContext);
|
||||||
|
|
||||||
|
/* if storing the hCard fails we disconnect */
|
||||||
|
if (coStr.rv != SCARD_S_SUCCESS)
|
||||||
|
SCardDisconnect(coStr.hCard, SCARD_LEAVE_CARD);
|
||||||
|
}
|
||||||
|
|
||||||
WRITE_BODY(coStr);
|
WRITE_BODY(coStr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -963,7 +969,7 @@ static LONG MSGAddHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard,
|
||||||
if (listLength >= contextMaxCardHandles)
|
if (listLength >= contextMaxCardHandles)
|
||||||
{
|
{
|
||||||
Log4(PCSC_LOG_DEBUG,
|
Log4(PCSC_LOG_DEBUG,
|
||||||
"Too many card handles for thread context @%p: %d (max is %d)"
|
"Too many card handles for thread context @%p: %d (max is %d). "
|
||||||
"Restart pcscd with --max-card-handle-per-thread value",
|
"Restart pcscd with --max-card-handle-per-thread value",
|
||||||
threadContext, listLength, contextMaxCardHandles);
|
threadContext, listLength, contextMaxCardHandles);
|
||||||
retval = SCARD_E_NO_MEMORY;
|
retval = SCARD_E_NO_MEMORY;
|
||||||
|
|
|
@ -41,6 +41,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef __winscard_svc_h__
|
#ifndef __winscard_svc_h__
|
||||||
#define __winscard_svc_h__
|
#define __winscard_svc_h__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "wintypes.h"
|
||||||
|
|
||||||
LONG ContextsInitialize(int, int);
|
LONG ContextsInitialize(int, int);
|
||||||
void ContextsDeinitialize(void);
|
void ContextsDeinitialize(void);
|
||||||
LONG CreateContextThread(uint32_t *);
|
LONG CreateContextThread(uint32_t *);
|
||||||
|
|
Loading…
Reference in New Issue