Update upstream source from tag 'upstream/1.9.1'
Update to upstream version '1.9.1'
with Debian dir 5375534638
This commit is contained in:
commit
c6ab85d366
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
|
||||
14 June 2020
|
||||
- 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@
|
||||
|
||||
# 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 \
|
||||
$(top_srcdir)/src/PCSC/pcsclite.h.in AUTHORS COPYING ChangeLog \
|
||||
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)
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
|
@ -203,6 +203,8 @@ am__relativize = \
|
|||
GZIP_ENV = --best
|
||||
DIST_ARCHIVES = $(distdir).tar.bz2
|
||||
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
|
||||
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
|
||||
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
|
||||
|
@ -689,7 +691,7 @@ distcheck: dist
|
|||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||
--srcdir=../.. --prefix="$$dc_install_base" \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(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.
|
||||
|
||||
|
@ -311,7 +311,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
|
|||
[am__api_version='1.16'
|
||||
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.
|
||||
m4_if([$1], [1.16.2], [],
|
||||
m4_if([$1], [1.16.3], [],
|
||||
[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.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
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_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_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_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
MISSING="\${SHELL} '$am_aux_dir/missing'"
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --is-lightweight"; then
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# 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.
|
||||
|
@ -587,8 +587,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='pcsc-lite'
|
||||
PACKAGE_TARNAME='pcsc-lite'
|
||||
PACKAGE_VERSION='1.9.0'
|
||||
PACKAGE_STRING='pcsc-lite 1.9.0'
|
||||
PACKAGE_VERSION='1.9.1'
|
||||
PACKAGE_STRING='pcsc-lite 1.9.1'
|
||||
PACKAGE_BUGREPORT=''
|
||||
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.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
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]...
|
||||
|
||||
|
@ -1466,7 +1466,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
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
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1618,7 +1618,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
pcsc-lite configure 1.9.0
|
||||
pcsc-lite configure 1.9.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
|
@ -2094,7 +2094,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
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
|
||||
|
||||
$ $0 $@
|
||||
|
@ -2648,12 +2648,7 @@ program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
|
|||
am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
MISSING="\${SHELL} '$am_aux_dir/missing'"
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --is-lightweight"; then
|
||||
|
@ -2958,7 +2953,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='pcsc-lite'
|
||||
VERSION='1.9.0'
|
||||
VERSION='1.9.1'
|
||||
|
||||
|
||||
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
|
||||
# values after options handling.
|
||||
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
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -16263,7 +16258,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
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,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
AC_PREREQ([2.69])
|
||||
|
||||
AC_INIT([pcsc-lite],[1.9.0])
|
||||
AC_INIT([pcsc-lite],[1.9.1])
|
||||
AC_CONFIG_SRCDIR(src/pcscdaemon.c)
|
||||
AM_INIT_AUTOMAKE(1.8 dist-bzip2 no-dist-gzip)
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
SUBDIRS = . example
|
||||
|
||||
doc_DATA = \
|
||||
README.DAEMON README.polkit
|
||||
README.polkit
|
||||
|
||||
man_MANS = pcscd.8 reader.conf.5
|
||||
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@
|
||||
|
||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
@ -375,7 +375,7 @@ usbdropdir = @usbdropdir@
|
|||
usbdropdir_exp = @usbdropdir_exp@
|
||||
SUBDIRS = . example
|
||||
doc_DATA = \
|
||||
README.DAEMON README.polkit
|
||||
README.polkit
|
||||
|
||||
man_MANS = pcscd.8 reader.conf.5
|
||||
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@
|
||||
|
||||
# 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@
|
||||
|
||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
PROGRAM=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
|
||||
|
||||
|
||||
|
@ -2141,7 +2141,7 @@ include the following information:
|
|||
compiler: $LTCC
|
||||
compiler flags: $LTCFLAGS
|
||||
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`
|
||||
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@
|
||||
|
||||
# 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 */
|
||||
#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) */
|
||||
#define PCSCLITE_MAX_READERS_CONTEXTS 16
|
||||
|
||||
|
|
|
@ -75,15 +75,15 @@ short ATRDecodeAtr(int *availableProtocols, int *currentProtocol,
|
|||
LogXxd(PCSC_LOG_DEBUG, "ATR: ", pucAtr, dwLength);
|
||||
#endif
|
||||
|
||||
if (dwLength < 2)
|
||||
return 0; /** @retval 0 Atr must have TS and T0 */
|
||||
|
||||
/*
|
||||
* Zero out the bitmasks
|
||||
*/
|
||||
*availableProtocols = SCARD_PROTOCOL_UNDEFINED;
|
||||
*currentProtocol = SCARD_PROTOCOL_UNDEFINED;
|
||||
|
||||
if (dwLength < 2)
|
||||
return 0; /** @retval 0 Atr must have TS and T0 */
|
||||
|
||||
/*
|
||||
* Decode the TS byte
|
||||
*/
|
||||
|
@ -218,8 +218,8 @@ short ATRDecodeAtr(int *availableProtocols, int *currentProtocol,
|
|||
}
|
||||
|
||||
#ifdef ATR_DEBUG
|
||||
Log3(PCSC_LOG_DEBUG, "CurrentProtocol: %d, AvailableProtocols: %d",
|
||||
*currentProtocol, *availableProtocols);
|
||||
Log3(PCSC_LOG_DEBUG, "CurrentProtocol: T=%d, AvailableProtocols: %d",
|
||||
*currentProtocol - SCARD_PROTOCOL_T0, *availableProtocols);
|
||||
#endif
|
||||
|
||||
return 1; /** @retval 1 Success */
|
||||
|
|
|
@ -39,6 +39,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef __atrhandler_h__
|
||||
#define __atrhandler_h__
|
||||
|
||||
#include "wintypes.h"
|
||||
|
||||
/*
|
||||
* Decodes the ATR
|
||||
*/
|
||||
|
|
|
@ -35,6 +35,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef __configfile_h__
|
||||
#define __configfile_h__
|
||||
|
||||
#include "readerfactory.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
|
|
@ -38,6 +38,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef __dyn_generic_h__
|
||||
#define __dyn_generic_h__
|
||||
|
||||
#include "wintypes.h"
|
||||
|
||||
LONG DYN_LoadLibrary(void **, char *);
|
||||
LONG DYN_CloseLibrary(void **);
|
||||
LONG DYN_GetAddress(void *, /*@out@*/ void **, const char *, int);
|
||||
|
|
|
@ -104,7 +104,7 @@ LONG EHUnregisterClientForEvent(int32_t filedes)
|
|||
{
|
||||
LONG rv = EHTryToUnregisterClientForEvent(filedes);
|
||||
|
||||
if (rv < 0)
|
||||
if (rv != SCARD_S_SUCCESS)
|
||||
Log2(PCSC_LOG_ERROR, "Can't remove client: %d", filedes);
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -41,6 +41,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pcsclite.h"
|
||||
#include "readerfactory.h"
|
||||
#include "wintypes.h"
|
||||
|
||||
/**
|
||||
* Define an exported public reader state structure so each
|
||||
* 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__
|
||||
#define __hotplug_h__
|
||||
|
||||
#include "wintypes.h"
|
||||
|
||||
#ifndef PCSCLITE_HP_DROPDIR
|
||||
#define PCSCLITE_HP_DROPDIR "/usr/local/pcsc/drivers/"
|
||||
#endif
|
||||
|
|
|
@ -78,6 +78,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
extern char Add_Interface_In_Name;
|
||||
extern char Add_Serial_In_Name;
|
||||
|
||||
/* we use the default libusb context */
|
||||
|
@ -106,6 +107,7 @@ static struct _driverTracker
|
|||
char *libraryPath;
|
||||
char *readerName;
|
||||
int ifdCapabilities;
|
||||
char *CFBundleName;
|
||||
} *driverTracker = NULL;
|
||||
#define DRIVER_TRACKER_SIZE_STEP 8
|
||||
|
||||
|
@ -121,8 +123,10 @@ static struct _readerTracker
|
|||
|
||||
static LONG HPAddHotPluggable(struct libusb_device *dev,
|
||||
struct libusb_device_descriptor desc,
|
||||
const char bus_device[], int interface,
|
||||
struct _driverTracker *driver);
|
||||
const char bus_device[],
|
||||
const struct libusb_interface *idesc,
|
||||
struct _driverTracker *driver,
|
||||
struct _driverTracker *classdriver);
|
||||
static LONG HPRemoveHotPluggable(int reader_index);
|
||||
|
||||
static LONG HPReadBundleValues(void)
|
||||
|
@ -170,6 +174,7 @@ static LONG HPReadBundleValues(void)
|
|||
list_t *manuIDs, *productIDs, *readerNames;
|
||||
char *libraryPath;
|
||||
int ifdCapabilities;
|
||||
char *CFBundleName;
|
||||
|
||||
/*
|
||||
* 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_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 */
|
||||
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].libraryPath = strdup(fullLibPath);
|
||||
driverTracker[listCount].ifdCapabilities = ifdCapabilities;
|
||||
driverTracker[listCount].CFBundleName = CFBundleName;
|
||||
|
||||
#ifdef DEBUG_HOTPLUG
|
||||
Log2(PCSC_LOG_INFO, "Found driver for: %s",
|
||||
|
@ -255,6 +269,7 @@ static LONG HPReadBundleValues(void)
|
|||
driverTracker[i].libraryPath = NULL;
|
||||
driverTracker[i].readerName = NULL;
|
||||
driverTracker[i].ifdCapabilities = 0;
|
||||
driverTracker[i].CFBundleName = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -278,6 +293,44 @@ static LONG HPReadBundleValues(void)
|
|||
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)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -292,7 +345,8 @@ static void HPRescanUsbBus(void)
|
|||
cnt = libusb_get_device_list(ctx, &devs);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -304,78 +358,76 @@ static void HPRescanUsbBus(void)
|
|||
struct libusb_config_descriptor *config_desc;
|
||||
uint8_t bus_number = libusb_get_bus_number(dev);
|
||||
uint8_t device_address = libusb_get_device_address(dev);
|
||||
struct _driverTracker *driver, *classdriver;
|
||||
int interface;
|
||||
|
||||
int r = libusb_get_device_descriptor(dev, &desc);
|
||||
if (r < 0)
|
||||
{
|
||||
Log3(PCSC_LOG_ERROR, "failed to get device descriptor for %d/%d",
|
||||
bus_number, device_address);
|
||||
Log4(PCSC_LOG_ERROR,
|
||||
"failed to get device descriptor for %d/%d: %s",
|
||||
bus_number, device_address, libusb_error_name(r));
|
||||
continue;
|
||||
}
|
||||
|
||||
r = libusb_get_active_config_descriptor(dev, &config_desc);
|
||||
if (r < 0)
|
||||
{
|
||||
Log3(PCSC_LOG_ERROR, "failed to get device config for %d/%d",
|
||||
bus_number, device_address);
|
||||
Log4(PCSC_LOG_ERROR, "failed to get device config for %d/%d: %s",
|
||||
bus_number, device_address, libusb_error_name(r));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check if the device is supported by one driver */
|
||||
for (i=0; i<driverSize; i++)
|
||||
driver = get_driver(desc.idVendor, desc.idProduct, &classdriver);
|
||||
if (NULL == driver)
|
||||
{
|
||||
if (driverTracker[i].libraryPath != NULL &&
|
||||
desc.idVendor == driverTracker[i].manuID &&
|
||||
desc.idProduct == driverTracker[i].productID)
|
||||
/* not a smart card reader */
|
||||
#ifdef DEBUG_HOTPLUG
|
||||
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;
|
||||
|
||||
#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,
|
||||
if (strncmp(readerTracker[j].bus_device,
|
||||
bus_device, BUS_DEVICE_STRSIZE) == 0)
|
||||
{
|
||||
/* The reader is already known */
|
||||
readerTracker[j].status = READER_PRESENT;
|
||||
newreader = FALSE;
|
||||
{
|
||||
/* The reader is already known */
|
||||
readerTracker[j].status = READER_PRESENT;
|
||||
newreader = FALSE;
|
||||
#ifdef DEBUG_HOTPLUG
|
||||
Log2(PCSC_LOG_DEBUG, "Refresh USB device: %s",
|
||||
bus_device);
|
||||
Log2(PCSC_LOG_DEBUG, "Refresh USB device: %s",
|
||||
bus_device);
|
||||
#endif
|
||||
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]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* New reader found */
|
||||
if (newreader)
|
||||
HPAddHotPluggable(dev, desc, bus_device,
|
||||
&config_desc->interface[interface], driver, classdriver);
|
||||
}
|
||||
|
||||
libusb_free_config_descriptor(config_desc);
|
||||
}
|
||||
|
||||
|
@ -399,6 +451,7 @@ static void HPRescanUsbBus(void)
|
|||
free(driverTracker[i].bundleName);
|
||||
free(driverTracker[i].libraryPath);
|
||||
free(driverTracker[i].readerName);
|
||||
free(driverTracker[i].CFBundleName);
|
||||
}
|
||||
free(driverTracker);
|
||||
|
||||
|
@ -410,7 +463,7 @@ static void HPRescanUsbBus(void)
|
|||
libusb_free_device_list(devs, 1);
|
||||
}
|
||||
|
||||
static void HPEstablishUSBNotifications(int pipefd[2])
|
||||
static void * HPEstablishUSBNotifications(int pipefd[2])
|
||||
{
|
||||
int i, do_polling;
|
||||
int r;
|
||||
|
@ -419,17 +472,21 @@ static void HPEstablishUSBNotifications(int pipefd[2])
|
|||
r = libusb_init(ctx);
|
||||
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 */
|
||||
kill(getpid(), SIGTERM);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* scan the USB bus for devices at startup */
|
||||
HPRescanUsbBus();
|
||||
|
||||
/* 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 */
|
||||
do_polling = FALSE;
|
||||
|
@ -464,7 +521,11 @@ static void HPEstablishUSBNotifications(int pipefd[2])
|
|||
{
|
||||
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)
|
||||
{
|
||||
Log1(PCSC_LOG_INFO, "Reload serial configuration");
|
||||
|
@ -477,6 +538,8 @@ static void HPEstablishUSBNotifications(int pipefd[2])
|
|||
close(rescan_pipe[0]);
|
||||
rescan_pipe[0] = -1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LONG HPSearchHotPluggables(void)
|
||||
|
@ -505,7 +568,11 @@ LONG HPSearchHotPluggables(void)
|
|||
(PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, pipefd);
|
||||
|
||||
/* 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 */
|
||||
close(pipefd[0]);
|
||||
|
@ -529,21 +596,20 @@ LONG HPStopHotPluggables(void)
|
|||
|
||||
static LONG HPAddHotPluggable(struct libusb_device *dev,
|
||||
struct libusb_device_descriptor desc,
|
||||
const char bus_device[], int interface,
|
||||
struct _driverTracker *driver)
|
||||
const char bus_device[],
|
||||
const struct libusb_interface *idesc,
|
||||
struct _driverTracker *driver,
|
||||
struct _driverTracker *classdriver)
|
||||
{
|
||||
int i;
|
||||
uint8_t iInterface = 0;
|
||||
uint8_t iSerialNumber = 0;
|
||||
char deviceName[MAX_DEVICENAME];
|
||||
|
||||
Log2(PCSC_LOG_INFO, "Adding USB device: %s", bus_device);
|
||||
|
||||
if (interface >= 0)
|
||||
snprintf(deviceName, sizeof(deviceName), "usb:%04x/%04x:libhal:/org/freedesktop/Hal/devices/usb_device_%04x_%04x_serialnotneeded_if%d",
|
||||
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);
|
||||
snprintf(deviceName, sizeof(deviceName), "usb:%04x/%04x:libusb-1.0:%s",
|
||||
desc.idVendor, desc.idProduct, bus_device);
|
||||
|
||||
deviceName[sizeof(deviceName) -1] = '\0';
|
||||
|
||||
|
@ -567,8 +633,15 @@ static LONG HPAddHotPluggable(struct libusb_device *dev,
|
|||
strncpy(readerTracker[i].bus_device, bus_device,
|
||||
sizeof(readerTracker[i].bus_device));
|
||||
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;
|
||||
int ret;
|
||||
|
@ -576,45 +649,104 @@ static LONG HPAddHotPluggable(struct libusb_device *dev,
|
|||
ret = libusb_open(dev, &device);
|
||||
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
|
||||
{
|
||||
unsigned char interfaceName[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);
|
||||
|
||||
if (ret < 0)
|
||||
if (ret_interface > 0 && ret_serial > 0)
|
||||
{
|
||||
Log2(PCSC_LOG_ERROR,
|
||||
"libusb_get_string_descriptor_ascii failed: %d", ret);
|
||||
readerTracker[i].fullName = strdup(driver->readerName);
|
||||
snprintf(fullname, sizeof(fullname), "%s [%s] (%s)",
|
||||
driver->readerName, interfaceName, serialNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
char fullname[MAX_READERNAME];
|
||||
|
||||
snprintf(fullname, sizeof(fullname), "%s (%s)",
|
||||
driver->readerName, serialNumber);
|
||||
readerTracker[i].fullName = strdup(fullname);
|
||||
if (ret_interface > 0)
|
||||
{
|
||||
snprintf(fullname, sizeof(fullname), "%s [%s]",
|
||||
driver->readerName, interfaceName);
|
||||
}
|
||||
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);
|
||||
|
||||
if (RFAddReader(readerTracker[i].fullName, PCSCLITE_HP_BASE_PORT + i,
|
||||
driver->libraryPath, deviceName) == SCARD_S_SUCCESS)
|
||||
readerTracker[i].status = READER_PRESENT;
|
||||
else
|
||||
LONG ret;
|
||||
ret = RFAddReader(readerTracker[i].fullName, PCSCLITE_HP_BASE_PORT + i,
|
||||
driver->libraryPath, deviceName);
|
||||
/* 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);
|
||||
|
||||
return 1;
|
||||
|
@ -654,7 +786,8 @@ void HPReCheckSerialReaders(void)
|
|||
if (rescan_pipe[1] >= 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 suspectDeviceNumber;
|
||||
char dirpath[FILENAME_MAX];
|
||||
char filename[FILENAME_MAX];
|
||||
char filename[FILENAME_MAX * 2];
|
||||
int fd, ret;
|
||||
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).
|
||||
* This function sets the appropriate protocol to be used on the card.
|
||||
*/
|
||||
LONG IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol, UCHAR ucFlags,
|
||||
UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
|
||||
RESPONSECODE IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol,
|
||||
UCHAR ucFlags, UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
|
||||
{
|
||||
RESPONSECODE rv;
|
||||
|
||||
|
@ -102,9 +102,9 @@ LONG IFDSetPTS(READER_CONTEXT * rContext, DWORD dwProtocol, UCHAR ucFlags,
|
|||
/**
|
||||
* 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
|
||||
RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
|
||||
|
@ -160,7 +160,7 @@ LONG IFDOpenIFD(READER_CONTEXT * rContext)
|
|||
/**
|
||||
* Close a communication channel to the IFD.
|
||||
*/
|
||||
LONG IFDCloseIFD(READER_CONTEXT * rContext)
|
||||
RESPONSECODE IFDCloseIFD(READER_CONTEXT * rContext)
|
||||
{
|
||||
RESPONSECODE rv;
|
||||
int repeat;
|
||||
|
@ -201,7 +201,7 @@ again:
|
|||
/**
|
||||
* Set capabilities in the reader.
|
||||
*/
|
||||
LONG IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
||||
RESPONSECODE IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
||||
DWORD dwLength, PUCHAR pucValue)
|
||||
{
|
||||
RESPONSECODE rv;
|
||||
|
@ -232,7 +232,7 @@ LONG IFDSetCapabilities(READER_CONTEXT * rContext, DWORD dwTag,
|
|||
* Other functions int this file will call
|
||||
* 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)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
LONG IFDPowerICC(READER_CONTEXT * rContext, DWORD dwAction,
|
||||
RESPONSECODE IFDPowerICC(READER_CONTEXT * rContext, DWORD dwAction,
|
||||
PUCHAR pucAtr, PDWORD pdwAtrLen)
|
||||
{
|
||||
RESPONSECODE rv;
|
||||
|
@ -548,6 +548,9 @@ LONG IFDTransmit(READER_CONTEXT * rContext, SCARD_IO_HEADER pioTxPci,
|
|||
return SCARD_E_READER_UNAVAILABLE;
|
||||
}
|
||||
|
||||
if (rv == IFD_ICC_NOT_PRESENT)
|
||||
return SCARD_E_NO_SMARTCARD;
|
||||
|
||||
return SCARD_E_NOT_TRANSACTED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,13 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef __ifdwrapper_h__
|
||||
#define __ifdwrapper_h__
|
||||
|
||||
LONG IFDOpenIFD(READER_CONTEXT *);
|
||||
LONG IFDCloseIFD(READER_CONTEXT *);
|
||||
LONG IFDPowerICC(READER_CONTEXT *, DWORD, PUCHAR, /*@out@*/ PDWORD);
|
||||
#include "ifdhandler.h"
|
||||
#include "readerfactory.h"
|
||||
#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 IFDControl_v2(READER_CONTEXT *, PUCHAR, DWORD, /*@out@*/ PUCHAR,
|
||||
PDWORD);
|
||||
|
@ -49,8 +53,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
DWORD, LPDWORD);
|
||||
LONG IFDTransmit(READER_CONTEXT *, SCARD_IO_HEADER,
|
||||
PUCHAR, DWORD, /*@out@*/ PUCHAR, PDWORD, PSCARD_IO_HEADER);
|
||||
LONG IFDSetPTS(READER_CONTEXT *, DWORD, UCHAR, UCHAR, UCHAR, UCHAR);
|
||||
LONG IFDSetCapabilities(READER_CONTEXT *, DWORD, DWORD, PUCHAR);
|
||||
LONG IFDGetCapabilities(READER_CONTEXT *, DWORD, PDWORD, /*@out@*/ PUCHAR);
|
||||
RESPONSECODE IFDSetPTS(READER_CONTEXT *, DWORD, UCHAR, UCHAR, UCHAR, UCHAR);
|
||||
RESPONSECODE IFDSetCapabilities(READER_CONTEXT *, DWORD, DWORD, PUCHAR);
|
||||
RESPONSECODE IFDGetCapabilities(READER_CONTEXT *, DWORD, PDWORD, /*@out@*/ PUCHAR);
|
||||
|
||||
#endif /* __ifdwrapper_h__ */
|
||||
|
|
|
@ -42,14 +42,14 @@
|
|||
#define SCARD_INSERTED 0x0002 /**< Card was inserted */
|
||||
#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_RUN_PID PCSCLITE_IPC_DIR "/pcscd.pid"
|
||||
|
||||
#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_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) 2001-2018 by Ludovic Rousseau <ludovic.rousseau@free.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);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ DWORD PHSetProtocol(struct ReaderContext * rContext,
|
|||
UCHAR ucChosen;
|
||||
|
||||
/* App has specified no protocol */
|
||||
if (dwPreferred == 0)
|
||||
if (dwPreferred == SCARD_PROTOCOL_UNDEFINED)
|
||||
return SET_PROTOCOL_WRONG_ARGUMENT;
|
||||
|
||||
/* requested protocol is not available */
|
||||
|
@ -108,27 +108,38 @@ DWORD PHSetProtocol(struct ReaderContext * rContext,
|
|||
(SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1));
|
||||
rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
if (IFD_SUCCESS == rv)
|
||||
protocol = ucChosen;
|
||||
else
|
||||
if (IFD_NOT_SUPPORTED == rv)
|
||||
Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d",
|
||||
(SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
|
||||
else
|
||||
if (IFD_PROTOCOL_NOT_SUPPORTED == rv)
|
||||
Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d",
|
||||
switch(rv)
|
||||
{
|
||||
case IFD_SUCCESS:
|
||||
protocol = ucChosen;
|
||||
break;
|
||||
|
||||
case IFD_NOT_SUPPORTED:
|
||||
case IFD_PROTOCOL_NOT_SUPPORTED:
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log3(PCSC_LOG_INFO, "PTS failed (%ld), using T=%d", rv,
|
||||
(SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
|
||||
|
||||
/* 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;
|
||||
/* no other protocol to use */
|
||||
Log2(PCSC_LOG_INFO, "PTS protocol failed (%ld)", rv);
|
||||
protocol = 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;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef __prothandler_h__
|
||||
#define __prothandler_h__
|
||||
|
||||
#include "readerfactory.h"
|
||||
#include "wintypes.h"
|
||||
|
||||
DWORD PHSetProtocol(struct ReaderContext *, DWORD, UCHAR, UCHAR);
|
||||
|
||||
#define SET_PROTOCOL_WRONG_ARGUMENT -1
|
||||
|
|
|
@ -372,8 +372,12 @@ LONG RFAddReader(const char *readerNameLong, int port, const char *library,
|
|||
rv = RFInitializeReader(sReadersContexts[dwContext]);
|
||||
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 */
|
||||
Log2(PCSC_LOG_ERROR, "%s init failed.", readerName);
|
||||
Log2(log_level, "%s init failed.", readerName);
|
||||
(void)RFRemoveReader(readerName, port);
|
||||
return rv;
|
||||
}
|
||||
|
@ -595,7 +599,7 @@ LONG RFRemoveReader(const char *readerName, int port)
|
|||
|
||||
for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
|
||||
{
|
||||
if (sReadersContexts[i]->vHandle != 0)
|
||||
if (sReadersContexts[i] && (sReadersContexts[i]->vHandle != 0))
|
||||
{
|
||||
strncpy(lpcStripReader,
|
||||
sReadersContexts[i]->readerState->readerName,
|
||||
|
@ -1068,7 +1072,8 @@ LONG RFUnlockAllSharing(SCARDHANDLE hCard, READER_CONTEXT * rContext)
|
|||
|
||||
LONG RFInitializeReader(READER_CONTEXT * rContext)
|
||||
{
|
||||
LONG rv;
|
||||
LONG rv = SCARD_S_SUCCESS;
|
||||
RESPONSECODE rvd;
|
||||
|
||||
/* Spawn the event handler thread */
|
||||
Log3(PCSC_LOG_INFO, "Attempting startup of %s using %s",
|
||||
|
@ -1098,26 +1103,29 @@ LONG RFInitializeReader(READER_CONTEXT * rContext)
|
|||
#endif
|
||||
|
||||
/* 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);
|
||||
|
||||
/* IFDOpenIFD() failed */
|
||||
/* the reader was not started correctly */
|
||||
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)
|
||||
|
@ -1373,6 +1381,8 @@ void RFCleanupReaders(void)
|
|||
Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08lX", rv);
|
||||
|
||||
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@
|
||||
|
||||
# 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";
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
/* contains pointers to real functions */
|
||||
static struct
|
||||
{
|
||||
|
@ -135,6 +137,7 @@ static struct
|
|||
.SCardSetAttrib = (p_SCardSetAttrib(*))internal_error,
|
||||
.pcsc_stringify_error = (p_pcsc_stringify_error(*))internal_stringify_error
|
||||
};
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#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
|
||||
*/
|
||||
if (rv == SCARD_S_SUCCESS)
|
||||
if (rv == IFD_SUCCESS)
|
||||
{
|
||||
rContext->readerState->cardAtrLength = dwAtrLen;
|
||||
rContext->readerState->readerState =
|
||||
|
@ -907,7 +907,7 @@ LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
|||
/* the protocol is unset after a power on */
|
||||
rContext->readerState->cardProtocol = SCARD_PROTOCOL_UNDEFINED;
|
||||
|
||||
if (rv == SCARD_S_SUCCESS)
|
||||
if (rv == IFD_SUCCESS)
|
||||
{
|
||||
if (SCARD_UNPOWER_CARD == dwDisposition)
|
||||
rContext->readerState->readerState = SCARD_PRESENT;
|
||||
|
@ -1156,7 +1156,7 @@ LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
|
|||
/*
|
||||
* Set up the status bit masks on readerState
|
||||
*/
|
||||
if (rv == SCARD_S_SUCCESS)
|
||||
if (rv == IFD_SUCCESS)
|
||||
{
|
||||
rContext->readerState->cardAtrLength = dwAtrLen;
|
||||
rContext->readerState->readerState =
|
||||
|
@ -1580,7 +1580,7 @@ LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
|||
unsigned long i;
|
||||
unsigned long prot = rContext->readerState->cardProtocol;
|
||||
|
||||
for (i = 0 ; prot != 1 ; i++)
|
||||
for (i = 0 ; prot != 1 && i < 16; i++)
|
||||
prot >>= 1;
|
||||
|
||||
sSendPci.Protocol = i;
|
||||
|
@ -1618,6 +1618,14 @@ LONG SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
|||
{
|
||||
*pcbRecvLength = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pcsclite.h"
|
||||
#include "wintypes.h"
|
||||
|
||||
/** Major version of the current message protocol */
|
||||
#define PROTOCOL_VERSION_MAJOR 4
|
||||
/** Minor version of the current message protocol */
|
||||
|
|
|
@ -507,9 +507,15 @@ static void * ContextThread(LPVOID newContext)
|
|||
coStr.dwActiveProtocol = dwActiveProtocol;
|
||||
|
||||
if (coStr.rv == SCARD_S_SUCCESS)
|
||||
{
|
||||
coStr.rv = MSGAddHandle(coStr.hContext, coStr.hCard,
|
||||
threadContext);
|
||||
|
||||
/* if storing the hCard fails we disconnect */
|
||||
if (coStr.rv != SCARD_S_SUCCESS)
|
||||
SCardDisconnect(coStr.hCard, SCARD_LEAVE_CARD);
|
||||
}
|
||||
|
||||
WRITE_BODY(coStr);
|
||||
}
|
||||
break;
|
||||
|
@ -963,7 +969,7 @@ static LONG MSGAddHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard,
|
|||
if (listLength >= contextMaxCardHandles)
|
||||
{
|
||||
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",
|
||||
threadContext, listLength, contextMaxCardHandles);
|
||||
retval = SCARD_E_NO_MEMORY;
|
||||
|
|
|
@ -41,6 +41,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef __winscard_svc_h__
|
||||
#define __winscard_svc_h__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "wintypes.h"
|
||||
|
||||
LONG ContextsInitialize(int, int);
|
||||
void ContextsDeinitialize(void);
|
||||
LONG CreateContextThread(uint32_t *);
|
||||
|
|
Loading…
Reference in New Issue