chansrv: work on smartcard, mstsc and 64 bit client
This commit is contained in:
parent
1483c75911
commit
38eba8aac1
@ -57,6 +57,7 @@ PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
|
||||
PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_RAW, 8 };
|
||||
|
||||
#define LLOG_LEVEL 5
|
||||
//#define LLOG_LEVEL 11
|
||||
#define LLOGLN(_level, _args) \
|
||||
do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
|
||||
|
||||
@ -482,7 +483,8 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
||||
*phCard = GET_UINT32(msg, 0);
|
||||
*pdwActiveProtocol = GET_UINT32(msg, 4);
|
||||
status = GET_UINT32(msg, 8);
|
||||
LLOGLN(10, ("SCardReleaseContext: got status 0x%8.8x", status));
|
||||
LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard %d",
|
||||
status, *phCard));
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -510,7 +512,8 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||
int bytes;
|
||||
int status;
|
||||
|
||||
LLOGLN(10, ("SCardDisconnect:"));
|
||||
LLOGLN(10, ("SCardDisconnect: hCard %d dwDisposition %d",
|
||||
hCard, dwDisposition));
|
||||
if (g_sck == -1)
|
||||
{
|
||||
LLOGLN(0, ("SCardDisconnect: error, not connected"));
|
||||
@ -549,7 +552,12 @@ SCardBeginTransaction(SCARDHANDLE hCard)
|
||||
int bytes;
|
||||
int status;
|
||||
|
||||
LLOGLN(10, ("SCardBeginTransaction:"));
|
||||
LLOGLN(10, ("SCardBeginTransaction: hCard %d", hCard));
|
||||
if (hCard == 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardBeginTransaction: error, bad hCard"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
if (g_sck == -1)
|
||||
{
|
||||
LLOGLN(0, ("SCardBeginTransaction: error, not connected"));
|
||||
@ -632,6 +640,11 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
|
||||
int to_copy;
|
||||
|
||||
LLOGLN(10, ("SCardStatus:"));
|
||||
if (hCard == 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardStatus: error, bad hCard"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
if (g_sck == -1)
|
||||
{
|
||||
LLOGLN(0, ("SCardStatus: error, not connected"));
|
||||
@ -734,11 +747,13 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
|
||||
offset = 12;
|
||||
for (index = 0; index < cReaders; index++)
|
||||
{
|
||||
rgReaderStates[index].dwCurrentState &= ~2;
|
||||
rgReaderStates[index].dwEventState &= ~2;
|
||||
rname = rgReaderStates[index].szReader;
|
||||
if (strcmp(rname, "\\\\?PnP?\\Notification") == 0)
|
||||
{
|
||||
LLOGLN(10, (" found \\\\?PnP?\\Notification"));
|
||||
dwCurrentState = 0x00010000;
|
||||
LLOGLN(10, (" \\\\?PnP?\\Notification present"));
|
||||
dwCurrentState = 0;
|
||||
dwEventState = 0;
|
||||
cbAtr = 0;
|
||||
memset(atr, 0, 36);
|
||||
@ -793,6 +808,30 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
|
||||
offset = 4;
|
||||
LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", cReaders));
|
||||
for (index = 0; index < cReaders; index++)
|
||||
{
|
||||
rname = rgReaderStates[index].szReader;
|
||||
#if 1
|
||||
if (strcmp(rname, "\\\\?PnP?\\Notification") == 0)
|
||||
{
|
||||
LLOGLN(10, (" out szReader %s", rgReaderStates[index].szReader));
|
||||
dwCurrentState = GET_UINT32(msg, offset);
|
||||
rgReaderStates[index].dwCurrentState = dwCurrentState;
|
||||
offset += 4;
|
||||
LLOGLN(10, (" out dwCurrentState 0x%8.8x", dwCurrentState));
|
||||
// disable PnP for now
|
||||
dwEventState = 4; // GET_UINT32(msg, offset);
|
||||
rgReaderStates[index].dwEventState = dwEventState;
|
||||
offset += 4;
|
||||
LLOGLN(10, (" out dwEventState 0x%8.8x", dwEventState));
|
||||
cbAtr = GET_UINT32(msg, offset);
|
||||
rgReaderStates[index].cbAtr = cbAtr;
|
||||
offset += 4;
|
||||
LLOGLN(10, (" out cbAtr %d", cbAtr));
|
||||
memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33);
|
||||
offset += 36;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
LLOGLN(10, (" out szReader %s", rgReaderStates[index].szReader));
|
||||
dwCurrentState = GET_UINT32(msg, offset);
|
||||
@ -810,6 +849,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
|
||||
memcpy(rgReaderStates[index].rgbAtr, msg + offset, 33);
|
||||
offset += 36;
|
||||
}
|
||||
}
|
||||
status = GET_UINT32(msg, offset);
|
||||
offset += 4;
|
||||
free(msg);
|
||||
@ -1147,13 +1187,38 @@ SCardFreeMemory(SCARDCONTEXT hContext, LPCVOID pvMem)
|
||||
PCSC_API LONG
|
||||
SCardCancel(SCARDCONTEXT hContext)
|
||||
{
|
||||
LLOGLN(0, ("SCardCancel:"));
|
||||
char msg[256];
|
||||
int code;
|
||||
int bytes;
|
||||
int status;
|
||||
|
||||
LLOGLN(10, ("SCardCancel:"));
|
||||
if (g_sck == -1)
|
||||
{
|
||||
LLOGLN(0, ("SCardCancel: error, not connected"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
return SCARD_S_SUCCESS;
|
||||
SET_UINT32(msg, 0, hContext);
|
||||
if (send_message(SCARD_CANCEL, msg, 4) != 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardCancel: error, send_message"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
bytes = 256;
|
||||
code = SCARD_CANCEL;
|
||||
if (get_message(&code, msg, &bytes) != 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardCancel: error, get_message"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
if ((code != SCARD_RELEASE_CONTEXT) || (bytes != 4))
|
||||
{
|
||||
LLOGLN(0, ("SCardCancel: error, bad code"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
status = GET_UINT32(msg, 0);
|
||||
LLOGLN(10, ("SCardCancel: got status 0x%8.8x", status));
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -166,35 +166,54 @@ static int APP_CC scard_get_free_slot(void);
|
||||
static void APP_CC scard_release_resources(void);
|
||||
#endif
|
||||
static void APP_CC scard_send_EstablishContext(IRP *irp, int scope);
|
||||
static void APP_CC scard_send_ReleaseContext(IRP *irp, tui32 context);
|
||||
static void APP_CC scard_send_IsContextValid(IRP* irp, tui32 context);
|
||||
static void APP_CC scard_send_ListReaders(IRP *irp, tui32 context,
|
||||
static void APP_CC scard_send_ReleaseContext(IRP *irp,
|
||||
char *context, int context_bytes);
|
||||
static void APP_CC scard_send_IsContextValid(IRP* irp,
|
||||
char *context, int context_bytes);
|
||||
static void APP_CC scard_send_ListReaders(IRP *irp,
|
||||
char *context, int context_bytes,
|
||||
char *groups, int cchReaders,
|
||||
int wide);
|
||||
static void APP_CC scard_send_GetStatusChange(IRP *irp, tui32 context, int wide,
|
||||
static void APP_CC scard_send_GetStatusChange(IRP *irp,
|
||||
char *context, int context_bytes,
|
||||
int wide,
|
||||
tui32 timeout, tui32 num_readers,
|
||||
READER_STATE *rsa);
|
||||
static void APP_CC scard_send_Connect(IRP *irp, tui32 context, int wide,
|
||||
static void APP_CC scard_send_Connect(IRP *irp,
|
||||
char *context, int context_bytes,
|
||||
int wide,
|
||||
READER_STATE *rs);
|
||||
static void APP_CC scard_send_Reconnect(IRP *irp, tui32 context,
|
||||
tui32 sc_handle, READER_STATE *rs);
|
||||
static void APP_CC scard_send_BeginTransaction(IRP *irp, tui32 sc_handle);
|
||||
static void APP_CC scard_send_EndTransaction(IRP *irp, tui32 sc_handle,
|
||||
static void APP_CC scard_send_Reconnect(IRP *irp,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
READER_STATE *rs);
|
||||
static void APP_CC scard_send_BeginTransaction(IRP *irp,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes);
|
||||
static void APP_CC scard_send_EndTransaction(IRP *irp,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
tui32 dwDisposition);
|
||||
static void APP_CC scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
|
||||
static void APP_CC scard_send_Status(IRP *irp, int wide,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
int cchReaderLen, int cbAtrLen);
|
||||
static void APP_CC scard_send_Disconnect(IRP *irp, tui32 context,
|
||||
tui32 sc_handle, int dwDisposition);
|
||||
static int APP_CC scard_send_Transmit(IRP *irp, tui32 sc_handle,
|
||||
static void APP_CC scard_send_Disconnect(IRP *irp,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
int dwDisposition);
|
||||
static int APP_CC scard_send_Transmit(IRP *irp,
|
||||
char *context, int context_byte,
|
||||
char *card, int card_bytes,
|
||||
char *send_data, int send_bytes,
|
||||
int recv_bytes,
|
||||
struct xrdp_scard_io_request *send_ior,
|
||||
struct xrdp_scard_io_request *recv_ior);
|
||||
static int APP_CC scard_send_Control(IRP* irp, tui32 sc_handle,
|
||||
static int APP_CC scard_send_Control(IRP* irp, char *card, int card_bytes,
|
||||
char *send_data, int send_bytes,
|
||||
int recv_bytes, int control_code);
|
||||
static int APP_CC scard_send_Cancel(IRP *irp, tui32 context);
|
||||
static int APP_CC scard_send_GetAttrib(IRP *irp, tui32 sc_handle,
|
||||
static int APP_CC scard_send_Cancel(IRP *irp, char *context, int context_bytes);
|
||||
static int APP_CC scard_send_GetAttrib(IRP *irp, char *card, int card_bytes,
|
||||
READER_STATE *rs);
|
||||
|
||||
/******************************************************************************
|
||||
@ -364,7 +383,8 @@ scard_send_establish_context(void *user_data, int scope)
|
||||
* Release a previously established Smart Card context
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_release_context(void *user_data, tui32 context)
|
||||
scard_send_release_context(void *user_data,
|
||||
char *context, int context_bytes)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -382,7 +402,7 @@ scard_send_release_context(void *user_data, tui32 context)
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_ReleaseContext(irp, context);
|
||||
scard_send_ReleaseContext(irp, context, context_bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -391,7 +411,7 @@ scard_send_release_context(void *user_data, tui32 context)
|
||||
* Checks if a previously established context is still valid
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_is_valid_context(void *user_data, tui32 context)
|
||||
scard_send_is_valid_context(void *user_data, char *context, int context_bytes)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -409,7 +429,7 @@ scard_send_is_valid_context(void *user_data, tui32 context)
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_IsContextValid(irp, context);
|
||||
scard_send_IsContextValid(irp, context, context_bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -418,8 +438,8 @@ scard_send_is_valid_context(void *user_data, tui32 context)
|
||||
*
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_list_readers(void *user_data, tui32 context, char *groups,
|
||||
int cchReaders, int wide)
|
||||
scard_send_list_readers(void *user_data, char *context, int context_bytes,
|
||||
char *groups, int cchReaders, int wide)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -436,7 +456,8 @@ scard_send_list_readers(void *user_data, tui32 context, char *groups,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_ListReaders(irp, context, groups, cchReaders, wide);
|
||||
scard_send_ListReaders(irp, context, context_bytes, groups,
|
||||
cchReaders, wide);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -451,8 +472,8 @@ scard_send_list_readers(void *user_data, tui32 context, char *groups,
|
||||
* @param rsa array of READER_STATEs
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_get_status_change(void *user_data, tui32 context, int wide,
|
||||
tui32 timeout, tui32 num_readers,
|
||||
scard_send_get_status_change(void *user_data, char *context, int context_bytes,
|
||||
int wide, tui32 timeout, tui32 num_readers,
|
||||
READER_STATE* rsa)
|
||||
{
|
||||
IRP *irp;
|
||||
@ -471,7 +492,8 @@ scard_send_get_status_change(void *user_data, tui32 context, int wide,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_GetStatusChange(irp, context, wide, timeout, num_readers, rsa);
|
||||
scard_send_GetStatusChange(irp, context, context_bytes, wide, timeout,
|
||||
num_readers, rsa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -483,8 +505,8 @@ scard_send_get_status_change(void *user_data, tui32 context, int wide,
|
||||
* @param wide TRUE if unicode string
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_connect(void *user_data, tui32 context, int wide,
|
||||
READER_STATE* rs)
|
||||
scard_send_connect(void *user_data, char *context, int context_bytes,
|
||||
int wide, READER_STATE* rs)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -502,7 +524,7 @@ scard_send_connect(void *user_data, tui32 context, int wide,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_Connect(irp, context, wide, rs);
|
||||
scard_send_Connect(irp, context, context_bytes, wide, rs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -519,8 +541,8 @@ scard_send_connect(void *user_data, tui32 context, int wide,
|
||||
* rs.init_type
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_reconnect(void *user_data, tui32 context, tui32 sc_handle,
|
||||
READER_STATE* rs)
|
||||
scard_send_reconnect(void *user_data, char *context, int context_bytes,
|
||||
char *card, int card_bytes, READER_STATE* rs)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -538,7 +560,7 @@ scard_send_reconnect(void *user_data, tui32 context, tui32 sc_handle,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_Reconnect(irp, context, sc_handle, rs);
|
||||
scard_send_Reconnect(irp, context, context_bytes, card, card_bytes, rs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -550,7 +572,8 @@ scard_send_reconnect(void *user_data, tui32 context, tui32 sc_handle,
|
||||
* @param con connection to client
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_begin_transaction(void *user_data, tui32 sc_handle)
|
||||
scard_send_begin_transaction(void *user_data, char *context, int context_bytes,
|
||||
char *card, int card_bytes)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -568,7 +591,7 @@ scard_send_begin_transaction(void *user_data, tui32 sc_handle)
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_BeginTransaction(irp, sc_handle);
|
||||
scard_send_BeginTransaction(irp, context, context_bytes, card, card_bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -581,7 +604,8 @@ scard_send_begin_transaction(void *user_data, tui32 sc_handle)
|
||||
* @param sc_handle handle to smartcard
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_end_transaction(void *user_data, tui32 sc_handle,
|
||||
scard_send_end_transaction(void *user_data, char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
tui32 dwDisposition)
|
||||
{
|
||||
IRP *irp;
|
||||
@ -600,7 +624,8 @@ scard_send_end_transaction(void *user_data, tui32 sc_handle,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_EndTransaction(irp, sc_handle, dwDisposition);
|
||||
scard_send_EndTransaction(irp, context, context_bytes,
|
||||
card, card_bytes, dwDisposition);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -612,7 +637,8 @@ scard_send_end_transaction(void *user_data, tui32 sc_handle,
|
||||
* @param wide TRUE if unicode string
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_status(void *user_data, int wide, tui32 sc_handle,
|
||||
scard_send_status(void *user_data, int wide, char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
int cchReaderLen, int cbAtrLen)
|
||||
{
|
||||
IRP *irp;
|
||||
@ -631,7 +657,8 @@ scard_send_status(void *user_data, int wide, tui32 sc_handle,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_Status(irp, wide, sc_handle, cchReaderLen, cbAtrLen);
|
||||
scard_send_Status(irp, wide, context, context_bytes, card, card_bytes,
|
||||
cchReaderLen, cbAtrLen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -643,8 +670,8 @@ scard_send_status(void *user_data, int wide, tui32 sc_handle,
|
||||
* @param sc_handle handle to smartcard
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_disconnect(void *user_data, tui32 context, tui32 sc_handle,
|
||||
int dwDisposition)
|
||||
scard_send_disconnect(void *user_data, char *context, int context_bytes,
|
||||
char *card, int card_bytes, int dwDisposition)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -662,7 +689,8 @@ scard_send_disconnect(void *user_data, tui32 context, tui32 sc_handle,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_Disconnect(irp, context, sc_handle, dwDisposition);
|
||||
scard_send_Disconnect(irp, context, context_bytes,
|
||||
card, card_bytes, dwDisposition);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -672,7 +700,8 @@ scard_send_disconnect(void *user_data, tui32 context, tui32 sc_handle,
|
||||
* associated with a valid context.
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_transmit(void *user_data, tui32 sc_handle,
|
||||
scard_send_transmit(void *user_data, char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
char *send_data, int send_bytes, int recv_bytes,
|
||||
struct xrdp_scard_io_request *send_ior,
|
||||
struct xrdp_scard_io_request *recv_ior)
|
||||
@ -693,8 +722,9 @@ scard_send_transmit(void *user_data, tui32 sc_handle,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_Transmit(irp, sc_handle, send_data, send_bytes, recv_bytes,
|
||||
send_ior, recv_ior);
|
||||
scard_send_Transmit(irp, context, context_bytes, card, card_bytes,
|
||||
send_data, send_bytes,
|
||||
recv_bytes, send_ior, recv_ior);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -703,7 +733,7 @@ scard_send_transmit(void *user_data, tui32 sc_handle,
|
||||
* Communicate directly with the smart card reader
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_control(void *user_data, tui32 sc_handle,
|
||||
scard_send_control(void *user_data, char *card, int card_bytes,
|
||||
char *send_data, int send_bytes,
|
||||
int recv_bytes, int control_code)
|
||||
{
|
||||
@ -723,7 +753,7 @@ scard_send_control(void *user_data, tui32 sc_handle,
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_Control(irp, sc_handle, send_data,
|
||||
scard_send_Control(irp, card, card_bytes, send_data,
|
||||
send_bytes, recv_bytes, control_code);
|
||||
|
||||
return 0;
|
||||
@ -733,7 +763,7 @@ scard_send_control(void *user_data, tui32 sc_handle,
|
||||
* Cancel any outstanding calls
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_cancel(void *user_data, tui32 context)
|
||||
scard_send_cancel(void *user_data, char *context, int context_bytes)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -751,7 +781,7 @@ scard_send_cancel(void *user_data, tui32 context)
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_Cancel(irp, context);
|
||||
scard_send_Cancel(irp, context, context_bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -760,7 +790,8 @@ scard_send_cancel(void *user_data, tui32 context)
|
||||
* Get reader attributes
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_get_attrib(void *user_data, tui32 sc_handle, READER_STATE* rs)
|
||||
scard_send_get_attrib(void *user_data, char *card, int card_bytes,
|
||||
READER_STATE* rs)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -778,7 +809,7 @@ scard_send_get_attrib(void *user_data, tui32 sc_handle, READER_STATE* rs)
|
||||
irp->user_data = user_data;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_GetAttrib(irp, sc_handle, rs);
|
||||
scard_send_GetAttrib(irp, card, card_bytes, rs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -966,7 +997,7 @@ scard_send_EstablishContext(IRP *irp, int scope)
|
||||
* Release a previously established Smart Card context
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_ReleaseContext(IRP *irp, tui32 context)
|
||||
scard_send_ReleaseContext(IRP *irp, char *context, int context_bytes)
|
||||
{
|
||||
/* see [MS-RDPESC] 3.1.4.2 */
|
||||
|
||||
@ -988,10 +1019,10 @@ scard_send_ReleaseContext(IRP *irp, tui32 context)
|
||||
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
s_mark_end(s);
|
||||
|
||||
@ -1017,7 +1048,7 @@ scard_send_ReleaseContext(IRP *irp, tui32 context)
|
||||
* Checks if a previously established context is still valid
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_IsContextValid(IRP *irp, tui32 context)
|
||||
scard_send_IsContextValid(IRP *irp, char *context, int context_bytes)
|
||||
{
|
||||
/* see [MS-RDPESC] 3.1.4.3 */
|
||||
|
||||
@ -1049,14 +1080,19 @@ scard_send_IsContextValid(IRP *irp, tui32 context)
|
||||
* u32 4 bytes context
|
||||
*/
|
||||
|
||||
xstream_wr_u32_le(s, 16);
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
|
||||
/* insert context */
|
||||
xstream_wr_u32_le(s, 4);
|
||||
xstream_wr_u32_le(s, context);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
s_mark_end(s);
|
||||
|
||||
s_pop_layer(s, mcs_hdr);
|
||||
bytes = (int) (s->end - s->p);
|
||||
bytes -= 8;
|
||||
out_uint32_le(s, bytes);
|
||||
|
||||
s_pop_layer(s, iso_hdr);
|
||||
bytes = (int) (s->end - s->p);
|
||||
bytes -= 28;
|
||||
@ -1074,8 +1110,8 @@ scard_send_IsContextValid(IRP *irp, tui32 context)
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_ListReaders(IRP *irp, tui32 context, char *groups,
|
||||
int cchReaders, int wide)
|
||||
scard_send_ListReaders(IRP *irp, char *context, int context_bytes,
|
||||
char *groups, int cchReaders, int wide)
|
||||
{
|
||||
/* see [MS-RDPESC] 2.2.2.4 */
|
||||
|
||||
@ -1121,7 +1157,7 @@ scard_send_ListReaders(IRP *irp, tui32 context, char *groups,
|
||||
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
out_uint32_le(s, bytes_groups);
|
||||
out_uint32_le(s, val);
|
||||
@ -1129,8 +1165,8 @@ scard_send_ListReaders(IRP *irp, tui32 context, char *groups,
|
||||
out_uint32_le(s, cchReaders);
|
||||
|
||||
/* insert context */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, context);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
if (bytes_groups > 0)
|
||||
{
|
||||
@ -1206,7 +1242,8 @@ align_s(struct stream *s, int bytes)
|
||||
* @param rsa array of READER_STATEs
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
||||
scard_send_GetStatusChange(IRP* irp, char *context, int context_bytes,
|
||||
int wide, tui32 timeout,
|
||||
tui32 num_readers, READER_STATE* rsa)
|
||||
{
|
||||
/* see [MS-RDPESC] 2.2.2.11 for ASCII */
|
||||
@ -1239,7 +1276,7 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
||||
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
|
||||
out_uint32_le(s, timeout);
|
||||
@ -1247,8 +1284,8 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
||||
out_uint32_le(s, 0x00020004); /* ? */
|
||||
|
||||
/* insert context */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, context);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
out_uint32_le(s, num_readers);
|
||||
|
||||
@ -1336,7 +1373,8 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
||||
* @param rs reader state
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
||||
scard_send_Connect(IRP* irp, char *context, int context_bytes,
|
||||
int wide, READER_STATE* rs)
|
||||
{
|
||||
/* see [MS-RDPESC] 2.2.2.13 for ASCII */
|
||||
/* see [MS-RDPESC] 2.2.2.14 for Wide char */
|
||||
@ -1367,7 +1405,7 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020004);
|
||||
out_uint32_le(s, rs->dwShareMode);
|
||||
out_uint32_le(s, rs->dwPreferredProtocols);
|
||||
@ -1396,8 +1434,8 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
||||
align_s(s, 4);
|
||||
|
||||
/* insert context */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, context);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
out_uint32_le(s, 0);
|
||||
|
||||
s_mark_end(s);
|
||||
@ -1432,7 +1470,8 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
||||
* rs.init_type
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_Reconnect(IRP *irp, tui32 context, tui32 sc_handle, READER_STATE *rs)
|
||||
scard_send_Reconnect(IRP *irp, char *context, int context_bytes,
|
||||
char *card, int card_bytes, READER_STATE *rs)
|
||||
{
|
||||
/* see [MS-RDPESC] 2.2.2.15 */
|
||||
/* see [MS-RDPESC] 3.1.4.36 */
|
||||
@ -1470,14 +1509,15 @@ scard_send_Reconnect(IRP *irp, tui32 context, tui32 sc_handle, READER_STATE *rs)
|
||||
* u32 4 bytes handle
|
||||
*/
|
||||
|
||||
xstream_seek(s, 24);
|
||||
xstream_wr_u32_le(s, rs->dwShareMode);
|
||||
xstream_wr_u32_le(s, rs->dwPreferredProtocols);
|
||||
xstream_wr_u32_le(s, rs->init_type);
|
||||
xstream_wr_u32_le(s, 4);
|
||||
xstream_wr_u32_le(s, context);
|
||||
xstream_wr_u32_le(s, 4);
|
||||
xstream_wr_u32_le(s, sc_handle);
|
||||
xstream_seek(s, 24); /* TODO */
|
||||
|
||||
out_uint32_le(s, rs->dwShareMode);
|
||||
out_uint32_le(s, rs->dwPreferredProtocols);
|
||||
out_uint32_le(s, rs->init_type);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint8a(s, card, card_bytes);
|
||||
|
||||
s_mark_end(s);
|
||||
|
||||
@ -1501,7 +1541,8 @@ scard_send_Reconnect(IRP *irp, tui32 context, tui32 sc_handle, READER_STATE *rs)
|
||||
* @param con connection to client
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
|
||||
scard_send_BeginTransaction(IRP *irp, char *context, int context_bytes,
|
||||
char *card, int card_bytes)
|
||||
{
|
||||
/* see [MS-RDPESC] 4.9 */
|
||||
|
||||
@ -1523,17 +1564,20 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
|
||||
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint32_le(s, 0x00020004);
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, 0x00000002);
|
||||
|
||||
/* insert handle */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, sc_handle);
|
||||
/* insert context */
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
/* insert card */
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint8a(s, card, card_bytes);
|
||||
|
||||
out_uint32_le(s, 0x00000000);
|
||||
|
||||
s_mark_end(s);
|
||||
@ -1564,7 +1608,9 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
|
||||
* @param sc_handle handle to smartcard
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
|
||||
scard_send_EndTransaction(IRP *irp, char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
tui32 dwDisposition)
|
||||
{
|
||||
/* see [MS-RDPESC] 3.1.4.32 */
|
||||
|
||||
@ -1586,17 +1632,20 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
|
||||
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint32_le(s, 0x00020004);
|
||||
out_uint32_le(s, dwDisposition);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, 0x00000009);
|
||||
|
||||
/* insert handle */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, sc_handle);
|
||||
/* insert context */
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
/* insert card */
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint8a(s, card, card_bytes);
|
||||
|
||||
out_uint32_le(s, 0);
|
||||
|
||||
s_mark_end(s);
|
||||
@ -1626,7 +1675,8 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
|
||||
* @param wide TRUE if unicode string
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
|
||||
scard_send_Status(IRP *irp, int wide, char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
int cchReaderLen, int cbAtrLen)
|
||||
{
|
||||
/* see [MS-RDPESC] 2.2.2.18 */
|
||||
@ -1666,18 +1716,22 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
|
||||
*/
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint32_le(s, 0x00020004);
|
||||
out_uint32_le(s, 0x00000001);
|
||||
out_uint32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */
|
||||
out_uint32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, 0x00000007);
|
||||
/* insert sc_handle */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, sc_handle);
|
||||
|
||||
/* insert context */
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
/* insert card */
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint8a(s, card, card_bytes);
|
||||
|
||||
out_uint32_le(s, 0);
|
||||
|
||||
s_mark_end(s);
|
||||
@ -1709,8 +1763,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle,
|
||||
* @param sc_handle handle to smartcard
|
||||
*****************************************************************************/
|
||||
static void APP_CC
|
||||
scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
|
||||
int dwDisposition)
|
||||
scard_send_Disconnect(IRP *irp, char *context, int context_bytes,
|
||||
char *card, int card_bytes, int dwDisposition)
|
||||
{
|
||||
/* see [MS-RDPESC] 3.1.4.30 */
|
||||
|
||||
@ -1732,19 +1786,19 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
|
||||
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint32_le(s, 0x00020004);
|
||||
out_uint32_le(s, dwDisposition);
|
||||
|
||||
/* insert context */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, context);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
/* insert handle */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, sc_handle);
|
||||
/* insert card */
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint8a(s, card, card_bytes);
|
||||
|
||||
out_uint32_le(s, 0x00000000);
|
||||
|
||||
@ -1773,7 +1827,8 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
|
||||
* associated with a valid context.
|
||||
*****************************************************************************/
|
||||
static int APP_CC
|
||||
scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data,
|
||||
scard_send_Transmit(IRP *irp, char *context, int context_bytes,
|
||||
char *card, int card_bytes, char *send_data,
|
||||
int send_bytes, int recv_bytes,
|
||||
struct xrdp_scard_io_request *send_ior,
|
||||
struct xrdp_scard_io_request *recv_ior)
|
||||
@ -1876,10 +1931,10 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data,
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000); /* map0 */
|
||||
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint32_le(s, 0x00020004); /* map1 */
|
||||
|
||||
out_uint32_le(s, send_ior->dwProtocol);
|
||||
@ -1900,12 +1955,12 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data,
|
||||
out_uint32_le(s, recv_bytes);
|
||||
|
||||
/* map0 */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, 5);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
/* map1 */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, sc_handle);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint8a(s, card, card_bytes);
|
||||
|
||||
if (send_ior->extra_bytes > 0)
|
||||
{
|
||||
@ -1965,7 +2020,7 @@ scard_send_Transmit(IRP *irp, tui32 sc_handle, char *send_data,
|
||||
* Communicate directly with the smart card reader
|
||||
*****************************************************************************/
|
||||
static int APP_CC
|
||||
scard_send_Control(IRP *irp, tui32 sc_handle, char *send_data,
|
||||
scard_send_Control(IRP *irp, char *card, int card_bytes, char *send_data,
|
||||
int send_bytes, int recv_bytes, int control_code)
|
||||
{
|
||||
/* see [MS-RDPESC] 2.2.2.19 */
|
||||
@ -2001,8 +2056,8 @@ scard_send_Control(IRP *irp, tui32 sc_handle, char *send_data,
|
||||
out_uint32_le(s, recv_bytes);
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, 0); /* context ? */
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, sc_handle);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint8a(s, card, card_bytes);
|
||||
if (send_bytes > 0)
|
||||
{
|
||||
out_uint32_le(s, send_bytes);
|
||||
@ -2040,7 +2095,7 @@ scard_send_Control(IRP *irp, tui32 sc_handle, char *send_data,
|
||||
* Cancel any outstanding calls
|
||||
*****************************************************************************/
|
||||
static int APP_CC
|
||||
scard_send_Cancel(IRP *irp, tui32 context)
|
||||
scard_send_Cancel(IRP *irp, char *context, int context_bytes)
|
||||
{
|
||||
/* see [MS-RDPESC] 3.1.4.27 */
|
||||
|
||||
@ -2062,10 +2117,10 @@ scard_send_Cancel(IRP *irp, tui32 context)
|
||||
|
||||
s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
|
||||
out_uint32_le(s, 0x00000000);
|
||||
out_uint32_le(s, 0x00000004);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint32_le(s, 0x00020000);
|
||||
out_uint32_le(s, 4);
|
||||
out_uint32_le(s, context);
|
||||
out_uint32_le(s, context_bytes);
|
||||
out_uint8a(s, context, context_bytes);
|
||||
|
||||
s_mark_end(s);
|
||||
|
||||
@ -2092,7 +2147,7 @@ scard_send_Cancel(IRP *irp, tui32 context)
|
||||
* Get reader attributes
|
||||
*****************************************************************************/
|
||||
static int APP_CC
|
||||
scard_send_GetAttrib(IRP *irp, tui32 sc_handle, READER_STATE *rs)
|
||||
scard_send_GetAttrib(IRP *irp, char *card, int card_bytes, READER_STATE *rs)
|
||||
{
|
||||
/* see [MS-RDPESC] 2.2.2.21 */
|
||||
|
||||
@ -2128,13 +2183,13 @@ scard_send_GetAttrib(IRP *irp, tui32 sc_handle, READER_STATE *rs)
|
||||
* u32 4 bytes handle
|
||||
*/
|
||||
|
||||
xstream_seek(s, 24);
|
||||
xstream_wr_u32_le(s, rs->dwAttribId);
|
||||
xstream_wr_u32_le(s, 0);
|
||||
xstream_wr_u32_le(s, rs->dwAttrLen);
|
||||
xstream_seek(s, 24); /* TODO */
|
||||
out_uint32_le(s, rs->dwAttribId);
|
||||
out_uint32_le(s, 0);
|
||||
out_uint32_le(s, rs->dwAttrLen);
|
||||
xstream_seek(s, 8);
|
||||
xstream_wr_u32_le(s, 4);
|
||||
xstream_wr_u32_le(s, sc_handle);
|
||||
out_uint32_le(s, card_bytes);
|
||||
out_uint8a(s, card, card_bytes);
|
||||
|
||||
s_mark_end(s);
|
||||
|
||||
|
@ -111,41 +111,59 @@ int APP_CC scard_check_wait_objs(void);
|
||||
int APP_CC scard_init(void);
|
||||
int APP_CC scard_deinit(void);
|
||||
int APP_CC scard_send_establish_context(void *user_data, int scope);
|
||||
int APP_CC scard_send_release_context(void *user_data, tui32 context);
|
||||
int APP_CC scard_send_is_valid_context(void *user_data, tui32 context);
|
||||
int APP_CC scard_send_list_readers(void *user_data, tui32 context,
|
||||
int APP_CC scard_send_release_context(void *user_data,
|
||||
char *context, int context_bytes);
|
||||
int APP_CC scard_send_is_valid_context(void *user_data,
|
||||
char *context, int context_bytes);
|
||||
int APP_CC scard_send_list_readers(void *user_data,
|
||||
char *context, int context_bytes,
|
||||
char *groups, int cchReaders, int wide);
|
||||
|
||||
int APP_CC scard_send_get_status_change(void *user_data, tui32 context,
|
||||
int APP_CC scard_send_get_status_change(void *user_data,
|
||||
char *context, int context_bytes,
|
||||
int wide, tui32 timeout,
|
||||
tui32 num_readers, READER_STATE* rsa);
|
||||
|
||||
int APP_CC scard_send_connect(void *user_data, tui32 context, int wide,
|
||||
int APP_CC scard_send_connect(void *user_data,
|
||||
char *context, int context_bytes, int wide,
|
||||
READER_STATE* rs);
|
||||
|
||||
int APP_CC scard_send_reconnect(void *user_data, tui32 context,
|
||||
tui32 sc_handle, READER_STATE* rs);
|
||||
int APP_CC scard_send_reconnect(void *user_data,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
READER_STATE* rs);
|
||||
|
||||
int APP_CC scard_send_begin_transaction(void *user_data, tui32 sc_handle);
|
||||
int APP_CC scard_send_end_transaction(void *user_data, tui32 sc_handle,
|
||||
int APP_CC scard_send_begin_transaction(void *user_data,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes);
|
||||
int APP_CC scard_send_end_transaction(void *user_data,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
tui32 dwDisposition);
|
||||
int APP_CC scard_send_status(void *user_data, int wide, tui32 sc_handle,
|
||||
int APP_CC scard_send_status(void *user_data, int wide,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
int cchReaderLen, int cbAtrLen);
|
||||
int APP_CC scard_send_disconnect(void *user_data, tui32 context,
|
||||
tui32 sc_handle, int dwDisposition);
|
||||
int APP_CC scard_send_disconnect(void *user_data,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
int dwDisposition);
|
||||
|
||||
int APP_CC scard_send_transmit(void *user_data, tui32 sc_handle,
|
||||
int APP_CC scard_send_transmit(void *user_data,
|
||||
char *context, int context_bytes,
|
||||
char *card, int card_bytes,
|
||||
char *send_data, int send_bytes, int recv_bytes,
|
||||
struct xrdp_scard_io_request *send_ior,
|
||||
struct xrdp_scard_io_request *recv_ior);
|
||||
|
||||
int APP_CC scard_send_control(void *user_data, tui32 sc_handle,
|
||||
int APP_CC scard_send_control(void *user_data, char *card, int card_bytes,
|
||||
char *send_data, int send_bytes,
|
||||
int recv_bytes, int control_code);
|
||||
|
||||
int APP_CC scard_send_cancel(void *user_data, tui32 context);
|
||||
int APP_CC scard_send_cancel(void *user_data,
|
||||
char *context, int context_bytes);
|
||||
|
||||
int APP_CC scard_send_get_attrib(void *user_data, tui32 sc_handle,
|
||||
int APP_CC scard_send_get_attrib(void *user_data, char *card, int card_bytes,
|
||||
READER_STATE* rs);
|
||||
|
||||
/*
|
||||
|
@ -63,6 +63,7 @@
|
||||
#define XRDP_PCSC_STATE_GOT_CO (1 << 8) /* control */
|
||||
#define XRDP_PCSC_STATE_GOT_D (1 << 9) /* disconnect */
|
||||
#define XRDP_PCSC_STATE_GOT_ST (1 << 10) /* get status */
|
||||
#define XRDP_PCSC_STATE_GOT_CANCEL (1 << 11) /* cancel */
|
||||
|
||||
#if 0
|
||||
/* TODO: put this in con */
|
||||
@ -74,15 +75,20 @@ extern int g_display_num; /* in chansrv.c */
|
||||
|
||||
static int g_uds_client_id = 0; /* auto incremented for each unix domain
|
||||
socket connection */
|
||||
static int g_autoinc = 0; /* general purpose autoinc */
|
||||
|
||||
struct pcsc_card /* item for list of open cards in one context */
|
||||
{
|
||||
tui32 card;
|
||||
tui32 app_card; /* application card, always 4 bytes */
|
||||
int card_bytes; /* client card bytes */
|
||||
char card[8]; /* client card */
|
||||
};
|
||||
|
||||
struct pcsc_context
|
||||
{
|
||||
tui32 context;
|
||||
tui32 app_context; /* application context, always 4 byte */
|
||||
int context_bytes; /* client context bytes */
|
||||
char context[8]; /* client context */
|
||||
struct list *cards; /* these need to be released on close */
|
||||
};
|
||||
|
||||
@ -94,6 +100,7 @@ struct pcsc_uds_client
|
||||
struct list *contexts; /* struct pcsc_context */
|
||||
int pcsc_state;
|
||||
int pcsc_extra1;
|
||||
struct pcsc_context *connect_context;
|
||||
};
|
||||
|
||||
static struct list *g_uds_clients = 0; /* struct pcsc_uds_client */
|
||||
@ -162,6 +169,87 @@ get_uds_client_by_id(int uds_client_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
struct pcsc_context *
|
||||
get_pcsc_context_by_app_context(struct pcsc_uds_client *uds_client,
|
||||
int app_context)
|
||||
{
|
||||
struct pcsc_context *rv;
|
||||
int index;
|
||||
|
||||
if (uds_client == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (uds_client->contexts == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for (index = 0; index < uds_client->contexts->count; index++)
|
||||
{
|
||||
rv = (struct pcsc_context *)
|
||||
list_get_item(uds_client->contexts, index);
|
||||
if (rv->app_context == app_context)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
struct pcsc_card *
|
||||
get_pcsc_card_by_app_card(struct pcsc_uds_client *uds_client,
|
||||
int app_card, struct pcsc_context **acontext)
|
||||
{
|
||||
struct pcsc_card *lcard;
|
||||
struct pcsc_context *lcontext;
|
||||
int index;
|
||||
int index1;
|
||||
|
||||
LLOGLN(10, ("get_pcsc_card_by_app_card:"));
|
||||
LLOGLN(10, (" app_card %d", app_card));
|
||||
if (uds_client == 0)
|
||||
{
|
||||
LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
|
||||
return 0;
|
||||
}
|
||||
if (uds_client->contexts == 0)
|
||||
{
|
||||
LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
|
||||
return 0;
|
||||
}
|
||||
for (index = 0; index < uds_client->contexts->count; index++)
|
||||
{
|
||||
lcontext = (struct pcsc_context *)
|
||||
list_get_item(uds_client->contexts, index);
|
||||
if (lcontext != 0)
|
||||
{
|
||||
if (lcontext->cards != 0)
|
||||
{
|
||||
for (index1 = 0; index1 < lcontext->cards->count; index1++)
|
||||
{
|
||||
lcard = (struct pcsc_card *)
|
||||
list_get_item(lcontext->cards, index1);
|
||||
if (lcard != 0)
|
||||
{
|
||||
if (lcard->app_card == app_card)
|
||||
{
|
||||
if (acontext != 0)
|
||||
{
|
||||
*acontext = lcontext;
|
||||
}
|
||||
return lcard;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
free_uds_client(struct pcsc_uds_client *uds_client)
|
||||
@ -199,8 +287,9 @@ free_uds_client(struct pcsc_uds_client *uds_client)
|
||||
list_delete(context->cards);
|
||||
}
|
||||
LLOGLN(10, (" left over context 0x%8.8x", context->context));
|
||||
scard_send_cancel(0, context->context);
|
||||
scard_send_release_context(0, context->context);
|
||||
scard_send_cancel(0, context->context, context->context_bytes);
|
||||
scard_send_release_context(0, context->context,
|
||||
context->context_bytes);
|
||||
g_free(context);
|
||||
}
|
||||
}
|
||||
@ -212,8 +301,9 @@ free_uds_client(struct pcsc_uds_client *uds_client)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
uds_client_add_context(struct pcsc_uds_client *uds_client, tui32 context)
|
||||
static struct pcsc_context *
|
||||
uds_client_add_context(struct pcsc_uds_client *uds_client,
|
||||
char *context, int context_bytes)
|
||||
{
|
||||
struct pcsc_context *pcscContext;
|
||||
|
||||
@ -223,25 +313,52 @@ uds_client_add_context(struct pcsc_uds_client *uds_client, tui32 context)
|
||||
if (pcscContext == 0)
|
||||
{
|
||||
LLOGLN(0, ("uds_client_add_context: error"));
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
pcscContext->context = context;
|
||||
g_autoinc++;
|
||||
pcscContext->app_context = g_autoinc;
|
||||
pcscContext->context_bytes = context_bytes;
|
||||
g_memcpy(pcscContext->context, context, context_bytes);
|
||||
if (uds_client->contexts == 0)
|
||||
{
|
||||
uds_client->contexts = list_create();
|
||||
if (uds_client->contexts == 0)
|
||||
{
|
||||
LLOGLN(0, ("uds_client_add_context: error"));
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
list_add_item(uds_client->contexts, (tintptr) pcscContext);
|
||||
return pcscContext;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
uds_client_remove_context(struct pcsc_uds_client *uds_client,
|
||||
struct pcsc_context *acontext)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (uds_client->contexts == 0)
|
||||
{
|
||||
LLOGLN(0, ("uds_client_remove_context: error"));
|
||||
return 1;
|
||||
}
|
||||
index = list_index_of(uds_client->contexts, (tintptr) acontext);
|
||||
if (index < 0)
|
||||
{
|
||||
LLOGLN(0, ("uds_client_remove_context: error"));
|
||||
return 1;
|
||||
}
|
||||
list_remove_item(uds_client->contexts, index);
|
||||
g_free(acontext); // TODO free cards
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
uds_client_remove_context(struct pcsc_uds_client *uds_client, tui32 context)
|
||||
uds_client_remove_context1(struct pcsc_uds_client *uds_client,
|
||||
char *context, int context_bytes)
|
||||
{
|
||||
int index;
|
||||
struct pcsc_context *pcscContext;
|
||||
@ -258,7 +375,8 @@ uds_client_remove_context(struct pcsc_uds_client *uds_client, tui32 context)
|
||||
list_get_item(uds_client->contexts, index);
|
||||
if (pcscContext != 0)
|
||||
{
|
||||
if (pcscContext->context == context)
|
||||
if ((pcscContext->context_bytes == context_bytes) &&
|
||||
(g_memcmp(pcscContext->context, context, context_bytes) == 0))
|
||||
{
|
||||
list_remove_item(uds_client->contexts, index);
|
||||
g_free(pcscContext);
|
||||
@ -270,6 +388,40 @@ uds_client_remove_context(struct pcsc_uds_client *uds_client, tui32 context)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct pcsc_card *
|
||||
context_add_card(struct pcsc_uds_client *uds_client,
|
||||
struct pcsc_context *acontext,
|
||||
char *card, int card_bytes)
|
||||
{
|
||||
struct pcsc_card *pcscCard;
|
||||
|
||||
LLOGLN(10, ("context_add_card:"));
|
||||
pcscCard = (struct pcsc_card * )
|
||||
g_malloc(sizeof(struct pcsc_card), 1);
|
||||
if (pcscCard == 0)
|
||||
{
|
||||
LLOGLN(0, ("context_add_card: error"));
|
||||
return 0;
|
||||
}
|
||||
g_autoinc++;
|
||||
pcscCard->app_card = g_autoinc;
|
||||
pcscCard->card_bytes = card_bytes;
|
||||
g_memcpy(pcscCard->card, card, card_bytes);
|
||||
if (acontext->cards == 0)
|
||||
{
|
||||
acontext->cards = list_create();
|
||||
if (acontext->cards == 0)
|
||||
{
|
||||
LLOGLN(0, ("context_add_card: error"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
list_add_item(acontext->cards, (tintptr) pcscCard);
|
||||
LLOGLN(10, (" new app_card %d", pcscCard->app_card));
|
||||
return pcscCard;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
|
||||
@ -386,11 +538,13 @@ scard_function_establish_context_return(void *user_data,
|
||||
{
|
||||
int bytes;
|
||||
int uds_client_id;
|
||||
tui32 context;
|
||||
tui32 context_len;
|
||||
int context_bytes;
|
||||
int app_context;
|
||||
char context[8];
|
||||
struct stream *out_s;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
struct trans *con;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_function_establish_context_return:"));
|
||||
LLOGLN(10, (" status 0x%8.8x", status));
|
||||
@ -411,25 +565,29 @@ scard_function_establish_context_return(void *user_data,
|
||||
return 1;
|
||||
}
|
||||
uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
|
||||
context = 0;
|
||||
lcontext = 0;
|
||||
app_context = 0;
|
||||
g_memset(context, 0, 8);
|
||||
if (status == 0)
|
||||
{
|
||||
in_uint8s(in_s, 28);
|
||||
in_uint32_le(in_s, context_len);
|
||||
if (context_len != 4)
|
||||
in_uint32_le(in_s, context_bytes);
|
||||
if (context_bytes > 8)
|
||||
{
|
||||
LLOGLN(0, ("scard_function_establish_context_return: opps "
|
||||
"context_len %d", context_len));
|
||||
"context_bytes %d", context_bytes));
|
||||
g_hexdump(in_s->p, context_bytes);
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(in_s, context);
|
||||
uds_client_add_context(uds_client, context);
|
||||
in_uint8a(in_s, context, context_bytes);
|
||||
lcontext = uds_client_add_context(uds_client, context, context_bytes);
|
||||
app_context = lcontext->app_context;
|
||||
LLOGLN(10, ("scard_function_establish_context_return: "
|
||||
"context 0x%8.8x", context));
|
||||
"app_context %d", app_context));
|
||||
}
|
||||
out_s = trans_get_out_s(con, 8192);
|
||||
s_push_layer(out_s, iso_hdr, 8);
|
||||
out_uint32_le(out_s, context);
|
||||
out_uint32_le(out_s, app_context);
|
||||
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
||||
s_mark_end(out_s);
|
||||
bytes = (int) (out_s->end - out_s->data);
|
||||
@ -446,21 +604,30 @@ scard_process_release_context(struct trans *con, struct stream *in_s)
|
||||
{
|
||||
int hContext;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
struct pcsc_context *lcontext;
|
||||
void *user_data;
|
||||
|
||||
LLOGLN(10, ("scard_process_release_context:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_RC)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_establish_context: opps"));
|
||||
LLOGLN(0, ("scard_process_release_context: opps"));
|
||||
return 1;
|
||||
}
|
||||
uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_RC;
|
||||
in_uint32_le(in_s, hContext);
|
||||
LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext));
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_release_context(user_data, hContext);
|
||||
uds_client_remove_context(uds_client, hContext);
|
||||
lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
|
||||
if (lcontext == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_release_context: "
|
||||
"get_pcsc_context_by_app_context failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_release_context(user_data, lcontext->context,
|
||||
lcontext->context_bytes);
|
||||
uds_client_remove_context(uds_client, lcontext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -517,6 +684,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
|
||||
char *groups;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_process_list_readers:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -535,7 +703,15 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
|
||||
LLOGLN(10, ("scard_process_list_readers: hContext 0x%8.8x cchReaders %d",
|
||||
hContext, cchReaders));
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_list_readers(user_data, hContext, groups, cchReaders, 1);
|
||||
lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
|
||||
if (lcontext == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_list_readers: "
|
||||
"get_pcsc_context_by_app_context failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_list_readers(user_data, lcontext->context,
|
||||
lcontext->context_bytes, groups, cchReaders, 1);
|
||||
g_free(groups);
|
||||
return 0;
|
||||
}
|
||||
@ -635,10 +811,6 @@ scard_function_list_readers_return(void *user_data,
|
||||
{
|
||||
out_uint8a(out_s, lreader_name[index], 100);
|
||||
}
|
||||
//if (readers == 0)
|
||||
//{
|
||||
// status = 0x8010002E; /* SCARD_E_NO_READERS_AVAILABLE */
|
||||
//}
|
||||
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
||||
s_mark_end(out_s);
|
||||
bytes = (int) (out_s->end - out_s->data);
|
||||
@ -657,6 +829,7 @@ scard_process_connect(struct trans *con, struct stream *in_s)
|
||||
READER_STATE rs;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_process_connect:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -675,7 +848,16 @@ scard_process_connect(struct trans *con, struct stream *in_s)
|
||||
"dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode,
|
||||
rs.dwPreferredProtocols));
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_connect(user_data, hContext, 1, &rs);
|
||||
lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
|
||||
if (lcontext == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_connect: "
|
||||
"get_pcsc_context_by_app_context failed"));
|
||||
return 1;
|
||||
}
|
||||
uds_client->connect_context = lcontext;
|
||||
scard_send_connect(user_data, lcontext->context, lcontext->context_bytes,
|
||||
1, &rs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -692,6 +874,9 @@ scard_function_connect_return(void *user_data,
|
||||
struct stream *out_s;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
struct trans *con;
|
||||
char *card;
|
||||
int card_bytes;
|
||||
struct pcsc_card *lcard;
|
||||
|
||||
LLOGLN(10, ("scard_function_connect_return:"));
|
||||
LLOGLN(10, (" status 0x%8.8x", status));
|
||||
@ -717,8 +902,11 @@ scard_function_connect_return(void *user_data,
|
||||
{
|
||||
in_uint8s(in_s, 36);
|
||||
in_uint32_le(in_s, dwActiveProtocol);
|
||||
in_uint8s(in_s, 4);
|
||||
in_uint32_le(in_s, hCard);
|
||||
in_uint32_le(in_s, card_bytes);
|
||||
in_uint8p(in_s, card, card_bytes);
|
||||
lcard = context_add_card(uds_client, uds_client->connect_context,
|
||||
card, card_bytes);
|
||||
hCard = lcard->app_card;
|
||||
LLOGLN(10, (" hCard %d dwActiveProtocol %d", hCard, dwActiveProtocol));
|
||||
}
|
||||
out_s = trans_get_out_s(con, 8192);
|
||||
@ -739,11 +927,12 @@ scard_function_connect_return(void *user_data,
|
||||
int APP_CC
|
||||
scard_process_disconnect(struct trans *con, struct stream *in_s)
|
||||
{
|
||||
int hContext;
|
||||
int hCard;
|
||||
int dwDisposition;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_context *lcontext;
|
||||
struct pcsc_card *lcard;
|
||||
|
||||
LLOGLN(10, ("scard_process_disconnect:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -755,11 +944,17 @@ scard_process_disconnect(struct trans *con, struct stream *in_s)
|
||||
uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_D;
|
||||
in_uint32_le(in_s, hCard);
|
||||
in_uint32_le(in_s, dwDisposition);
|
||||
|
||||
hContext = 1;
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_disconnect(user_data, hContext, hCard, dwDisposition);
|
||||
|
||||
lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
|
||||
if ((lcontext == 0) || (lcard == 0))
|
||||
{
|
||||
LLOGLN(0, ("scard_process_disconnect: "
|
||||
"get_pcsc_card_by_app_card failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_disconnect(user_data,
|
||||
lcontext->context, lcontext->context_bytes,
|
||||
lcard->card, lcard->card_bytes, dwDisposition);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -769,8 +964,6 @@ scard_function_disconnect_return(void *user_data,
|
||||
struct stream *in_s,
|
||||
int len, int status)
|
||||
{
|
||||
int dwActiveProtocol;
|
||||
int hCard;
|
||||
int bytes;
|
||||
int uds_client_id;
|
||||
struct stream *out_s;
|
||||
@ -795,17 +988,6 @@ scard_function_disconnect_return(void *user_data,
|
||||
return 1;
|
||||
}
|
||||
uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_D;
|
||||
dwActiveProtocol = 0;
|
||||
hCard = 0;
|
||||
if (status == 0)
|
||||
{
|
||||
in_uint8s(in_s, 36);
|
||||
in_uint32_le(in_s, dwActiveProtocol);
|
||||
in_uint8s(in_s, 4);
|
||||
in_uint32_le(in_s, hCard);
|
||||
LLOGLN(10, ("scard_function_connect_return: hCard %d "
|
||||
"dwActiveProtocol %d", hCard, dwActiveProtocol));
|
||||
}
|
||||
out_s = trans_get_out_s(con, 8192);
|
||||
s_push_layer(out_s, iso_hdr, 8);
|
||||
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
||||
@ -825,6 +1007,8 @@ scard_process_begin_transaction(struct trans *con, struct stream *in_s)
|
||||
int hCard;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_card *lcard;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_process_begin_transaction:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -837,7 +1021,16 @@ scard_process_begin_transaction(struct trans *con, struct stream *in_s)
|
||||
in_uint32_le(in_s, hCard);
|
||||
LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_begin_transaction(user_data, hCard);
|
||||
lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
|
||||
if ((lcard == 0) || (lcontext == 0))
|
||||
{
|
||||
LLOGLN(0, ("scard_process_begin_transaction: "
|
||||
"get_pcsc_card_by_app_card failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_begin_transaction(user_data,
|
||||
lcontext->context, lcontext->context_bytes,
|
||||
lcard->card, lcard->card_bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -892,6 +1085,8 @@ scard_process_end_transaction(struct trans *con, struct stream *in_s)
|
||||
int dwDisposition;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_card *lcard;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_process_end_transaction:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -905,7 +1100,17 @@ scard_process_end_transaction(struct trans *con, struct stream *in_s)
|
||||
in_uint32_le(in_s, dwDisposition);
|
||||
LLOGLN(10, ("scard_process_end_transaction: hCard 0x%8.8x", hCard));
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_end_transaction(user_data, hCard, dwDisposition);
|
||||
lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
|
||||
if ((lcard == 0) || (lcontext == 0))
|
||||
{
|
||||
LLOGLN(0, ("scard_process_end_transaction: "
|
||||
"get_pcsc_card_by_app_card failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_end_transaction(user_data,
|
||||
lcontext->context, lcontext->context_bytes,
|
||||
lcard->card, lcard->card_bytes,
|
||||
dwDisposition);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -952,18 +1157,6 @@ scard_function_end_transaction_return(void *user_data,
|
||||
return trans_force_write(con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_function_cancel_return(void *user_data,
|
||||
struct stream *in_s,
|
||||
int len, int status)
|
||||
{
|
||||
LLOGLN(10, ("scard_function_cancel_return:"));
|
||||
//g_hexdump(in_s->p, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
@ -987,6 +1180,8 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
|
||||
struct xrdp_scard_io_request recv_ior;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_card *lcard;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_process_transmit:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -1016,7 +1211,16 @@ scard_process_transmit(struct trans *con, struct stream *in_s)
|
||||
//g_hexdump(in_s->p, send_bytes);
|
||||
LLOGLN(10, ("scard_process_transmit: recv_bytes %d", recv_bytes));
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_transmit(user_data, hCard, send_data, send_bytes, recv_bytes,
|
||||
lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
|
||||
if ((lcard == 0) || (lcontext == 0))
|
||||
{
|
||||
LLOGLN(0, ("scard_process_transmit: "
|
||||
"get_pcsc_card_by_app_card failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_transmit(user_data, lcontext->context, lcontext->context_bytes,
|
||||
lcard->card, lcard->card_bytes,
|
||||
send_data, send_bytes, recv_bytes,
|
||||
&send_ior, &recv_ior);
|
||||
return 0;
|
||||
}
|
||||
@ -1116,6 +1320,7 @@ scard_process_control(struct trans *con, struct stream *in_s)
|
||||
char *send_data;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_card *lcard;
|
||||
|
||||
LLOGLN(10, ("scard_process_control:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -1134,7 +1339,15 @@ scard_process_control(struct trans *con, struct stream *in_s)
|
||||
in_uint32_le(in_s, recv_bytes);
|
||||
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_control(user_data, hCard, send_data, send_bytes, recv_bytes,
|
||||
lcard = get_pcsc_card_by_app_card(uds_client, hCard, 0);
|
||||
if (lcard == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_control: "
|
||||
"get_pcsc_card_by_app_card failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_control(user_data, lcard->card, lcard->card_bytes,
|
||||
send_data, send_bytes, recv_bytes,
|
||||
control_code);
|
||||
|
||||
return 0;
|
||||
@ -1205,6 +1418,8 @@ scard_process_status(struct trans *con, struct stream *in_s)
|
||||
int cbAtrLen;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_card *lcard;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_process_status:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -1220,7 +1435,16 @@ scard_process_status(struct trans *con, struct stream *in_s)
|
||||
in_uint32_le(in_s, cbAtrLen);
|
||||
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_status(user_data, 1, hCard, cchReaderLen, cbAtrLen);
|
||||
lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
|
||||
if ((lcard == 0) || (lcontext == 0))
|
||||
{
|
||||
LLOGLN(0, ("scard_process_status: "
|
||||
"get_pcsc_card_by_app_card failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_status(user_data, 1, lcontext->context, lcontext->context_bytes,
|
||||
lcard->card, lcard->card_bytes,
|
||||
cchReaderLen, cbAtrLen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1343,6 +1567,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
|
||||
READER_STATE *rsa;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_process_get_status_change:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
@ -1383,8 +1608,16 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
|
||||
"%d cReaders %d", hContext, dwTimeout, cReaders));
|
||||
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
scard_send_get_status_change(user_data, hContext, 1, dwTimeout, cReaders, rsa);
|
||||
|
||||
lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
|
||||
if (lcontext == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_get_status_change: "
|
||||
"get_pcsc_context_by_app_context failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_get_status_change(user_data,
|
||||
lcontext->context, lcontext->context_bytes,
|
||||
1, dwTimeout, cReaders, rsa);
|
||||
g_free(rsa);
|
||||
|
||||
return 0;
|
||||
@ -1466,6 +1699,80 @@ scard_function_get_status_change_return(void *user_data,
|
||||
return trans_force_write(con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_process_cancel(struct trans *con, struct stream *in_s)
|
||||
{
|
||||
int hContext;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
void *user_data;
|
||||
struct pcsc_context *lcontext;
|
||||
|
||||
LLOGLN(10, ("scard_process_cancel:"));
|
||||
uds_client = (struct pcsc_uds_client *) (con->callback_data);
|
||||
if (uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_CANCEL)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_cancel: opps"));
|
||||
return 1;
|
||||
}
|
||||
uds_client->pcsc_state |= XRDP_PCSC_STATE_GOT_CANCEL;
|
||||
in_uint32_le(in_s, hContext);
|
||||
LLOGLN(10, ("scard_process_cancel: hContext 0x%8.8x", hContext));
|
||||
user_data = (void *) (tintptr) (uds_client->uds_client_id);
|
||||
lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
|
||||
if (lcontext == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_cancel: "
|
||||
"get_pcsc_context_by_app_context failed"));
|
||||
return 1;
|
||||
}
|
||||
scard_send_cancel(user_data, lcontext->context, lcontext->context_bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_function_cancel_return(void *user_data,
|
||||
struct stream *in_s,
|
||||
int len, int status)
|
||||
{
|
||||
int bytes;
|
||||
int uds_client_id;
|
||||
struct stream *out_s;
|
||||
struct pcsc_uds_client *uds_client;
|
||||
struct trans *con;
|
||||
|
||||
LLOGLN(10, ("scard_function_cancel_return:"));
|
||||
LLOGLN(10, (" status 0x%8.8x", status));
|
||||
uds_client_id = (int) (tintptr) user_data;
|
||||
uds_client = (struct pcsc_uds_client *)
|
||||
get_uds_client_by_id(uds_client_id);
|
||||
if (uds_client == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_function_cancel_return: "
|
||||
"get_uds_client_by_id failed"));
|
||||
return 1;
|
||||
}
|
||||
con = uds_client->con;
|
||||
if ((uds_client->pcsc_state & XRDP_PCSC_STATE_GOT_CANCEL) == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_function_cancel_return: opps"));
|
||||
return 1;
|
||||
}
|
||||
uds_client->pcsc_state &= ~XRDP_PCSC_STATE_GOT_CANCEL;
|
||||
out_s = trans_get_out_s(con, 8192);
|
||||
s_push_layer(out_s, iso_hdr, 8);
|
||||
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
||||
s_mark_end(out_s);
|
||||
bytes = (int) (out_s->end - out_s->data);
|
||||
s_pop_layer(out_s, iso_hdr);
|
||||
out_uint32_le(out_s, bytes - 8);
|
||||
out_uint32_le(out_s, 0x0D); /* SCARD_CANCEL 0x0D */
|
||||
return trans_force_write(con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
@ -1555,7 +1862,8 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
|
||||
break;
|
||||
|
||||
case 0x0D: /* SCARD_CANCEL */
|
||||
LLOGLN(0, ("scard_process_msg: SCARD_CANCEL"));
|
||||
LLOGLN(10, ("scard_process_msg: SCARD_CANCEL"));
|
||||
rv = scard_process_cancel(con, in_s);
|
||||
break;
|
||||
|
||||
case 0x0E: /* SCARD_CANCEL_TRANSACTION */
|
||||
|
Loading…
Reference in New Issue
Block a user