From 89ad7638e4e65854dca6c8db9c057cf6a6c9cbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 3 Apr 2014 15:27:55 -0400 Subject: [PATCH] channels/smartcard: migrate code to libwinpr-smartcard --- channels/smartcard/client/smartcard_main.c | 3 +- channels/smartcard/client/smartcard_main.h | 67 +------- .../smartcard/client/smartcard_operations.c | 78 +++------ winpr/include/winpr/io.h | 25 ++- winpr/include/winpr/smartcard.h | 26 +++ winpr/libwinpr/smartcard/smartcard.c | 161 ++++++++++++++++++ 6 files changed, 239 insertions(+), 121 deletions(-) diff --git a/channels/smartcard/client/smartcard_main.c b/channels/smartcard/client/smartcard_main.c index fa4874b06..a3584c54b 100644 --- a/channels/smartcard/client/smartcard_main.c +++ b/channels/smartcard/client/smartcard_main.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -148,7 +149,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) smartcard->name = name; } - smartcard->IrpQueue = MessageQueue_New(); + smartcard->IrpQueue = MessageQueue_New(NULL); smartcard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) smartcard_thread_func, smartcard, CREATE_SUSPENDED, NULL); diff --git a/channels/smartcard/client/smartcard_main.h b/channels/smartcard/client/smartcard_main.h index 4187fd89d..61ec8dc73 100644 --- a/channels/smartcard/client/smartcard_main.h +++ b/channels/smartcard/client/smartcard_main.h @@ -27,74 +27,13 @@ #include #include +#include #include -#define BOOL PCSC_BOOL -#include -#include -#include -#undef BOOL - -/* - * When using Windows Server 2008 R2 as the Terminal Services (TS) - * server, and with a smart card reader connected to the TS client machine - * and used to authenticate to an existing login session, the TS server - * will initiate the protocol initialization of MS-RDPEFS, Section 1.3.1, - * twice as it re-establishes a connection. The TS server starts both - * initializations with a "Server Announce Request" message. - * When the TS client receives this message, as per Section 3.2.5.1.2, - * - * The client SHOULD treat this packet as the beginning - * of a new sequence. The client SHOULD also cancel all - * outstanding requests and release previous references to - * all devices. - * - * As of this writing, the code does not cancel all outstanding requests. - * This leads to a problem where, after the first MS-RDPEFS initialization, - * the TS server sends an SCARD_IOCTL_GETSTATUSCHANGEx control in a message - * that uses an available "CompletionID". The - * TS client doesn't respond immediately because it is blocking while - * waiting for a change in the smart card's status in the reader. - * Then the TS server initiates a second MS-RDPEFS initialization sequence. - * As noted above, this should cancel the outstanding - * SCARD_IOCTL_GETSTATUSCHANGEx request, but it does not. - * At this point, the TS server is free to reuse the previously used - * "CompletionID", and it does reuse it for other SCARD_IOCTLs. - * Therefore, when the user removes (for example) the card from the reader, - * the TS client sends an "IOCompetion" message in response to the - * GETSTATUSCHANGEx using the original "CompletionID". The TS server does not - * expect this "CompletionID" and so, as per Section 3.1.5.2 of MS-RDPEFS, - * it treats that "IOCompletion" message as an error and terminates the - * virtual channel. - * - * The following structure is part of a work-around for this missing - * capability of canceling outstanding requests. This work-around - * allows the TS client to send an "IOCompletion" back to the - * TS server for the second (and subsequent) SCARD_IOCTLs that use - * the same "CompletionID" as the still outstanding - * SCARD_IOCTL_GETSTATUSCHANGEx. The work-around in the TS client - * prevents the client from sending the "IOCompletion" back (when - * the user removes the card) for the SCARD_IOCTL_GETSTATUSCHANGEx. - * - * This TS client expects the responses from the PCSC daemon for the second - * and subsequent SCARD_IOCTLs that use the same "CompletionID" - * to arrive at the TS client before the daemon's response to the - * SCARD_IOCTL_GETSTATUSCHANGEx. This is a race condition. - * - * The "CompletionIDs" are a global pool of IDs across all "DeviceIDs". - * However, this problem of duplicate "CompletionIDs" only affects smart cards. - * - * This structure tracks outstanding Terminal Services server "CompletionIDs" - * used by the redirected smart card device. - */ - struct _COMPLETIONIDINFO { - UINT32 ID; /* CompletionID */ - BOOL duplicate; /* Indicates whether or not this - * CompletionID is a duplicate of an - * earlier, outstanding, CompletionID. - */ + UINT32 ID; + BOOL duplicate; }; typedef struct _COMPLETIONIDINFO COMPLETIONIDINFO; diff --git a/channels/smartcard/client/smartcard_operations.c b/channels/smartcard/client/smartcard_operations.c index 49c105bcc..0c7722d55 100644 --- a/channels/smartcard/client/smartcard_operations.c +++ b/channels/smartcard/client/smartcard_operations.c @@ -28,36 +28,10 @@ #include #include -#ifdef _WIN32 -#include -#else -#include -#define BOOL PCSC_BOOL -#include -#include -#if !defined(__APPLE__) -#include -#else -/* On OS X reader.h isn't available so define it here */ -#endif -#define SCARD_ATTR_VALUE(Class, Tag) ((((ULONG)(Class)) << 16) | ((ULONG)(Tag))) -#define SCARD_CLASS_SYSTEM 0x7fff /**< System-specific definitions */ -#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_A SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0003) -#define SCARD_ATTR_DEVICE_FRIENDLY_NAME_W SCARD_ATTR_VALUE(SCARD_CLASS_SYSTEM, 0x0005) -#ifdef UNICODE -#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_W /**< Reader's display name. */ -#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_W /**< Reader's system name. */ -#else -#define SCARD_ATTR_DEVICE_FRIENDLY_NAME SCARD_ATTR_DEVICE_FRIENDLY_NAME_A /**< Reader's display name. */ -#define SCARD_ATTR_DEVICE_SYSTEM_NAME SCARD_ATTR_DEVICE_SYSTEM_NAME_A /**< Reader's system name. */ -#define SCARD_CTL_CODE(code) (0x42000000 + (code)) -#endif -#undef BOOL -#endif - #include #include #include +#include #include #include @@ -489,9 +463,9 @@ static BOOL check_handle_is_forwarded(SMARTCARD_DEVICE *scard, LONG status; DWORD state = 0, protocol = 0; DWORD readerLen; - DWORD atrLen = MAX_ATR_SIZE; + DWORD atrLen = SCARD_ATR_LENGTH; char* readerName = NULL; - BYTE pbAtr[MAX_ATR_SIZE]; + BYTE pbAtr[SCARD_ATR_LENGTH]; assert(scard); assert(hCard); @@ -777,7 +751,7 @@ static UINT32 handle_ReleaseContext(SMARTCARD_DEVICE* scard, IRP* irp) ZeroMemory(&scard->hContext, sizeof(scard->hContext)); if (status) - DEBUG_SCARD("%s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("%s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("success 0x%08lx", hContext); @@ -815,7 +789,7 @@ static UINT32 handle_IsValidContext(SMARTCARD_DEVICE* scard, IRP* irp) status = SCardIsValidContext(hContext); if (status) - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext); @@ -914,7 +888,7 @@ static UINT32 handle_ListReaders(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wide) #endif if (status != SCARD_S_SUCCESS) { - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); goto finish; } @@ -1014,7 +988,7 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wid { DEBUG_WARN("length violation %d [%d]", 12, Stream_GetRemainingLength(irp->input)); - status =SCARD_F_INTERNAL_ERROR; + status = SCARD_F_INTERNAL_ERROR; goto finish; } @@ -1127,7 +1101,7 @@ static UINT32 handle_GetStatusChange(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wid status = SCardGetStatusChange(hContext, (DWORD) dwTimeout, readerStates, (DWORD) readerCount); if (status != SCARD_S_SUCCESS) - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("Success"); @@ -1163,7 +1137,7 @@ finish: cur = &readerStates[i]; if (cur->szReader) - free(cur->szReader); + free((void*) cur->szReader); cur->szReader = NULL; } free(readerStates); @@ -1172,7 +1146,7 @@ finish: return status; } -static UINT32 handle_Cancel(SMARTCARD_DEVICE *scard, IRP* irp) +static UINT32 handle_Cancel(SMARTCARD_DEVICE* scard, IRP* irp) { int redirect = 0; LONG status; @@ -1201,9 +1175,9 @@ static UINT32 handle_Cancel(SMARTCARD_DEVICE *scard, IRP* irp) status = SCardCancel(hContext); if (status != SCARD_S_SUCCESS) - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else - DEBUG_SCARD("Success context: 0x%08x %s", (unsigned) hContext, pcsc_stringify_error(status)); + DEBUG_SCARD("Success context: 0x%08x %s", (unsigned) hContext, SCardGetErrorString(status)); smartcard_output_alignment(irp, 8); @@ -1283,7 +1257,7 @@ static UINT32 handle_Connect(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wide) (DWORD) dwPreferredProtocol, &hCard, (DWORD *) &dwActiveProtocol); if (status != SCARD_S_SUCCESS) - DEBUG_WARN("Failure: %s 0x%08x", pcsc_stringify_error(status), (unsigned) status); + DEBUG_WARN("Failure: %s 0x%08x", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("Success 0x%08x", (unsigned) hCard); @@ -1361,7 +1335,7 @@ static UINT32 handle_Reconnect(SMARTCARD_DEVICE* scard, IRP* irp) (DWORD) dwInitialization, (LPDWORD) &dwActiveProtocol); if (status != SCARD_S_SUCCESS) - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("Success (proto: 0x%08x)", (unsigned) dwActiveProtocol); @@ -1420,7 +1394,7 @@ static UINT32 handle_Disconnect(SMARTCARD_DEVICE* scard, IRP* irp) status = SCardDisconnect(hCard, (DWORD) dwDisposition); if (status != SCARD_S_SUCCESS) - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("Success"); @@ -1475,7 +1449,7 @@ static UINT32 handle_BeginTransaction(SMARTCARD_DEVICE* scard, IRP* irp) status = SCardBeginTransaction(hCard); if (status != SCARD_S_SUCCESS) - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("Success hcard: 0x%08x", (unsigned) hCard); @@ -1529,7 +1503,7 @@ static UINT32 handle_EndTransaction(SMARTCARD_DEVICE* scard, IRP* irp) status = SCardEndTransaction(hCard, dwDisposition); if (status != SCARD_S_SUCCESS) - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("Success hcard: 0x%08x", (unsigned) hCard); @@ -1546,9 +1520,9 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp) SCARDCONTEXT hContext; DWORD state = 0, protocol = 0; DWORD readerLen; - DWORD atrLen = MAX_ATR_SIZE; + DWORD atrLen = SCARD_ATR_LENGTH; char* readerName = NULL; - BYTE pbAtr[MAX_ATR_SIZE]; + BYTE pbAtr[SCARD_ATR_LENGTH]; #ifdef WITH_DEBUG_SCARD int i; @@ -1605,7 +1579,7 @@ static UINT32 handle_State(SMARTCARD_DEVICE* scard, IRP* irp) if (status != SCARD_S_SUCCESS) { - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); status = smartcard_output_return(irp, status); goto finish; } @@ -1653,7 +1627,7 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, BOOL wide) SCARDCONTEXT hContext; DWORD state, protocol; DWORD readerLen = 0; - DWORD atrLen = MAX_ATR_SIZE; + DWORD atrLen = SCARD_ATR_LENGTH; char* readerName = NULL; BYTE *pbAtr = NULL; UINT32 dataLength = 0; @@ -1716,7 +1690,7 @@ static DWORD handle_Status(SMARTCARD_DEVICE *scard, IRP* irp, BOOL wide) if (status != SCARD_S_SUCCESS) { - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); status = smartcard_output_return(irp, status); goto finish; } @@ -1999,7 +1973,7 @@ static UINT32 handle_Transmit(SMARTCARD_DEVICE* scard, IRP* irp) if (status != SCARD_S_SUCCESS) { - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); } else { @@ -2126,7 +2100,7 @@ static UINT32 handle_Control(SMARTCARD_DEVICE* scard, IRP* irp) sendBuffer, (DWORD) outBufferSize, &nBytesReturned); if (status != SCARD_S_SUCCESS) - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned) status); else DEBUG_SCARD("Success (out: %u bytes)", (unsigned) nBytesReturned); @@ -2263,7 +2237,7 @@ static UINT32 handle_GetAttrib(SMARTCARD_DEVICE* scard, IRP* irp) if (status != SCARD_S_SUCCESS) { - DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned int) status); + DEBUG_SCARD("Failure: %s (0x%08x)", SCardGetErrorString(status), (unsigned int) status); status = smartcard_output_return(irp, status); goto finish; } @@ -2447,7 +2421,7 @@ static UINT32 handle_LocateCardsByATR(SMARTCARD_DEVICE* scard, IRP* irp, BOOL wi if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", - pcsc_stringify_error(status), (unsigned) status); + SCardGetErrorString(status), (unsigned) status); status = smartcard_output_return(irp, status); goto finish; } diff --git a/winpr/include/winpr/io.h b/winpr/include/winpr/io.h index f0ce89ed6..74aed8f3d 100644 --- a/winpr/include/winpr/io.h +++ b/winpr/include/winpr/io.h @@ -82,10 +82,6 @@ WINPR_API BOOL CancelSynchronousIo(HANDLE hThread); } #endif -/* - * WinPR I/O Manager Custom API - */ - #define DEVICE_TYPE ULONG #define FILE_DEVICE_BEEP 0x00000001 @@ -156,6 +152,27 @@ WINPR_API BOOL CancelSynchronousIo(HANDLE hThread); #define FILE_DEVICE_BIOMETRIC 0x00000044 #define FILE_DEVICE_PMI 0x00000045 +#define CTL_CODE(DeviceType, Function, Method, Access) \ + (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) + +#define DEVICE_TYPE_FROM_CTL_CODE(ctrlCode) (((DWORD)(ctrlCode & 0xFFFF0000)) >> 16) + +#define METHOD_FROM_CTL_CODE(ctrlCode) ((DWORD)(ctrlCode & 3)) + +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +#define FILE_ANY_ACCESS 0 +#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) +#define FILE_READ_ACCESS (0x0001) +#define FILE_WRITE_ACCESS (0x0002) + +/* + * WinPR I/O Manager Custom API + */ + typedef HANDLE PDRIVER_OBJECT_EX; typedef HANDLE PDEVICE_OBJECT_EX; diff --git a/winpr/include/winpr/smartcard.h b/winpr/include/winpr/smartcard.h index 175d188c4..706972868 100644 --- a/winpr/include/winpr/smartcard.h +++ b/winpr/include/winpr/smartcard.h @@ -23,6 +23,7 @@ #include #include +#include #include #ifdef _WIN32 @@ -87,6 +88,7 @@ #define SCARD_E_PIN_CACHE_EXPIRED ((DWORD)0x80100032L) #define SCARD_E_NO_PIN_CACHE ((DWORD)0x80100033L) #define SCARD_E_READ_ONLY_CARD ((DWORD)0x80100034L) + #define SCARD_W_UNSUPPORTED_CARD ((DWORD)0x80100065L) #define SCARD_W_UNRESPONSIVE_CARD ((DWORD)0x80100066L) #define SCARD_W_UNPOWERED_CARD ((DWORD)0x80100067L) @@ -335,6 +337,14 @@ typedef void (WINAPI *LPOCNDSCPROC)(SCARDCONTEXT hSCardContext, SCARDHANDLE hCar #define SCARD_AUDIT_CHV_FAILURE 0x0 #define SCARD_AUDIT_CHV_SUCCESS 0x1 +#define SCardListCardTypes SCardListCards + +#define PCSCardIntroduceCardType(hContext, szCardName, pbAtr, pbAtrMask, cbAtrLen, pguidPrimaryProvider, rgguidInterfaces, dwInterfaceCount) \ + SCardIntroduceCardType(hContext, szCardName, pguidPrimaryProvider, rgguidInterfaces, dwInterfaceCount, pbAtr, pbAtrMask, cbAtrLen) + +#define SCardGetReaderCapabilities SCardGetAttrib +#define SCardSetReaderCapabilities SCardSetAttrib + typedef struct { LPCSTR szReader; @@ -673,6 +683,8 @@ WINSCARDAPI LONG WINAPI SCardGetStatusChangeA(SCARDCONTEXT hContext, WINSCARDAPI LONG WINAPI SCardGetStatusChangeW(SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATEW rgReaderStates, DWORD cReaders); +WINSCARDAPI LONG WINAPI SCardCancel(SCARDCONTEXT hContext); + WINSCARDAPI LONG WINAPI SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol); @@ -819,5 +831,19 @@ WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent); #endif +/** + * Extended API + */ + +#ifdef __cplusplus +extern "C" { +#endif + +WINSCARDAPI const char* WINAPI SCardGetErrorString(LONG errorCode); + +#ifdef __cplusplus +} +#endif + #endif /* WINPR_SMARTCARD_H */ diff --git a/winpr/libwinpr/smartcard/smartcard.c b/winpr/libwinpr/smartcard/smartcard.c index 424229679..a02496489 100644 --- a/winpr/libwinpr/smartcard/smartcard.c +++ b/winpr/libwinpr/smartcard/smartcard.c @@ -424,6 +424,18 @@ WINSCARDAPI LONG WINAPI SCardGetStatusChangeW(SCARDCONTEXT hContext, return 0; } +WINSCARDAPI LONG WINAPI SCardCancel(SCARDCONTEXT hContext) +{ + InitializeSCardStubs(); + + if (g_PCSCLite && g_PCSCLite->pfnSCardCancel) + { + return g_PCSCLite->pfnSCardCancel(hContext); + } + + return 0; +} + WINSCARDAPI LONG WINAPI SCardConnectA(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) @@ -688,3 +700,152 @@ WINSCARDAPI LONG WINAPI SCardAudit(SCARDCONTEXT hContext, DWORD dwEvent) } #endif + +/** + * Extended API + */ + +WINSCARDAPI const char* WINAPI SCardGetErrorString(LONG errorCode) +{ + switch (errorCode) + { + case SCARD_S_SUCCESS: + return "SCARD_S_SUCCESS"; + case SCARD_F_INTERNAL_ERROR: + return "SCARD_F_INTERNAL_ERROR"; + case SCARD_E_CANCELLED: + return "SCARD_E_CANCELLED"; + case SCARD_E_INVALID_HANDLE: + return "SCARD_E_INVALID_HANDLE"; + case SCARD_E_INVALID_PARAMETER: + return "SCARD_E_INVALID_PARAMETER"; + case SCARD_E_INVALID_TARGET: + return "SCARD_E_INVALID_TARGET"; + case SCARD_E_NO_MEMORY: + return "SCARD_E_NO_MEMORY"; + case SCARD_F_WAITED_TOO_LONG: + return "SCARD_F_WAITED_TOO_LONG"; + case SCARD_E_INSUFFICIENT_BUFFER: + return "SCARD_E_INSUFFICIENT_BUFFER"; + case SCARD_E_UNKNOWN_READER: + return "SCARD_E_UNKNOWN_READER"; + case SCARD_E_TIMEOUT: + return "SCARD_E_TIMEOUT"; + case SCARD_E_SHARING_VIOLATION: + return "SCARD_E_SHARING_VIOLATION"; + case SCARD_E_NO_SMARTCARD: + return "SCARD_E_NO_SMARTCARD"; + case SCARD_E_UNKNOWN_CARD: + return "SCARD_E_UNKNOWN_CARD"; + case SCARD_E_CANT_DISPOSE: + return "SCARD_E_CANT_DISPOSE"; + case SCARD_E_PROTO_MISMATCH: + return "SCARD_E_PROTO_MISMATCH"; + case SCARD_E_NOT_READY: + return "SCARD_E_NOT_READY"; + case SCARD_E_INVALID_VALUE: + return "SCARD_E_INVALID_VALUE"; + case SCARD_E_SYSTEM_CANCELLED: + return "SCARD_E_SYSTEM_CANCELLED"; + case SCARD_F_COMM_ERROR: + return "SCARD_F_COMM_ERROR"; + case SCARD_F_UNKNOWN_ERROR: + return "SCARD_F_UNKNOWN_ERROR"; + case SCARD_E_INVALID_ATR: + return "SCARD_E_INVALID_ATR"; + case SCARD_E_NOT_TRANSACTED: + return "SCARD_E_NOT_TRANSACTED"; + case SCARD_E_READER_UNAVAILABLE: + return "SCARD_E_READER_UNAVAILABLE"; + case SCARD_P_SHUTDOWN: + return "SCARD_P_SHUTDOWN"; + case SCARD_E_PCI_TOO_SMALL: + return "SCARD_E_PCI_TOO_SMALL"; + case SCARD_E_READER_UNSUPPORTED: + return "SCARD_E_READER_UNSUPPORTED"; + case SCARD_E_DUPLICATE_READER: + return "SCARD_E_DUPLICATE_READER"; + case SCARD_E_CARD_UNSUPPORTED: + return "SCARD_E_CARD_UNSUPPORTED"; + case SCARD_E_NO_SERVICE: + return "SCARD_E_NO_SERVICE"; + case SCARD_E_SERVICE_STOPPED: + return "SCARD_E_SERVICE_STOPPED"; + case SCARD_E_UNEXPECTED: + return "SCARD_E_UNEXPECTED"; + case SCARD_E_ICC_INSTALLATION: + return "SCARD_E_ICC_INSTALLATION"; + case SCARD_E_ICC_CREATEORDER: + return "SCARD_E_ICC_CREATEORDER"; + case SCARD_E_UNSUPPORTED_FEATURE: + return "SCARD_E_UNSUPPORTED_FEATURE"; + case SCARD_E_DIR_NOT_FOUND: + return "SCARD_E_DIR_NOT_FOUND"; + case SCARD_E_FILE_NOT_FOUND: + return "SCARD_E_FILE_NOT_FOUND"; + case SCARD_E_NO_DIR: + return "SCARD_E_NO_DIR"; + case SCARD_E_NO_FILE: + return "SCARD_E_NO_FILE"; + case SCARD_E_NO_ACCESS: + return "SCARD_E_NO_ACCESS"; + case SCARD_E_WRITE_TOO_MANY: + return "SCARD_E_WRITE_TOO_MANY"; + case SCARD_E_BAD_SEEK: + return "SCARD_E_BAD_SEEK"; + case SCARD_E_INVALID_CHV: + return "SCARD_E_INVALID_CHV"; + case SCARD_E_UNKNOWN_RES_MNG: + return "SCARD_E_UNKNOWN_RES_MNG"; + case SCARD_E_NO_SUCH_CERTIFICATE: + return "SCARD_E_NO_SUCH_CERTIFICATE"; + case SCARD_E_CERTIFICATE_UNAVAILABLE: + return "SCARD_E_CERTIFICATE_UNAVAILABLE"; + case SCARD_E_NO_READERS_AVAILABLE: + return "SCARD_E_NO_READERS_AVAILABLE"; + case SCARD_E_COMM_DATA_LOST: + return "SCARD_E_COMM_DATA_LOST"; + case SCARD_E_NO_KEY_CONTAINER: + return "SCARD_E_NO_KEY_CONTAINER"; + case SCARD_E_SERVER_TOO_BUSY: + return "SCARD_E_SERVER_TOO_BUSY"; + case SCARD_E_PIN_CACHE_EXPIRED: + return "SCARD_E_PIN_CACHE_EXPIRED"; + case SCARD_E_NO_PIN_CACHE: + return "SCARD_E_NO_PIN_CACHE"; + case SCARD_E_READ_ONLY_CARD: + return "SCARD_E_READ_ONLY_CARD"; + case SCARD_W_UNSUPPORTED_CARD: + return "SCARD_W_UNSUPPORTED_CARD"; + case SCARD_W_UNRESPONSIVE_CARD: + return "SCARD_W_UNRESPONSIVE_CARD"; + case SCARD_W_UNPOWERED_CARD: + return "SCARD_W_UNPOWERED_CARD"; + case SCARD_W_RESET_CARD: + return "SCARD_W_RESET_CARD"; + case SCARD_W_REMOVED_CARD: + return "SCARD_W_REMOVED_CARD"; + case SCARD_W_SECURITY_VIOLATION: + return "SCARD_W_SECURITY_VIOLATION"; + case SCARD_W_WRONG_CHV: + return "SCARD_W_WRONG_CHV"; + case SCARD_W_CHV_BLOCKED: + return "SCARD_W_CHV_BLOCKED"; + case SCARD_W_EOF: + return "SCARD_W_EOF"; + case SCARD_W_CANCELLED_BY_USER: + return "SCARD_W_CANCELLED_BY_USER"; + case SCARD_W_CARD_NOT_AUTHENTICATED: + return "SCARD_W_CARD_NOT_AUTHENTICATED"; + case SCARD_W_CACHE_ITEM_NOT_FOUND: + return "SCARD_W_CACHE_ITEM_NOT_FOUND"; + case SCARD_W_CACHE_ITEM_STALE: + return "SCARD_W_CACHE_ITEM_STALE"; + case SCARD_W_CACHE_ITEM_TOO_BIG: + return "SCARD_W_CACHE_ITEM_TOO_BIG"; + default: + return "SCARD_E_UNKNOWN"; + } + + return "SCARD_E_UNKNOWN"; +}