From b206de3314b33b1d3264271dba2daa080898aad5 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Mon, 16 Sep 2013 00:10:04 -0700 Subject: [PATCH] pcsc: work on pcsclite lib --- sesman/chansrv/pcsc/xrdp_pcsc.c | 537 +++++++++++++++++++++++++++++--- 1 file changed, 495 insertions(+), 42 deletions(-) diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c index f41efbf1..251fdd82 100644 --- a/sesman/chansrv/pcsc/xrdp_pcsc.c +++ b/sesman/chansrv/pcsc/xrdp_pcsc.c @@ -2,8 +2,14 @@ #include #include #include +#include +#include +#include +#include #include #include +#include +#include #define PCSC_API @@ -42,18 +48,40 @@ typedef struct _SCARD_IO_REQUEST unsigned long cbPciLength; } SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST; -#define LLOG_LEVEL 11 +#define LLOG_LEVEL 5 #define LLOGLN(_level, _args) \ do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0) +#define SCARD_ESTABLISH_CONTEXT 0x01 +#define SCARD_RELEASE_CONTEXT 0x02 +#define SCARD_LIST_READERS 0x03 +#define SCARD_GET_STATUS_CHANGE 0x0C + #define SCARD_S_SUCCESS 0x00000000 #define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001) -static int g_fd = 0; /* unix domain socket */ +#define SET_UINT32(_data, _offset, _val) do { \ + (((BYTE*)(_data)) + (_offset))[0] = ((_val) >> 0) & 0xff; \ + (((BYTE*)(_data)) + (_offset))[1] = ((_val) >> 8) & 0xff; \ + (((BYTE*)(_data)) + (_offset))[2] = ((_val) >> 16) & 0xff; \ + (((BYTE*)(_data)) + (_offset))[3] = ((_val) >> 24) & 0xff; } while (0) + +#define GET_UINT32(_data, _offset) \ + ((((BYTE*)(_data)) + (_offset))[0] << 0) | \ + ((((BYTE*)(_data)) + (_offset))[1] << 8) | \ + ((((BYTE*)(_data)) + (_offset))[2] << 16) | \ + ((((BYTE*)(_data)) + (_offset))[3] << 24) + +#define LMIN(_val1, _val2) (_val1) < (_val2) ? (_val1) : (_val2) +#define LMAX(_val1, _val2) (_val1) > (_val2) ? (_val1) : (_val2) + +static int g_sck = -1; /* unix domain socket */ + +static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; /*****************************************************************************/ static int -get_display_num_from_display(char *display_text) +get_display_num_from_display(const char *display_text) { int rv; int index; @@ -105,73 +133,233 @@ get_display_num_from_display(char *display_text) host[host_index] = 0; disp[disp_index] = 0; scre[scre_index] = 0; + LLOGLN(0, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]", + host, disp, scre)); rv = atoi(disp); - return 0; + return rv; } /*****************************************************************************/ -PCSC_API LONG -SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, - LPSCARDCONTEXT phContext) +static int +connect_to_chansrv(void) { - int sck; + int bytes; int dis; + int error; char *xrdp_session; char *xrdp_display; char *home_str; - char text[256]; + struct sockaddr_un saddr; + struct sockaddr *psaddr; - LLOGLN(10, ("SCardEstablishContext:")); xrdp_session = getenv("XRDP_SESSION"); if (xrdp_session == NULL) { /* XRDP_SESSION must be set */ - return SCARD_F_INTERNAL_ERROR; + LLOGLN(0, ("connect_to_chansrv: error, not xrdp session")); + return 1; } xrdp_display = getenv("DISPLAY"); if (xrdp_display == NULL) { /* DISPLAY must be set */ - return SCARD_F_INTERNAL_ERROR; + LLOGLN(0, ("connect_to_chansrv: error, display not set")); + return 1; } home_str = getenv("HOME"); if (home_str == NULL) { /* HOME must be set */ - return SCARD_F_INTERNAL_ERROR; + LLOGLN(0, ("connect_to_chansrv: error, home not set")); + return 1; } dis = get_display_num_from_display(xrdp_display); if (dis < 10) { /* DISPLAY must be > 9 */ + LLOGLN(0, ("connect_to_chansrv: error, display not > 9 %d", dis)); + return 1; + } + if (g_sck == -1) + { + g_sck = socket(PF_LOCAL, SOCK_STREAM, 0); + if (g_sck == -1) + { + LLOGLN(0, ("connect_to_chansrv: error, socket failed")); + return 1; + } + memset(&saddr, 0, sizeof(struct sockaddr_un)); + saddr.sun_family = AF_UNIX; + bytes = sizeof(saddr.sun_path); + snprintf(saddr.sun_path, bytes, "%s/.pcsc%d/pcscd.comm", home_str, dis); + saddr.sun_path[bytes - 1] = 0; + LLOGLN(0, ("connect_to_chansrv: connecting to %s", saddr.sun_path)); + psaddr = (struct sockaddr *) &saddr; + bytes = sizeof(struct sockaddr_un); + error = connect(g_sck, psaddr, bytes); + if (error == 0) + { + } + else + { + perror("connect_to_chansrv"); + close(g_sck); + g_sck = -1; + LLOGLN(0, ("connect_to_chansrv: error, open %s", saddr.sun_path)); + return 1; + } + } + return 0; +} + +/*****************************************************************************/ +static int +send_message(int code, char *data, int bytes) +{ + char header[8]; + + SET_UINT32(header, 0, bytes); + SET_UINT32(header, 4, code); + if (send(g_sck, header, 8, 0) != 8) + { + return 1; + } + if (send(g_sck, data, bytes, 0) != bytes) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +static int +get_message(int *code, char *data, int *bytes) +{ + char header[8]; + int max_bytes; + + if (recv(g_sck, header, 8, 0) != 8) + { + return 1; + } + max_bytes = *bytes; + *bytes = GET_UINT32(header, 0); + *code = GET_UINT32(header, 4); + if (*bytes > max_bytes) + { + return 1; + } + if (recv(g_sck, data, *bytes, 0) != *bytes) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +PCSC_API LONG +SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, + LPSCARDCONTEXT phContext) +{ + char msg[256]; + DWORD context; + int code; + int bytes; + int status; + + LLOGLN(0, ("SCardEstablishContext:")); + if (g_sck == -1) + { + if (connect_to_chansrv() != 0) + { + LLOGLN(0, ("SCardEstablishContext: error, can not connect " + "to chansrv")); + return SCARD_F_INTERNAL_ERROR; + } + } + pthread_mutex_lock(&g_mutex); + SET_UINT32(msg, 0, dwScope); + if (send_message(SCARD_ESTABLISH_CONTEXT, msg, 4) != 0) + { + LLOGLN(0, ("SCardEstablishContext: error, send_message")); + pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - if (g_fd == 0) + bytes = 256; + if (get_message(&code, msg, &bytes) != 0) { - g_fd = socket(PF_LOCAL, SOCK_STREAM, 0); - snprintf(text, 255, "%s/.pcsc%d", home_str, dis); + LLOGLN(0, ("SCardEstablishContext: error, get_message")); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; } - if (g_fd == 0) + if ((code != SCARD_ESTABLISH_CONTEXT) || (bytes != 8)) { + LLOGLN(0, ("SCardEstablishContext: error, bad code")); + pthread_mutex_unlock(&g_mutex); return SCARD_F_INTERNAL_ERROR; } - *phContext = 0; - return SCARD_S_SUCCESS; + pthread_mutex_unlock(&g_mutex); + context = GET_UINT32(msg, 0); + status = GET_UINT32(msg, 4); + LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", context)); + *phContext = context; + return status; } /*****************************************************************************/ PCSC_API LONG SCardReleaseContext(SCARDCONTEXT hContext) { - LLOGLN(10, ("SCardReleaseContext:")); - return SCARD_S_SUCCESS; + char msg[256]; + int code; + int bytes; + int status; + + LLOGLN(0, ("SCardReleaseContext:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardReleaseContext: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + SET_UINT32(msg, 0, hContext); + if (send_message(SCARD_RELEASE_CONTEXT, msg, 4) != 0) + { + LLOGLN(0, ("SCardReleaseContext: error, send_message")); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + bytes = 256; + if (get_message(&code, msg, &bytes) != 0) + { + LLOGLN(0, ("SCardReleaseContext: error, get_message")); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + if ((code != SCARD_RELEASE_CONTEXT) || (bytes != 4)) + { + LLOGLN(0, ("SCardReleaseContext: error, bad code")); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_unlock(&g_mutex); + status = GET_UINT32(msg, 0); + LLOGLN(10, ("SCardReleaseContext: got status 0x%8.8x", status)); + return status; } /*****************************************************************************/ PCSC_API LONG SCardIsValidContext(SCARDCONTEXT hContext) { - LLOGLN(10, ("SCardIsValidContext:")); + LLOGLN(0, ("SCardIsValidContext:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardIsValidContext: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -181,7 +369,14 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol) { - LLOGLN(10, ("SCardConnect:")); + LLOGLN(0, ("SCardConnect:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardConnect: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -191,7 +386,14 @@ SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, DWORD dwPreferredProtocols, DWORD dwInitialization, LPDWORD pdwActiveProtocol) { - LLOGLN(10, ("SCardReconnect:")); + LLOGLN(0, ("SCardReconnect:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardReconnect: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -199,7 +401,14 @@ SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode, PCSC_API LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) { - LLOGLN(10, ("SCardDisconnect:")); + LLOGLN(0, ("SCardDisconnect:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardDisconnect: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -208,6 +417,13 @@ PCSC_API LONG SCardBeginTransaction(SCARDHANDLE hCard) { LLOGLN(0, ("SCardBeginTransaction:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardBeginTransaction: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -215,7 +431,14 @@ SCardBeginTransaction(SCARDHANDLE hCard) PCSC_API LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition) { - LLOGLN(10, ("SCardEndTransaction:")); + LLOGLN(0, ("SCardEndTransaction:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardEndTransaction: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -225,7 +448,14 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen) { - LLOGLN(10, ("SCardStatus:")); + LLOGLN(0, ("SCardStatus:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardStatus: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -234,12 +464,91 @@ PCSC_API LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, LPSCARD_READERSTATE rgReaderStates, DWORD cReaders) { - LLOGLN(10, ("SCardGetStatusChange:")); - LLOGLN(10, ("SCardGetStatusChange: dwTimeout %d cReaders %d", - dwTimeout, cReaders)); - memset(rgReaderStates, 0, sizeof(SCARD_READERSTATE)); - usleep(60000000); - return SCARD_S_SUCCESS; + char *msg; + int bytes; + int code; + int index; + int offset; + int str_len; + int status; + + LLOGLN(0, ("SCardGetStatusChange:")); + LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders)); + if (g_sck == -1) + { + LLOGLN(0, ("SCardGetStatusChange: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + msg = (char *) malloc(8192); + SET_UINT32(msg, 0, hContext); + SET_UINT32(msg, 4, dwTimeout); + SET_UINT32(msg, 8, cReaders); + offset = 12; + for (index = 0; index < cReaders; index++) + { + str_len = strlen(rgReaderStates[index].szReader); + str_len = LMIN(str_len, 99); + memset(msg + offset, 0, 100); + memcpy(msg + offset, rgReaderStates[index].szReader, str_len); + offset += 100; + LLOGLN(10, (" in dwCurrentState %d", rgReaderStates[index].dwCurrentState)); + SET_UINT32(msg, offset, rgReaderStates[index].dwCurrentState); + offset += 4; + LLOGLN(10, (" in dwEventState %d", rgReaderStates[index].dwEventState)); + SET_UINT32(msg, offset, rgReaderStates[index].dwEventState); + offset += 4; + LLOGLN(10, (" in cbAtr %d", rgReaderStates[index].cbAtr)); + SET_UINT32(msg, offset, rgReaderStates[index].cbAtr); + offset += 4; + memset(msg + offset, 0, 36); + memcpy(msg + offset, rgReaderStates[index].rgbAtr, 33); + offset += 36; + } + pthread_mutex_lock(&g_mutex); + if (send_message(SCARD_GET_STATUS_CHANGE, msg, offset) != 0) + { + LLOGLN(0, ("SCardGetStatusChange: error, send_message")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + bytes = 8192; + if (get_message(&code, msg, &bytes) != 0) + { + LLOGLN(0, ("SCardGetStatusChange: error, get_message")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + if (code != SCARD_GET_STATUS_CHANGE) + { + LLOGLN(0, ("SCardGetStatusChange: error, bad code")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_unlock(&g_mutex); + cReaders = GET_UINT32(msg, 0); + offset = 4; + LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", cReaders)); + for (index = 0; index < cReaders; index++) + { + rgReaderStates[index].dwCurrentState = GET_UINT32(msg, offset); + offset += 4; + LLOGLN(10, (" out dwCurrentState %d", rgReaderStates[index].dwCurrentState)); + rgReaderStates[index].dwEventState = GET_UINT32(msg, offset); + offset += 4; + LLOGLN(10, (" out dwEventState %d", rgReaderStates[index].dwEventState)); + rgReaderStates[index].cbAtr = GET_UINT32(msg, offset); + offset += 4; + LLOGLN(10, (" out cbAtr %d", rgReaderStates[index].cbAtr)); + memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33); + offset += 36; + } + status = GET_UINT32(msg, offset); + offset += 4; + free(msg); + return status; } /*****************************************************************************/ @@ -248,7 +557,14 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength, LPDWORD lpBytesReturned) { - LLOGLN(10, ("SCardControl:")); + LLOGLN(0, ("SCardControl:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardControl: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -259,7 +575,14 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength) { - LLOGLN(10, ("SCardTransmit:")); + LLOGLN(0, ("SCardTransmit:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardTransmit: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -268,7 +591,14 @@ PCSC_API LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups, LPDWORD pcchGroups) { - LLOGLN(10, ("SCardListReaderGroups:")); + LLOGLN(0, ("SCardListReaderGroups:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardListReaderGroups: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -277,15 +607,95 @@ PCSC_API LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) { - LLOGLN(10, ("SCardListReaders:")); - return SCARD_S_SUCCESS; + char* msg; + char* reader_names; + int reader_names_index; + int code; + int bytes; + int num_readers; + int status; + int offset; + int index; + char reader[100]; + + LLOGLN(0, ("SCardListReaders:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardListReaders: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + msg = (char *) malloc(8192); + pthread_mutex_lock(&g_mutex); + SET_UINT32(msg, 0, hContext); + if (send_message(SCARD_LIST_READERS, msg, 4) != 0) + { + LLOGLN(0, ("SCardListReaders: error, send_message")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + bytes = 8192; + if (get_message(&code, msg, &bytes) != 0) + { + LLOGLN(0, ("SCardListReaders: error, get_message")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + if (code != SCARD_LIST_READERS) + { + LLOGLN(0, ("SCardListReaders: error, bad code")); + free(msg); + pthread_mutex_unlock(&g_mutex); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_unlock(&g_mutex); + offset = 0; + num_readers = GET_UINT32(msg, offset); + offset += 4; + LLOGLN(10, ("hi - mszReaders %p pcchReaders %p num_readers %d", mszReaders, pcchReaders, num_readers)); + reader_names = (char *) malloc(8192); + reader_names_index = 0; + for (index = 0; index < num_readers; index++) + { + memcpy(reader, msg + offset, 100); + bytes = strlen(reader); + memcpy(reader_names + reader_names_index, reader, bytes); + reader_names_index += bytes; + reader_names[reader_names_index] = 0; + reader_names_index++; + offset += 100; + LLOGLN(10, ("SCardListReaders: readername %s", reader)); + } + reader_names[reader_names_index] = 0; + reader_names_index++; + status = GET_UINT32(msg, offset); + offset += 4; + if (pcchReaders != 0) + { + *pcchReaders = reader_names_index; + } + if (mszReaders != 0) + { + memcpy(mszReaders, reader_names, reader_names_index); + } + free(msg); + free(reader_names); + return status; } /*****************************************************************************/ PCSC_API LONG SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) { - LLOGLN(10, ("SCardFreeMemory:")); + LLOGLN(0, ("SCardFreeMemory:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardFreeMemory: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -293,7 +703,14 @@ SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem) PCSC_API LONG SCardCancel(SCARDCONTEXT hContext) { - LLOGLN(10, ("SCardCancel:")); + LLOGLN(0, ("SCardCancel:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardCancel: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -302,7 +719,14 @@ PCSC_API LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPBYTE pbAttr, LPDWORD pcbAttrLen) { - LLOGLN(10, ("SCardGetAttrib:")); + LLOGLN(0, ("SCardGetAttrib:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardGetAttrib: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } @@ -311,6 +735,35 @@ PCSC_API LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr, DWORD cbAttrLen) { - LLOGLN(10, ("SCardSetAttrib:")); + LLOGLN(0, ("SCardSetAttrib:")); + if (g_sck == -1) + { + LLOGLN(0, ("SCardSetAttrib: error, not connected")); + return SCARD_F_INTERNAL_ERROR; + } + pthread_mutex_lock(&g_mutex); + pthread_mutex_unlock(&g_mutex); return SCARD_S_SUCCESS; } + +static char g_error_str[512]; + +/*****************************************************************************/ +char * +pcsc_stringify_error(const long code) +{ + switch (code) + { + case SCARD_S_SUCCESS: + snprintf(g_error_str, 511, "Command successful."); + break; + case SCARD_F_INTERNAL_ERROR: + snprintf(g_error_str, 511, "Internal error."); + break; + default: + snprintf(g_error_str, 511, "error 0x%8.8x", (int)code); + break; + } + g_error_str[511] = 0; + return g_error_str; +}