channels/smartcard: migrate code to libwinpr-smartcard
This commit is contained in:
parent
d5ca2162ad
commit
89ad7638e4
@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
@ -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);
|
||||
|
||||
|
@ -27,74 +27,13 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/smartcard.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#define BOOL PCSC_BOOL
|
||||
#include <PCSC/pcsclite.h>
|
||||
#include <PCSC/reader.h>
|
||||
#include <PCSC/winscard.h>
|
||||
#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;
|
||||
|
||||
|
@ -28,36 +28,10 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winscard.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#define BOOL PCSC_BOOL
|
||||
#include <PCSC/pcsclite.h>
|
||||
#include <PCSC/winscard.h>
|
||||
#if !defined(__APPLE__)
|
||||
#include <PCSC/reader.h>
|
||||
#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 <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/smartcard.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#include <winpr/io.h>
|
||||
#include <winpr/error.h>
|
||||
|
||||
#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 */
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user