246 lines
6.7 KiB
C
246 lines
6.7 KiB
C
/*
|
|
* MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
|
|
*
|
|
* Copyright (C) 1999-2002
|
|
* David Corcoran <corcoran@musclecard.com>
|
|
* Copyright (C) 2006-2009
|
|
* Ludovic Rousseau <ludovic.rousseau@free.fr>
|
|
*
|
|
* This file is dual licenced:
|
|
* - BSD-like, see the COPYING file
|
|
* - GNU Lesser General Licence 2.1 or (at your option) any later version.
|
|
*
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
3. The name of the author may not be used to endorse or promote products
|
|
derived from this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @brief This handles pcsc_stringify_error()
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
|
|
#include "config.h"
|
|
#include "misc.h"
|
|
#include "pcsclite.h"
|
|
#include "string.h"
|
|
|
|
#ifdef NO_LOG
|
|
PCSC_API const 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.
|
|
*
|
|
* @warning
|
|
* The returned string uses a Thread-Local Storage (TLS) buffer and is valid:
|
|
* -# only while the thread on which it was obtained is alive.
|
|
* -# until the next call to this function on the same thread.
|
|
*
|
|
* @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 const char* pcsc_stringify_error(const LONG pcscError)
|
|
{
|
|
/* Use a Thread-local storage so that the returned buffer
|
|
* is thread safe */
|
|
static __thread char strError[75];
|
|
const char *msg = NULL;
|
|
|
|
switch (pcscError)
|
|
{
|
|
case SCARD_S_SUCCESS:
|
|
msg = "Command successful.";
|
|
break;
|
|
case SCARD_F_INTERNAL_ERROR:
|
|
msg = "Internal error.";
|
|
break;
|
|
case SCARD_E_CANCELLED:
|
|
msg = "Command cancelled.";
|
|
break;
|
|
case SCARD_E_INVALID_HANDLE:
|
|
msg = "Invalid handle.";
|
|
break;
|
|
case SCARD_E_INVALID_PARAMETER:
|
|
msg = "Invalid parameter given.";
|
|
break;
|
|
case SCARD_E_INVALID_TARGET:
|
|
msg = "Invalid target given.";
|
|
break;
|
|
case SCARD_E_NO_MEMORY:
|
|
msg = "Not enough memory.";
|
|
break;
|
|
case SCARD_F_WAITED_TOO_LONG:
|
|
msg = "Waited too long.";
|
|
break;
|
|
case SCARD_E_INSUFFICIENT_BUFFER:
|
|
msg = "Insufficient buffer.";
|
|
break;
|
|
case SCARD_E_UNKNOWN_READER:
|
|
msg = "Unknown reader specified.";
|
|
break;
|
|
case SCARD_E_TIMEOUT:
|
|
msg = "Command timeout.";
|
|
break;
|
|
case SCARD_E_SHARING_VIOLATION:
|
|
msg = "Sharing violation.";
|
|
break;
|
|
case SCARD_E_NO_SMARTCARD:
|
|
msg = "No smart card inserted.";
|
|
break;
|
|
case SCARD_E_UNKNOWN_CARD:
|
|
msg = "Unknown card.";
|
|
break;
|
|
case SCARD_E_CANT_DISPOSE:
|
|
msg = "Cannot dispose handle.";
|
|
break;
|
|
case SCARD_E_PROTO_MISMATCH:
|
|
msg = "Card protocol mismatch.";
|
|
break;
|
|
case SCARD_E_NOT_READY:
|
|
msg = "Subsystem not ready.";
|
|
break;
|
|
case SCARD_E_INVALID_VALUE:
|
|
msg = "Invalid value given.";
|
|
break;
|
|
case SCARD_E_SYSTEM_CANCELLED:
|
|
msg = "System cancelled.";
|
|
break;
|
|
case SCARD_F_COMM_ERROR:
|
|
msg = "RPC transport error.";
|
|
break;
|
|
case SCARD_F_UNKNOWN_ERROR:
|
|
msg = "Unknown error.";
|
|
break;
|
|
case SCARD_E_INVALID_ATR:
|
|
msg = "Invalid ATR.";
|
|
break;
|
|
case SCARD_E_NOT_TRANSACTED:
|
|
msg = "Transaction failed.";
|
|
break;
|
|
case SCARD_E_READER_UNAVAILABLE:
|
|
msg = "Reader is unavailable.";
|
|
break;
|
|
/* case SCARD_P_SHUTDOWN: */
|
|
case SCARD_E_PCI_TOO_SMALL:
|
|
msg = "PCI struct too small.";
|
|
break;
|
|
case SCARD_E_READER_UNSUPPORTED:
|
|
msg = "Reader is unsupported.";
|
|
break;
|
|
case SCARD_E_DUPLICATE_READER:
|
|
msg = "Reader already exists.";
|
|
break;
|
|
case SCARD_E_CARD_UNSUPPORTED:
|
|
msg = "Card is unsupported.";
|
|
break;
|
|
case SCARD_E_NO_SERVICE:
|
|
msg = "Service not available.";
|
|
break;
|
|
case SCARD_E_SERVICE_STOPPED:
|
|
msg = "Service was stopped.";
|
|
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:
|
|
msg = "Cannot find a smart card reader.";
|
|
break;
|
|
/* case SCARD_E_COMM_DATA_LOST: */
|
|
/* case SCARD_E_NO_KEY_CONTAINER: */
|
|
/* case SCARD_E_SERVER_TOO_BUSY: */
|
|
case SCARD_W_UNSUPPORTED_CARD:
|
|
msg = "Card is not supported.";
|
|
break;
|
|
case SCARD_W_UNRESPONSIVE_CARD:
|
|
msg = "Card is unresponsive.";
|
|
break;
|
|
case SCARD_W_UNPOWERED_CARD:
|
|
msg = "Card is unpowered.";
|
|
break;
|
|
case SCARD_W_RESET_CARD:
|
|
msg = "Card was reset.";
|
|
break;
|
|
case SCARD_W_REMOVED_CARD:
|
|
msg = "Card was removed.";
|
|
break;
|
|
case SCARD_W_SECURITY_VIOLATION:
|
|
msg = "Access denied.";
|
|
break;
|
|
/* 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:
|
|
msg = "Feature not supported.";
|
|
break;
|
|
default:
|
|
(void)snprintf(strError, sizeof(strError)-1, "Unknown error: 0x%08lX",
|
|
pcscError);
|
|
};
|
|
|
|
if (msg)
|
|
(void)strncpy(strError, msg, sizeof(strError));
|
|
else
|
|
(void)snprintf(strError, sizeof(strError)-1, "Unknown error: 0x%08lX",
|
|
pcscError);
|
|
|
|
/* add a null byte */
|
|
strError[sizeof(strError)-1] = '\0';
|
|
|
|
return strError;
|
|
}
|
|
#endif
|
|
|