108#include <sys/types.h>
138static bool sharing_shall_block =
true;
140#define COLOR_RED "\33[01;31m"
141#define COLOR_GREEN "\33[32m"
142#define COLOR_BLUE "\33[34m"
143#define COLOR_MAGENTA "\33[35m"
144#define COLOR_NORMAL "\33[0m"
155 fprintf(
stderr, COLOR_GREEN
"%c " COLOR_BLUE
"[%lX] " COLOR_GREEN
"%s ",
166#define API_TRACE_IN(...) trace(__FUNCTION__, '<', __VA_ARGS__);
167#define API_TRACE_OUT(...) trace(__FUNCTION__, '>', __VA_ARGS__);
169#define API_TRACE_IN(...)
170#define API_TRACE_OUT(...)
175#define PROFILE_FILE "/tmp/pcsc_profile"
186#define PROFILE_START profile_start();
187#define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
204 fprintf(
stderr, COLOR_RED
"Can't open %s: %s" COLOR_NORMAL
"\n",
243 fprintf(
stderr, COLOR_BLUE
" WARNING: no start info for %s\n",
f);
256 COLOR_RED
"RESULT %s " COLOR_MAGENTA
"%ld "
257 COLOR_BLUE
"0x%08lX %s" COLOR_NORMAL
"\n",
258 f,
d, rv, pcsc_stringify_error(rv));
261 COLOR_NORMAL
"\n",
f,
d);
269#define PROFILE_END(rv)
284static int CHANNEL_MAP_seeker(
const void *
el,
const void *key)
290 Log3(PCSC_LOG_CRITICAL,
291 "CHANNEL_MAP_seeker called with NULL pointer: el=%p, key=%p",
322static list_t contextMapList;
324static int SCONTEXTMAP_seeker(
const void *
el,
const void *key)
330 Log3(PCSC_LOG_CRITICAL,
331 "SCONTEXTMAP_seeker called with NULL pointer: el=%p, key=%p",
374static LONG SCardGetContextChannelAndLockFromHandle(
SCARDHANDLE,
376static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE,
380static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
495DESTRUCTOR
static void destructor(
void)
497 list_destroy(&contextMapList);
554 lrv = list_init(&contextMapList);
557 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d",
562 lrv = list_attributes_seeker(&contextMapList,
566 Log2(PCSC_LOG_CRITICAL,
567 "list_attributes_seeker failed with return value: %d",
lrv);
568 list_destroy(&contextMapList);
572 if (
getenv(
"PCSCLITE_NO_BLOCKING"))
574 Log1(PCSC_LOG_INFO,
"Disable shared blocking");
575 sharing_shall_block =
false;
604 Log1(PCSC_LOG_CRITICAL,
605 "Your pcscd is too old and does not support CMD_VERSION");
609 Log3(PCSC_LOG_INFO,
"Server is protocol version %d:%d",
696 API_TRACE_IN(
"%ld", hContext)
803 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE
phCard,
811 API_TRACE_IN(
"%ld %s %ld %ld", hContext, szReader, dwShareMode, dwPreferredProtocols)
821 if (szReader ==
NULL)
827 if (
strlen(szReader) > MAX_READERNAME)
958 DWORD dwPreferredProtocols, DWORD dwInitialization,
967 API_TRACE_IN(
"%ld %ld %ld", hCard, dwShareMode, dwPreferredProtocols)
1064 API_TRACE_IN(
"%ld %ld", hCard, dwDisposition)
1097 SCardRemoveHandle(hCard);
1155 API_TRACE_IN(
"%ld", hCard)
1255 API_TRACE_IN(
"%ld", hCard)
1754 const char *readerName;
1768 if (
strcasecmp(readerName,
"\\\\?PnP?\\Notification") != 0)
1781 Log2(PCSC_LOG_DEBUG,
"Event Loop Start, dwTimeout: %ld",
dwTimeout);
1804 const char *readerName;
1819 if (
strcasecmp(readerName,
"\\\\?PnP?\\Notification") == 0)
1829 Log1(PCSC_LOG_INFO,
"Reader list changed");
1861 Log0(PCSC_LOG_DEBUG);
1882 Log0(PCSC_LOG_DEBUG);
1900 Log0(PCSC_LOG_DEBUG);
1911 Log0(PCSC_LOG_DEBUG);
1919#ifndef DISABLE_AUTO_POWER_ON
1950 Log0(PCSC_LOG_DEBUG);
1968 Log0(PCSC_LOG_DEBUG);
1978 Log0(PCSC_LOG_DEBUG);
1988 Log0(PCSC_LOG_DEBUG);
2002 Log0(PCSC_LOG_DEBUG);
2016 Log0(PCSC_LOG_DEBUG);
2029 Log0(PCSC_LOG_DEBUG);
2036 Log0(PCSC_LOG_DEBUG);
2048 Log0(PCSC_LOG_DEBUG);
2138 Log1(PCSC_LOG_DEBUG,
"Event Loop End");
2211 DWORD cbSendLength, LPVOID
pbRecvBuffer, DWORD cbRecvLength,
2448 *(
unsigned char **)pbAttr =
buf;
2511 if (
NULL == pbAttr || 0 == cbAttrLen)
2522static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
2664 LPDWORD pcbRecvLength)
2853 API_TRACE_IN(
"%ld", hContext)
3038 const char ReaderGroup[] =
"SCard$DefaultReaders\0";
3127 API_TRACE_IN(
"%ld", hContext)
3213 API_TRACE_IN(
"%ld", hContext)
3254 Log2(PCSC_LOG_DEBUG,
"Allocating new SCONTEXTMAP @%p",
newContextMap);
3264 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d",
lrv);
3269 CHANNEL_MAP_seeker);
3272 Log2(PCSC_LOG_CRITICAL,
3273 "list_attributes_seeker failed with return value: %d",
lrv);
3281 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3343 return list_seek(&contextMapList, &hContext);
3379 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3395 Log2(PCSC_LOG_CRITICAL,
3396 "list_delete failed with return value: %d",
lrv);
3426 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3451 Log2(PCSC_LOG_CRITICAL,
3452 "list_delete failed with return value: %d",
lrv);
3460static LONG SCardGetContextChannelAndLockFromHandle(
SCARDHANDLE hCard,
3480static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE hCard,
3492 listSize = list_size(&contextMapList);
3499 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3534 Log3(PCSC_LOG_INFO,
"PCSC Not Running: %s: %s",
3583 dwClientID, 0,
NULL);
This handles card insertion/removal events, updates ATR, protocol, and status information.
#define PCSCLITE_SHARING_EXCLUSIVE_CONTEXT
Reader used in exclusive mode.
#define PCSCLITE_SHARING_NO_CONTEXT
No application is using the reader.
#define PCSCLITE_SHARING_LAST_CONTEXT
One application is using the reader.
#define SCARD_E_INVALID_HANDLE
The supplied handle was invalid.
#define SCARD_E_UNKNOWN_READER
The specified reader name is not recognized.
#define SCARD_E_INVALID_PARAMETER
One or more of the supplied parameters could not be properly interpreted.
#define SCARD_E_CANCELLED
The action was cancelled by an SCardCancel request.
#define SCARD_S_SUCCESS
No error was encountered.
#define SCARD_E_NO_MEMORY
Not enough memory available to complete this command.
#define SCARD_E_NO_READERS_AVAILABLE
Cannot find a smart card reader.
#define SCARD_E_SHARING_VIOLATION
The smart card cannot be accessed because of other connections outstanding.
#define SCARD_E_INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted.
#define SCARD_E_TIMEOUT
The user-specified timeout value has expired.
#define SCARD_E_INSUFFICIENT_BUFFER
The data buffer to receive returned data is too small for the returned data.
#define SCARD_E_NO_SERVICE
The Smart card resource manager is not running.
#define SCARD_E_READER_UNAVAILABLE
The specified reader is not currently available for use.
This keeps a list of defines for pcsc-lite.
#define PCSCLITE_STATUS_POLL_RATE
Status polling rate.
@ POWER_STATE_POWERED
powered
#define PCSCLITE_LOCK_POLL_RATE
Lock polling rate.
#define SCARD_STATE_IGNORE
Ignore this reader.
#define SCARD_SWALLOWED
Card not powered.
LONG SCARDCONTEXT
hContext returned by SCardEstablishContext()
#define SCARD_PROTOCOL_T1
T=1 active protocol.
#define SCARD_PRESENT
Card is present.
#define SCARD_PROTOCOL_T0
T=0 active protocol.
#define SCARD_STATE_INUSE
Shared Mode.
#define SCARD_AUTOALLOCATE
see SCardFreeMemory()
#define SCARD_STATE_UNAVAILABLE
Status unavailable.
#define SCARD_STATE_PRESENT
Card inserted.
#define SCARD_ABSENT
Card is absent.
#define SCARD_UNKNOWN
Unknown state.
#define SCARD_STATE_UNKNOWN
Reader unknown.
#define INFINITE
Infinite timeout.
#define SCARD_STATE_EMPTY
Card removed.
#define SCARD_PROTOCOL_RAW
Raw active protocol.
#define SCARD_STATE_MUTE
Unresponsive card.
#define SCARD_STATE_CHANGED
State has changed.
#define SCARD_PROTOCOL_ANY
IFD determines prot.
#define MAX_BUFFER_SIZE
Maximum Tx/Rx Buffer for short APDU.
#define MAX_BUFFER_SIZE_EXTENDED
enhanced (64K + APDU + Lc + Le + SW) Tx/Rx Buffer
#define SCARD_STATE_EXCLUSIVE
Exclusive Mode.
#define SCARD_STATE_UNAWARE
App wants status.
LONG SCARDHANDLE
hCard returned by SCardConnect()
#define PCSCLITE_MAX_READERS_CONTEXTS
Maximum readers context (a slot is count as a reader)
This keeps track of a list of currently available reader structures.
Protocol Control Information (PCI)
Represents an Application Context Channel.
Represents an Application Context on the Client side.
pthread_mutex_t mMutex
Mutex for this context.
SCARDCONTEXT hContext
Application Context ID.
DWORD dwClientID
Client Connection ID.
bool cancellable
We are in a cancellable call.
contained in SCARD_BEGIN_TRANSACTION Messages.
contained in SCARD_CANCEL Messages.
contained in SCARD_CONNECT Messages.
contained in SCARD_CONTROL Messages.
contained in SCARD_DISCONNECT Messages.
contained in SCARD_END_TRANSACTION Messages.
Information contained in SCARD_ESTABLISH_CONTEXT Messages.
contained in SCARD_GET_ATTRIB and Messages.
Define an exported public reader state structure so each application gets instant notification of cha...
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
uint32_t eventCounter
number of card events
uint32_t readerState
SCARD_* bit field.
uint32_t cardAtrLength
ATR length.
contained in SCARD_RECONNECT Messages.
Information contained in SCARD_RELEASE_CONTEXT Messages.
contained in SCARD_STATUS Messages.
contained in SCARD_TRANSMIT Messages.
Information transmitted in CMD_VERSION Messages.
int32_t major
IPC major PROTOCOL_VERSION_MAJOR.
Information contained in CMD_WAIT_READER_STATE_CHANGE Messages.
This handles abstract system level calls.
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
long int time_sub(struct timeval *a, struct timeval *b)
return the difference (as long int) in µs between 2 struct timeval r = a - b
This handles smart card reader communications.
static short isExecuted
Make sure the initialization code is executed only once.
static void SCardLockThread(void)
Locks a mutex so another thread must wait to use this function.
static void SCardRemoveContext(SCARDCONTEXT)
Removes an Application Context from a control vector.
static SCONTEXTMAP * SCardGetAndLockContext(SCARDCONTEXT)
Get the SCONTEXTMAP * from the Application Context vector _psContextMap for the passed context.
static bool SCardGetContextValidity(SCARDCONTEXT hContext)
Tell if a context index from the Application Context vector _psContextMap is valid or not.
static void SCardUnlockThread(void)
Unlocks a mutex so another thread may use the client.
static pthread_mutex_t clientMutex
Ensure that some functions be accessed in thread-safe mode.
LONG SCardCheckDaemonAvailability(void)
Checks if the server is running.
static SCONTEXTMAP * SCardGetContextTH(SCARDCONTEXT)
Get the address from the Application Context list _psContextMap for the passed context.
static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT)
Creates a communication context to the PC/SC Resource Manager.
PCSC_API const SCARD_IO_REQUEST g_rgSCardRawPci
Protocol Control Information for raw access.
static LONG SCardAddContext(SCARDCONTEXT, DWORD)
Functions for managing instances of SCardEstablishContext() These functions keep track of Context han...
PCSC_API const SCARD_IO_REQUEST g_rgSCardT1Pci
Protocol Control Information for T=1.
static READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS]
Area used to read status information about the readers.
PCSC_API const SCARD_IO_REQUEST g_rgSCardT0Pci
Protocol Control Information for T=0.
INTERNAL int ClientSetupSession(uint32_t *pdwClientID)
Prepares a communication channel for the client to talk to the server.
INTERNAL LONG MessageReceiveTimeout(uint32_t command, void *buffer_void, uint64_t buffer_size, int32_t filedes, long timeOut)
Called by the Client to get the response from the server or vice-versa.
INTERNAL LONG MessageSendWithHeader(uint32_t command, uint32_t dwClientID, uint64_t size, void *data_void)
Wrapper for the MessageSend() function.
INTERNAL LONG MessageSend(void *buffer_void, uint64_t buffer_size, int32_t filedes)
Sends a menssage from client to server or vice-versa.
INTERNAL void ClientCloseSession(uint32_t dwClientID)
Closes the socket used by the client to communicate with the server.
INTERNAL LONG MessageReceive(void *buffer_void, uint64_t buffer_size, int32_t filedes)
Called by the Client to get the response from the server or vice-versa.
This defines some structures and #defines to be used over the transport layer.
#define PROTOCOL_VERSION_MAJOR
Major version of the current message protocol.
#define PROTOCOL_VERSION_MINOR
Minor version of the current message protocol.
@ SCARD_DISCONNECT
used by SCardDisconnect()
@ SCARD_SET_ATTRIB
used by SCardSetAttrib()
@ SCARD_RELEASE_CONTEXT
used by SCardReleaseContext()
@ CMD_STOP_WAITING_READER_STATE_CHANGE
stop waiting for a reader state change
@ CMD_GET_READERS_STATE
get the readers state
@ SCARD_CONTROL
used by SCardControl()
@ CMD_VERSION
get the client/server protocol version
@ CMD_WAIT_READER_STATE_CHANGE
wait for a reader state change
@ SCARD_RECONNECT
used by SCardReconnect()
@ SCARD_STATUS
used by SCardStatus()
@ SCARD_GET_ATTRIB
used by SCardGetAttrib()
@ SCARD_BEGIN_TRANSACTION
used by SCardBeginTransaction()
@ SCARD_TRANSMIT
used by SCardTransmit()
@ SCARD_END_TRANSACTION
used by SCardEndTransaction()
@ SCARD_CANCEL
used by SCardCancel()
@ SCARD_CONNECT
used by SCardConnect()
@ SCARD_ESTABLISH_CONTEXT
used by SCardEstablishContext()