summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sesman/chansrv/smartcard.c544
-rw-r--r--sesman/chansrv/smartcard.h46
-rw-r--r--sesman/chansrv/smartcard_pcsc.c8
3 files changed, 568 insertions, 30 deletions
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index 1a81efea..d5ebea2c 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -104,7 +104,7 @@ do \
#define SCARD_IOCTL_INTRODUCE_READER 0x00090060 /* IntroduceReader */
#define SCARD_IOCTL_FORGET_READER 0x00090068 /* IntroduceReader */
#define SCARD_IOCTL_ADD_READER_TO_GROUP 0x00090070 /* AddReaderToGroup */
-#define SCARD_IOCTL_REMOVE_READER_FROM_GROUP 0x00090078 /* RemoveReaderFromGroup */
+#define SCARD_IOCTL_REMOVE_READER_FROM_GROUP 0x00090078 /* RemoveReaderFromGroup*/
#define SCARD_IOCTL_GET_STATUS_CHANGE_A 0x000900A0 /* GetStatusChangeA */
#define SCARD_IOCTL_GET_STATUS_CHANGE_W 0x000900A4 /* GetStatusChangeW */
#define SCARD_IOCTL_CANCEL 0x000900A8 /* Cancel */
@@ -179,9 +179,21 @@ static void APP_CC scard_send_Reconnect(IRP* irp, tui32 context,
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_Status(IRP* irp, int wide, tui32 sc_handle);
+
static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context,
tui32 sc_handle);
+static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle,
+ READER_STATE* rs);
+
+static int APP_CC scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle,
+ READER_STATE* rs);
+
+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);
+
/******************************************************************************
** local callbacks into this module **
******************************************************************************/
@@ -220,7 +232,8 @@ static void APP_CC scard_handle_BeginTransaction_Return(struct stream *s, IRP *i
tui32 IoStatus);
static void APP_CC scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
- tui32 DeviceId, tui32 CompletionId,
+ tui32 DeviceId,
+ tui32 CompletionId,
tui32 IoStatus);
static void APP_CC scard_handle_Status_Return(struct stream *s, IRP *irp,
@@ -231,6 +244,27 @@ static void APP_CC scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
tui32 DeviceId, tui32 CompletionId,
tui32 IoStatus);
+
+static void APP_CC scard_handle_Transmit_Return(struct stream *s, IRP *irp,
+ tui32 DeviceId,
+ tui32 CompletionId,
+ tui32 IoStatus);
+
+static void APP_CC scard_handle_Control_Return(struct stream *s, IRP *irp,
+ tui32 DeviceId,
+ tui32 CompletionId,
+ tui32 IoStatus);
+
+static void APP_CC scard_handle_Cancel_Return(struct stream *s, IRP *irp,
+ tui32 DeviceId,
+ tui32 CompletionId,
+ tui32 IoStatus);
+
+static void APP_CC scard_handle_GetAttrib_Return(struct stream *s, IRP *irp,
+ tui32 DeviceId,
+ tui32 CompletionId,
+ tui32 IoStatus);
+
/******************************************************************************
** **
** externally accessible functions, defined in smartcard.h **
@@ -626,6 +660,116 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle)
return 0;
}
+/**
+ * The Transmit_Call structure is used to send data to the smart card
+ * associated with a valid context.
+ *****************************************************************************/
+int APP_CC
+scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs)
+{
+ IRP *irp;
+
+ /* setup up IRP */
+ if ((irp = devredir_irp_new()) == NULL)
+ {
+ log_error("system out of memory");
+ return 1;
+ }
+
+ irp->scard_index = g_scard_index;
+ irp->CompletionId = g_completion_id++;
+ irp->DeviceId = g_device_id;
+ irp->callback = scard_handle_Transmit_Return;
+ irp->user_data = con;
+
+ /* send IRP to client */
+ scard_send_Transmit(irp, sc_handle, rs);
+
+ return 0;
+}
+
+/**
+ * Communicate directly with the smart card reader
+ *****************************************************************************/
+int APP_CC
+scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
+ READER_STATE* rs)
+{
+ IRP *irp;
+
+ /* setup up IRP */
+ if ((irp = devredir_irp_new()) == NULL)
+ {
+ log_error("system out of memory");
+ return 1;
+ }
+
+ irp->scard_index = g_scard_index;
+ irp->CompletionId = g_completion_id++;
+ irp->DeviceId = g_device_id;
+ irp->callback = scard_handle_Control_Return;
+ irp->user_data = con;
+
+ /* send IRP to client */
+ scard_send_Control(irp, context, sc_handle, rs);
+
+ return 0;
+}
+
+/**
+ * Cancel any outstanding calls
+ *****************************************************************************/
+int APP_CC
+scard_send_cancel(struct trans *con, tui32 context)
+{
+ IRP *irp;
+
+ /* setup up IRP */
+ if ((irp = devredir_irp_new()) == NULL)
+ {
+ log_error("system out of memory");
+ return 1;
+ }
+
+ irp->scard_index = g_scard_index;
+ irp->CompletionId = g_completion_id++;
+ irp->DeviceId = g_device_id;
+ irp->callback = scard_handle_Cancel_Return;
+ irp->user_data = con;
+
+ /* send IRP to client */
+ scard_send_Cancel(irp, context);
+
+ return 0;
+}
+
+/**
+ * Get reader attributes
+ *****************************************************************************/
+int APP_CC
+scard_send_get_attrib(struct trans *con, tui32 sc_handle, READER_STATE* rs)
+{
+ IRP *irp;
+
+ /* setup up IRP */
+ if ((irp = devredir_irp_new()) == NULL)
+ {
+ log_error("system out of memory");
+ return 1;
+ }
+
+ irp->scard_index = g_scard_index;
+ irp->CompletionId = g_completion_id++;
+ irp->DeviceId = g_device_id;
+ irp->callback = scard_handle_GetAttrib_Return;
+ irp->user_data = con;
+
+ /* send IRP to client */
+ scard_send_GetAttrib(irp, sc_handle, rs);
+
+ return 0;
+}
+
/******************************************************************************
** **
** static functions local to this file **
@@ -1151,15 +1295,15 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
* u32 4 bytes filler
* 20 bytes unused (s->p currently pointed here at unused[0])
* u32 4 bytes dwShareMode
- * u32 4 bytes dwPreferredProtocol
+ * u32 4 bytes dwPreferredProtocols
* xx bytes reader name
* u32 4 bytes context length (len)
* len bytes context
*/
xstream_seek(s, 20);
- xstream_wr_u32_le(s, rs->shared_mode_flag);
- xstream_wr_u32_le(s, rs->preferred_protocol);
+ xstream_wr_u32_le(s, rs->dwShareMode);
+ xstream_wr_u32_le(s, rs->dwPreferredProtocols);
/* insert reader name */
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
@@ -1233,7 +1377,7 @@ scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
* u32 4 bytes filler
* 24 bytes unused (s->p currently pointed here at unused[0])
* u32 4 bytes dwShareMode
- * u32 4 bytes dwPreferredProtocol
+ * u32 4 bytes dwPreferredProtocols
* u32 4 bytes dwInitialization
* u32 4 bytes context length
* u32 4 bytes context
@@ -1242,8 +1386,8 @@ scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
*/
xstream_seek(s, 24);
- xstream_wr_u32_le(s, rs->shared_mode_flag);
- xstream_wr_u32_le(s, rs->preferred_protocol);
+ 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);
@@ -1499,6 +1643,250 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle)
xstream_free(s);
}
+/**
+ * The Transmit_Call structure is used to send data to the smart card
+ * associated with a valid context.
+ *****************************************************************************/
+static int APP_CC
+scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs)
+{
+ /* see [MS-RDPESC] 2.2.2.19 */
+
+ SMARTCARD* sc;
+ struct stream* s;
+ int bytes;
+
+ if ((sc = smartcards[irp->scard_index]) == NULL)
+ {
+ log_error("smartcards[%d] is NULL", irp->scard_index);
+ return;
+ }
+
+ if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL)
+ return;
+
+ /*
+ * command format
+ *
+ * ......
+ * 20 bytes padding
+ * u32 4 bytes len 8, LE, v1
+ * u32 4 bytes filler
+ * 12 bytes unused (s->p currently pointed here at unused[0])
+ * u32 4 bytes map0
+ * 4 bytes unused
+ * u32 4 bytes map1
+ * u32 4 bytes dwProtocol
+ * u32 4 bytes cbPciLength
+ * u32 4 bytes map2
+ * u32 4 byts cbSendLength
+ * u32 4 bytes map3
+ * u32 4 bytes map4
+ * u32 4 bytes map5
+ * u32 4 bytes map6
+ * u32 4 bytes cbRecvLength
+ * u32 4 bytes len of sc_handle
+ * u32 4 bytes sc_handle
+ */
+
+ xstream_seek(s, 12);
+ xstream_wr_u32_le(s, rs->map0);
+ xstream_seek(s, 4);
+ xstream_wr_u32_le(s, rs->map1);
+ xstream_wr_u32_le(s, rs->dwProtocol);
+ xstream_wr_u32_le(s, rs->cbPciLength);
+ xstream_wr_u32_le(s, rs->map2);
+ xstream_wr_u32_le(s, rs->cbSendLength);
+ xstream_wr_u32_le(s, rs->map3);
+ xstream_wr_u32_le(s, rs->map4);
+ xstream_wr_u32_le(s, rs->map5);
+ xstream_wr_u32_le(s, rs->map6);
+ xstream_wr_u32_le(s, rs->cbRecvLength);
+ xstream_wr_u32_le(s, 4);
+ xstream_wr_u32_le(s, sc_handle);
+
+ /* get stream len */
+ bytes = xstream_len(s);
+
+ /* InputBufferLength is number of bytes AFTER 20 byte padding */
+ *(s->data + 28) = bytes - 56;
+
+ /* send to client */
+ send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+ xstream_free(s);
+}
+
+/**
+ * Communicate directly with the smart card reader
+ *****************************************************************************/
+static int APP_CC
+scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
+{
+ /* see [MS-RDPESC] 2.2.2.19 */
+
+ SMARTCARD* sc;
+ struct stream* s;
+ int bytes;
+
+ if ((sc = smartcards[irp->scard_index]) == NULL)
+ {
+ log_error("smartcards[%d] is NULL", irp->scard_index);
+ return;
+ }
+
+ if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CONTROL)) == NULL)
+ return;
+
+ /*
+ * command format
+ *
+ * ......
+ * 20 bytes padding
+ * u32 4 bytes len 8, LE, v1
+ * u32 4 bytes filler
+ * 12 bytes unused (s->p currently pointed here at unused[0])
+ * u32 4 bytes map0
+ * 4 bytes unused
+ * u32 4 bytes map1
+ * u32 4 bytes dwControlCode
+ * u32 4 bytes cbRecvLength
+ * u32 4 bytes map2
+ * 4 bytes unused
+ * u32 4 bytes cbOutBufferSize
+ * u32 4 bytes context len
+ * u32 4 bytes context
+ * u32 4 bytes handle len
+ * u32 4 bytes handle
+ */
+
+ xstream_seek(s, 12);
+ xstream_wr_u32_le(s, rs->map0);
+ xstream_wr_u32_le(s, 0);
+ xstream_wr_u32_le(s, rs->map1);
+ xstream_wr_u32_le(s, rs->dwControlCode);
+ xstream_wr_u32_le(s, rs->cbRecvLength);
+ xstream_wr_u32_le(s, rs->map2);
+ xstream_wr_u32_le(s, 0);
+ xstream_wr_u32_le(s, rs->cbOutBufferSize);
+ 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);
+
+ /* get stream len */
+ bytes = xstream_len(s);
+
+ /* InputBufferLength is number of bytes AFTER 20 byte padding */
+ *(s->data + 28) = bytes - 56;
+
+ /* send to client */
+ send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+ xstream_free(s);
+}
+
+/**
+ * Cancel any outstanding calls
+ *****************************************************************************/
+static int APP_CC scard_send_Cancel(IRP* irp, tui32 context)
+{
+ /* see [MS-RDPESC] 3.1.4.27 */
+
+ SMARTCARD* sc;
+ struct stream* s;
+ int bytes;
+
+ if ((sc = smartcards[irp->scard_index]) == NULL)
+ {
+ log_error("smartcards[%d] is NULL", irp->scard_index);
+ return;
+ }
+
+ if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CANCEL)) == NULL)
+ return;
+
+ /*
+ * command format
+ *
+ * ......
+ * 20 bytes padding
+ * u32 4 bytes len 8, LE, v1
+ * u32 4 bytes filler
+ * 16 bytes unused (s->p currently pointed here at unused[0])
+ * u32 4 bytes context len
+ * u32 4 bytes context
+ */
+
+ xstream_seek(s, 16);
+ xstream_wr_u32_le(s, 4);
+ xstream_wr_u32_le(s, context);
+
+ /* get stream len */
+ bytes = xstream_len(s);
+
+ /* InputBufferLength is number of bytes AFTER 20 byte padding */
+ *(s->data + 28) = bytes - 56;
+
+ /* send to client */
+ send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+ xstream_free(s);
+}
+
+/**
+ * Get reader attributes
+ *****************************************************************************/
+static int APP_CC
+scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
+{
+ /* see [MS-RDPESC] 2.2.2.21 */
+
+ SMARTCARD* sc;
+ struct stream* s;
+ int bytes;
+
+ if ((sc = smartcards[irp->scard_index]) == NULL)
+ {
+ log_error("smartcards[%d] is NULL", irp->scard_index);
+ return;
+ }
+
+ if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_GETATTRIB)) == NULL)
+ return;
+
+ /*
+ * command format
+ *
+ * ......
+ * 20 bytes padding
+ * u32 4 bytes len 8, LE, v1
+ * u32 4 bytes filler
+ * 24 bytes unused (s->p currently pointed here at unused[0])
+ * u32 4 bytes dwAttribId
+ * 4 bytes unused
+ * u32 4 bytes dwAttrLen
+ * 8 bytes unused
+ * u32 4 bytes handle len
+ * 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, 8);
+ xstream_wr_u32_le(s, 4);
+ xstream_wr_u32_le(s, sc_handle);
+
+ /* get stream len */
+ bytes = xstream_len(s);
+
+ /* InputBufferLength is number of bytes AFTER 20 byte padding */
+ *(s->data + 28) = bytes - 56;
+
+ /* send to client */
+ send_channel_data(g_rdpdr_chan_id, s->data, bytes);
+ xstream_free(s);
+}
+
/******************************************************************************
** **
** local callbacks into this module **
@@ -1557,7 +1945,7 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
}
if (IoStatus != 0)
{
- log_error("ReleaseContext failed, device not usable");
+ log_error("ReleaseContext failed");
/* LK_TODO delete irp and smartcard entry */
return;
}
@@ -1617,7 +2005,7 @@ scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
}
if (IoStatus != 0)
{
- log_error("failed to list readers - device not usable");
+ log_error("failed to list readers");
/* LK_TODO delete irp and smartcard entry */
return;
}
@@ -1649,7 +2037,7 @@ scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp,
}
if (IoStatus != 0)
{
- log_error("failed to get status change - device not usable");
+ log_error("failed to get status change");
/* LK_TODO delete irp and smartcard entry */
return;
}
@@ -1682,7 +2070,7 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
if (IoStatus != 0)
{
- log_error("failed to connect - device not usable");
+ log_error("failed to connect");
/* LK_TODO delete irp and smartcard entry */
return;
}
@@ -1746,7 +2134,7 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
if (IoStatus != 0)
{
- log_error("BeginTransaction failed, device not usable");
+ log_error("BeginTransaction failed");
/* LK_TODO delete irp and smartcard entry */
return;
}
@@ -1778,7 +2166,7 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
if (IoStatus != 0)
{
- log_error("EndTransaction failed, device not usable");
+ log_error("EndTransaction failed");
/* LK_TODO delete irp and smartcard entry */
return;
}
@@ -1810,7 +2198,7 @@ scard_handle_Status_Return(struct stream *s, IRP *irp,
if (IoStatus != 0)
{
- log_error("StatusCall failed, device not usable");
+ log_error("StatusCall failed");
/* LK_TODO delete irp and smartcard entry */
return;
}
@@ -1842,7 +2230,131 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
if (IoStatus != 0)
{
- log_error("Disconnect failed, device not usable");
+ log_error("Disconnect failed");
+ /* LK_TODO delete irp and smartcard entry */
+ return;
+ }
+
+ /* get OutputBufferLen */
+ xstream_rd_u32_le(s, len);
+
+ log_debug("leaving");
+}
+
+/**
+ *
+ *****************************************************************************/
+static void APP_CC
+scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
+ tui32 CompletionId, tui32 IoStatus)
+{
+ tui32 len;
+
+ log_debug("entered");
+
+ /* sanity check */
+ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
+ {
+ log_error("DeviceId/CompletionId do not match those in IRP");
+ return;
+ }
+
+ if (IoStatus != 0)
+ {
+ log_error("Transmit failed");
+ /* LK_TODO delete irp and smartcard entry */
+ return;
+ }
+
+ /* get OutputBufferLen */
+ xstream_rd_u32_le(s, len);
+
+ log_debug("leaving");
+}
+
+/**
+ *
+ *****************************************************************************/
+static void APP_CC
+scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
+ tui32 CompletionId,tui32 IoStatus)
+{
+ tui32 len;
+
+ log_debug("entered");
+
+ /* sanity check */
+ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
+ {
+ log_error("DeviceId/CompletionId do not match those in IRP");
+ return;
+ }
+
+ if (IoStatus != 0)
+ {
+ log_error("Control failed");
+ /* LK_TODO delete irp and smartcard entry */
+ return;
+ }
+
+ /* get OutputBufferLen */
+ xstream_rd_u32_le(s, len);
+
+ log_debug("leaving");
+}
+
+/**
+ *
+ *****************************************************************************/
+static void APP_CC
+scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId,
+ tui32 CompletionId, tui32 IoStatus)
+{
+ tui32 len;
+
+ log_debug("entered");
+
+ /* sanity check */
+ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
+ {
+ log_error("DeviceId/CompletionId do not match those in IRP");
+ return;
+ }
+
+ if (IoStatus != 0)
+ {
+ log_error("Cancel_call failed");
+ /* LK_TODO delete irp and smartcard entry */
+ return;
+ }
+
+ /* get OutputBufferLen */
+ xstream_rd_u32_le(s, len);
+
+ log_debug("leaving");
+}
+
+/**
+ *
+ *****************************************************************************/
+static void APP_CC
+scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId,
+ tui32 CompletionId, tui32 IoStatus)
+{
+ tui32 len;
+
+ log_debug("entered");
+
+ /* sanity check */
+ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
+ {
+ log_error("DeviceId/CompletionId do not match those in IRP");
+ return;
+ }
+
+ if (IoStatus != 0)
+ {
+ log_error("GetAttrib_call failed");
/* LK_TODO delete irp and smartcard entry */
return;
}
diff --git a/sesman/chansrv/smartcard.h b/sesman/chansrv/smartcard.h
index a2019535..600aef04 100644
--- a/sesman/chansrv/smartcard.h
+++ b/sesman/chansrv/smartcard.h
@@ -63,13 +63,13 @@ typedef struct reader_state
* SCARD_SHARE_DIRECT app demands direct control of smart card, hence
* it is not available to other readers
*/
- tui32 shared_mode_flag;
+ tui32 dwShareMode;
/*
* This field MUST have a value from Table A which is logically
* OR'ed with a value from Table B.
*/
- tui32 preferred_protocol;
+ tui32 dwPreferredProtocols;
/*
* initialization type, must be one of the initialization type
@@ -77,6 +77,24 @@ typedef struct reader_state
*/
tui32 init_type;
+ /* required by scard_send_transmit(), scard_send_control() */
+ tui32 map0;
+ tui32 map1;
+ tui32 map2;
+ tui32 map3;
+ tui32 map4;
+ tui32 map5;
+ tui32 map6;
+
+ tui32 dwProtocol;
+ tui32 cbPciLength;
+ tui32 cbSendLength;
+ tui32 cbRecvLength;
+ tui32 dwControlCode;
+ tui32 cbOutBufferSize;
+ tui32 dwAttribId;
+ tui32 dwAttrLen;
+
} READER_STATE;
void scard_device_announce(tui32 device_id);
@@ -104,14 +122,22 @@ int APP_CC scard_send_end_transaction(struct trans *con, tui32 sc_handle);
int APP_CC scard_send_status(struct trans *con, int wide, tui32 sc_handle);
int APP_CC scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle);
+int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle,
+ READER_STATE* rs);
+
+int APP_CC scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
+ READER_STATE* rs);
+
+int APP_CC scard_send_cancel(struct trans *con, tui32 context);
+
+int APP_CC scard_send_get_attrib(struct trans *con, tui32 sc_handle,
+ READER_STATE* rs);
+
/*
- SCardReconnect
- SCardTransmit
- SCardControl
- SCardListReaderGroups
- not needed: SCardFreeMemory
- SCardCancel
- SCardGetAttrib
- SCardSetAttrib
+ * Notes:
+ * SCardTransmit - partially done
+ * SCardControl - partially done
+ * SCardListReaderGroups - not supported
+ * SCardSetAttrib - not supported
*/
#endif /* end #ifndef _SMARTCARD_C */
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index 7af1871c..a9c5f3e4 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -338,11 +338,11 @@ scard_process_connect(struct trans *con, struct stream *in_s)
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C;
in_uint32_le(in_s, hContext);
in_uint8a(in_s, szReader, 100);
- in_uint32_le(in_s, rs.shared_mode_flag);
- in_uint32_le(in_s, rs.preferred_protocol);
+ in_uint32_le(in_s, rs.dwShareMode);
+ in_uint32_le(in_s, rs.dwPreferredProtocols);
LLOGLN(0, ("scard_process_connect: dwShareMode 0x%8.8x "
- "dwPreferredProtocols 0x%8.8x", rs.shared_mode_flag,
- rs.preferred_protocol));
+ "dwPreferredProtocols 0x%8.8x", rs.dwShareMode,
+ rs.dwPreferredProtocols));
scard_send_connect(con, hContext, 1, &rs);
return 0;
}