chansrv: work on smartcard
This commit is contained in:
parent
b69c144c7d
commit
62bdacda9b
@ -393,8 +393,9 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
||||
int offset;
|
||||
|
||||
LLOGLN(0, ("SCardConnect:"));
|
||||
LLOGLN(0, ("SCardConnect: hContext %p szReader %s dwShareMode %d dwPreferredProtocols %d",
|
||||
hContext, szReader, dwShareMode, dwPreferredProtocols));
|
||||
LLOGLN(0, ("SCardConnect: hContext %p szReader %s dwShareMode %d "
|
||||
"dwPreferredProtocols %d",
|
||||
(void*)hContext, szReader, dwShareMode, dwPreferredProtocols));
|
||||
if (g_sck == -1)
|
||||
{
|
||||
LLOGLN(0, ("SCardConnect: error, not connected"));
|
||||
@ -595,15 +596,83 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
|
||||
LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
|
||||
LPDWORD pcbAtrLen)
|
||||
{
|
||||
char *msg;
|
||||
int code;
|
||||
int bytes;
|
||||
int status;
|
||||
int offset;
|
||||
int cchReaderLen;
|
||||
int to_copy;
|
||||
|
||||
LLOGLN(0, ("SCardStatus:"));
|
||||
if (g_sck == -1)
|
||||
{
|
||||
LLOGLN(0, ("SCardStatus: error, not connected"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
cchReaderLen = *pcchReaderLen;
|
||||
msg = (char *) malloc(8192);
|
||||
SET_UINT32(msg, 0, hCard);
|
||||
SET_UINT32(msg, 4, cchReaderLen);
|
||||
SET_UINT32(msg, 8, *pcbAtrLen);
|
||||
pthread_mutex_lock(&g_mutex);
|
||||
if (send_message(SCARD_STATUS, msg, 12) != 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardStatus: error, send_message"));
|
||||
free(msg);
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
bytes = 8192;
|
||||
if (get_message(&code, msg, &bytes) != 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardStatus: error, get_message"));
|
||||
free(msg);
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
if (code != SCARD_STATUS)
|
||||
{
|
||||
LLOGLN(0, ("SCardStatus: error, bad code"));
|
||||
free(msg);
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_S_SUCCESS;
|
||||
|
||||
LLOGLN(0, ("SCardStatus: cchReaderLen %d", *pcchReaderLen));
|
||||
offset = 0;
|
||||
*pcchReaderLen = GET_UINT32(msg, offset);
|
||||
LLOGLN(0, ("SCardStatus: cchReaderLen %d", *pcchReaderLen));
|
||||
offset += 4;
|
||||
if (cchReaderLen > 0)
|
||||
{
|
||||
to_copy = cchReaderLen - 1;
|
||||
if (*pcchReaderLen < to_copy)
|
||||
{
|
||||
to_copy = *pcchReaderLen;
|
||||
}
|
||||
memcpy(mszReaderName, msg + offset, to_copy);
|
||||
mszReaderName[to_copy] = 0;
|
||||
}
|
||||
LLOGLN(0, ("SCardStatus: mszReaderName %s", mszReaderName));
|
||||
offset += *pcchReaderLen;
|
||||
*pdwState = GET_UINT32(msg, offset);
|
||||
LLOGLN(0, ("SCardStatus: dwState %d", *pdwState));
|
||||
offset += 4;
|
||||
*pdwProtocol = GET_UINT32(msg, offset);
|
||||
LLOGLN(0, ("SCardStatus: dwProtocol %d", *pdwProtocol));
|
||||
offset += 4;
|
||||
*pcbAtrLen = GET_UINT32(msg, offset);
|
||||
offset += 4;
|
||||
LLOGLN(0, ("SCardStatus: cbAtrLen %d", *pcbAtrLen));
|
||||
memcpy(pbAtr, msg + offset, *pcbAtrLen);
|
||||
offset += *pcbAtrLen;
|
||||
status = GET_UINT32(msg, offset);
|
||||
LLOGLN(0, ("SCardStatus: status %d", status));
|
||||
offset += 4;
|
||||
free(msg);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -716,9 +785,14 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
|
||||
LLOGLN(0, ("SCardControl: error, not connected"));
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
LLOGLN(0, ("SCardControl: dwControlCode %d", dwControlCode));
|
||||
LLOGLN(0, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode));
|
||||
LLOGLN(0, ("SCardControl: cbSendLength %d", cbSendLength));
|
||||
LLOGLN(0, ("SCardControl: cbRecvLength %d", cbRecvLength));
|
||||
dwControlCode = dwControlCode & ~0x42000000;
|
||||
dwControlCode = dwControlCode << 2;
|
||||
dwControlCode = dwControlCode | (49 << 16);
|
||||
LLOGLN(0, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode));
|
||||
|
||||
msg = (char *) malloc(8192);
|
||||
offset = 0;
|
||||
SET_UINT32(msg, offset, hCard);
|
||||
|
@ -160,42 +160,36 @@ extern int g_rdpdr_chan_id; /* in chansrv.c */
|
||||
static struct stream * APP_CC scard_make_new_ioctl(IRP *irp, tui32 ioctl);
|
||||
static int APP_CC scard_add_new_device(tui32 device_id);
|
||||
static int APP_CC scard_get_free_slot(void);
|
||||
#if 0
|
||||
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, int wide);
|
||||
|
||||
static void APP_CC scard_send_GetStatusChange(IRP* irp, tui32 context, int wide,
|
||||
tui32 timeout, tui32 num_readers,
|
||||
READER_STATE* rsa);
|
||||
|
||||
static void APP_CC scard_send_Connect(IRP* irp, tui32 context, 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,
|
||||
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, tui32 sc_handle,
|
||||
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,
|
||||
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 context, tui32 sc_handle,
|
||||
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,
|
||||
READER_STATE* rs);
|
||||
|
||||
@ -613,7 +607,8 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle,
|
||||
* @param wide TRUE if unicode string
|
||||
*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_send_status(struct trans *con, int wide, tui32 sc_handle)
|
||||
scard_send_status(struct trans *con, int wide, tui32 sc_handle,
|
||||
int cchReaderLen, int cbAtrLen)
|
||||
{
|
||||
IRP *irp;
|
||||
|
||||
@ -631,7 +626,7 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle)
|
||||
irp->user_data = con;
|
||||
|
||||
/* send IRP to client */
|
||||
scard_send_Status(irp, wide, sc_handle);
|
||||
scard_send_Status(irp, wide, sc_handle, cchReaderLen, cbAtrLen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -902,6 +897,7 @@ scard_get_free_slot(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Release resources prior to shutting down
|
||||
*****************************************************************************/
|
||||
@ -919,6 +915,7 @@ scard_release_resources(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
@ -1179,7 +1176,6 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
||||
tui32 ioctl;
|
||||
int bytes;
|
||||
int i;
|
||||
int len;
|
||||
int num_chars;
|
||||
int index;
|
||||
twchar w_reader_name[100];
|
||||
@ -1282,7 +1278,6 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
||||
struct stream* s;
|
||||
tui32 ioctl;
|
||||
int bytes;
|
||||
int len;
|
||||
int num_chars;
|
||||
int index;
|
||||
twchar w_reader_name[100];
|
||||
@ -1539,7 +1534,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, tui32 sc_handle,
|
||||
int cchReaderLen, int cbAtrLen)
|
||||
{
|
||||
/* see [MS-RDPESC] 2.2.2.18 */
|
||||
|
||||
@ -1554,11 +1550,12 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle)
|
||||
return;
|
||||
}
|
||||
|
||||
ioctl = (wide) ? SCARD_IOCTL_CONNECT_W :
|
||||
SCARD_IOCTL_CONNECT_A;
|
||||
|
||||
ioctl = wide ? SCARD_IOCTL_STATUS_W : SCARD_IOCTL_STATUS_A;
|
||||
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
|
||||
{
|
||||
log_error("scard_make_new_ioctl");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* command format
|
||||
@ -1577,8 +1574,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle)
|
||||
*/
|
||||
|
||||
xstream_seek(s, 28);
|
||||
xstream_wr_u32_le(s, -1); /* readerLen, see [MS-RDPESC] 4.11 */
|
||||
xstream_wr_u32_le(s, 36); /* atrLen, see [MS-RDPESC] 4.11 */
|
||||
xstream_wr_u32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */
|
||||
xstream_wr_u32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */
|
||||
xstream_seek(s, 8);
|
||||
|
||||
/* insert sc_handle */
|
||||
@ -1680,11 +1677,14 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
|
||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||
{
|
||||
log_error("smartcards[%d] is NULL", irp->scard_index);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL)
|
||||
return;
|
||||
{
|
||||
log_error("scard_make_new_ioctl");
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_debug("send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d "
|
||||
"extra_bytes %d recv dwProtocol %d cbPciLength %d", send_bytes,
|
||||
@ -1768,6 +1768,7 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, char *send_data,
|
||||
/* send to client */
|
||||
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
||||
xstream_free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1787,11 +1788,14 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
|
||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||
{
|
||||
log_error("smartcards[%d] is NULL", irp->scard_index);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CONTROL)) == NULL)
|
||||
return;
|
||||
{
|
||||
log_error("scard_make_new_ioctl");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* command format
|
||||
@ -1849,6 +1853,7 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
|
||||
/* send to client */
|
||||
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
||||
xstream_free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1866,11 +1871,14 @@ scard_send_Cancel(IRP* irp, tui32 context)
|
||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||
{
|
||||
log_error("smartcards[%d] is NULL", irp->scard_index);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CANCEL)) == NULL)
|
||||
return;
|
||||
{
|
||||
log_error("scard_make_new_ioctl");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* command format
|
||||
@ -1897,6 +1905,7 @@ scard_send_Cancel(IRP* irp, tui32 context)
|
||||
/* send to client */
|
||||
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
||||
xstream_free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1914,11 +1923,14 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||
{
|
||||
log_error("smartcards[%d] is NULL", irp->scard_index);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_GETATTRIB)) == NULL)
|
||||
return;
|
||||
{
|
||||
log_error("scard_make_new_ioctl");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* command format
|
||||
@ -1953,6 +1965,7 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
||||
/* send to client */
|
||||
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
||||
xstream_free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -2025,11 +2038,16 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
static void APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp,
|
||||
tui32 DeviceId, tui32 CompletionId,
|
||||
tui32 IoStatus)
|
||||
/**
|
||||
*
|
||||
*****************************************************************************/
|
||||
static void
|
||||
APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp,
|
||||
tui32 DeviceId, tui32 CompletionId,
|
||||
tui32 IoStatus)
|
||||
{
|
||||
tui32 len;
|
||||
struct trans *con;
|
||||
|
||||
log_debug("entered");
|
||||
|
||||
@ -2049,7 +2067,9 @@ static void APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_is_context_valid_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2163,6 +2183,7 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp,
|
||||
tui32 IoStatus)
|
||||
{
|
||||
tui32 len;
|
||||
struct trans *con;
|
||||
|
||||
log_debug("entered");
|
||||
|
||||
@ -2182,7 +2203,9 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_reconnect_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2215,11 +2238,9 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_begin_transaction_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2252,11 +2273,9 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_end_transaction_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2269,6 +2288,7 @@ scard_handle_Status_Return(struct stream *s, IRP *irp,
|
||||
tui32 IoStatus)
|
||||
{
|
||||
tui32 len;
|
||||
struct trans *con;
|
||||
|
||||
log_debug("entered");
|
||||
|
||||
@ -2288,7 +2308,9 @@ scard_handle_Status_Return(struct stream *s, IRP *irp,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_status_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2321,11 +2343,9 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_disconnect_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2357,11 +2377,9 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_transmit_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2393,11 +2411,9 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_control_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2409,6 +2425,7 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
||||
tui32 CompletionId, tui32 IoStatus)
|
||||
{
|
||||
tui32 len;
|
||||
struct trans *con;
|
||||
|
||||
log_debug("entered");
|
||||
|
||||
@ -2428,7 +2445,9 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_cancel_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
@ -2440,6 +2459,7 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
||||
tui32 CompletionId, tui32 IoStatus)
|
||||
{
|
||||
tui32 len;
|
||||
struct trans *con;
|
||||
|
||||
log_debug("entered");
|
||||
|
||||
@ -2459,6 +2479,8 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_get_attrib_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
@ -128,7 +128,8 @@ int APP_CC scard_send_reconnect(struct trans *con, tui32 context,
|
||||
int APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle);
|
||||
int APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle,
|
||||
tui32 dwDisposition);
|
||||
int APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle);
|
||||
int APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle,
|
||||
int cchReaderLen, int cbAtrLen);
|
||||
int APP_CC scard_send_disconnect(struct trans *con, tui32 context,
|
||||
tui32 sc_handle, int dwDisposition);
|
||||
|
||||
|
@ -61,6 +61,7 @@
|
||||
#define XRDP_PCSC_STATE_GOT_TR (1 << 7) /* transmit */
|
||||
#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 */
|
||||
|
||||
/* TODO: put this in con */
|
||||
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
|
||||
@ -73,8 +74,10 @@ struct pcsc_client
|
||||
struct trans *con;
|
||||
};
|
||||
|
||||
#if 0
|
||||
static struct pcsc_client *g_head = 0;
|
||||
static struct pcsc_client *g_tail = 0;
|
||||
#endif
|
||||
|
||||
static struct trans *g_lis = 0;
|
||||
static struct trans *g_con = 0; /* todo, remove this */
|
||||
@ -202,7 +205,6 @@ scard_function_release_context_return(struct trans *con,
|
||||
{
|
||||
int bytes;
|
||||
struct stream *out_s;
|
||||
tui32 context;
|
||||
|
||||
LLOGLN(0, ("scard_function_release_context_return:"));
|
||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0)
|
||||
@ -547,6 +549,26 @@ scard_function_end_transaction_return(struct trans *con,
|
||||
return trans_force_write(con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_function_cancel_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_function_get_attrib_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
@ -600,7 +622,6 @@ scard_function_transmit_return(struct trans *con,
|
||||
struct stream *out_s;
|
||||
int bytes;
|
||||
int val;
|
||||
int got_recv_pci;
|
||||
int cbRecvLength;
|
||||
struct xrdp_scard_io_request recv_ior;
|
||||
char *recvBuf;
|
||||
@ -617,11 +638,9 @@ scard_function_transmit_return(struct trans *con,
|
||||
in_uint8s(in_s, 20);
|
||||
in_uint32_le(in_s, val);
|
||||
g_memset(&recv_ior, 0, sizeof(recv_ior));
|
||||
got_recv_pci = 0;
|
||||
if (val != 0)
|
||||
{
|
||||
/* pioRecvPci */
|
||||
got_recv_pci = 1;
|
||||
LLOGLN(0, ("scard_function_transmit_return: pioRecvPci not zero!"));
|
||||
}
|
||||
in_uint8s(in_s, 4);
|
||||
@ -724,6 +743,117 @@ scard_function_control_return(struct trans *con,
|
||||
return trans_force_write(con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_process_status(struct trans *con, struct stream *in_s)
|
||||
{
|
||||
int hCard;
|
||||
int cchReaderLen;
|
||||
int cbAtrLen;
|
||||
|
||||
LLOGLN(0, ("scard_process_status:"));
|
||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_control: opps"));
|
||||
return 1;
|
||||
}
|
||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ST;
|
||||
LLOGLN(0, ("scard_process_control:"));
|
||||
|
||||
in_uint32_le(in_s, hCard);
|
||||
in_uint32_le(in_s, cchReaderLen);
|
||||
in_uint32_le(in_s, cbAtrLen);
|
||||
|
||||
scard_send_status(con, 1, hCard, cchReaderLen, cbAtrLen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MS_SCARD_UNKNOWN 0
|
||||
#define MS_SCARD_ABSENT 1
|
||||
#define MS_SCARD_PRESENT 2
|
||||
#define MS_SCARD_SWALLOWED 3
|
||||
#define MS_SCARD_POWERED 4
|
||||
#define MS_SCARD_NEGOTIABLE 5
|
||||
#define MS_SCARD_SPECIFIC 6
|
||||
|
||||
#define PC_SCARD_UNKNOWN 0x0001 /**< Unknown state */
|
||||
#define PC_SCARD_ABSENT 0x0002 /**< Card is absent */
|
||||
#define PC_SCARD_PRESENT 0x0004 /**< Card is present */
|
||||
#define PC_SCARD_SWALLOWED 0x0008 /**< Card not powered */
|
||||
#define PC_SCARD_POWERED 0x0010 /**< Card is powered */
|
||||
#define PC_SCARD_NEGOTIABLE 0x0020 /**< Ready for PTS */
|
||||
#define PC_SCARD_SPECIFIC 0x0040 /**< PTS has been set */
|
||||
|
||||
static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT,
|
||||
PC_SCARD_PRESENT, PC_SCARD_SWALLOWED,
|
||||
PC_SCARD_POWERED, PC_SCARD_NEGOTIABLE,
|
||||
PC_SCARD_SPECIFIC };
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_function_status_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len)
|
||||
{
|
||||
struct stream *out_s;
|
||||
int index;
|
||||
int bytes;
|
||||
int dwReaderLen;
|
||||
int dwState;
|
||||
int dwProtocol;
|
||||
int dwAtrLen;
|
||||
char attr[32];
|
||||
twchar reader_name[100];
|
||||
char lreader_name[100];
|
||||
|
||||
g_hexdump(in_s->p, len);
|
||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST) == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_function_status_return: opps"));
|
||||
return 1;
|
||||
}
|
||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ST;
|
||||
in_uint8s(in_s, 20);
|
||||
in_uint32_le(in_s, dwReaderLen);
|
||||
in_uint8s(in_s, 4);
|
||||
in_uint32_le(in_s, dwState);
|
||||
dwState = g_ms2pc[dwState % 6];
|
||||
in_uint32_le(in_s, dwProtocol);
|
||||
in_uint8a(in_s, attr, 32);
|
||||
in_uint32_le(in_s, dwAtrLen);
|
||||
in_uint32_le(in_s, dwReaderLen);
|
||||
dwReaderLen /= 2;
|
||||
g_memset(reader_name, 0, sizeof(reader_name));
|
||||
g_memset(lreader_name, 0, sizeof(lreader_name));
|
||||
for (index = 0; index < dwReaderLen; index++)
|
||||
{
|
||||
in_uint16_le(in_s, reader_name[index]);
|
||||
}
|
||||
g_wcstombs(lreader_name, reader_name, 99);
|
||||
LLOGLN(0, ("scard_function_status_return: dwAtrLen %d dwReaderLen %d "
|
||||
"dwProtocol %d dwState %d name %s",
|
||||
dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name));
|
||||
out_s = trans_get_out_s(con, 8192);
|
||||
s_push_layer(out_s, iso_hdr, 8);
|
||||
dwReaderLen = g_strlen(lreader_name);
|
||||
out_uint32_le(out_s, dwReaderLen);
|
||||
out_uint8a(out_s, lreader_name, dwReaderLen);
|
||||
out_uint32_le(out_s, dwState);
|
||||
out_uint32_le(out_s, dwProtocol);
|
||||
out_uint32_le(out_s, dwAtrLen);
|
||||
out_uint8a(out_s, attr, dwAtrLen);
|
||||
out_uint32_le(out_s, 0); /* 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, 0x0B); /* SCARD_STATUS 0x0B */
|
||||
return trans_force_write(con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
@ -832,6 +962,25 @@ scard_function_get_status_change_return(struct trans *con,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_function_is_context_valid_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC scard_function_reconnect_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
@ -893,6 +1042,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
|
||||
|
||||
case 0x0B: /* SCARD_STATUS */
|
||||
LLOGLN(0, ("scard_process_msg: SCARD_STATUS"));
|
||||
rv = scard_process_status(con, in_s);
|
||||
break;
|
||||
|
||||
case 0x0C: /* SCARD_GET_STATUS_CHANGE */
|
||||
@ -930,7 +1080,6 @@ int DEFAULT_CC
|
||||
my_pcsc_trans_data_in(struct trans *trans)
|
||||
{
|
||||
struct stream *s;
|
||||
int id;
|
||||
int size;
|
||||
int command;
|
||||
int error;
|
||||
@ -998,7 +1147,6 @@ scard_pcsc_init(void)
|
||||
char *home;
|
||||
int disp;
|
||||
int error;
|
||||
int index;
|
||||
|
||||
LLOGLN(0, ("scard_pcsc_init:"));
|
||||
if (g_lis == 0)
|
||||
|
@ -49,11 +49,41 @@ int APP_CC scard_function_control_return(struct trans *con,
|
||||
int APP_CC scard_function_get_status_change_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_connect_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_status_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_begin_transaction_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_end_transaction_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_is_context_valid_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_reconnect_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_disconnect_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_cancel_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
int APP_CC scard_function_get_attrib_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
#endif /* end #ifndef _SMARTCARD_PCSC_H */
|
||||
|
Loading…
Reference in New Issue
Block a user