From a82d98a93da2fed31aa83dd02fb69522895852c8 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Sun, 28 Jul 2013 13:43:49 +0200 Subject: [PATCH] copied helper files from PCSC-Lite --- virtualsmartcard/configure.ac | 4 +- virtualsmartcard/src/libpcsclite/Makefile.am | 5 +- virtualsmartcard/src/libpcsclite/debug.c | 132 +++++++++++ virtualsmartcard/src/libpcsclite/error.c | 208 ++++++++++++++++++ .../src/libpcsclite/libpcsclite.pc.in | 2 +- virtualsmartcard/src/libpcsclite/misc.h | 58 +++++ virtualsmartcard/src/libpcsclite/strlcpy.c | 60 +++++ virtualsmartcard/src/libpcsclite/strlcpycat.h | 24 ++ virtualsmartcard/src/libpcsclite/winscard.c | 131 ----------- 9 files changed, 488 insertions(+), 136 deletions(-) create mode 100644 virtualsmartcard/src/libpcsclite/debug.c create mode 100644 virtualsmartcard/src/libpcsclite/error.c create mode 100644 virtualsmartcard/src/libpcsclite/misc.h create mode 100644 virtualsmartcard/src/libpcsclite/strlcpy.c create mode 100644 virtualsmartcard/src/libpcsclite/strlcpycat.h diff --git a/virtualsmartcard/configure.ac b/virtualsmartcard/configure.ac index d098a47..7eeea1b 100644 --- a/virtualsmartcard/configure.ac +++ b/virtualsmartcard/configure.ac @@ -117,9 +117,9 @@ AC_ARG_ENABLE(vpcdhost, [vpcdhost="${enableval}"], [vpcdhost=/dev/null]) AC_SUBST(vpcdhost) if test "${vpcdhost}" = "/dev/null"; then - AC_DEFINE_UNQUOTED(VPCDHOST, NULL, [OpenPICC character device]) + AC_DEFINE_UNQUOTED(VPCDHOST, NULL, [address of vicc]) else - AC_DEFINE_UNQUOTED(VPCDHOST, "${vpcdhost}", [OpenPICC character device]) + AC_DEFINE_UNQUOTED(VPCDHOST, "${vpcdhost}", [address of vicc]) fi diff --git a/virtualsmartcard/src/libpcsclite/Makefile.am b/virtualsmartcard/src/libpcsclite/Makefile.am index 6b40e9b..1b6b98b 100644 --- a/virtualsmartcard/src/libpcsclite/Makefile.am +++ b/virtualsmartcard/src/libpcsclite/Makefile.am @@ -4,9 +4,10 @@ lib_LTLIBRARIES = libpcsclite.la libpcsclite_la_CPPFLAGS = $(PCSC_CFLAGS) -I$(srcdir)/../vpcd libpcsclite_la_LDFLAGS = -no-undefined -libpcsclite_la_SOURCES = winscard.c $(top_builddir)/src/vpcd/libvpcd.la +libpcsclite_la_SOURCES = winscard.c debug.c strlcpy.c error.c \ + $(top_builddir)/src/vpcd/libvpcd.la -noinst_HEADERS = pcsclite.h +noinst_HEADERS = pcsclite.h strlcpycat.h misc.h nobase_include_HEADERS = \ PCSC/pcsclite.h \ diff --git a/virtualsmartcard/src/libpcsclite/debug.c b/virtualsmartcard/src/libpcsclite/debug.c new file mode 100644 index 0000000..7713f61 --- /dev/null +++ b/virtualsmartcard/src/libpcsclite/debug.c @@ -0,0 +1,132 @@ +/* + * MUSCLE SmartCard Development ( http://www.linuxnet.com ) + * + * Copyright (C) 1999-2002 + * David Corcoran + * Copyright (C) 2002-2011 + * Ludovic Rousseau + * + * $Id: debug.c 6551 2013-03-06 13:44:17Z rousseau $ + */ + +/** + * @file + * @brief This handles debugging for libpcsclite. + */ + +#include "config.h" +#include +#include +#include +#include +#include + +#include "debuglog.h" +#include "strlcpycat.h" + +#define DEBUG_BUF_SIZE 2048 + +#ifdef NO_LOG + +void log_msg(const int priority, const char *fmt, ...) +{ + (void)priority; + (void)fmt; +} + +#else + +/** default level is quiet to avoid polluting fd 2 (possibly NOT stderr) */ +static char LogLevel = 20; + +static signed char LogDoColor = 0; /**< no color by default */ + +static void log_init(void) +{ + char *e; + +#ifdef LIBPCSCLITE + e = getenv("PCSCLITE_DEBUG"); +#else + e = getenv("MUSCLECARD_DEBUG"); +#endif + if (e) + LogLevel = atoi(e); + + /* log to stderr and stderr is a tty? */ + if (isatty(fileno(stderr))) + { + char *term; + + term = getenv("TERM"); + if (term) + { + const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" }; + unsigned int i; + + /* for each known color terminal */ + for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++) + { + /* we found a supported term? */ + if (0 == strcmp(terms[i], term)) + { + LogDoColor = 1; + break; + } + } + } + } +} /* log_init */ + +void log_msg(const int priority, const char *fmt, ...) +{ + char DebugBuffer[DEBUG_BUF_SIZE]; + va_list argptr; + static int is_initialized = 0; + + if (!is_initialized) + { + log_init(); + is_initialized = 1; + } + + if (priority < LogLevel) /* log priority lower than threshold? */ + return; + + va_start(argptr, fmt); + (void)vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr); + va_end(argptr); + + { + if (LogDoColor) + { + const char *color_pfx = "", *color_sfx = "\33[0m"; + + switch (priority) + { + case PCSC_LOG_CRITICAL: + color_pfx = "\33[01;31m"; /* bright + Red */ + break; + + case PCSC_LOG_ERROR: + color_pfx = "\33[35m"; /* Magenta */ + break; + + case PCSC_LOG_INFO: + color_pfx = "\33[34m"; /* Blue */ + break; + + case PCSC_LOG_DEBUG: + color_pfx = ""; /* normal (black) */ + color_sfx = ""; + break; + } + fprintf(stderr, "%s%s%s\n", color_pfx, DebugBuffer, color_sfx); + } + else + fprintf(stderr, "%s\n", DebugBuffer); + } +} /* log_msg */ + +#endif + diff --git a/virtualsmartcard/src/libpcsclite/error.c b/virtualsmartcard/src/libpcsclite/error.c new file mode 100644 index 0000000..6f2bb34 --- /dev/null +++ b/virtualsmartcard/src/libpcsclite/error.c @@ -0,0 +1,208 @@ +/* + * MUSCLE SmartCard Development ( http://www.linuxnet.com ) + * + * Copyright (C) 1999-2002 + * David Corcoran + * Copyright (C) 2006-2009 + * Ludovic Rousseau + * + * This file is dual licenced: + * - BSD-like, see the COPYING file + * - GNU Lesser General Licence 2.1 or (at your option) any later version. + * + * $Id: error.c 5964 2011-09-24 09:22:24Z rousseau $ + */ + +/** + * @file + * @brief This handles pcsc_stringify_error() + */ + +#include +#include + +#include "config.h" +#include "misc.h" +#include "pcsclite.h" +#include "strlcpycat.h" + +#ifdef NO_LOG +PCSC_API char* pcsc_stringify_error(const long pcscError) +{ + static char strError[] = "0x12345678"; + + snprintf(strError, sizeof(strError), "0x%08lX", pcscError); + + return strError; +} +#else +/** + * @brief Returns a human readable text for the given PC/SC error code. + * + * @ingroup API + * @param[in] pcscError Error code to be translated to text. + * + * @return Text representing the error code passed. + * + * @code + * SCARDCONTEXT hContext; + * LONG rv; + * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); + * if (rv != SCARD_S_SUCCESS) + * printf("SCardEstablishContext: %s (0x%lX)\n", + * pcsc_stringify_error(rv), rv); + * @endcode + */ +PCSC_API char* pcsc_stringify_error(const LONG pcscError) +{ + static char strError[75]; + + switch (pcscError) + { + case SCARD_S_SUCCESS: + (void)strlcpy(strError, "Command successful.", sizeof(strError)); + break; + case SCARD_F_INTERNAL_ERROR: + (void)strlcpy(strError, "Internal error.", sizeof(strError)); + break; + case SCARD_E_CANCELLED: + (void)strlcpy(strError, "Command cancelled.", sizeof(strError)); + break; + case SCARD_E_INVALID_HANDLE: + (void)strlcpy(strError, "Invalid handle.", sizeof(strError)); + break; + case SCARD_E_INVALID_PARAMETER: + (void)strlcpy(strError, "Invalid parameter given.", sizeof(strError)); + break; + case SCARD_E_INVALID_TARGET: + (void)strlcpy(strError, "Invalid target given.", sizeof(strError)); + break; + case SCARD_E_NO_MEMORY: + (void)strlcpy(strError, "Not enough memory.", sizeof(strError)); + break; + case SCARD_F_WAITED_TOO_LONG: + (void)strlcpy(strError, "Waited too long.", sizeof(strError)); + break; + case SCARD_E_INSUFFICIENT_BUFFER: + (void)strlcpy(strError, "Insufficient buffer.", sizeof(strError)); + break; + case SCARD_E_UNKNOWN_READER: + (void)strlcpy(strError, "Unknown reader specified.", sizeof(strError)); + break; + case SCARD_E_TIMEOUT: + (void)strlcpy(strError, "Command timeout.", sizeof(strError)); + break; + case SCARD_E_SHARING_VIOLATION: + (void)strlcpy(strError, "Sharing violation.", sizeof(strError)); + break; + case SCARD_E_NO_SMARTCARD: + (void)strlcpy(strError, "No smart card inserted.", sizeof(strError)); + break; + case SCARD_E_UNKNOWN_CARD: + (void)strlcpy(strError, "Unknown card.", sizeof(strError)); + break; + case SCARD_E_CANT_DISPOSE: + (void)strlcpy(strError, "Cannot dispose handle.", sizeof(strError)); + break; + case SCARD_E_PROTO_MISMATCH: + (void)strlcpy(strError, "Card protocol mismatch.", sizeof(strError)); + break; + case SCARD_E_NOT_READY: + (void)strlcpy(strError, "Subsystem not ready.", sizeof(strError)); + break; + case SCARD_E_INVALID_VALUE: + (void)strlcpy(strError, "Invalid value given.", sizeof(strError)); + break; + case SCARD_E_SYSTEM_CANCELLED: + (void)strlcpy(strError, "System cancelled.", sizeof(strError)); + break; + case SCARD_F_COMM_ERROR: + (void)strlcpy(strError, "RPC transport error.", sizeof(strError)); + break; + case SCARD_F_UNKNOWN_ERROR: + (void)strlcpy(strError, "Unknown error.", sizeof(strError)); + break; + case SCARD_E_INVALID_ATR: + (void)strlcpy(strError, "Invalid ATR.", sizeof(strError)); + break; + case SCARD_E_NOT_TRANSACTED: + (void)strlcpy(strError, "Transaction failed.", sizeof(strError)); + break; + case SCARD_E_READER_UNAVAILABLE: + (void)strlcpy(strError, "Reader is unavailable.", sizeof(strError)); + break; + /* case SCARD_P_SHUTDOWN: */ + case SCARD_E_PCI_TOO_SMALL: + (void)strlcpy(strError, "PCI struct too small.", sizeof(strError)); + break; + case SCARD_E_READER_UNSUPPORTED: + (void)strlcpy(strError, "Reader is unsupported.", sizeof(strError)); + break; + case SCARD_E_DUPLICATE_READER: + (void)strlcpy(strError, "Reader already exists.", sizeof(strError)); + break; + case SCARD_E_CARD_UNSUPPORTED: + (void)strlcpy(strError, "Card is unsupported.", sizeof(strError)); + break; + case SCARD_E_NO_SERVICE: + (void)strlcpy(strError, "Service not available.", sizeof(strError)); + break; + case SCARD_E_SERVICE_STOPPED: + (void)strlcpy(strError, "Service was stopped.", sizeof(strError)); + break; + /* case SCARD_E_UNEXPECTED: */ + /* case SCARD_E_ICC_CREATEORDER: */ + /* case SCARD_E_UNSUPPORTED_FEATURE: */ + /* case SCARD_E_DIR_NOT_FOUND: */ + /* case SCARD_E_NO_DIR: */ + /* case SCARD_E_NO_FILE: */ + /* case SCARD_E_NO_ACCESS: */ + /* case SCARD_E_WRITE_TOO_MANY: */ + /* case SCARD_E_BAD_SEEK: */ + /* case SCARD_E_INVALID_CHV: */ + /* case SCARD_E_UNKNOWN_RES_MNG: */ + /* case SCARD_E_NO_SUCH_CERTIFICATE: */ + /* case SCARD_E_CERTIFICATE_UNAVAILABLE: */ + case SCARD_E_NO_READERS_AVAILABLE: + (void)strlcpy(strError, "Cannot find a smart card reader.", sizeof(strError)); + break; + /* case SCARD_E_COMM_DATA_LOST: */ + /* case SCARD_E_NO_KEY_CONTAINER: */ + /* case SCARD_E_SERVER_TOO_BUSY: */ + case SCARD_W_UNSUPPORTED_CARD: + (void)strlcpy(strError, "Card is not supported.", sizeof(strError)); + break; + case SCARD_W_UNRESPONSIVE_CARD: + (void)strlcpy(strError, "Card is unresponsive.", sizeof(strError)); + break; + case SCARD_W_UNPOWERED_CARD: + (void)strlcpy(strError, "Card is unpowered.", sizeof(strError)); + break; + case SCARD_W_RESET_CARD: + (void)strlcpy(strError, "Card was reset.", sizeof(strError)); + break; + case SCARD_W_REMOVED_CARD: + (void)strlcpy(strError, "Card was removed.", sizeof(strError)); + break; + /* case SCARD_W_SECURITY_VIOLATION: */ + /* case SCARD_W_WRONG_CHV: */ + /* case SCARD_W_CHV_BLOCKED: */ + /* case SCARD_W_EOF: */ + /* case SCARD_W_CANCELLED_BY_USER: */ + /* case SCARD_W_CARD_NOT_AUTHENTICATED: */ + + case SCARD_E_UNSUPPORTED_FEATURE: + (void)strlcpy(strError, "Feature not supported.", sizeof(strError)); + break; + default: + (void)snprintf(strError, sizeof(strError)-1, "Unknown error: 0x%08lX", + pcscError); + }; + + /* add a null byte */ + strError[sizeof(strError)-1] = '\0'; + + return strError; +} +#endif + diff --git a/virtualsmartcard/src/libpcsclite/libpcsclite.pc.in b/virtualsmartcard/src/libpcsclite/libpcsclite.pc.in index 6fe9ca4..f59d02c 100644 --- a/virtualsmartcard/src/libpcsclite/libpcsclite.pc.in +++ b/virtualsmartcard/src/libpcsclite/libpcsclite.pc.in @@ -7,4 +7,4 @@ Name: @PACKAGE_NAME@ Description: PC/SC smart card interface Version: @VERSION@ Libs: -L${libdir} -lpcsclite -lvpcd -Cflags: -DNO_LOG -I${includedir} +Cflags: -I${includedir} diff --git a/virtualsmartcard/src/libpcsclite/misc.h b/virtualsmartcard/src/libpcsclite/misc.h new file mode 100644 index 0000000..77ffd36 --- /dev/null +++ b/virtualsmartcard/src/libpcsclite/misc.h @@ -0,0 +1,58 @@ +/* + * This handles GCC attributes + * + * MUSCLE SmartCard Development ( http://www.linuxnet.com ) + * + * Copyright (C) 2005-2010 + * Ludovic Rousseau + * + * $Id: misc.h 5434 2010-12-08 14:13:21Z rousseau $ + */ + +#ifndef __misc_h__ +#define __misc_h__ + +/* + * Declare the function as internal to the library: the function name is + * not exported and can't be used by a program linked to the library + * + * see http://gcc.gnu.org/onlinedocs/gcc-3.3.5/gcc/Function-Attributes.html#Function-Attributes + * see http://www.nedprod.com/programs/gccvisibility.html + */ +#if defined __GNUC__ && (! defined (__sun)) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) +#define INTERNAL __attribute__ ((visibility("hidden"))) +#define PCSC_API __attribute__ ((visibility("default"))) +#elif (! defined __GNUC__ ) && defined (__sun) +/* http://wikis.sun.com/display/SunStudio/Macros+for+Shared+Library+Symbol+Visibility */ +#define INTERNAL __hidden +#define PCSC_API __global +#else +#define INTERNAL +#define PCSC_API +#endif +#define EXTERNAL PCSC_API + +#if defined __GNUC__ + +/* GNU Compiler Collection (GCC) */ +#define CONSTRUCTOR __attribute__ ((constructor)) +#define DESTRUCTOR __attribute__ ((destructor)) + +#else + +/* SUN C compiler does not use __attribute__ but #pragma init (function) + * We can't use a # inside a #define so it is not possible to use + * #define CONSTRUCTOR_DECLARATION(x) #pragma init (x) + * The #pragma is used directly where needed */ + +/* any other */ +#define CONSTRUCTOR +#define DESTRUCTOR + +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#endif /* __misc_h__ */ diff --git a/virtualsmartcard/src/libpcsclite/strlcpy.c b/virtualsmartcard/src/libpcsclite/strlcpy.c new file mode 100644 index 0000000..1a612a3 --- /dev/null +++ b/virtualsmartcard/src/libpcsclite/strlcpy.c @@ -0,0 +1,60 @@ +/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_STRLCPY + +#include +#include +#include "strlcpycat.h" + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif diff --git a/virtualsmartcard/src/libpcsclite/strlcpycat.h b/virtualsmartcard/src/libpcsclite/strlcpycat.h new file mode 100644 index 0000000..d21f1e9 --- /dev/null +++ b/virtualsmartcard/src/libpcsclite/strlcpycat.h @@ -0,0 +1,24 @@ +/* + * MUSCLE SmartCard Development ( http://www.linuxnet.com ) + * + * Copyright (C) 2004-2010 + * Ludovic Rousseau + * + * $Id: strlcpycat.h 4974 2010-06-01 09:43:47Z rousseau $ + */ + +/** + * @file + * @brief prototypes of strlcpy()/strlcat() imported from OpenBSD + */ + +#ifdef HAVE_STRLCPY +#include +#else +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_STRLCAT +size_t strlcat(char *dst, const char *src, size_t siz); +#endif + diff --git a/virtualsmartcard/src/libpcsclite/winscard.c b/virtualsmartcard/src/libpcsclite/winscard.c index e60e135..78e6a2f 100644 --- a/virtualsmartcard/src/libpcsclite/winscard.c +++ b/virtualsmartcard/src/libpcsclite/winscard.c @@ -596,134 +596,3 @@ PCSC_API LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) return SCARD_S_SUCCESS; } - -/* copied from error.c of pcsc-lite-1.5.5 */ -char *pcsc_stringify_error(const long pcscError) -{ - static char strError[75]; - - switch (pcscError) { - case SCARD_S_SUCCESS: - (void)strncpy(strError, "Command successful.", sizeof(strError)); - break; - case SCARD_E_CANCELLED: - (void)strncpy(strError, "Command cancelled.", sizeof(strError)); - break; - case SCARD_E_CANT_DISPOSE: - (void)strncpy(strError, "Cannot dispose handle.", sizeof(strError)); - break; - case SCARD_E_INSUFFICIENT_BUFFER: - (void)strncpy(strError, "Insufficient buffer.", sizeof(strError)); - break; - case SCARD_E_INVALID_ATR: - (void)strncpy(strError, "Invalid ATR.", sizeof(strError)); - break; - case SCARD_E_INVALID_HANDLE: - (void)strncpy(strError, "Invalid handle.", sizeof(strError)); - break; - case SCARD_E_INVALID_PARAMETER: - (void)strncpy(strError, "Invalid parameter given.", sizeof(strError)); - break; - case SCARD_E_INVALID_TARGET: - (void)strncpy(strError, "Invalid target given.", sizeof(strError)); - break; - case SCARD_E_INVALID_VALUE: - (void)strncpy(strError, "Invalid value given.", sizeof(strError)); - break; - case SCARD_E_NO_MEMORY: - (void)strncpy(strError, "Not enough memory.", sizeof(strError)); - break; - case SCARD_F_COMM_ERROR: - (void)strncpy(strError, "RPC transport error.", sizeof(strError)); - break; - case SCARD_F_INTERNAL_ERROR: - (void)strncpy(strError, "Internal error.", sizeof(strError)); - break; - case SCARD_F_UNKNOWN_ERROR: - (void)strncpy(strError, "Unknown error.", sizeof(strError)); - break; - case SCARD_F_WAITED_TOO_LONG: - (void)strncpy(strError, "Waited too long.", sizeof(strError)); - break; - case SCARD_E_UNKNOWN_READER: - (void)strncpy(strError, "Unknown reader specified.", sizeof(strError)); - break; - case SCARD_E_TIMEOUT: - (void)strncpy(strError, "Command timeout.", sizeof(strError)); - break; - case SCARD_E_SHARING_VIOLATION: - (void)strncpy(strError, "Sharing violation.", sizeof(strError)); - break; - case SCARD_E_NO_SMARTCARD: - (void)strncpy(strError, "No smart card inserted.", sizeof(strError)); - break; - case SCARD_E_UNKNOWN_CARD: - (void)strncpy(strError, "Unknown card.", sizeof(strError)); - break; - case SCARD_E_PROTO_MISMATCH: - (void)strncpy(strError, "Card protocol mismatch.", sizeof(strError)); - break; - case SCARD_E_NOT_READY: - (void)strncpy(strError, "Subsystem not ready.", sizeof(strError)); - break; - case SCARD_E_SYSTEM_CANCELLED: - (void)strncpy(strError, "System cancelled.", sizeof(strError)); - break; - case SCARD_E_NOT_TRANSACTED: - (void)strncpy(strError, "Transaction failed.", sizeof(strError)); - break; - case SCARD_E_READER_UNAVAILABLE: - (void)strncpy(strError, "Reader is unavailable.", sizeof(strError)); - break; - case SCARD_W_UNSUPPORTED_CARD: - (void)strncpy(strError, "Card is not supported.", sizeof(strError)); - break; - case SCARD_W_UNRESPONSIVE_CARD: - (void)strncpy(strError, "Card is unresponsive.", sizeof(strError)); - break; - case SCARD_W_UNPOWERED_CARD: - (void)strncpy(strError, "Card is unpowered.", sizeof(strError)); - break; - case SCARD_W_RESET_CARD: - (void)strncpy(strError, "Card was reset.", sizeof(strError)); - break; - case SCARD_W_REMOVED_CARD: - (void)strncpy(strError, "Card was removed.", sizeof(strError)); - break; - case SCARD_STATE_PRESENT: - (void)strncpy(strError, "Card was inserted.", sizeof(strError)); - break; - case SCARD_E_UNSUPPORTED_FEATURE: - (void)strncpy(strError, "Feature not supported.", sizeof(strError)); - break; - case SCARD_E_PCI_TOO_SMALL: - (void)strncpy(strError, "PCI struct too small.", sizeof(strError)); - break; - case SCARD_E_READER_UNSUPPORTED: - (void)strncpy(strError, "Reader is unsupported.", sizeof(strError)); - break; - case SCARD_E_DUPLICATE_READER: - (void)strncpy(strError, "Reader already exists.", sizeof(strError)); - break; - case SCARD_E_CARD_UNSUPPORTED: - (void)strncpy(strError, "Card is unsupported.", sizeof(strError)); - break; - case SCARD_E_NO_SERVICE: - (void)strncpy(strError, "Service not available.", sizeof(strError)); - break; - case SCARD_E_SERVICE_STOPPED: - (void)strncpy(strError, "Service was stopped.", sizeof(strError)); - break; - case SCARD_E_NO_READERS_AVAILABLE: - (void)strncpy(strError, "Cannot find a smart card reader.", sizeof(strError)); - break; - default: - (void)snprintf(strError, sizeof(strError)-1, "Unkown error: 0x%08lX", - pcscError); - }; - - /* add a null byte */ - strError[sizeof(strError)-1] = '\0'; - - return strError; -}