common: fix conflict

This commit is contained in:
speidy 2013-10-30 19:47:26 +02:00
commit 0d2a4ce195
10 changed files with 1222 additions and 192 deletions

View File

@ -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];

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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:

View File

@ -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

View File

@ -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");
} }

View File

@ -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);

View File

@ -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)

View File

@ -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 */