chansrv: work on getting MSTSC smartcard working
This commit is contained in:
parent
7ca01ac381
commit
3d4fbb883a
@ -1139,7 +1139,7 @@ SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
|
|||||||
PCSC_API char *
|
PCSC_API char *
|
||||||
pcsc_stringify_error(const long code)
|
pcsc_stringify_error(const long code)
|
||||||
{
|
{
|
||||||
LLOGLN(10, ("pcsc_stringify_error: %d", (int)code));
|
LLOGLN(10, ("pcsc_stringify_error: 0x%8.8x", (int)code));
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case SCARD_S_SUCCESS:
|
case SCARD_S_SUCCESS:
|
||||||
|
@ -831,9 +831,9 @@ scard_make_new_ioctl(IRP *irp, tui32 ioctl)
|
|||||||
0);
|
0);
|
||||||
|
|
||||||
xstream_wr_u32_le(s, 2048); /* OutputBufferLength */
|
xstream_wr_u32_le(s, 2048); /* OutputBufferLength */
|
||||||
xstream_wr_u32_le(s, 0); /* InputBufferLength - insert later */
|
s_push_layer(s, iso_hdr, 4); /* InputBufferLength - insert later */
|
||||||
xstream_wr_u32_le(s, ioctl); /* Ioctl Code */
|
xstream_wr_u32_le(s, ioctl); /* Ioctl Code */
|
||||||
xstream_seek(s, 20); /* padding */
|
out_uint8s(s, 20); /* padding */
|
||||||
|
|
||||||
/* [MS-RPCE] 2.2.6.1 */
|
/* [MS-RPCE] 2.2.6.1 */
|
||||||
xstream_wr_u32_le(s, 0x00081001); /* len 8, LE, v1 */
|
xstream_wr_u32_le(s, 0x00081001); /* len 8, LE, v1 */
|
||||||
@ -967,7 +967,10 @@ scard_send_ReleaseContext(IRP* irp, tui32 context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RELEASE_CONTEXT)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RELEASE_CONTEXT)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1019,7 +1022,10 @@ scard_send_IsContextValid(IRP* irp, tui32 context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_IS_VALID_CONTEXT)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_IS_VALID_CONTEXT)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1073,10 +1079,20 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide)
|
|||||||
SCARD_IOCTL_LIST_READERS_A;
|
SCARD_IOCTL_LIST_READERS_A;
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
xstream_wr_u32_le(s, 72); /* number of bytes to follow */
|
xstream_wr_u32_le(s, 72); /* number of bytes to follow */
|
||||||
xstream_seek(s, 28); /* freerdp does not use this */
|
|
||||||
|
out_uint32_le(s, 0x00000000);
|
||||||
|
out_uint32_le(s, 0x00000004);
|
||||||
|
out_uint32_le(s, 0x00020000);
|
||||||
|
out_uint32_le(s, 0x00000024);
|
||||||
|
out_uint32_le(s, 0x00020004);
|
||||||
|
out_uint32_le(s, 0x00000000);
|
||||||
|
out_uint32_le(s, 0xFFFFFFFF);
|
||||||
|
|
||||||
/* insert context */
|
/* insert context */
|
||||||
xstream_wr_u32_le(s, 4);
|
xstream_wr_u32_le(s, 4);
|
||||||
@ -1110,6 +1126,10 @@ scard_send_ListReaders(IRP *irp, tui32 context, int wide)
|
|||||||
|
|
||||||
/* send to client */
|
/* send to client */
|
||||||
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
||||||
|
|
||||||
|
//g_writeln("scard_send_ListReaders:");
|
||||||
|
//g_hexdump(s->data, bytes);
|
||||||
|
|
||||||
xstream_free(s);
|
xstream_free(s);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1190,27 +1210,34 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
|||||||
SCARD_IOCTL_GET_STATUS_CHANGE_A;
|
SCARD_IOCTL_GET_STATUS_CHANGE_A;
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
xstream_seek(s, 16); /* unused */
|
s_push_layer(s, mcs_hdr, 4); /* set later */
|
||||||
xstream_wr_u32_le(s, timeout);
|
out_uint32_le(s, 0x00000000);
|
||||||
xstream_wr_u32_le(s, num_readers);
|
out_uint32_le(s, 0x00000004);
|
||||||
xstream_wr_u32_le(s, 0); /* unused */
|
out_uint32_le(s, 0x00020000);
|
||||||
|
|
||||||
|
out_uint32_le(s, timeout);
|
||||||
|
out_uint32_le(s, num_readers);
|
||||||
|
out_uint32_le(s, 0x00020004); /* ? */
|
||||||
|
|
||||||
/* insert context */
|
/* insert context */
|
||||||
xstream_wr_u32_le(s, 4);
|
out_uint32_le(s, 4);
|
||||||
xstream_wr_u32_le(s, context);
|
out_uint32_le(s, context);
|
||||||
|
|
||||||
xstream_wr_u32_le(s, 0); /* unused */
|
out_uint32_le(s, num_readers); /* ? */
|
||||||
|
|
||||||
/* insert card reader state */
|
/* insert card reader state */
|
||||||
for (i = 0; i < num_readers; i++)
|
for (i = 0; i < num_readers; i++)
|
||||||
{
|
{
|
||||||
rs = &rsa[i];
|
rs = &rsa[i];
|
||||||
xstream_wr_u32_le(s, 0); /* unused */
|
out_uint32_le(s, 0x00020008); /* ? */
|
||||||
xstream_wr_u32_le(s, rs->current_state);
|
out_uint32_le(s, rs->current_state);
|
||||||
xstream_wr_u32_le(s, rs->event_state);
|
out_uint32_le(s, rs->event_state);
|
||||||
xstream_wr_u32_le(s, rs->atr_len);
|
out_uint32_le(s, rs->atr_len);
|
||||||
xstream_copyin(s, rs->atr, 33);
|
xstream_copyin(s, rs->atr, 33);
|
||||||
out_uint8s(s, 3);
|
out_uint8s(s, 3);
|
||||||
}
|
}
|
||||||
@ -1222,13 +1249,14 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
|||||||
{
|
{
|
||||||
rs = &rsa[i];
|
rs = &rsa[i];
|
||||||
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
|
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
|
||||||
xstream_wr_u32_le(s, 0); /* unused */
|
out_uint32_le(s, num_chars + 2);
|
||||||
xstream_wr_u32_le(s, 0); /* unused */
|
out_uint32_le(s, 0);
|
||||||
xstream_wr_u32_le(s, num_chars);
|
out_uint32_le(s, num_chars + 2);
|
||||||
for (index = 0; index < num_chars; index++)
|
for (index = 0; index < num_chars; index++)
|
||||||
{
|
{
|
||||||
xstream_wr_u16_le(s, w_reader_name[index]);
|
out_uint16_le(s, w_reader_name[index]);
|
||||||
}
|
}
|
||||||
|
out_uint16_le(s, 0);
|
||||||
align_s(s, 4);
|
align_s(s, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1239,25 +1267,38 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
|||||||
{
|
{
|
||||||
rs = &rsa[i];
|
rs = &rsa[i];
|
||||||
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
|
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
|
||||||
xstream_wr_u32_le(s, 0); /* unused */
|
out_uint32_le(s, num_chars + 2);
|
||||||
xstream_wr_u32_le(s, 0); /* unused */
|
out_uint32_le(s, 0);
|
||||||
xstream_wr_u32_le(s, num_chars);
|
out_uint32_le(s, num_chars + 2);
|
||||||
for (index = 0; index < num_chars; index++)
|
for (index = 0; index < num_chars; index++)
|
||||||
{
|
{
|
||||||
xstream_wr_u8(s, w_reader_name[index]);
|
out_uint8(s, w_reader_name[index]);
|
||||||
}
|
}
|
||||||
|
out_uint8(s, 0);
|
||||||
align_s(s, 4);
|
align_s(s, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get stream len */
|
s_mark_end(s);
|
||||||
bytes = xstream_len(s);
|
|
||||||
|
|
||||||
/* InputBufferLength is number of bytes AFTER 20 byte padding */
|
s_pop_layer(s, mcs_hdr);
|
||||||
*(s->data + 28) = bytes - 56;
|
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;
|
||||||
|
out_uint32_le(s, bytes);
|
||||||
|
|
||||||
|
bytes = (int) (s->end - s->data);
|
||||||
|
|
||||||
/* send to client */
|
/* send to client */
|
||||||
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
send_channel_data(g_rdpdr_chan_id, s->data, bytes);
|
||||||
|
|
||||||
|
//g_writeln("scard_send_GetStatusChange:");
|
||||||
|
//g_hexdump(s->data, bytes);
|
||||||
|
|
||||||
xstream_free(s);
|
xstream_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1292,7 +1333,10 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
|||||||
SCARD_IOCTL_CONNECT_A;
|
SCARD_IOCTL_CONNECT_A;
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1377,7 +1421,10 @@ scard_send_Reconnect(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RECONNECT)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RECONNECT)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1438,7 +1485,10 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_BEGIN_TRANSACTION)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_BEGIN_TRANSACTION)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1492,7 +1542,10 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_END_TRANSACTION)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_END_TRANSACTION)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1618,7 +1671,10 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_DISCONNECT)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_DISCONNECT)) == NULL)
|
||||||
|
{
|
||||||
|
log_error("scard_make_new_ioctl failed");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -2091,16 +2147,10 @@ scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
|
|||||||
log_error("DeviceId/CompletionId do not match those in IRP");
|
log_error("DeviceId/CompletionId do not match those in IRP");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (IoStatus != 0)
|
|
||||||
{
|
|
||||||
log_error("failed to list readers");
|
|
||||||
/* LK_TODO delete irp and smartcard entry */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
xstream_rd_u32_le(s, len);
|
||||||
con = (struct trans *) (irp->user_data);
|
con = (struct trans *) (irp->user_data);
|
||||||
scard_function_list_readers_return(con, s, len);
|
scard_function_list_readers_return(con, s, len, IoStatus);
|
||||||
devredir_irp_delete(irp);
|
devredir_irp_delete(irp);
|
||||||
log_debug("leaving");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
@ -2123,16 +2173,10 @@ scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp,
|
|||||||
log_error("DeviceId/CompletionId do not match those in IRP");
|
log_error("DeviceId/CompletionId do not match those in IRP");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (IoStatus != 0)
|
|
||||||
{
|
|
||||||
log_error("failed to get status change");
|
|
||||||
/* LK_TODO delete irp and smartcard entry */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
xstream_rd_u32_le(s, len);
|
||||||
con = (struct trans *) (irp->user_data);
|
con = (struct trans *) (irp->user_data);
|
||||||
scard_function_get_status_change_return(con, s, len);
|
scard_function_get_status_change_return(con, s, len, IoStatus);
|
||||||
devredir_irp_delete(irp);
|
devredir_irp_delete(irp);
|
||||||
log_debug("leaving");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,9 @@ scard_function_establish_context_return(struct trans *con,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_EC;
|
||||||
|
|
||||||
|
//g_hexdump(in_s->p, len);
|
||||||
|
|
||||||
in_uint8s(in_s, 28);
|
in_uint8s(in_s, 28);
|
||||||
in_uint32_le(in_s, context_len);
|
in_uint32_le(in_s, context_len);
|
||||||
if (context_len != 4)
|
if (context_len != 4)
|
||||||
@ -248,7 +251,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
scard_function_list_readers_return(struct trans *con,
|
scard_function_list_readers_return(struct trans *con,
|
||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
int len)
|
int len, int status)
|
||||||
{
|
{
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
int chr;
|
int chr;
|
||||||
@ -273,9 +276,10 @@ scard_function_list_readers_return(struct trans *con,
|
|||||||
in_uint8s(in_s, 28);
|
in_uint8s(in_s, 28);
|
||||||
len -= 28;
|
len -= 28;
|
||||||
in_uint32_le(in_s, len);
|
in_uint32_le(in_s, len);
|
||||||
//g_writeln("len %d", len);
|
|
||||||
rn_index = 0;
|
rn_index = 0;
|
||||||
readers = 0;
|
readers = 0;
|
||||||
|
if (status == 0)
|
||||||
|
{
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
in_uint16_le(in_s, chr);
|
in_uint16_le(in_s, chr);
|
||||||
@ -285,7 +289,6 @@ scard_function_list_readers_return(struct trans *con,
|
|||||||
if (reader_name[0] != 0)
|
if (reader_name[0] != 0)
|
||||||
{
|
{
|
||||||
g_wcstombs(lreader_name[readers], reader_name, 99);
|
g_wcstombs(lreader_name[readers], reader_name, 99);
|
||||||
//g_writeln("1 %s", lreader_name[readers]);
|
|
||||||
g_memset(reader_name, 0, sizeof(reader_name));
|
g_memset(reader_name, 0, sizeof(reader_name));
|
||||||
readers++;
|
readers++;
|
||||||
}
|
}
|
||||||
@ -303,21 +306,20 @@ scard_function_list_readers_return(struct trans *con,
|
|||||||
if (reader_name[0] != 0)
|
if (reader_name[0] != 0)
|
||||||
{
|
{
|
||||||
g_wcstombs(lreader_name[readers], reader_name, 99);
|
g_wcstombs(lreader_name[readers], reader_name, 99);
|
||||||
//g_writeln("2 %s", lreader_name[readers]);
|
|
||||||
g_memset(reader_name, 0, sizeof(reader_name));
|
g_memset(reader_name, 0, sizeof(reader_name));
|
||||||
readers++;
|
readers++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out_s = trans_get_out_s(con, 8192);
|
out_s = trans_get_out_s(con, 8192);
|
||||||
s_push_layer(out_s, iso_hdr, 8);
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
out_uint32_le(out_s, readers);
|
out_uint32_le(out_s, readers);
|
||||||
for (index = 0; index < readers; index++)
|
for (index = 0; index < readers; index++)
|
||||||
{
|
{
|
||||||
//g_writeln("3 - %s", lreader_name[index]);
|
|
||||||
out_uint8a(out_s, lreader_name[index], 100);
|
out_uint8a(out_s, lreader_name[index], 100);
|
||||||
}
|
}
|
||||||
out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
|
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
||||||
s_mark_end(out_s);
|
s_mark_end(out_s);
|
||||||
bytes = (int) (out_s->end - out_s->data);
|
bytes = (int) (out_s->end - out_s->data);
|
||||||
s_pop_layer(out_s, iso_hdr);
|
s_pop_layer(out_s, iso_hdr);
|
||||||
@ -913,7 +915,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
scard_function_get_status_change_return(struct trans *con,
|
scard_function_get_status_change_return(struct trans *con,
|
||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
int len)
|
int len, int status)
|
||||||
{
|
{
|
||||||
int bytes;
|
int bytes;
|
||||||
int index;
|
int index;
|
||||||
@ -925,6 +927,7 @@ scard_function_get_status_change_return(struct trans *con,
|
|||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
|
|
||||||
LLOGLN(10, ("scard_function_get_status_change_return:"));
|
LLOGLN(10, ("scard_function_get_status_change_return:"));
|
||||||
|
LLOGLN(10, (" status 0x%8.8x", status));
|
||||||
//g_hexdump(in_s->p, len);
|
//g_hexdump(in_s->p, len);
|
||||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0)
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC) == 0)
|
||||||
{
|
{
|
||||||
@ -932,13 +935,22 @@ scard_function_get_status_change_return(struct trans *con,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC;
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_GSC;
|
||||||
in_uint8s(in_s, 28);
|
|
||||||
in_uint32_le(in_s, cReaders);
|
|
||||||
if (cReaders > 0)
|
|
||||||
{
|
|
||||||
out_s = trans_get_out_s(con, 8192);
|
out_s = trans_get_out_s(con, 8192);
|
||||||
s_push_layer(out_s, iso_hdr, 8);
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
out_uint32_le(out_s, 0); /* cReaders */
|
||||||
|
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in_uint8s(in_s, 28);
|
||||||
|
in_uint32_le(in_s, cReaders);
|
||||||
|
LLOGLN(10, (" cReaders %d", cReaders));
|
||||||
out_uint32_le(out_s, cReaders);
|
out_uint32_le(out_s, cReaders);
|
||||||
|
if (cReaders > 0)
|
||||||
|
{
|
||||||
for (index = 0; index < cReaders; index++)
|
for (index = 0; index < cReaders; index++)
|
||||||
{
|
{
|
||||||
in_uint32_le(in_s, current_state);
|
in_uint32_le(in_s, current_state);
|
||||||
@ -950,7 +962,10 @@ scard_function_get_status_change_return(struct trans *con,
|
|||||||
in_uint8a(in_s, atr, 36);
|
in_uint8a(in_s, atr, 36);
|
||||||
out_uint8a(out_s, atr, 36);
|
out_uint8a(out_s, atr, 36);
|
||||||
}
|
}
|
||||||
out_uint32_le(out_s, 0); /* SCARD_S_SUCCESS status */
|
}
|
||||||
|
out_uint32_le(out_s, status); /* SCARD_S_SUCCESS status */
|
||||||
|
}
|
||||||
|
|
||||||
s_mark_end(out_s);
|
s_mark_end(out_s);
|
||||||
bytes = (int) (out_s->end - out_s->data);
|
bytes = (int) (out_s->end - out_s->data);
|
||||||
s_pop_layer(out_s, iso_hdr);
|
s_pop_layer(out_s, iso_hdr);
|
||||||
@ -958,8 +973,6 @@ scard_function_get_status_change_return(struct trans *con,
|
|||||||
out_uint32_le(out_s, 0x0C); /* SCARD_ESTABLISH_CONTEXT 0x0C */
|
out_uint32_le(out_s, 0x0C); /* SCARD_ESTABLISH_CONTEXT 0x0C */
|
||||||
return trans_force_write(con);
|
return trans_force_write(con);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* returns error */
|
/* returns error */
|
||||||
|
@ -36,7 +36,7 @@ int APP_CC scard_function_release_context_return(struct trans *con,
|
|||||||
int len);
|
int len);
|
||||||
int APP_CC scard_function_list_readers_return(struct trans *con,
|
int APP_CC scard_function_list_readers_return(struct trans *con,
|
||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
int len);
|
int len, int status);
|
||||||
|
|
||||||
int APP_CC scard_function_transmit_return(struct trans *con,
|
int APP_CC scard_function_transmit_return(struct trans *con,
|
||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
@ -48,7 +48,7 @@ int APP_CC scard_function_control_return(struct trans *con,
|
|||||||
|
|
||||||
int APP_CC scard_function_get_status_change_return(struct trans *con,
|
int APP_CC scard_function_get_status_change_return(struct trans *con,
|
||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
int len);
|
int len, int status);
|
||||||
|
|
||||||
int APP_CC scard_function_connect_return(struct trans *con,
|
int APP_CC scard_function_connect_return(struct trans *con,
|
||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
|
Loading…
Reference in New Issue
Block a user