common: fix conflict
This commit is contained in:
commit
0d2a4ce195
@ -100,8 +100,8 @@ struct xrdp_client_info
|
|||||||
char orders[32];
|
char orders[32];
|
||||||
int order_flags_ex;
|
int order_flags_ex;
|
||||||
int use_bulk_comp;
|
int use_bulk_comp;
|
||||||
int use_fast_path;
|
|
||||||
int pointer_flags; /* 0 color, 1 new, 2 no new */
|
int pointer_flags; /* 0 color, 1 new, 2 no new */
|
||||||
|
int use_fast_path;
|
||||||
int require_credentials; /* when true, credentials *must* be passed on cmd line */
|
int require_credentials; /* when true, credentials *must* be passed on cmd line */
|
||||||
char client_addr[256];
|
char client_addr[256];
|
||||||
char client_port[256];
|
char client_port[256];
|
||||||
|
@ -92,6 +92,11 @@ then
|
|||||||
[AC_MSG_ERROR([please install libjpeg-dev or libjpeg-devel])])
|
[AC_MSG_ERROR([please install libjpeg-dev or libjpeg-devel])])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! test -z "$enable_xrdpdebug"
|
||||||
|
then
|
||||||
|
CFLAGS="-g -O0"
|
||||||
|
fi
|
||||||
|
|
||||||
# checking for fuse
|
# checking for fuse
|
||||||
if ! test -z "$enable_fuse"
|
if ! test -z "$enable_fuse"
|
||||||
then
|
then
|
||||||
|
@ -207,6 +207,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
xrdp_orders_init(self);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -469,7 +470,10 @@ xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy,
|
|||||||
char *present_ptr;
|
char *present_ptr;
|
||||||
char *order_flags_ptr;
|
char *order_flags_ptr;
|
||||||
|
|
||||||
xrdp_orders_check(self, 23);
|
if (xrdp_orders_check(self, 23) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD;
|
order_flags = RDP_ORDER_STANDARD;
|
||||||
|
|
||||||
@ -637,7 +641,10 @@ xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y,
|
|||||||
char *present_ptr = (char *)NULL;
|
char *present_ptr = (char *)NULL;
|
||||||
char *order_flags_ptr = (char *)NULL;
|
char *order_flags_ptr = (char *)NULL;
|
||||||
|
|
||||||
xrdp_orders_check(self, 25);
|
if (xrdp_orders_check(self, 25) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD;
|
order_flags = RDP_ORDER_STANDARD;
|
||||||
|
|
||||||
@ -826,7 +833,10 @@ xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y,
|
|||||||
char *order_flags_ptr;
|
char *order_flags_ptr;
|
||||||
struct xrdp_brush blank_brush;
|
struct xrdp_brush blank_brush;
|
||||||
|
|
||||||
xrdp_orders_check(self, 39);
|
if (xrdp_orders_check(self, 39) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD;
|
order_flags = RDP_ORDER_STANDARD;
|
||||||
|
|
||||||
@ -1040,7 +1050,10 @@ xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y,
|
|||||||
char *present_ptr;
|
char *present_ptr;
|
||||||
char *order_flags_ptr;
|
char *order_flags_ptr;
|
||||||
|
|
||||||
xrdp_orders_check(self, 21);
|
if (xrdp_orders_check(self, 21) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD;
|
order_flags = RDP_ORDER_STANDARD;
|
||||||
|
|
||||||
@ -1208,7 +1221,10 @@ xrdp_orders_line(struct xrdp_orders *self, int mix_mode,
|
|||||||
rop = 0x0d; /* R2_COPYPEN */
|
rop = 0x0d; /* R2_COPYPEN */
|
||||||
}
|
}
|
||||||
|
|
||||||
xrdp_orders_check(self, 32);
|
if (xrdp_orders_check(self, 32) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD;
|
order_flags = RDP_ORDER_STANDARD;
|
||||||
|
|
||||||
@ -1407,7 +1423,10 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
|
|||||||
char *present_ptr = (char *)NULL;
|
char *present_ptr = (char *)NULL;
|
||||||
char *order_flags_ptr = (char *)NULL;
|
char *order_flags_ptr = (char *)NULL;
|
||||||
|
|
||||||
xrdp_orders_check(self, 30);
|
if (xrdp_orders_check(self, 30) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD;
|
order_flags = RDP_ORDER_STANDARD;
|
||||||
|
|
||||||
@ -1614,7 +1633,10 @@ xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat,
|
|||||||
char* present_ptr;
|
char* present_ptr;
|
||||||
char* order_flags_ptr;
|
char* order_flags_ptr;
|
||||||
|
|
||||||
xrdp_orders_check(self, 80);
|
if (xrdp_orders_check(self, 80) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD;
|
order_flags = RDP_ORDER_STANDARD;
|
||||||
if (self->orders_state.last_order != RDP_ORDER_COMPOSITE)
|
if (self->orders_state.last_order != RDP_ORDER_COMPOSITE)
|
||||||
@ -1940,8 +1962,10 @@ xrdp_orders_text(struct xrdp_orders *self,
|
|||||||
char *present_ptr = (char *)NULL;
|
char *present_ptr = (char *)NULL;
|
||||||
char *order_flags_ptr = (char *)NULL;
|
char *order_flags_ptr = (char *)NULL;
|
||||||
|
|
||||||
//xrdp_orders_check(self, 100);
|
if (xrdp_orders_check(self, 44 + data_len) != 0)
|
||||||
xrdp_orders_check(self, 44+data_len);
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD;
|
order_flags = RDP_ORDER_STANDARD;
|
||||||
|
|
||||||
@ -2127,7 +2151,10 @@ xrdp_orders_send_palette(struct xrdp_orders *self, int *palette,
|
|||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
xrdp_orders_check(self, 2000);
|
if (xrdp_orders_check(self, 2000) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
||||||
out_uint8(self->out_s, order_flags);
|
out_uint8(self->out_s, order_flags);
|
||||||
@ -2187,7 +2214,10 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self,
|
|||||||
|
|
||||||
Bpp = (bpp + 7) / 8;
|
Bpp = (bpp + 7) / 8;
|
||||||
bufsize = (width + e) * height * Bpp;
|
bufsize = (width + e) * height * Bpp;
|
||||||
xrdp_orders_check(self, bufsize + 16);
|
if (xrdp_orders_check(self, bufsize + 16) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
||||||
out_uint8(self->out_s, order_flags);
|
out_uint8(self->out_s, order_flags);
|
||||||
@ -2294,7 +2324,10 @@ height(%d)", lines_sending, height);
|
|||||||
|
|
||||||
bufsize = (int)(s->p - p);
|
bufsize = (int)(s->p - p);
|
||||||
Bpp = (bpp + 7) / 8;
|
Bpp = (bpp + 7) / 8;
|
||||||
xrdp_orders_check(self, bufsize + 16);
|
if (xrdp_orders_check(self, bufsize + 16) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
||||||
out_uint8(self->out_s, order_flags);
|
out_uint8(self->out_s, order_flags);
|
||||||
@ -2360,7 +2393,10 @@ xrdp_orders_send_font(struct xrdp_orders *self,
|
|||||||
datasize = FONT_DATASIZE(font_char);
|
datasize = FONT_DATASIZE(font_char);
|
||||||
flags = 8;
|
flags = 8;
|
||||||
}
|
}
|
||||||
xrdp_orders_check(self, datasize + 18);
|
if (xrdp_orders_check(self, datasize + 18) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
||||||
out_uint8(self->out_s, order_flags);
|
out_uint8(self->out_s, order_flags);
|
||||||
@ -2417,7 +2453,10 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
|
|||||||
|
|
||||||
Bpp = (bpp + 7) / 8;
|
Bpp = (bpp + 7) / 8;
|
||||||
bufsize = (width + e) * height * Bpp;
|
bufsize = (width + e) * height * Bpp;
|
||||||
xrdp_orders_check(self, bufsize + 14);
|
if (xrdp_orders_check(self, bufsize + 14) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
||||||
out_uint8(self->out_s, order_flags);
|
out_uint8(self->out_s, order_flags);
|
||||||
@ -2545,7 +2584,10 @@ height(%d)", lines_sending, height);
|
|||||||
|
|
||||||
bufsize = (int)(s->p - p);
|
bufsize = (int)(s->p - p);
|
||||||
Bpp = (bpp + 7) / 8;
|
Bpp = (bpp + 7) / 8;
|
||||||
xrdp_orders_check(self, bufsize + 14);
|
if (xrdp_orders_check(self, bufsize + 14) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
||||||
out_uint8(self->out_s, order_flags);
|
out_uint8(self->out_s, order_flags);
|
||||||
@ -2632,7 +2674,10 @@ xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
Bpp = (bpp + 7) / 8;
|
Bpp = (bpp + 7) / 8;
|
||||||
xrdp_orders_check(self, bufsize + 30);
|
if (xrdp_orders_check(self, bufsize + 30) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
||||||
out_uint8(self->out_s, order_flags);
|
out_uint8(self->out_s, order_flags);
|
||||||
@ -2771,7 +2816,10 @@ xrdp_orders_send_brush(struct xrdp_orders *self, int width, int height,
|
|||||||
int order_flags = 0;
|
int order_flags = 0;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
xrdp_orders_check(self, size + 12);
|
if (xrdp_orders_check(self, size + 12) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY;
|
||||||
out_uint8(self->out_s, order_flags);
|
out_uint8(self->out_s, order_flags);
|
||||||
@ -2813,7 +2861,10 @@ xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id,
|
|||||||
bytes += num_del_list * 2;
|
bytes += num_del_list * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
xrdp_orders_check(self, bytes);
|
if (xrdp_orders_check(self, bytes) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */
|
order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */
|
||||||
@ -2854,7 +2905,10 @@ xrdp_orders_send_switch_os_surface(struct xrdp_orders *self, int id)
|
|||||||
int order_flags;
|
int order_flags;
|
||||||
int cache_id;
|
int cache_id;
|
||||||
|
|
||||||
xrdp_orders_check(self, 3);
|
if (xrdp_orders_check(self, 3) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */
|
order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */
|
||||||
|
@ -34,7 +34,10 @@ xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id)
|
|||||||
int field_present_flags;
|
int field_present_flags;
|
||||||
|
|
||||||
order_size = 11;
|
order_size = 11;
|
||||||
xrdp_orders_check(self, order_size);
|
if (xrdp_orders_check(self, order_size) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
||||||
@ -64,7 +67,10 @@ xrdp_orders_send_window_cached_icon(struct xrdp_orders *self,
|
|||||||
int field_present_flags;
|
int field_present_flags;
|
||||||
|
|
||||||
order_size = 14;
|
order_size = 14;
|
||||||
xrdp_orders_check(self, order_size);
|
if (xrdp_orders_check(self, order_size) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
||||||
@ -155,7 +161,10 @@ xrdp_orders_send_window_icon(struct xrdp_orders *self,
|
|||||||
order_size += icon_info->cmap_bytes + 2;
|
order_size += icon_info->cmap_bytes + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
xrdp_orders_check(self, order_size);
|
if (xrdp_orders_check(self, order_size) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
||||||
@ -324,7 +333,10 @@ xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
|
|||||||
order_size += 8 * window_state->num_visibility_rects;
|
order_size += 8 * window_state->num_visibility_rects;
|
||||||
}
|
}
|
||||||
|
|
||||||
xrdp_orders_check(self, order_size);
|
if (xrdp_orders_check(self, order_size) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
||||||
@ -465,7 +477,10 @@ xrdp_orders_send_notify_delete(struct xrdp_orders *self, int window_id,
|
|||||||
int field_present_flags;
|
int field_present_flags;
|
||||||
|
|
||||||
order_size = 15;
|
order_size = 15;
|
||||||
xrdp_orders_check(self, order_size);
|
if (xrdp_orders_check(self, order_size) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
||||||
@ -560,7 +575,10 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders *self,
|
|||||||
order_size += 3;
|
order_size += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
xrdp_orders_check(self, order_size);
|
if (xrdp_orders_check(self, order_size) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
||||||
@ -651,7 +669,10 @@ xrdp_orders_send_monitored_desktop(struct xrdp_orders *self,
|
|||||||
order_size += mdo->num_window_ids * 4;
|
order_size += mdo->num_window_ids * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
xrdp_orders_check(self, order_size);
|
if (xrdp_orders_check(self, order_size) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
self->order_count++;
|
self->order_count++;
|
||||||
order_flags = RDP_ORDER_SECONDARY;
|
order_flags = RDP_ORDER_SECONDARY;
|
||||||
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */
|
||||||
|
@ -48,6 +48,14 @@ typedef struct _SCARD_IO_REQUEST
|
|||||||
unsigned long cbPciLength;
|
unsigned long cbPciLength;
|
||||||
} SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
|
} SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
|
||||||
|
|
||||||
|
#define SCARD_PROTOCOL_T0 0x0001 /**< T=0 active protocol. */
|
||||||
|
#define SCARD_PROTOCOL_T1 0x0002 /**< T=1 active protocol. */
|
||||||
|
#define SCARD_PROTOCOL_RAW 0x0004 /**< Raw active protocol. */
|
||||||
|
|
||||||
|
PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_T0, 8 };
|
||||||
|
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 5
|
||||||
#define LLOGLN(_level, _args) \
|
#define LLOGLN(_level, _args) \
|
||||||
do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
|
do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
|
||||||
@ -284,7 +292,7 @@ SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2,
|
|||||||
int bytes;
|
int bytes;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardEstablishContext:"));
|
LLOGLN(10, ("SCardEstablishContext:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
if (connect_to_chansrv() != 0)
|
if (connect_to_chansrv() != 0)
|
||||||
@ -332,7 +340,7 @@ SCardReleaseContext(SCARDCONTEXT hContext)
|
|||||||
int bytes;
|
int bytes;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardReleaseContext:"));
|
LLOGLN(10, ("SCardReleaseContext:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardReleaseContext: error, not connected"));
|
LLOGLN(0, ("SCardReleaseContext: error, not connected"));
|
||||||
@ -369,7 +377,7 @@ SCardReleaseContext(SCARDCONTEXT hContext)
|
|||||||
PCSC_API LONG
|
PCSC_API LONG
|
||||||
SCardIsValidContext(SCARDCONTEXT hContext)
|
SCardIsValidContext(SCARDCONTEXT hContext)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardIsValidContext:"));
|
LLOGLN(10, ("SCardIsValidContext:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardIsValidContext: error, not connected"));
|
LLOGLN(0, ("SCardIsValidContext: error, not connected"));
|
||||||
@ -392,13 +400,15 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
|||||||
int status;
|
int status;
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardConnect:"));
|
LLOGLN(10, ("SCardConnect:"));
|
||||||
|
LLOGLN(10, ("SCardConnect: hContext %p szReader %s dwShareMode %d "
|
||||||
|
"dwPreferredProtocols %d",
|
||||||
|
(void*)hContext, szReader, dwShareMode, dwPreferredProtocols));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardConnect: error, not connected"));
|
LLOGLN(0, ("SCardConnect: error, not connected"));
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&g_mutex);
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
SET_UINT32(msg, offset, hContext);
|
SET_UINT32(msg, offset, hContext);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
@ -409,12 +419,13 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
|||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
memcpy(msg + offset, szReader, bytes);
|
memcpy(msg + offset, szReader, bytes);
|
||||||
memset(msg + bytes, 0, 100 - bytes);
|
memset(msg + offset + bytes, 0, 100 - bytes);
|
||||||
offset += 100;
|
offset += 100;
|
||||||
SET_UINT32(msg, offset, dwShareMode);
|
SET_UINT32(msg, offset, dwShareMode);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
SET_UINT32(msg, offset, dwPreferredProtocols);
|
SET_UINT32(msg, offset, dwPreferredProtocols);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
pthread_mutex_lock(&g_mutex);
|
||||||
if (send_message(SCARD_CONNECT, msg, offset) != 0)
|
if (send_message(SCARD_CONNECT, msg, offset) != 0)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardConnect: error, send_message"));
|
LLOGLN(0, ("SCardConnect: error, send_message"));
|
||||||
@ -463,15 +474,43 @@ SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
|
|||||||
PCSC_API LONG
|
PCSC_API LONG
|
||||||
SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardDisconnect:"));
|
char msg[256];
|
||||||
|
int code;
|
||||||
|
int bytes;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
LLOGLN(10, ("SCardDisconnect:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardDisconnect: error, not connected"));
|
LLOGLN(0, ("SCardDisconnect: error, not connected"));
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
|
SET_UINT32(msg, 0, hCard);
|
||||||
|
SET_UINT32(msg, 4, dwDisposition);
|
||||||
|
if (send_message(SCARD_DISCONNECT, msg, 8) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardDisconnect: error, send_message"));
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
bytes = 256;
|
||||||
|
if (get_message(&code, msg, &bytes) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardDisconnect: error, get_message"));
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
if ((code != SCARD_DISCONNECT) || (bytes != 4))
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardDisconnect: error, bad code"));
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_S_SUCCESS;
|
status = GET_UINT32(msg, 0);
|
||||||
|
LLOGLN(10, ("SCardDisconnect: got status 0x%8.8x", status));
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -483,7 +522,7 @@ SCardBeginTransaction(SCARDHANDLE hCard)
|
|||||||
int bytes;
|
int bytes;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardBeginTransaction:"));
|
LLOGLN(10, ("SCardBeginTransaction:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardBeginTransaction: error, not connected"));
|
LLOGLN(0, ("SCardBeginTransaction: error, not connected"));
|
||||||
@ -520,15 +559,43 @@ SCardBeginTransaction(SCARDHANDLE hCard)
|
|||||||
PCSC_API LONG
|
PCSC_API LONG
|
||||||
SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
|
SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardEndTransaction:"));
|
char msg[256];
|
||||||
|
int code;
|
||||||
|
int bytes;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
LLOGLN(10, ("SCardEndTransaction:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardEndTransaction: error, not connected"));
|
LLOGLN(0, ("SCardEndTransaction: error, not connected"));
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
|
SET_UINT32(msg, 0, hCard);
|
||||||
|
SET_UINT32(msg, 4, dwDisposition);
|
||||||
|
if (send_message(SCARD_END_TRANSACTION, msg, 8) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardEndTransaction: error, send_message"));
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
bytes = 256;
|
||||||
|
if (get_message(&code, msg, &bytes) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardEndTransaction: error, get_message"));
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
if ((code != SCARD_END_TRANSACTION) || (bytes != 4))
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardEndTransaction: error, bad code"));
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_S_SUCCESS;
|
status = GET_UINT32(msg, 0);
|
||||||
|
LLOGLN(10, ("SCardEndTransaction: got status 0x%8.8x", status));
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -537,15 +604,83 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
|
|||||||
LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
|
LPDWORD pdwState, LPDWORD pdwProtocol, LPBYTE pbAtr,
|
||||||
LPDWORD pcbAtrLen)
|
LPDWORD pcbAtrLen)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardStatus:"));
|
char *msg;
|
||||||
|
int code;
|
||||||
|
int bytes;
|
||||||
|
int status;
|
||||||
|
int offset;
|
||||||
|
int cchReaderLen;
|
||||||
|
int to_copy;
|
||||||
|
|
||||||
|
LLOGLN(10, ("SCardStatus:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardStatus: error, not connected"));
|
LLOGLN(0, ("SCardStatus: error, not connected"));
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
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);
|
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);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_S_SUCCESS;
|
|
||||||
|
LLOGLN(10, ("SCardStatus: cchReaderLen %d", *pcchReaderLen));
|
||||||
|
offset = 0;
|
||||||
|
*pcchReaderLen = GET_UINT32(msg, offset);
|
||||||
|
LLOGLN(10, ("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(10, ("SCardStatus: mszReaderName %s", mszReaderName));
|
||||||
|
offset += *pcchReaderLen;
|
||||||
|
*pdwState = GET_UINT32(msg, offset);
|
||||||
|
LLOGLN(10, ("SCardStatus: dwState %d", *pdwState));
|
||||||
|
offset += 4;
|
||||||
|
*pdwProtocol = GET_UINT32(msg, offset);
|
||||||
|
LLOGLN(10, ("SCardStatus: dwProtocol %d", *pdwProtocol));
|
||||||
|
offset += 4;
|
||||||
|
*pcbAtrLen = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
LLOGLN(10, ("SCardStatus: cbAtrLen %d", *pcbAtrLen));
|
||||||
|
memcpy(pbAtr, msg + offset, *pcbAtrLen);
|
||||||
|
offset += *pcbAtrLen;
|
||||||
|
status = GET_UINT32(msg, offset);
|
||||||
|
LLOGLN(10, ("SCardStatus: status %d", status));
|
||||||
|
offset += 4;
|
||||||
|
free(msg);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -561,7 +696,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
|
|||||||
int str_len;
|
int str_len;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
LLOGLN(0, ("SCardGetStatusChange:"));
|
LLOGLN(10, ("SCardGetStatusChange:"));
|
||||||
LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders));
|
LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
@ -646,15 +781,76 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
|
|||||||
DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
|
DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
|
||||||
LPDWORD lpBytesReturned)
|
LPDWORD lpBytesReturned)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardControl:"));
|
char *msg;
|
||||||
|
int bytes;
|
||||||
|
int code;
|
||||||
|
int offset;
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
LLOGLN(10, ("SCardControl:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardControl: error, not connected"));
|
LLOGLN(0, ("SCardControl: error, not connected"));
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
LLOGLN(10, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode));
|
||||||
|
LLOGLN(10, ("SCardControl: cbSendLength %d", cbSendLength));
|
||||||
|
LLOGLN(10, ("SCardControl: cbRecvLength %d", cbRecvLength));
|
||||||
|
|
||||||
|
/* #define SCARD_CTL_CODE(code) (0x42000000 + (code))
|
||||||
|
control_code = (control_code & 0x3ffc) >> 2;
|
||||||
|
control_code = SCARD_CTL_CODE(control_code); */
|
||||||
|
|
||||||
|
/* PCSC to Windows control code conversion */
|
||||||
|
dwControlCode = dwControlCode - 0x42000000;
|
||||||
|
dwControlCode = dwControlCode << 2;
|
||||||
|
dwControlCode = dwControlCode | (49 << 16);
|
||||||
|
LLOGLN(10, ("SCardControl: dwControlCode 0x%8.8x", dwControlCode));
|
||||||
|
|
||||||
|
msg = (char *) malloc(8192);
|
||||||
|
offset = 0;
|
||||||
|
SET_UINT32(msg, offset, hCard);
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, dwControlCode);
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, cbSendLength);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(msg + offset, pbSendBuffer, cbSendLength);
|
||||||
|
offset += cbSendLength;
|
||||||
|
SET_UINT32(msg, offset, cbRecvLength);
|
||||||
|
offset += 4;
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
|
if (send_message(SCARD_CONTROL, msg, offset) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardControl: 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, ("SCardControl: error, get_message"));
|
||||||
|
free(msg);
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
if (code != SCARD_CONTROL)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardControl: error, bad code"));
|
||||||
|
free(msg);
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_S_SUCCESS;
|
offset = 0;
|
||||||
|
*lpBytesReturned = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned);
|
||||||
|
offset += *lpBytesReturned;
|
||||||
|
status = GET_UINT32(msg, offset);
|
||||||
|
free(msg);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -664,15 +860,118 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
|
|||||||
SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,
|
SCARD_IO_REQUEST *pioRecvPci, LPBYTE pbRecvBuffer,
|
||||||
LPDWORD pcbRecvLength)
|
LPDWORD pcbRecvLength)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardTransmit:"));
|
char *msg;
|
||||||
|
int bytes;
|
||||||
|
int code;
|
||||||
|
int offset;
|
||||||
|
int status;
|
||||||
|
int extra_len;
|
||||||
|
|
||||||
|
LLOGLN(10, ("SCardTransmit:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardTransmit: error, not connected"));
|
LLOGLN(0, ("SCardTransmit: error, not connected"));
|
||||||
return SCARD_F_INTERNAL_ERROR;
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
LLOGLN(10, ("SCardTransmit: cbSendLength %d", cbSendLength));
|
||||||
|
LLOGLN(10, ("SCardTransmit: pioRecvPci %p", pioRecvPci));
|
||||||
|
if (pioRecvPci != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(10, ("SCardTransmit: pioRecvPci->dwProtocol %d",
|
||||||
|
(int)pioRecvPci->dwProtocol));
|
||||||
|
LLOGLN(10, ("SCardTransmit: pioRecvPci->cbPciLength %d",
|
||||||
|
(int)pioRecvPci->cbPciLength));
|
||||||
|
}
|
||||||
|
msg = (char *) malloc(8192);
|
||||||
|
offset = 0;
|
||||||
|
SET_UINT32(msg, offset, hCard);
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, pioSendPci->dwProtocol);
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, pioSendPci->cbPciLength);
|
||||||
|
offset += 4;
|
||||||
|
extra_len = pioSendPci->cbPciLength - 8;
|
||||||
|
SET_UINT32(msg, offset, extra_len);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(msg + offset, pioSendPci + 1, extra_len);
|
||||||
|
offset += extra_len;
|
||||||
|
SET_UINT32(msg, offset, cbSendLength);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(msg + offset, pbSendBuffer, cbSendLength);
|
||||||
|
offset += cbSendLength;
|
||||||
|
if ((pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8))
|
||||||
|
{
|
||||||
|
SET_UINT32(msg, offset, 0); /* dwProtocol */
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, 0); /* cbPciLength */
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, 0); /* extra_len */
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SET_UINT32(msg, offset, pioRecvPci->dwProtocol);
|
||||||
|
offset += 4;
|
||||||
|
SET_UINT32(msg, offset, pioRecvPci->cbPciLength);
|
||||||
|
offset += 4;
|
||||||
|
extra_len = pioRecvPci->cbPciLength - 8;
|
||||||
|
SET_UINT32(msg, offset, extra_len);
|
||||||
|
offset += 4;
|
||||||
|
memcpy(msg + offset, pioRecvPci + 1, extra_len);
|
||||||
|
offset += extra_len;
|
||||||
|
}
|
||||||
|
SET_UINT32(msg, offset, *pcbRecvLength);
|
||||||
|
offset += 4;
|
||||||
pthread_mutex_lock(&g_mutex);
|
pthread_mutex_lock(&g_mutex);
|
||||||
|
if (send_message(SCARD_TRANSMIT, msg, offset) != 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardTransmit: 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, ("SCardTransmit: error, get_message"));
|
||||||
|
free(msg);
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
if (code != SCARD_TRANSMIT)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("SCardTransmit: error, bad code"));
|
||||||
|
free(msg);
|
||||||
|
pthread_mutex_unlock(&g_mutex);
|
||||||
|
return SCARD_F_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
pthread_mutex_unlock(&g_mutex);
|
pthread_mutex_unlock(&g_mutex);
|
||||||
return SCARD_S_SUCCESS;
|
offset = 0;
|
||||||
|
if (pioRecvPci == 0)
|
||||||
|
{
|
||||||
|
offset += 8;
|
||||||
|
extra_len = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
offset += extra_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pioRecvPci->dwProtocol = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
pioRecvPci->cbPciLength = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
extra_len = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
offset += extra_len;
|
||||||
|
}
|
||||||
|
*pcbRecvLength = GET_UINT32(msg, offset);
|
||||||
|
offset += 4;
|
||||||
|
LLOGLN(10, ("SCardTransmit: cbRecvLength %d", *pcbRecvLength));
|
||||||
|
memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength);
|
||||||
|
offset += *pcbRecvLength;
|
||||||
|
status = GET_UINT32(msg, offset);
|
||||||
|
free(msg);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -680,7 +979,7 @@ PCSC_API LONG
|
|||||||
SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
|
SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
|
||||||
LPDWORD pcchGroups)
|
LPDWORD pcchGroups)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardListReaderGroups:"));
|
LLOGLN(10, ("SCardListReaderGroups:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardListReaderGroups: error, not connected"));
|
LLOGLN(0, ("SCardListReaderGroups: error, not connected"));
|
||||||
@ -707,7 +1006,7 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
|
|||||||
int index;
|
int index;
|
||||||
char reader[100];
|
char reader[100];
|
||||||
|
|
||||||
LLOGLN(0, ("SCardListReaders:"));
|
LLOGLN(10, ("SCardListReaders:"));
|
||||||
if (g_sck == -1)
|
if (g_sck == -1)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("SCardListReaders: error, not connected"));
|
LLOGLN(0, ("SCardListReaders: error, not connected"));
|
||||||
@ -742,7 +1041,8 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
|
|||||||
offset = 0;
|
offset = 0;
|
||||||
num_readers = GET_UINT32(msg, offset);
|
num_readers = GET_UINT32(msg, offset);
|
||||||
offset += 4;
|
offset += 4;
|
||||||
LLOGLN(10, ("hi - mszReaders %p pcchReaders %p num_readers %d", mszReaders, pcchReaders, num_readers));
|
LLOGLN(10, ("SCardListReaders: mszReaders %p pcchReaders %p num_readers %d",
|
||||||
|
mszReaders, pcchReaders, num_readers));
|
||||||
reader_names = (char *) malloc(8192);
|
reader_names = (char *) malloc(8192);
|
||||||
reader_names_index = 0;
|
reader_names_index = 0;
|
||||||
for (index = 0; index < num_readers; index++)
|
for (index = 0; index < num_readers; index++)
|
||||||
@ -836,9 +1136,10 @@ SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId, LPCBYTE pbAttr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
char *
|
PCSC_API char *
|
||||||
pcsc_stringify_error(const long code)
|
pcsc_stringify_error(const long code)
|
||||||
{
|
{
|
||||||
|
LLOGLN(10, ("pcsc_stringify_error: %d", (int)code));
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case SCARD_S_SUCCESS:
|
case SCARD_S_SUCCESS:
|
||||||
|
@ -16,5 +16,19 @@ deb http://packages.medibuntu.org/ precise free non-free
|
|||||||
deb http://drbl.sourceforge.net/drbl-core drbl stable
|
deb http://drbl.sourceforge.net/drbl-core drbl stable
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
apt-get install dpkg-dev
|
do all this in a new directory
|
||||||
apt-get build-dep pulseaudio
|
|
||||||
|
root
|
||||||
|
sudo apt-get install dpkg-dev
|
||||||
|
|
||||||
|
non root
|
||||||
|
apt-get source pulseaudio
|
||||||
|
|
||||||
|
root
|
||||||
|
sudo apt-get build-dep pulseaudio
|
||||||
|
|
||||||
|
cd pulseaudio-1.1
|
||||||
|
|
||||||
|
non root
|
||||||
|
dpkg-buildpackage -rfakeroot -uc -b
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
#define LOG_DEBUG 2
|
#define LOG_DEBUG 2
|
||||||
|
|
||||||
#ifndef LOG_LEVEL
|
#ifndef LOG_LEVEL
|
||||||
#define LOG_LEVEL LOG_DEBUG
|
#define LOG_LEVEL LOG_INFO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define log_error(_params...) \
|
#define log_error(_params...) \
|
||||||
@ -160,37 +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 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_add_new_device(tui32 device_id);
|
||||||
static int APP_CC scard_get_free_slot(void);
|
static int APP_CC scard_get_free_slot(void);
|
||||||
|
#if 0
|
||||||
static void APP_CC scard_release_resources(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_EstablishContext(IRP* irp, int scope);
|
||||||
static void APP_CC scard_send_ReleaseContext(IRP* irp, tui32 context);
|
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_IsContextValid(IRP* irp, tui32 context);
|
||||||
static void APP_CC scard_send_ListReaders(IRP* irp, tui32 context, int wide);
|
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,
|
static void APP_CC scard_send_GetStatusChange(IRP* irp, tui32 context, int wide,
|
||||||
tui32 timeout, tui32 num_readers,
|
tui32 timeout, tui32 num_readers,
|
||||||
READER_STATE* rsa);
|
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, tui32 context, int wide,
|
||||||
READER_STATE* rs);
|
READER_STATE* rs);
|
||||||
|
|
||||||
static void APP_CC scard_send_Reconnect(IRP* irp, tui32 context,
|
static void APP_CC scard_send_Reconnect(IRP* irp, tui32 context,
|
||||||
tui32 sc_handle, READER_STATE* rs);
|
tui32 sc_handle, READER_STATE* rs);
|
||||||
|
|
||||||
static void APP_CC scard_send_BeginTransaction(IRP* irp, tui32 sc_handle);
|
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_EndTransaction(IRP* irp, tui32 sc_handle,
|
||||||
static void APP_CC scard_send_Status(IRP* irp, int wide, tui32 sc_handle);
|
tui32 dwDisposition);
|
||||||
|
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,
|
static void APP_CC scard_send_Disconnect(IRP* irp, tui32 context,
|
||||||
tui32 sc_handle);
|
tui32 sc_handle, int dwDisposition);
|
||||||
|
|
||||||
static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle,
|
static int APP_CC scard_send_Transmit(IRP* irp, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
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,
|
static int APP_CC scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
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_Cancel(IRP* irp, tui32 context);
|
||||||
|
|
||||||
static int APP_CC scard_send_GetAttrib(IRP* irp, tui32 sc_handle,
|
static int APP_CC scard_send_GetAttrib(IRP* irp, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
READER_STATE* rs);
|
||||||
|
|
||||||
@ -577,7 +576,8 @@ scard_send_begin_transaction(struct trans *con, tui32 sc_handle)
|
|||||||
* @param sc_handle handle to smartcard
|
* @param sc_handle handle to smartcard
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int APP_CC
|
int APP_CC
|
||||||
scard_send_end_transaction(struct trans *con, tui32 sc_handle)
|
scard_send_end_transaction(struct trans *con, tui32 sc_handle,
|
||||||
|
tui32 dwDisposition)
|
||||||
{
|
{
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
|
|
||||||
@ -595,7 +595,7 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle)
|
|||||||
irp->user_data = con;
|
irp->user_data = con;
|
||||||
|
|
||||||
/* send IRP to client */
|
/* send IRP to client */
|
||||||
scard_send_EndTransaction(irp, sc_handle);
|
scard_send_EndTransaction(irp, sc_handle, dwDisposition);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -607,7 +607,8 @@ scard_send_end_transaction(struct trans *con, tui32 sc_handle)
|
|||||||
* @param wide TRUE if unicode string
|
* @param wide TRUE if unicode string
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int APP_CC
|
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;
|
IRP *irp;
|
||||||
|
|
||||||
@ -625,7 +626,7 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle)
|
|||||||
irp->user_data = con;
|
irp->user_data = con;
|
||||||
|
|
||||||
/* send IRP to client */
|
/* send IRP to client */
|
||||||
scard_send_Status(irp, wide, sc_handle);
|
scard_send_Status(irp, wide, sc_handle, cchReaderLen, cbAtrLen);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -637,7 +638,8 @@ scard_send_status(struct trans *con, int wide, tui32 sc_handle)
|
|||||||
* @param sc_handle handle to smartcard
|
* @param sc_handle handle to smartcard
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int APP_CC
|
int APP_CC
|
||||||
scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle)
|
scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle,
|
||||||
|
int dwDisposition)
|
||||||
{
|
{
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
|
|
||||||
@ -655,7 +657,7 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle)
|
|||||||
irp->user_data = con;
|
irp->user_data = con;
|
||||||
|
|
||||||
/* send IRP to client */
|
/* send IRP to client */
|
||||||
scard_send_Disconnect(irp, context, sc_handle);
|
scard_send_Disconnect(irp, context, sc_handle, dwDisposition);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -665,7 +667,10 @@ scard_send_disconnect(struct trans *con, tui32 context, tui32 sc_handle)
|
|||||||
* associated with a valid context.
|
* associated with a valid context.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int APP_CC
|
int APP_CC
|
||||||
scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs)
|
scard_send_transmit(struct trans *con, 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)
|
||||||
{
|
{
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
|
|
||||||
@ -683,7 +688,8 @@ scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs)
|
|||||||
irp->user_data = con;
|
irp->user_data = con;
|
||||||
|
|
||||||
/* send IRP to client */
|
/* send IRP to client */
|
||||||
scard_send_Transmit(irp, sc_handle, rs);
|
scard_send_Transmit(irp, sc_handle, send_data, send_bytes, recv_bytes,
|
||||||
|
send_ior, recv_ior);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -693,7 +699,8 @@ scard_send_transmit(struct trans *con, tui32 sc_handle, READER_STATE* rs)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
int APP_CC
|
int APP_CC
|
||||||
scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
||||||
READER_STATE* rs)
|
char *send_data, int send_bytes,
|
||||||
|
int recv_bytes, int control_code)
|
||||||
{
|
{
|
||||||
IRP *irp;
|
IRP *irp;
|
||||||
|
|
||||||
@ -711,7 +718,8 @@ scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
|||||||
irp->user_data = con;
|
irp->user_data = con;
|
||||||
|
|
||||||
/* send IRP to client */
|
/* send IRP to client */
|
||||||
scard_send_Control(irp, context, sc_handle, rs);
|
scard_send_Control(irp, context, sc_handle, send_data,
|
||||||
|
send_bytes, recv_bytes, control_code);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -889,6 +897,7 @@ scard_get_free_slot(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* Release resources prior to shutting down
|
* Release resources prior to shutting down
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -906,6 +915,7 @@ scard_release_resources(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -1166,7 +1176,6 @@ scard_send_GetStatusChange(IRP* irp, tui32 context, int wide, tui32 timeout,
|
|||||||
tui32 ioctl;
|
tui32 ioctl;
|
||||||
int bytes;
|
int bytes;
|
||||||
int i;
|
int i;
|
||||||
int len;
|
|
||||||
int num_chars;
|
int num_chars;
|
||||||
int index;
|
int index;
|
||||||
twchar w_reader_name[100];
|
twchar w_reader_name[100];
|
||||||
@ -1269,7 +1278,6 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
|||||||
struct stream* s;
|
struct stream* s;
|
||||||
tui32 ioctl;
|
tui32 ioctl;
|
||||||
int bytes;
|
int bytes;
|
||||||
int len;
|
|
||||||
int num_chars;
|
int num_chars;
|
||||||
int index;
|
int index;
|
||||||
twchar w_reader_name[100];
|
twchar w_reader_name[100];
|
||||||
@ -1469,12 +1477,12 @@ scard_send_BeginTransaction(IRP *irp, tui32 sc_handle)
|
|||||||
* @param sc_handle handle to smartcard
|
* @param sc_handle handle to smartcard
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void APP_CC
|
static void APP_CC
|
||||||
scard_send_EndTransaction(IRP *irp, tui32 sc_handle)
|
scard_send_EndTransaction(IRP *irp, tui32 sc_handle, tui32 dwDisposition)
|
||||||
{
|
{
|
||||||
/* see [MS-RDPESC] 3.1.4.32 */
|
/* see [MS-RDPESC] 3.1.4.32 */
|
||||||
|
|
||||||
SMARTCARD* sc;
|
SMARTCARD *sc;
|
||||||
struct stream* s;
|
struct stream *s;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
@ -1501,7 +1509,7 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
xstream_seek(s, 24);
|
xstream_seek(s, 24);
|
||||||
xstream_wr_u32_le(s, SCARD_LEAVE_CARD);
|
xstream_wr_u32_le(s, dwDisposition);
|
||||||
xstream_seek(s, 8);
|
xstream_seek(s, 8);
|
||||||
|
|
||||||
/* insert handle */
|
/* insert handle */
|
||||||
@ -1526,7 +1534,8 @@ scard_send_EndTransaction(IRP *irp, tui32 sc_handle)
|
|||||||
* @param wide TRUE if unicode string
|
* @param wide TRUE if unicode string
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void APP_CC
|
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 */
|
/* see [MS-RDPESC] 2.2.2.18 */
|
||||||
|
|
||||||
@ -1541,11 +1550,12 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ioctl = (wide) ? SCARD_IOCTL_CONNECT_W :
|
ioctl = wide ? SCARD_IOCTL_STATUS_W : SCARD_IOCTL_STATUS_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");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1564,8 +1574,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
xstream_seek(s, 28);
|
xstream_seek(s, 28);
|
||||||
xstream_wr_u32_le(s, -1); /* readerLen, see [MS-RDPESC] 4.11 */
|
xstream_wr_u32_le(s, cchReaderLen); /* readerLen, see [MS-RDPESC] 4.11 */
|
||||||
xstream_wr_u32_le(s, 36); /* atrLen, see [MS-RDPESC] 4.11 */
|
xstream_wr_u32_le(s, cbAtrLen); /* atrLen, see [MS-RDPESC] 4.11 */
|
||||||
xstream_seek(s, 8);
|
xstream_seek(s, 8);
|
||||||
|
|
||||||
/* insert sc_handle */
|
/* insert sc_handle */
|
||||||
@ -1592,7 +1602,8 @@ scard_send_Status(IRP *irp, int wide, tui32 sc_handle)
|
|||||||
* @param sc_handle handle to smartcard
|
* @param sc_handle handle to smartcard
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void APP_CC
|
static void APP_CC
|
||||||
scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle)
|
scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle,
|
||||||
|
int dwDisposition)
|
||||||
{
|
{
|
||||||
/* see [MS-RDPESC] 3.1.4.30 */
|
/* see [MS-RDPESC] 3.1.4.30 */
|
||||||
|
|
||||||
@ -1625,7 +1636,7 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
xstream_seek(s, 24);
|
xstream_seek(s, 24);
|
||||||
xstream_wr_u32_le(s, SCARD_RESET_CARD);
|
xstream_wr_u32_le(s, dwDisposition);
|
||||||
|
|
||||||
/* insert context */
|
/* insert context */
|
||||||
xstream_wr_u32_le(s, 4);
|
xstream_wr_u32_le(s, 4);
|
||||||
@ -1651,22 +1662,35 @@ scard_send_Disconnect(IRP *irp, tui32 context, tui32 sc_handle)
|
|||||||
* associated with a valid context.
|
* associated with a valid context.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int APP_CC
|
static int APP_CC
|
||||||
scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
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)
|
||||||
{
|
{
|
||||||
/* see [MS-RDPESC] 2.2.2.19 */
|
/* see [MS-RDPESC] 2.2.2.19 */
|
||||||
|
|
||||||
SMARTCARD* sc;
|
SMARTCARD* sc;
|
||||||
struct stream* s;
|
struct stream* s;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
int val;
|
||||||
|
|
||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
log_error("smartcards[%d] is NULL", irp->scard_index);
|
log_error("smartcards[%d] is NULL", irp->scard_index);
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL)
|
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,
|
||||||
|
recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength,
|
||||||
|
send_ior->extra_bytes, recv_ior->dwProtocol, recv_ior->cbPciLength,
|
||||||
|
recv_ior->extra_bytes);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1693,21 +1717,48 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
xstream_seek(s, 12);
|
xstream_seek(s, 12);
|
||||||
xstream_wr_u32_le(s, rs->map0);
|
xstream_wr_u32_le(s, 0); // map0
|
||||||
xstream_seek(s, 4);
|
xstream_seek(s, 4);
|
||||||
xstream_wr_u32_le(s, rs->map1);
|
xstream_wr_u32_le(s, 0); // map1
|
||||||
xstream_wr_u32_le(s, rs->dwProtocol);
|
xstream_wr_u32_le(s, send_ior->dwProtocol);
|
||||||
xstream_wr_u32_le(s, rs->cbPciLength);
|
xstream_wr_u32_le(s, send_ior->cbPciLength);
|
||||||
xstream_wr_u32_le(s, rs->map2);
|
val = send_ior->extra_bytes > 0 ? 1 : 0;
|
||||||
xstream_wr_u32_le(s, rs->cbSendLength);
|
xstream_wr_u32_le(s, val); // map2
|
||||||
xstream_wr_u32_le(s, rs->map3);
|
xstream_wr_u32_le(s, send_bytes);
|
||||||
xstream_wr_u32_le(s, rs->map4);
|
val = send_bytes > 0 ? 1 : 0;
|
||||||
xstream_wr_u32_le(s, rs->map5);
|
xstream_wr_u32_le(s, val); // map3
|
||||||
xstream_wr_u32_le(s, rs->map6);
|
val = recv_ior->cbPciLength > 0 ? 1 : 0;
|
||||||
xstream_wr_u32_le(s, rs->cbRecvLength);
|
xstream_wr_u32_le(s, val); // map 4
|
||||||
|
xstream_wr_u32_le(s, 0); // map5
|
||||||
|
xstream_wr_u32_le(s, recv_bytes);
|
||||||
xstream_wr_u32_le(s, 4);
|
xstream_wr_u32_le(s, 4);
|
||||||
xstream_wr_u32_le(s, sc_handle);
|
xstream_wr_u32_le(s, sc_handle);
|
||||||
|
|
||||||
|
if (send_ior->extra_bytes > 0)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, send_ior->extra_bytes);
|
||||||
|
out_uint8a(s, send_ior->extra_data, send_ior->extra_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send_bytes > 0)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, send_bytes);
|
||||||
|
out_uint8a(s, send_data, send_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recv_ior->cbPciLength > 0)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, recv_ior->dwProtocol);
|
||||||
|
xstream_wr_u32_le(s, recv_ior->cbPciLength);
|
||||||
|
val = recv_ior->extra_bytes > 0 ? 1 : 0;
|
||||||
|
xstream_wr_u32_le(s, val);
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, recv_ior->extra_bytes);
|
||||||
|
out_uint8a(s, recv_ior->extra_data, recv_ior->extra_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* get stream len */
|
/* get stream len */
|
||||||
bytes = xstream_len(s);
|
bytes = xstream_len(s);
|
||||||
|
|
||||||
@ -1717,28 +1768,34 @@ scard_send_Transmit(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
|||||||
/* 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);
|
||||||
xstream_free(s);
|
xstream_free(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Communicate directly with the smart card reader
|
* Communicate directly with the smart card reader
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int APP_CC
|
static int APP_CC
|
||||||
scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
|
scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, char *send_data,
|
||||||
|
int send_bytes, int recv_bytes, int control_code)
|
||||||
{
|
{
|
||||||
/* see [MS-RDPESC] 2.2.2.19 */
|
/* see [MS-RDPESC] 2.2.2.19 */
|
||||||
|
|
||||||
SMARTCARD* sc;
|
SMARTCARD* sc;
|
||||||
struct stream* s;
|
struct stream* s;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
int val;
|
||||||
|
|
||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
log_error("smartcards[%d] is NULL", irp->scard_index);
|
log_error("smartcards[%d] is NULL", irp->scard_index);
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CONTROL)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CONTROL)) == NULL)
|
||||||
return;
|
{
|
||||||
|
log_error("scard_make_new_ioctl");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1763,19 +1820,30 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
xstream_seek(s, 12);
|
xstream_seek(s, 12);
|
||||||
xstream_wr_u32_le(s, rs->map0);
|
xstream_wr_u32_le(s, 0); // map0
|
||||||
|
xstream_seek(s, 4);
|
||||||
|
xstream_wr_u32_le(s, 0); // map1
|
||||||
|
|
||||||
|
xstream_wr_u32_le(s, control_code);
|
||||||
|
|
||||||
|
xstream_wr_u32_le(s, send_bytes);
|
||||||
|
|
||||||
|
val = send_bytes > 0 ? 1 : 0;
|
||||||
|
xstream_wr_u32_le(s, val); // map2
|
||||||
|
|
||||||
xstream_wr_u32_le(s, 0);
|
xstream_wr_u32_le(s, 0);
|
||||||
xstream_wr_u32_le(s, rs->map1);
|
xstream_wr_u32_le(s, recv_bytes);
|
||||||
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, 4);
|
||||||
xstream_wr_u32_le(s, context);
|
xstream_wr_u32_le(s, context);
|
||||||
xstream_wr_u32_le(s, 4);
|
xstream_wr_u32_le(s, 4);
|
||||||
xstream_wr_u32_le(s, sc_handle);
|
xstream_wr_u32_le(s, sc_handle);
|
||||||
|
|
||||||
|
if (send_bytes > 0)
|
||||||
|
{
|
||||||
|
xstream_wr_u32_le(s, send_bytes);
|
||||||
|
out_uint8a(s, send_data, send_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
/* get stream len */
|
/* get stream len */
|
||||||
bytes = xstream_len(s);
|
bytes = xstream_len(s);
|
||||||
|
|
||||||
@ -1785,12 +1853,14 @@ scard_send_Control(IRP* irp, tui32 context, tui32 sc_handle, READER_STATE* rs)
|
|||||||
/* 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);
|
||||||
xstream_free(s);
|
xstream_free(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel any outstanding calls
|
* Cancel any outstanding calls
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int APP_CC scard_send_Cancel(IRP* irp, tui32 context)
|
static int APP_CC
|
||||||
|
scard_send_Cancel(IRP* irp, tui32 context)
|
||||||
{
|
{
|
||||||
/* see [MS-RDPESC] 3.1.4.27 */
|
/* see [MS-RDPESC] 3.1.4.27 */
|
||||||
|
|
||||||
@ -1801,11 +1871,14 @@ static int APP_CC scard_send_Cancel(IRP* irp, tui32 context)
|
|||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
log_error("smartcards[%d] is NULL", irp->scard_index);
|
log_error("smartcards[%d] is NULL", irp->scard_index);
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CANCEL)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CANCEL)) == NULL)
|
||||||
return;
|
{
|
||||||
|
log_error("scard_make_new_ioctl");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1832,6 +1905,7 @@ static int APP_CC scard_send_Cancel(IRP* irp, tui32 context)
|
|||||||
/* 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);
|
||||||
xstream_free(s);
|
xstream_free(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1849,11 +1923,14 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
|||||||
if ((sc = smartcards[irp->scard_index]) == NULL)
|
if ((sc = smartcards[irp->scard_index]) == NULL)
|
||||||
{
|
{
|
||||||
log_error("smartcards[%d] is NULL", irp->scard_index);
|
log_error("smartcards[%d] is NULL", irp->scard_index);
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_GETATTRIB)) == NULL)
|
if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_GETATTRIB)) == NULL)
|
||||||
return;
|
{
|
||||||
|
log_error("scard_make_new_ioctl");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* command format
|
* command format
|
||||||
@ -1888,6 +1965,7 @@ scard_send_GetAttrib(IRP* irp, tui32 sc_handle, READER_STATE* rs)
|
|||||||
/* 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);
|
||||||
xstream_free(s);
|
xstream_free(s);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -1960,11 +2038,16 @@ scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
|
|||||||
log_debug("leaving");
|
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;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -1984,7 +2067,9 @@ static void APP_CC scard_handle_IsContextValid_Return(struct stream *s, IRP *irp
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2081,9 +2166,11 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
|
|||||||
|
|
||||||
/* 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_connect_return(con, s, len);
|
scard_function_connect_return(con, s, len);
|
||||||
devredir_irp_delete(irp);
|
devredir_irp_delete(irp);
|
||||||
|
|
||||||
log_debug("leaving");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2096,6 +2183,7 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp,
|
|||||||
tui32 IoStatus)
|
tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2115,7 +2203,9 @@ scard_handle_Reconnect_Return(struct stream *s, IRP *irp,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2128,6 +2218,7 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
|
|||||||
tui32 IoStatus)
|
tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2147,7 +2238,9 @@ scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2160,6 +2253,7 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
|
|||||||
tui32 IoStatus)
|
tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2179,7 +2273,9 @@ scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2192,6 +2288,7 @@ scard_handle_Status_Return(struct stream *s, IRP *irp,
|
|||||||
tui32 IoStatus)
|
tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2211,7 +2308,9 @@ scard_handle_Status_Return(struct stream *s, IRP *irp,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2224,6 +2323,7 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
|
|||||||
tui32 IoStatus)
|
tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2243,7 +2343,9 @@ scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2255,6 +2357,7 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
tui32 CompletionId, tui32 IoStatus)
|
tui32 CompletionId, tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2274,7 +2377,9 @@ scard_handle_Transmit_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2286,6 +2391,7 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
tui32 CompletionId,tui32 IoStatus)
|
tui32 CompletionId,tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2305,7 +2411,9 @@ scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2317,6 +2425,7 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
tui32 CompletionId, tui32 IoStatus)
|
tui32 CompletionId, tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2336,7 +2445,9 @@ scard_handle_Cancel_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2348,6 +2459,7 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
tui32 CompletionId, tui32 IoStatus)
|
tui32 CompletionId, tui32 IoStatus)
|
||||||
{
|
{
|
||||||
tui32 len;
|
tui32 len;
|
||||||
|
struct trans *con;
|
||||||
|
|
||||||
log_debug("entered");
|
log_debug("entered");
|
||||||
|
|
||||||
@ -2367,6 +2479,8 @@ scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, tui32 DeviceId,
|
|||||||
|
|
||||||
/* get OutputBufferLen */
|
/* get OutputBufferLen */
|
||||||
xstream_rd_u32_le(s, len);
|
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");
|
log_debug("leaving");
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,14 @@
|
|||||||
#define SCARD_RESET_CARD 0x00000001 /* reset smart card */
|
#define SCARD_RESET_CARD 0x00000001 /* reset smart card */
|
||||||
#define SCARD_UNPOWER_CARD 0x00000002 /* turn off and reset card */
|
#define SCARD_UNPOWER_CARD 0x00000002 /* turn off and reset card */
|
||||||
|
|
||||||
|
struct xrdp_scard_io_request
|
||||||
|
{
|
||||||
|
tui32 dwProtocol;
|
||||||
|
tui32 cbPciLength;
|
||||||
|
int extra_bytes;
|
||||||
|
char *extra_data;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct reader_state
|
typedef struct reader_state
|
||||||
{
|
{
|
||||||
char reader_name[128];
|
char reader_name[128];
|
||||||
@ -118,15 +126,21 @@ int APP_CC scard_send_reconnect(struct trans *con, tui32 context,
|
|||||||
tui32 sc_handle, READER_STATE* rs);
|
tui32 sc_handle, READER_STATE* rs);
|
||||||
|
|
||||||
int APP_CC scard_send_begin_transaction(struct trans *con, tui32 sc_handle);
|
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);
|
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);
|
tui32 dwDisposition);
|
||||||
int APP_CC scard_send_disconnect(struct trans *con, tui32 context, 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);
|
||||||
|
|
||||||
int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle,
|
int APP_CC scard_send_transmit(struct trans *con, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
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(struct trans *con, tui32 context, tui32 sc_handle,
|
int APP_CC scard_send_control(struct trans *con, tui32 context, tui32 sc_handle,
|
||||||
READER_STATE* rs);
|
char *send_data, int send_bytes,
|
||||||
|
int recv_bytes, int control_code);
|
||||||
|
|
||||||
int APP_CC scard_send_cancel(struct trans *con, tui32 context);
|
int APP_CC scard_send_cancel(struct trans *con, tui32 context);
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#if PCSC_STANDIN
|
#if PCSC_STANDIN
|
||||||
|
|
||||||
#define LLOG_LEVEL 11
|
#define LLOG_LEVEL 1
|
||||||
#define LLOGLN(_level, _args) \
|
#define LLOGLN(_level, _args) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
@ -57,6 +57,11 @@
|
|||||||
#define XRDP_PCSC_STATE_GOT_GSC (1 << 3) /* get status change */
|
#define XRDP_PCSC_STATE_GOT_GSC (1 << 3) /* get status change */
|
||||||
#define XRDP_PCSC_STATE_GOT_C (1 << 4) /* connect */
|
#define XRDP_PCSC_STATE_GOT_C (1 << 4) /* connect */
|
||||||
#define XRDP_PCSC_STATE_GOT_BT (1 << 5) /* begin transaction */
|
#define XRDP_PCSC_STATE_GOT_BT (1 << 5) /* begin transaction */
|
||||||
|
#define XRDP_PCSC_STATE_GOT_ET (1 << 6) /* end transaction */
|
||||||
|
#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 */
|
/* TODO: put this in con */
|
||||||
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
|
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
|
||||||
@ -69,8 +74,10 @@ struct pcsc_client
|
|||||||
struct trans *con;
|
struct trans *con;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
static struct pcsc_client *g_head = 0;
|
static struct pcsc_client *g_head = 0;
|
||||||
static struct pcsc_client *g_tail = 0;
|
static struct pcsc_client *g_tail = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct trans *g_lis = 0;
|
static struct trans *g_lis = 0;
|
||||||
static struct trans *g_con = 0; /* todo, remove this */
|
static struct trans *g_con = 0; /* todo, remove this */
|
||||||
@ -81,7 +88,7 @@ static int g_pub_file_fd = 0;
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
|
scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_pcsc_get_wait_objs"));
|
LLOGLN(10, ("scard_pcsc_get_wait_objs"));
|
||||||
if (g_lis != 0)
|
if (g_lis != 0)
|
||||||
{
|
{
|
||||||
trans_get_wait_objs(g_lis, objs, count);
|
trans_get_wait_objs(g_lis, objs, count);
|
||||||
@ -97,7 +104,7 @@ scard_pcsc_get_wait_objs(tbus *objs, int *count, int *timeout)
|
|||||||
int APP_CC
|
int APP_CC
|
||||||
scard_pcsc_check_wait_objs(void)
|
scard_pcsc_check_wait_objs(void)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_pcsc_check_wait_objs"));
|
LLOGLN(10, ("scard_pcsc_check_wait_objs"));
|
||||||
if (g_lis != 0)
|
if (g_lis != 0)
|
||||||
{
|
{
|
||||||
trans_check_wait_objs(g_lis);
|
trans_check_wait_objs(g_lis);
|
||||||
@ -116,7 +123,7 @@ scard_process_establish_context(struct trans *con, struct stream *in_s)
|
|||||||
{
|
{
|
||||||
int dwScope;
|
int dwScope;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_establish_context:"));
|
LLOGLN(10, ("scard_process_establish_context:"));
|
||||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC)
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_process_establish_context: opps"));
|
LLOGLN(0, ("scard_process_establish_context: opps"));
|
||||||
@ -124,7 +131,7 @@ scard_process_establish_context(struct trans *con, struct stream *in_s)
|
|||||||
}
|
}
|
||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_EC;
|
||||||
in_uint32_le(in_s, dwScope);
|
in_uint32_le(in_s, dwScope);
|
||||||
LLOGLN(0, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope));
|
LLOGLN(10, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope));
|
||||||
scard_send_establish_context(con, dwScope);
|
scard_send_establish_context(con, dwScope);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -141,7 +148,7 @@ scard_function_establish_context_return(struct trans *con,
|
|||||||
tui32 context_len;
|
tui32 context_len;
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_function_establish_context_return:"));
|
LLOGLN(10, ("scard_function_establish_context_return:"));
|
||||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0)
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_EC) == 0)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_function_establish_context_return: opps"));
|
LLOGLN(0, ("scard_function_establish_context_return: opps"));
|
||||||
@ -156,7 +163,7 @@ scard_function_establish_context_return(struct trans *con,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
in_uint32_le(in_s, context);
|
in_uint32_le(in_s, context);
|
||||||
LLOGLN(0, ("scard_function_establish_context_return: context 0x%8.8x", context));
|
LLOGLN(10, ("scard_function_establish_context_return: context 0x%8.8x", context));
|
||||||
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, context);
|
out_uint32_le(out_s, context);
|
||||||
@ -176,7 +183,7 @@ scard_process_release_context(struct trans *con, struct stream *in_s)
|
|||||||
{
|
{
|
||||||
int hContext;
|
int hContext;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_release_context:"));
|
LLOGLN(10, ("scard_process_release_context:"));
|
||||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC)
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_process_establish_context: opps"));
|
LLOGLN(0, ("scard_process_establish_context: opps"));
|
||||||
@ -184,7 +191,7 @@ scard_process_release_context(struct trans *con, struct stream *in_s)
|
|||||||
}
|
}
|
||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RC;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_RC;
|
||||||
in_uint32_le(in_s, hContext);
|
in_uint32_le(in_s, hContext);
|
||||||
LLOGLN(0, ("scard_process_release_context: hContext 0x%8.8x", hContext));
|
LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext));
|
||||||
scard_send_release_context(con, hContext);
|
scard_send_release_context(con, hContext);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -198,9 +205,8 @@ scard_function_release_context_return(struct trans *con,
|
|||||||
{
|
{
|
||||||
int bytes;
|
int bytes;
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
tui32 context;
|
|
||||||
|
|
||||||
LLOGLN(0, ("scard_function_release_context_return:"));
|
LLOGLN(10, ("scard_function_release_context_return:"));
|
||||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0)
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_RC) == 0)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_function_release_context_return: opps"));
|
LLOGLN(0, ("scard_function_release_context_return: opps"));
|
||||||
@ -225,7 +231,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
|
|||||||
{
|
{
|
||||||
int hContext;
|
int hContext;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_list_readers:"));
|
LLOGLN(10, ("scard_process_list_readers:"));
|
||||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR)
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_process_list_readers: opps"));
|
LLOGLN(0, ("scard_process_list_readers: opps"));
|
||||||
@ -233,7 +239,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
|
|||||||
}
|
}
|
||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_LR;
|
||||||
in_uint32_le(in_s, hContext);
|
in_uint32_le(in_s, hContext);
|
||||||
LLOGLN(0, ("scard_process_list_readers: dwScope 0x%8.8x", hContext));
|
LLOGLN(10, ("scard_process_list_readers: dwScope 0x%8.8x", hContext));
|
||||||
scard_send_list_readers(con, hContext, 1);
|
scard_send_list_readers(con, hContext, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -254,10 +260,10 @@ scard_function_list_readers_return(struct trans *con,
|
|||||||
char lreader_name[16][100];
|
char lreader_name[16][100];
|
||||||
|
|
||||||
LLOGLN(10, ("scard_function_list_readers_return:"));
|
LLOGLN(10, ("scard_function_list_readers_return:"));
|
||||||
g_hexdump(in_s->p, len);
|
//g_hexdump(in_s->p, len);
|
||||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0)
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_LR) == 0)
|
||||||
{
|
{
|
||||||
LLOGLN(10, ("scard_function_list_readers_return: opps"));
|
LLOGLN(0, ("scard_function_list_readers_return: opps"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR;
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_LR;
|
||||||
@ -267,7 +273,7 @@ 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);
|
//g_writeln("len %d", len);
|
||||||
rn_index = 0;
|
rn_index = 0;
|
||||||
readers = 0;
|
readers = 0;
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
@ -279,7 +285,7 @@ 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_writeln("1 %s", lreader_name[readers]);
|
||||||
g_memset(reader_name, 0, sizeof(reader_name));
|
g_memset(reader_name, 0, sizeof(reader_name));
|
||||||
readers++;
|
readers++;
|
||||||
}
|
}
|
||||||
@ -297,7 +303,7 @@ 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_writeln("2 %s", lreader_name[readers]);
|
||||||
g_memset(reader_name, 0, sizeof(reader_name));
|
g_memset(reader_name, 0, sizeof(reader_name));
|
||||||
readers++;
|
readers++;
|
||||||
}
|
}
|
||||||
@ -308,7 +314,7 @@ scard_function_list_readers_return(struct trans *con,
|
|||||||
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]);
|
//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, 0); /* SCARD_S_SUCCESS status */
|
||||||
@ -326,10 +332,9 @@ int APP_CC
|
|||||||
scard_process_connect(struct trans *con, struct stream *in_s)
|
scard_process_connect(struct trans *con, struct stream *in_s)
|
||||||
{
|
{
|
||||||
int hContext;
|
int hContext;
|
||||||
char szReader[100];
|
|
||||||
READER_STATE rs;
|
READER_STATE rs;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_connect:"));
|
LLOGLN(10, ("scard_process_connect:"));
|
||||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C)
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_process_connect: opps"));
|
LLOGLN(0, ("scard_process_connect: opps"));
|
||||||
@ -338,11 +343,11 @@ scard_process_connect(struct trans *con, struct stream *in_s)
|
|||||||
g_memset(&rs, 0, sizeof(rs));
|
g_memset(&rs, 0, sizeof(rs));
|
||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_C;
|
||||||
in_uint32_le(in_s, hContext);
|
in_uint32_le(in_s, hContext);
|
||||||
in_uint8a(in_s, szReader, 100);
|
in_uint8a(in_s, rs.reader_name, 100);
|
||||||
in_uint32_le(in_s, rs.dwShareMode);
|
in_uint32_le(in_s, rs.dwShareMode);
|
||||||
in_uint32_le(in_s, rs.dwPreferredProtocols);
|
in_uint32_le(in_s, rs.dwPreferredProtocols);
|
||||||
LLOGLN(0, ("scard_process_connect: dwShareMode 0x%8.8x "
|
LLOGLN(10, ("scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x "
|
||||||
"dwPreferredProtocols 0x%8.8x", rs.dwShareMode,
|
"dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode,
|
||||||
rs.dwPreferredProtocols));
|
rs.dwPreferredProtocols));
|
||||||
scard_send_connect(con, hContext, 1, &rs);
|
scard_send_connect(con, hContext, 1, &rs);
|
||||||
return 0;
|
return 0;
|
||||||
@ -359,7 +364,7 @@ scard_function_connect_return(struct trans *con,
|
|||||||
int bytes;
|
int bytes;
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
|
|
||||||
g_hexdump(in_s->p, len);
|
//g_hexdump(in_s->p, len);
|
||||||
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0)
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_C) == 0)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_function_connect_return: opps"));
|
LLOGLN(0, ("scard_function_connect_return: opps"));
|
||||||
@ -368,8 +373,9 @@ scard_function_connect_return(struct trans *con,
|
|||||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
|
||||||
in_uint8s(in_s, 36);
|
in_uint8s(in_s, 36);
|
||||||
in_uint32_le(in_s, dwActiveProtocol);
|
in_uint32_le(in_s, dwActiveProtocol);
|
||||||
in_uint8s(in_s, 36);
|
in_uint8s(in_s, 4);
|
||||||
in_uint32_le(in_s, hCard);
|
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);
|
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, hCard);
|
out_uint32_le(out_s, hCard);
|
||||||
@ -383,6 +389,66 @@ scard_function_connect_return(struct trans *con,
|
|||||||
return trans_force_write(con);
|
return trans_force_write(con);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* returns error */
|
||||||
|
int APP_CC
|
||||||
|
scard_process_disconnect(struct trans *con, struct stream *in_s)
|
||||||
|
{
|
||||||
|
int hContext;
|
||||||
|
int hCard;
|
||||||
|
int dwDisposition;
|
||||||
|
|
||||||
|
LLOGLN(10, ("scard_process_disconnect:"));
|
||||||
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_process_disconnect: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_D;
|
||||||
|
in_uint32_le(in_s, hCard);
|
||||||
|
in_uint32_le(in_s, dwDisposition);
|
||||||
|
|
||||||
|
hContext = 1;
|
||||||
|
|
||||||
|
scard_send_disconnect(con, hContext, hCard, dwDisposition);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
int APP_CC
|
||||||
|
scard_function_disconnect_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len)
|
||||||
|
{
|
||||||
|
int dwActiveProtocol;
|
||||||
|
int hCard;
|
||||||
|
int bytes;
|
||||||
|
struct stream *out_s;
|
||||||
|
|
||||||
|
//g_hexdump(in_s->p, len);
|
||||||
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_D) == 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_function_connect_return: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_D;
|
||||||
|
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, 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, 0x06); /* SCARD_DISCONNECT 0x06 */
|
||||||
|
return trans_force_write(con);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* returns error */
|
/* returns error */
|
||||||
int APP_CC
|
int APP_CC
|
||||||
@ -390,7 +456,7 @@ scard_process_begin_transaction(struct trans *con, struct stream *in_s)
|
|||||||
{
|
{
|
||||||
int hCard;
|
int hCard;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_begin_transaction:"));
|
LLOGLN(10, ("scard_process_begin_transaction:"));
|
||||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT)
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_process_begin_transaction: opps"));
|
LLOGLN(0, ("scard_process_begin_transaction: opps"));
|
||||||
@ -398,11 +464,395 @@ scard_process_begin_transaction(struct trans *con, struct stream *in_s)
|
|||||||
}
|
}
|
||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_BT;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_BT;
|
||||||
in_uint32_le(in_s, hCard);
|
in_uint32_le(in_s, hCard);
|
||||||
LLOGLN(0, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
|
LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
|
||||||
scard_send_begin_transaction(con, hCard);
|
scard_send_begin_transaction(con, hCard);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* returns error */
|
||||||
|
int APP_CC
|
||||||
|
scard_function_begin_transaction_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len)
|
||||||
|
{
|
||||||
|
struct stream *out_s;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
|
//g_hexdump(in_s->p, len);
|
||||||
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT) == 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_function_begin_transaction_return: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_BT;
|
||||||
|
|
||||||
|
out_s = trans_get_out_s(con, 8192);
|
||||||
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
|
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, 0x07); /* SCARD_BEGIN_TRANSACTION 0x07 */
|
||||||
|
return trans_force_write(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* returns error */
|
||||||
|
int APP_CC
|
||||||
|
scard_process_end_transaction(struct trans *con, struct stream *in_s)
|
||||||
|
{
|
||||||
|
int hCard;
|
||||||
|
int dwDisposition;
|
||||||
|
|
||||||
|
LLOGLN(10, ("scard_process_end_transaction:"));
|
||||||
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ET)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_process_end_transaction: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ET;
|
||||||
|
in_uint32_le(in_s, hCard);
|
||||||
|
in_uint32_le(in_s, dwDisposition);
|
||||||
|
LLOGLN(10, ("scard_process_end_transaction: hCard 0x%8.8x", hCard));
|
||||||
|
scard_send_end_transaction(con, hCard, dwDisposition);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* returns error */
|
||||||
|
int APP_CC
|
||||||
|
scard_function_end_transaction_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len)
|
||||||
|
{
|
||||||
|
struct stream *out_s;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
|
//g_hexdump(in_s->p, len);
|
||||||
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ET) == 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_function_end_transaction_return: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_ET;
|
||||||
|
|
||||||
|
out_s = trans_get_out_s(con, 8192);
|
||||||
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
|
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, 0x08); /* SCARD_END_TRANSACTION 0x08 */
|
||||||
|
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
|
||||||
|
scard_process_transmit(struct trans *con, struct stream *in_s)
|
||||||
|
{
|
||||||
|
int hCard;
|
||||||
|
int recv_bytes;
|
||||||
|
int send_bytes;
|
||||||
|
char *send_data;
|
||||||
|
struct xrdp_scard_io_request send_ior;
|
||||||
|
struct xrdp_scard_io_request recv_ior;
|
||||||
|
|
||||||
|
LLOGLN(10, ("scard_process_transmit:"));
|
||||||
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_process_transmit: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_TR;
|
||||||
|
LLOGLN(10, ("scard_process_transmit:"));
|
||||||
|
in_uint32_le(in_s, hCard);
|
||||||
|
in_uint32_le(in_s, send_ior.dwProtocol);
|
||||||
|
in_uint32_le(in_s, send_ior.cbPciLength);
|
||||||
|
in_uint32_le(in_s, send_ior.extra_bytes);
|
||||||
|
in_uint8p(in_s, send_ior.extra_data, send_ior.extra_bytes);
|
||||||
|
in_uint32_le(in_s, send_bytes);
|
||||||
|
in_uint8p(in_s, send_data, send_bytes);
|
||||||
|
in_uint32_le(in_s, recv_ior.dwProtocol);
|
||||||
|
in_uint32_le(in_s, recv_ior.cbPciLength);
|
||||||
|
in_uint32_le(in_s, recv_ior.extra_bytes);
|
||||||
|
in_uint8p(in_s, recv_ior.extra_data, recv_ior.extra_bytes);
|
||||||
|
in_uint32_le(in_s, recv_bytes);
|
||||||
|
LLOGLN(10, ("scard_process_transmit: send dwProtocol %d cbPciLength %d "
|
||||||
|
"recv dwProtocol %d cbPciLength %d send_bytes %d ",
|
||||||
|
send_ior.dwProtocol, send_ior.cbPciLength, recv_ior.dwProtocol,
|
||||||
|
recv_ior.cbPciLength, send_bytes));
|
||||||
|
//g_hexdump(in_s->p, send_bytes);
|
||||||
|
LLOGLN(10, ("scard_process_transmit: recv_bytes %d", recv_bytes));
|
||||||
|
scard_send_transmit(con, hCard, send_data, send_bytes, recv_bytes,
|
||||||
|
&send_ior, &recv_ior);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* returns error */
|
||||||
|
int APP_CC
|
||||||
|
scard_function_transmit_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len)
|
||||||
|
{
|
||||||
|
struct stream *out_s;
|
||||||
|
int bytes;
|
||||||
|
int val;
|
||||||
|
int cbRecvLength;
|
||||||
|
struct xrdp_scard_io_request recv_ior;
|
||||||
|
char *recvBuf;
|
||||||
|
|
||||||
|
LLOGLN(10, ("scard_function_transmit_return:"));
|
||||||
|
//g_hexdump(in_s->p, len);
|
||||||
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_TR) == 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_function_transmit_return: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_TR;
|
||||||
|
|
||||||
|
in_uint8s(in_s, 20);
|
||||||
|
in_uint32_le(in_s, val);
|
||||||
|
g_memset(&recv_ior, 0, sizeof(recv_ior));
|
||||||
|
if (val != 0)
|
||||||
|
{
|
||||||
|
/* pioRecvPci */
|
||||||
|
LLOGLN(0, ("scard_function_transmit_return: pioRecvPci not zero!"));
|
||||||
|
}
|
||||||
|
in_uint8s(in_s, 4);
|
||||||
|
in_uint32_le(in_s, val);
|
||||||
|
cbRecvLength = 0;
|
||||||
|
recvBuf = 0;
|
||||||
|
if (val != 0)
|
||||||
|
{
|
||||||
|
in_uint32_le(in_s, cbRecvLength);
|
||||||
|
in_uint8p(in_s, recvBuf, cbRecvLength);
|
||||||
|
}
|
||||||
|
LLOGLN(10, ("scard_function_transmit_return: cbRecvLength %d", cbRecvLength));
|
||||||
|
out_s = trans_get_out_s(con, 8192);
|
||||||
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
|
out_uint32_le(out_s, recv_ior.dwProtocol);
|
||||||
|
out_uint32_le(out_s, recv_ior.cbPciLength);
|
||||||
|
out_uint32_le(out_s, recv_ior.extra_bytes);
|
||||||
|
out_uint8a(out_s, recv_ior.extra_data, recv_ior.extra_bytes);
|
||||||
|
out_uint32_le(out_s, cbRecvLength);
|
||||||
|
out_uint8a(out_s, recvBuf, cbRecvLength);
|
||||||
|
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, 0x09); /* SCARD_TRANSMIT 0x09 */
|
||||||
|
return trans_force_write(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* returns error */
|
||||||
|
int APP_CC
|
||||||
|
scard_process_control(struct trans *con, struct stream *in_s)
|
||||||
|
{
|
||||||
|
tui32 context;
|
||||||
|
int hCard;
|
||||||
|
int send_bytes;
|
||||||
|
int recv_bytes;
|
||||||
|
int control_code;
|
||||||
|
char *send_data;
|
||||||
|
|
||||||
|
LLOGLN(10, ("scard_process_control:"));
|
||||||
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_process_control: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_CO;
|
||||||
|
LLOGLN(10, ("scard_process_control:"));
|
||||||
|
|
||||||
|
in_uint32_le(in_s, hCard);
|
||||||
|
in_uint32_le(in_s, control_code);
|
||||||
|
in_uint32_le(in_s, send_bytes);
|
||||||
|
in_uint8p(in_s, send_data, send_bytes);
|
||||||
|
in_uint32_le(in_s, recv_bytes);
|
||||||
|
|
||||||
|
context = 1;
|
||||||
|
|
||||||
|
scard_send_control(con, context, hCard, send_data, send_bytes, recv_bytes,
|
||||||
|
control_code);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* returns error */
|
||||||
|
int APP_CC
|
||||||
|
scard_function_control_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len)
|
||||||
|
{
|
||||||
|
struct stream *out_s;
|
||||||
|
int bytes;
|
||||||
|
int cbRecvLength;
|
||||||
|
char *recvBuf;
|
||||||
|
|
||||||
|
//g_hexdump(in_s->p, len);
|
||||||
|
if ((g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_CO) == 0)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_function_control_return: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_CO;
|
||||||
|
|
||||||
|
in_uint8s(in_s, 28);
|
||||||
|
in_uint32_le(in_s, cbRecvLength);
|
||||||
|
in_uint8p(in_s, recvBuf, cbRecvLength);
|
||||||
|
|
||||||
|
LLOGLN(10, ("scard_function_control_return: cbRecvLength %d", cbRecvLength));
|
||||||
|
out_s = trans_get_out_s(con, 8192);
|
||||||
|
s_push_layer(out_s, iso_hdr, 8);
|
||||||
|
out_uint32_le(out_s, cbRecvLength);
|
||||||
|
out_uint8a(out_s, recvBuf, cbRecvLength);
|
||||||
|
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, 0x0A); /* SCARD_CONTROL 0x0A */
|
||||||
|
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(10, ("scard_process_status:"));
|
||||||
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_ST)
|
||||||
|
{
|
||||||
|
LLOGLN(0, ("scard_process_status: opps"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_ST;
|
||||||
|
|
||||||
|
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(10, ("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 */
|
/* returns error */
|
||||||
int APP_CC
|
int APP_CC
|
||||||
@ -414,7 +864,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
|
|||||||
int cReaders;
|
int cReaders;
|
||||||
READER_STATE *rsa;
|
READER_STATE *rsa;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_get_status_change:"));
|
LLOGLN(10, ("scard_process_get_status_change:"));
|
||||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC)
|
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_GSC)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_process_get_status_change: opps"));
|
LLOGLN(0, ("scard_process_get_status_change: opps"));
|
||||||
@ -447,7 +897,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
|
|||||||
in_uint8a(in_s, rsa[index].atr, 36);
|
in_uint8a(in_s, rsa[index].atr, 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout "
|
LLOGLN(10, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout "
|
||||||
"%d cReaders %d", hContext, dwTimeout, cReaders));
|
"%d cReaders %d", hContext, dwTimeout, cReaders));
|
||||||
|
|
||||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_GSC;
|
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_GSC;
|
||||||
@ -474,8 +924,8 @@ scard_function_get_status_change_return(struct trans *con,
|
|||||||
tui8 atr[36];
|
tui8 atr[36];
|
||||||
struct stream *out_s;
|
struct stream *out_s;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_function_get_status_change_return:"));
|
LLOGLN(10, ("scard_function_get_status_change_return:"));
|
||||||
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)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("scard_function_establish_context_return: opps"));
|
LLOGLN(0, ("scard_function_establish_context_return: opps"));
|
||||||
@ -511,6 +961,25 @@ scard_function_get_status_change_return(struct trans *con,
|
|||||||
return 0;
|
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 */
|
/* returns error */
|
||||||
int APP_CC
|
int APP_CC
|
||||||
@ -518,26 +987,26 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
|
|||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
LLOGLN(0, ("scard_process_msg: command 0x%4.4x", command));
|
LLOGLN(10, ("scard_process_msg: command 0x%4.4x", command));
|
||||||
rv = 0;
|
rv = 0;
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case 0x01: /* SCARD_ESTABLISH_CONTEXT */
|
case 0x01: /* SCARD_ESTABLISH_CONTEXT */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_ESTABLISH_CONTEXT"));
|
LLOGLN(10, ("scard_process_msg: SCARD_ESTABLISH_CONTEXT"));
|
||||||
rv = scard_process_establish_context(con, in_s);
|
rv = scard_process_establish_context(con, in_s);
|
||||||
break;
|
break;
|
||||||
case 0x02: /* SCARD_RELEASE_CONTEXT */
|
case 0x02: /* SCARD_RELEASE_CONTEXT */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_RELEASE_CONTEXT"));
|
LLOGLN(10, ("scard_process_msg: SCARD_RELEASE_CONTEXT"));
|
||||||
rv = scard_process_release_context(con, in_s);
|
rv = scard_process_release_context(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x03: /* SCARD_LIST_READERS */
|
case 0x03: /* SCARD_LIST_READERS */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_LIST_READERS"));
|
LLOGLN(10, ("scard_process_msg: SCARD_LIST_READERS"));
|
||||||
rv = scard_process_list_readers(con, in_s);
|
rv = scard_process_list_readers(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x04: /* SCARD_CONNECT */
|
case 0x04: /* SCARD_CONNECT */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_CONNECT"));
|
LLOGLN(10, ("scard_process_msg: SCARD_CONNECT"));
|
||||||
rv = scard_process_connect(con, in_s);
|
rv = scard_process_connect(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -546,32 +1015,37 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x06: /* SCARD_DISCONNECT */
|
case 0x06: /* SCARD_DISCONNECT */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_DISCONNECT"));
|
LLOGLN(10, ("scard_process_msg: SCARD_DISCONNECT"));
|
||||||
|
rv = scard_process_disconnect(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x07: /* SCARD_BEGIN_TRANSACTION */
|
case 0x07: /* SCARD_BEGIN_TRANSACTION */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_BEGIN_TRANSACTION"));
|
LLOGLN(10, ("scard_process_msg: SCARD_BEGIN_TRANSACTION"));
|
||||||
rv = scard_process_begin_transaction(con, in_s);
|
rv = scard_process_begin_transaction(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08: /* SCARD_END_TRANSACTION */
|
case 0x08: /* SCARD_END_TRANSACTION */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_END_TRANSACTION"));
|
LLOGLN(10, ("scard_process_msg: SCARD_END_TRANSACTION"));
|
||||||
|
rv = scard_process_end_transaction(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x09: /* SCARD_TRANSMIT */
|
case 0x09: /* SCARD_TRANSMIT */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_TRANSMIT"));
|
LLOGLN(10, ("scard_process_msg: SCARD_TRANSMIT"));
|
||||||
|
rv = scard_process_transmit(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0A: /* SCARD_CONTROL */
|
case 0x0A: /* SCARD_CONTROL */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_CONTROL"));
|
LLOGLN(10, ("scard_process_msg: SCARD_CONTROL"));
|
||||||
|
rv = scard_process_control(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0B: /* SCARD_STATUS */
|
case 0x0B: /* SCARD_STATUS */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_STATUS"));
|
LLOGLN(10, ("scard_process_msg: SCARD_STATUS"));
|
||||||
|
rv = scard_process_status(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0C: /* SCARD_GET_STATUS_CHANGE */
|
case 0x0C: /* SCARD_GET_STATUS_CHANGE */
|
||||||
LLOGLN(0, ("scard_process_msg: SCARD_GET_STATUS_CHANGE"));
|
LLOGLN(10, ("scard_process_msg: SCARD_GET_STATUS_CHANGE"));
|
||||||
rv = scard_process_get_status_change(con, in_s);
|
rv = scard_process_get_status_change(con, in_s);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -605,12 +1079,11 @@ int DEFAULT_CC
|
|||||||
my_pcsc_trans_data_in(struct trans *trans)
|
my_pcsc_trans_data_in(struct trans *trans)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int id;
|
|
||||||
int size;
|
int size;
|
||||||
int command;
|
int command;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
LLOGLN(0, ("my_pcsc_trans_data_in:"));
|
LLOGLN(10, ("my_pcsc_trans_data_in:"));
|
||||||
if (trans == 0)
|
if (trans == 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -622,7 +1095,7 @@ my_pcsc_trans_data_in(struct trans *trans)
|
|||||||
s = trans_get_in_s(trans);
|
s = trans_get_in_s(trans);
|
||||||
in_uint32_le(s, size);
|
in_uint32_le(s, size);
|
||||||
in_uint32_le(s, command);
|
in_uint32_le(s, command);
|
||||||
LLOGLN(0, ("my_pcsc_trans_data_in: size %d command %d", size, command));
|
LLOGLN(10, ("my_pcsc_trans_data_in: size %d command %d", size, command));
|
||||||
error = trans_force_read(trans, size);
|
error = trans_force_read(trans, size);
|
||||||
if (error == 0)
|
if (error == 0)
|
||||||
{
|
{
|
||||||
@ -636,7 +1109,7 @@ my_pcsc_trans_data_in(struct trans *trans)
|
|||||||
int DEFAULT_CC
|
int DEFAULT_CC
|
||||||
my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
|
my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
|
||||||
{
|
{
|
||||||
LLOGLN(0, ("my_pcsc_trans_conn_in:"));
|
LLOGLN(10, ("my_pcsc_trans_conn_in:"));
|
||||||
|
|
||||||
if (trans == 0)
|
if (trans == 0)
|
||||||
{
|
{
|
||||||
@ -655,13 +1128,7 @@ my_pcsc_trans_conn_in(struct trans *trans, struct trans *new_trans)
|
|||||||
|
|
||||||
g_con = new_trans;
|
g_con = new_trans;
|
||||||
g_con->trans_data_in = my_pcsc_trans_data_in;
|
g_con->trans_data_in = my_pcsc_trans_data_in;
|
||||||
#if 1
|
|
||||||
g_con->header_size = 8;
|
g_con->header_size = 8;
|
||||||
#else
|
|
||||||
g_con->header_size = RXSHAREDSEGMENT_BYTES;
|
|
||||||
LLOGLN(0, ("my_pcsc_trans_conn_in: sizeof sharedSegmentMsg is %d",
|
|
||||||
sizeof(sharedSegmentMsg)));
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,7 +1140,6 @@ scard_pcsc_init(void)
|
|||||||
char *home;
|
char *home;
|
||||||
int disp;
|
int disp;
|
||||||
int error;
|
int error;
|
||||||
int index;
|
|
||||||
|
|
||||||
LLOGLN(0, ("scard_pcsc_init:"));
|
LLOGLN(0, ("scard_pcsc_init:"));
|
||||||
if (g_lis == 0)
|
if (g_lis == 0)
|
||||||
|
@ -38,11 +38,52 @@ int APP_CC scard_function_list_readers_return(struct trans *con,
|
|||||||
struct stream *in_s,
|
struct stream *in_s,
|
||||||
int len);
|
int len);
|
||||||
|
|
||||||
|
int APP_CC scard_function_transmit_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len);
|
||||||
|
|
||||||
|
int APP_CC scard_function_control_return(struct trans *con,
|
||||||
|
struct stream *in_s,
|
||||||
|
int len);
|
||||||
|
|
||||||
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 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,
|
||||||
int len);
|
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 */
|
#endif /* end #ifndef _SMARTCARD_PCSC_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user