Merge branch 'master' of github.com:neutrinolabs/xrdp
This commit is contained in:
commit
5e005bf26c
129
common/trans.c
129
common/trans.c
@ -90,6 +90,86 @@ trans_get_wait_objs(struct trans *self, tbus *objs, int *count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
trans_get_wait_objs_rw(struct trans *self,
|
||||
tbus *robjs, int *rcount,
|
||||
tbus *wobjs, int *wcount)
|
||||
{
|
||||
if (self == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (self->status != TRANS_STATUS_UP)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
robjs[*rcount] = self->sck;
|
||||
(*rcount)++;
|
||||
|
||||
if (self->wait_s != 0)
|
||||
{
|
||||
wobjs[*wcount] = self->sck;
|
||||
(*wcount)++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
send_waiting(struct trans *self, int block)
|
||||
{
|
||||
struct stream *temp_s;
|
||||
int bytes;
|
||||
int sent;
|
||||
int timeout;
|
||||
int cont;
|
||||
|
||||
timeout = block ? 100 : 0;
|
||||
cont = 1;
|
||||
while (cont)
|
||||
{
|
||||
if (self->wait_s != 0)
|
||||
{
|
||||
temp_s = self->wait_s;
|
||||
if (g_tcp_can_send(self->sck, timeout))
|
||||
{
|
||||
bytes = (int) (temp_s->end - temp_s->p);
|
||||
sent = g_tcp_send(self->sck, temp_s->p, bytes, 0);
|
||||
if (sent > 0)
|
||||
{
|
||||
temp_s->p += sent;
|
||||
if (temp_s->p >= temp_s->end)
|
||||
{
|
||||
self->wait_s = (struct stream *) (temp_s->next_packet);
|
||||
free_stream(temp_s);
|
||||
}
|
||||
}
|
||||
else if (sent == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!g_tcp_last_error_would_block(self->sck))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
cont = block;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
trans_check_wait_objs(struct trans *self)
|
||||
@ -203,6 +283,12 @@ trans_check_wait_objs(struct trans *self)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (send_waiting(self, 0) != 0)
|
||||
{
|
||||
/* error */
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -291,6 +377,12 @@ trans_force_write_s(struct trans *self, struct stream *out_s)
|
||||
size = (int)(out_s->end - out_s->data);
|
||||
total = 0;
|
||||
|
||||
if (send_waiting(self, 1) != 0)
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (total < size)
|
||||
{
|
||||
sent = g_tcp_send(self->sck, out_s->data + total, size - total, 0);
|
||||
@ -342,6 +434,43 @@ trans_force_write(struct trans *self)
|
||||
return trans_force_write_s(self, self->out_s);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
trans_write_copy(struct trans *self)
|
||||
{
|
||||
int size;
|
||||
struct stream *out_s;
|
||||
struct stream *wait_s;
|
||||
struct stream *temp_s;
|
||||
|
||||
if (self->status != TRANS_STATUS_UP)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
out_s = self->out_s;
|
||||
size = (int)(out_s->end - out_s->data);
|
||||
make_stream(wait_s);
|
||||
init_stream(wait_s, size);
|
||||
out_uint8a(wait_s, out_s->data, size);
|
||||
s_mark_end(wait_s);
|
||||
wait_s->p = wait_s->data;
|
||||
if (self->wait_s == 0)
|
||||
{
|
||||
self->wait_s = wait_s;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_s = self->wait_s;
|
||||
while (temp_s->next_packet != 0)
|
||||
{
|
||||
temp_s = (struct stream *) (temp_s->next_packet);
|
||||
}
|
||||
temp_s->next_packet = wait_s;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
trans_connect(struct trans *self, const char *server, const char *port,
|
||||
|
@ -54,6 +54,7 @@ struct trans
|
||||
struct stream* out_s;
|
||||
char* listen_filename;
|
||||
tis_term is_term; /* used to test for exit */
|
||||
struct stream* wait_s;
|
||||
};
|
||||
|
||||
struct trans* APP_CC
|
||||
@ -73,6 +74,8 @@ trans_force_read(struct trans* self, int size);
|
||||
int APP_CC
|
||||
trans_force_write(struct trans* self);
|
||||
int APP_CC
|
||||
trans_write_copy(struct trans* self);
|
||||
int APP_CC
|
||||
trans_connect(struct trans* self, const char* server, const char* port,
|
||||
int timeout);
|
||||
int APP_CC
|
||||
|
@ -8,7 +8,8 @@ EXTRA_DIST = \
|
||||
drdynvc.h \
|
||||
rail.h \
|
||||
sound.h \
|
||||
xcommon.h
|
||||
xcommon.h \
|
||||
mlog.h
|
||||
|
||||
EXTRA_DEFINES =
|
||||
EXTRA_INCLUDES =
|
||||
@ -51,7 +52,8 @@ xrdp_chansrv_SOURCES = \
|
||||
xcommon.c \
|
||||
drdynvc.c \
|
||||
chansrv_fuse.c \
|
||||
irp.c
|
||||
irp.c \
|
||||
fifo.c
|
||||
|
||||
xrdp_chansrv_LDFLAGS = \
|
||||
$(EXTRA_FLAGS)
|
||||
|
@ -293,11 +293,11 @@ send_data_from_chan_item(struct chan_item *chan_item)
|
||||
out_uint32_le(s, cod->s->size);
|
||||
out_uint8a(s, cod->s->p, size);
|
||||
s_mark_end(s);
|
||||
LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- "
|
||||
LOGM((LOG_LEVEL_DEBUG, "chansrv::send_data_from_chan_item: -- "
|
||||
"size %d chan_flags 0x%8.8x", size, chan_flags));
|
||||
g_sent = 1;
|
||||
error = trans_force_write(g_con_trans);
|
||||
|
||||
error = trans_write_copy(g_con_trans);
|
||||
if (error != 0)
|
||||
{
|
||||
return 1;
|
||||
@ -392,7 +392,7 @@ send_init_response_message(void)
|
||||
out_uint32_le(s, 2); /* msg id */
|
||||
out_uint32_le(s, 8); /* size */
|
||||
s_mark_end(s);
|
||||
return trans_force_write(g_con_trans);
|
||||
return trans_write_copy(g_con_trans);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -415,7 +415,7 @@ send_channel_setup_response_message(void)
|
||||
out_uint32_le(s, 4); /* msg id */
|
||||
out_uint32_le(s, 8); /* size */
|
||||
s_mark_end(s);
|
||||
return trans_force_write(g_con_trans);
|
||||
return trans_write_copy(g_con_trans);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -438,7 +438,7 @@ send_channel_data_response_message(void)
|
||||
out_uint32_le(s, 6); /* msg id */
|
||||
out_uint32_le(s, 8); /* size */
|
||||
s_mark_end(s);
|
||||
return trans_force_write(g_con_trans);
|
||||
return trans_write_copy(g_con_trans);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -637,7 +637,7 @@ process_message_channel_data(struct stream *s)
|
||||
if (chan_flags & 2) /* last */
|
||||
{
|
||||
s_mark_end(ls);
|
||||
trans_force_write(g_api_con_trans);
|
||||
trans_write_copy(g_api_con_trans);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1041,7 +1041,9 @@ THREAD_RV THREAD_CC
|
||||
channel_thread_loop(void *in_val)
|
||||
{
|
||||
tbus objs[32];
|
||||
tbus wobjs[32];
|
||||
int num_objs;
|
||||
int num_wobjs;
|
||||
int timeout;
|
||||
int error;
|
||||
THREAD_RV rv;
|
||||
@ -1055,12 +1057,13 @@ channel_thread_loop(void *in_val)
|
||||
{
|
||||
timeout = -1;
|
||||
num_objs = 0;
|
||||
num_wobjs = 0;
|
||||
objs[num_objs] = g_term_event;
|
||||
num_objs++;
|
||||
trans_get_wait_objs(g_lis_trans, objs, &num_objs);
|
||||
trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
|
||||
|
||||
while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0)
|
||||
while (g_obj_wait(objs, num_objs, wobjs, num_wobjs, timeout) == 0)
|
||||
{
|
||||
check_timeout();
|
||||
if (g_is_wait_obj_set(g_term_event))
|
||||
@ -1135,10 +1138,12 @@ channel_thread_loop(void *in_val)
|
||||
xfuse_check_wait_objs();
|
||||
timeout = -1;
|
||||
num_objs = 0;
|
||||
num_wobjs = 0;
|
||||
objs[num_objs] = g_term_event;
|
||||
num_objs++;
|
||||
trans_get_wait_objs(g_lis_trans, objs, &num_objs);
|
||||
trans_get_wait_objs(g_con_trans, objs, &num_objs);
|
||||
trans_get_wait_objs_rw(g_con_trans, objs, &num_objs,
|
||||
wobjs, &num_wobjs);
|
||||
trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
|
||||
trans_get_wait_objs(g_api_con_trans, objs, &num_objs);
|
||||
xcommon_get_wait_objs(objs, &num_objs, &timeout);
|
||||
|
@ -102,6 +102,7 @@ void xfuse_devredir_cb_file_close(void *vp) {}
|
||||
#include "os_calls.h"
|
||||
#include "chansrv_fuse.h"
|
||||
#include "list.h"
|
||||
#include "fifo.h"
|
||||
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
@ -223,6 +224,16 @@ struct dir_info
|
||||
int index;
|
||||
};
|
||||
|
||||
/* queue FUSE opendir commands so we run only one at a time */
|
||||
struct opendir_req
|
||||
{
|
||||
fuse_req_t req;
|
||||
fuse_ino_t ino;
|
||||
struct fuse_file_info *fi;
|
||||
};
|
||||
|
||||
FIFO g_fifo_opendir;
|
||||
|
||||
static struct list *g_req_list = 0;
|
||||
static struct xrdp_fs g_xrdp_fs; /* an inst of xrdp file system */
|
||||
static char *g_mount_point = 0; /* our FUSE mount point */
|
||||
@ -338,19 +349,22 @@ static void xfuse_cb_create(fuse_req_t req, fuse_ino_t parent,
|
||||
static void xfuse_cb_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
/* clipboard calls */
|
||||
int clipboard_request_file_data(int stream_id, int lindex, int offset,
|
||||
int request_bytes);
|
||||
|
||||
static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
|
||||
int to_set, struct fuse_file_info *fi);
|
||||
|
||||
static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
static void xfuse_cb_releasedir(fuse_req_t req, fuse_ino_t ino,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
/* clipboard calls */
|
||||
int clipboard_request_file_data(int stream_id, int lindex, int offset,
|
||||
int request_bytes);
|
||||
|
||||
/* misc calls */
|
||||
static void xfuse_mark_as_stale(int pinode);
|
||||
static void xfuse_delete_stale_entries(int pinode);
|
||||
@ -403,6 +417,9 @@ int xfuse_init()
|
||||
if (xfuse_init_xrdp_fs())
|
||||
return -1;
|
||||
|
||||
/* setup FIFOs */
|
||||
fifo_init(&g_fifo_opendir, 30);
|
||||
|
||||
/* setup FUSE callbacks */
|
||||
g_memset(&g_xfuse_ops, 0, sizeof(g_xfuse_ops));
|
||||
g_xfuse_ops.lookup = xfuse_cb_lookup;
|
||||
@ -424,6 +441,8 @@ int xfuse_init()
|
||||
|
||||
fuse_opt_add_arg(&args, "xrdp-chansrv");
|
||||
fuse_opt_add_arg(&args, g_fuse_root_path);
|
||||
//fuse_opt_add_arg(&args, "-s"); /* single threaded mode */
|
||||
//fuse_opt_add_arg(&args, "-d"); /* debug mode */
|
||||
|
||||
if (xfuse_init_lib(&args))
|
||||
{
|
||||
@ -444,6 +463,7 @@ int xfuse_init()
|
||||
int xfuse_deinit()
|
||||
{
|
||||
xfuse_deinit_xrdp_fs();
|
||||
fifo_deinit(&g_fifo_opendir);
|
||||
|
||||
if (g_ch != 0)
|
||||
{
|
||||
@ -901,12 +921,11 @@ static int xfuse_deinit_xrdp_fs()
|
||||
|
||||
static int xfuse_is_inode_valid(int ino)
|
||||
{
|
||||
/* our lowest ino is FIRST_INODE */
|
||||
if (ino < FIRST_INODE)
|
||||
/* is ino present in our table? */
|
||||
if ((ino < FIRST_INODE) || (ino >= g_xrdp_fs.next_node))
|
||||
return 0;
|
||||
|
||||
/* is ino present in our table? */
|
||||
if (ino >= g_xrdp_fs.next_node)
|
||||
if (g_xrdp_fs.inode_table[ino] == NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@ -989,6 +1008,11 @@ static void xfuse_dump_fs()
|
||||
|
||||
log_debug("found %d entries", g_xrdp_fs.num_entries - FIRST_INODE);
|
||||
|
||||
#if 0
|
||||
log_debug("not dumping xrdp fs");
|
||||
return;
|
||||
#endif
|
||||
|
||||
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
|
||||
{
|
||||
if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
|
||||
@ -1229,6 +1253,9 @@ static int xfuse_delete_file_with_xinode(XRDP_INODE *xinode)
|
||||
if ((xinode == NULL) || (xinode->mode & S_IFDIR))
|
||||
return -1;
|
||||
|
||||
log_always("deleting: inode=%d name=%s", xinode->inode, xinode->name);
|
||||
log_debug("deleting: inode=%d name=%s", xinode->inode, xinode->name);
|
||||
|
||||
g_xrdp_fs.inode_table[xinode->parent_inode]->nentries--;
|
||||
g_xrdp_fs.inode_table[xinode->inode] = NULL;
|
||||
free(xinode);
|
||||
@ -1281,6 +1308,12 @@ static int xfuse_recursive_delete_dir_with_xinode(XRDP_INODE *xinode)
|
||||
if ((xinode == NULL) || (xinode->mode & S_IFREG))
|
||||
return -1;
|
||||
|
||||
log_always("recursively deleting dir with inode=%d name=%s",
|
||||
xinode->inode, xinode->name);
|
||||
|
||||
log_debug("recursively deleting dir with inode=%d name=%s",
|
||||
xinode->inode, xinode->name);
|
||||
|
||||
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
|
||||
{
|
||||
if ((xip = g_xrdp_fs.inode_table[i]) == NULL)
|
||||
@ -1342,60 +1375,6 @@ static void xfuse_update_xrdpfs_size()
|
||||
g_xrdp_fs.inode_table = vp;
|
||||
}
|
||||
|
||||
/* LK_TODO do we still need this function */
|
||||
#if 0
|
||||
static void xfuse_enum_dir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
||||
off_t off, struct fuse_file_info *fi)
|
||||
{
|
||||
XRDP_INODE *xinode;
|
||||
XRDP_INODE *xinode1;
|
||||
struct dirbuf b;
|
||||
int first_time = 1;
|
||||
int i;
|
||||
|
||||
memset(&b, 0, sizeof(struct dirbuf));
|
||||
|
||||
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
|
||||
{
|
||||
if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
|
||||
continue;
|
||||
|
||||
/* match parent inode */
|
||||
if (xinode->parent_inode != ino)
|
||||
continue;
|
||||
|
||||
if (first_time)
|
||||
{
|
||||
first_time = 0;
|
||||
if (ino == 1)
|
||||
{
|
||||
xfuse_dirbuf_add(req, &b, ".", 1);
|
||||
xfuse_dirbuf_add(req, &b, "..", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
xinode1 = g_xrdp_fs.inode_table[ino];
|
||||
xfuse_dirbuf_add(req, &b, ".", ino);
|
||||
xfuse_dirbuf_add(req, &b, "..", xinode1->parent_inode);
|
||||
}
|
||||
}
|
||||
|
||||
xfuse_dirbuf_add(req, &b, xinode->name, xinode->inode);
|
||||
}
|
||||
|
||||
if (!first_time)
|
||||
{
|
||||
if (off < b.size)
|
||||
fuse_reply_buf(req, b.p + off, min(b.size - off, size));
|
||||
else
|
||||
fuse_reply_buf(req, NULL, 0);
|
||||
}
|
||||
|
||||
if (b.p)
|
||||
free(b.p);
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
** **
|
||||
** callbacks for devredir **
|
||||
@ -1464,8 +1443,9 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
|
||||
|
||||
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
|
||||
{
|
||||
XFUSE_INFO *fip;
|
||||
struct dir_info *di;
|
||||
XFUSE_INFO *fip;
|
||||
struct dir_info *di;
|
||||
struct opendir_req *odreq;
|
||||
|
||||
log_debug("vp=%p IoStatus=0x%x", vp, IoStatus);
|
||||
|
||||
@ -1473,7 +1453,7 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
|
||||
if (fip == NULL)
|
||||
{
|
||||
log_debug("fip is NULL");
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (IoStatus != 0)
|
||||
@ -1506,6 +1486,22 @@ done:
|
||||
|
||||
if (fip)
|
||||
free(fip);
|
||||
|
||||
/* remove current request */
|
||||
g_free(fifo_remove(&g_fifo_opendir));
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* process next request */
|
||||
odreq = fifo_peek(&g_fifo_opendir);
|
||||
if (!odreq)
|
||||
return;
|
||||
|
||||
if (xfuse_proc_opendir_req(odreq->req, odreq->ino, odreq->fi))
|
||||
g_free(fifo_remove(&g_fifo_opendir)); /* req failed */
|
||||
else
|
||||
break; /* req has been queued */
|
||||
}
|
||||
}
|
||||
|
||||
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId,
|
||||
@ -1903,15 +1899,19 @@ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
|
||||
}
|
||||
|
||||
xino = g_xrdp_fs.inode_table[ino];
|
||||
if (!xino)
|
||||
{
|
||||
log_debug("****** invalid ino=%d", (int) ino);
|
||||
fuse_reply_err(req, EBADF);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&stbuf, 0, sizeof(stbuf));
|
||||
stbuf.st_ino = ino;
|
||||
stbuf.st_mode = xino->mode;
|
||||
stbuf.st_nlink = xino->nlink;
|
||||
stbuf.st_size = xino->size;
|
||||
|
||||
fuse_reply_attr(req, &stbuf, 1.0);
|
||||
log_debug("exiting");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1977,8 +1977,7 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
||||
int i;
|
||||
int first_time;
|
||||
|
||||
log_debug("req=%p inode=%d name=%s size=%d offset=%d", req, ino,
|
||||
g_xrdp_fs.inode_table[ino]->name, size, off);
|
||||
log_debug("req=%p inode=%d size=%d offset=%d", req, ino, size, off);
|
||||
|
||||
/* do we have a valid inode? */
|
||||
if (!xfuse_is_inode_valid(ino))
|
||||
@ -2014,6 +2013,12 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
||||
{
|
||||
first_time = 0;
|
||||
ti = g_xrdp_fs.inode_table[ino];
|
||||
if (!ti)
|
||||
{
|
||||
log_debug("****** g_xrdp_fs.inode_table[%d] is NULL", ino);
|
||||
fuse_reply_buf(req, NULL, 0);
|
||||
return;
|
||||
}
|
||||
xfuse_dirbuf_add1(req, &b, ".", ino);
|
||||
xfuse_dirbuf_add1(req, &b, "..", ti->parent_inode);
|
||||
}
|
||||
@ -2451,6 +2456,12 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
|
||||
|
||||
/* if ino points to a dir, fail the open request */
|
||||
xinode = g_xrdp_fs.inode_table[ino];
|
||||
if (!xinode)
|
||||
{
|
||||
log_debug("****** g_xrdp_fs.inode_table[%d] is NULL", ino);
|
||||
fuse_reply_err(req, EBADF);
|
||||
return;
|
||||
}
|
||||
if (xinode->mode & S_IFDIR)
|
||||
{
|
||||
log_debug("reading a dir not allowed!");
|
||||
@ -2491,8 +2502,6 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
|
||||
fip->name[1023] = 0;
|
||||
fip->reply_type = RT_FUSE_REPLY_OPEN;
|
||||
|
||||
/* LK_TODO need to handle open permissions */
|
||||
|
||||
/* we want path minus 'root node of the share' */
|
||||
if ((cptr = strchr(full_path, '/')) == NULL)
|
||||
{
|
||||
@ -2532,6 +2541,12 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
|
||||
}
|
||||
|
||||
XRDP_INODE *xinode = g_xrdp_fs.inode_table[ino];
|
||||
if (!xinode)
|
||||
{
|
||||
log_debug("****** g_xrdp_fs.inode_table[%d] is NULL", ino);
|
||||
fuse_reply_err(req, 0);
|
||||
return;
|
||||
}
|
||||
if (xinode->is_loc_resource)
|
||||
{
|
||||
/* specified file is a local resource */
|
||||
@ -2748,7 +2763,12 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
|
||||
return;
|
||||
}
|
||||
|
||||
xinode = g_xrdp_fs.inode_table[ino];
|
||||
if ((xinode = g_xrdp_fs.inode_table[ino]) == NULL)
|
||||
{
|
||||
log_debug("g_xrdp_fs.inode_table[%d] is NULL", ino);
|
||||
fuse_reply_err(req, EBADF);
|
||||
return;
|
||||
}
|
||||
|
||||
if (to_set & FUSE_SET_ATTR_MODE)
|
||||
{
|
||||
@ -2813,8 +2833,39 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
|
||||
fuse_reply_attr(req, &st, 1.0); /* LK_TODO just faking for now */
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dir listing
|
||||
*****************************************************************************/
|
||||
static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct opendir_req *odreq;
|
||||
|
||||
/* save request */
|
||||
odreq = malloc(sizeof(struct opendir_req));
|
||||
odreq->req = req;
|
||||
odreq->ino = ino;
|
||||
odreq->fi = fi;
|
||||
|
||||
if (fifo_is_empty(&g_fifo_opendir))
|
||||
{
|
||||
fifo_insert(&g_fifo_opendir, odreq);
|
||||
xfuse_proc_opendir_req(req, ino, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* place req in FIFO; xfuse_devredir_cb_enum_dir_done() will handle it */
|
||||
fifo_insert(&g_fifo_opendir, odreq);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the next opendir req
|
||||
*
|
||||
* @return 0 of the request was sent for remote lookup, -1 otherwise
|
||||
*****************************************************************************/
|
||||
static int xfuse_proc_opendir_req(fuse_req_t req, fuse_ino_t ino,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct dir_info *di;
|
||||
XRDP_INODE *xinode;
|
||||
@ -2823,19 +2874,26 @@ static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino,
|
||||
char full_path[4096];
|
||||
char *cptr;
|
||||
|
||||
log_debug("inode=%d name=%s", ino, g_xrdp_fs.inode_table[ino]->name);
|
||||
log_debug("inode=%d", ino);
|
||||
|
||||
if (!xfuse_is_inode_valid(ino))
|
||||
{
|
||||
log_error("inode %d is not valid", ino);
|
||||
fuse_reply_err(req, EBADF);
|
||||
return;
|
||||
g_free(fifo_remove(&g_fifo_opendir));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ino == 1)
|
||||
goto done; /* special case; enumerate top level dir */
|
||||
|
||||
xinode = g_xrdp_fs.inode_table[ino];
|
||||
if ((xinode = g_xrdp_fs.inode_table[ino]) == NULL)
|
||||
{
|
||||
log_debug("g_xrdp_fs.inode_table[%d] is NULL", ino);
|
||||
fuse_reply_err(req, EBADF);
|
||||
g_free(fifo_remove(&g_fifo_opendir));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xinode->is_loc_resource)
|
||||
goto done;
|
||||
@ -2846,7 +2904,8 @@ static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino,
|
||||
if (xinode->is_synced)
|
||||
{
|
||||
xfuse_enum_dir(req, ino, size, off, fi);
|
||||
return;
|
||||
g_free(fifo_remove(&g_fifo_opendir));
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2867,7 +2926,8 @@ do_remote_lookup:
|
||||
{
|
||||
log_error("system out of memory");
|
||||
fuse_reply_err(req, ENOMEM);
|
||||
return;
|
||||
g_free(fifo_remove(&g_fifo_opendir));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fip->req = req;
|
||||
@ -2900,7 +2960,7 @@ do_remote_lookup:
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
return 0;
|
||||
|
||||
done:
|
||||
|
||||
@ -2908,6 +2968,8 @@ done:
|
||||
di->index = FIRST_INODE;
|
||||
fi->fh = (long) di;
|
||||
fuse_reply_open(req, fi);
|
||||
g_free(fifo_remove(&g_fifo_opendir));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1098,7 +1098,11 @@ dev_redir_file_open(void *fusep, tui32 device_id, char *path,
|
||||
#if 1
|
||||
/* without the 0x00000010 rdesktop opens files in */
|
||||
/* O_RDONLY instead of O_RDWR mode */
|
||||
DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA | DA_SYNCHRONIZE | 0x00000010;
|
||||
if (mode & O_RDWR)
|
||||
DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA | DA_SYNCHRONIZE | 0x00000010;
|
||||
else
|
||||
DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE;
|
||||
|
||||
CreateOptions = CO_FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
CreateDisposition = CD_FILE_OPEN; // WAS 1
|
||||
#else
|
||||
|
255
sesman/chansrv/fifo.c
Normal file
255
sesman/chansrv/fifo.c
Normal file
@ -0,0 +1,255 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* FIFO implementation to store a pointer to a user struct */
|
||||
|
||||
/* module based logging */
|
||||
#define MODULE_NAME "FIFO "
|
||||
#define LOCAL_DEBUG
|
||||
|
||||
#include "fifo.h"
|
||||
#include "mlog.h"
|
||||
|
||||
/**
|
||||
* Initialize a FIFO that grows as required
|
||||
*
|
||||
* @param fp pointer to a FIFO
|
||||
* @param num_entries initial size
|
||||
*
|
||||
* @return 0 on success, -1 on failure
|
||||
*****************************************************************************/
|
||||
int
|
||||
fifo_init(FIFO* fp, int num_entries)
|
||||
{
|
||||
log_debug_high("entered");
|
||||
|
||||
/* validate params */
|
||||
if (!fp)
|
||||
{
|
||||
log_debug_high("invalid parameters");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (num_entries < 1)
|
||||
num_entries = 10;
|
||||
|
||||
fp->rd_ptr = 0;
|
||||
fp->wr_ptr = 0;
|
||||
fp->user_data = (long *) g_malloc(sizeof(long) * num_entries);
|
||||
|
||||
if (fp->user_data)
|
||||
{
|
||||
fp->entries = num_entries;
|
||||
log_debug_low("FIFO created; rd_ptr=%d wr_ptr=%d entries=%d",
|
||||
fp->rd_ptr, fp->wr_ptr, fp->entries);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("FIFO create error; system out of memory");
|
||||
fp->entries = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deinit FIFO and release resources
|
||||
*
|
||||
* @param fp FIFO to deinit
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*****************************************************************************/
|
||||
int
|
||||
fifo_deinit(FIFO* fp)
|
||||
{
|
||||
log_debug_high("entered");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
log_debug_high("FIFO is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fp->user_data)
|
||||
{
|
||||
g_free(fp->user_data);
|
||||
fp->user_data = 0;
|
||||
}
|
||||
|
||||
fp->rd_ptr = 0;
|
||||
fp->wr_ptr = 0;
|
||||
fp->entries = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if FIFO is empty
|
||||
*
|
||||
* @param fp FIFO
|
||||
*
|
||||
* @return 1 if FIFO is empty, 0 otherwise
|
||||
*****************************************************************************/
|
||||
int
|
||||
fifo_is_empty(FIFO* fp)
|
||||
{
|
||||
log_debug_high("entered");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
log_debug_high("FIFO is null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (fp->rd_ptr == fp->wr_ptr) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert an item at the end
|
||||
*
|
||||
* @param fp FIFO
|
||||
* @param data data to insert into FIFO
|
||||
*
|
||||
* @param 0 on success, -1 on error
|
||||
*****************************************************************************/
|
||||
|
||||
int
|
||||
fifo_insert(FIFO* fp, void* data)
|
||||
{
|
||||
long* lp;
|
||||
int next_val; /* next value for wr_ptr */
|
||||
int i;
|
||||
|
||||
log_debug_high("entered");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
log_debug_high("FIFO is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
next_val = fp->wr_ptr + 1;
|
||||
if (next_val >= fp->entries)
|
||||
next_val = 0;
|
||||
|
||||
if (next_val == fp->rd_ptr)
|
||||
{
|
||||
/* FIFO is full, expand it by 10 entries */
|
||||
lp = (long *) g_malloc(sizeof(long) * (fp->entries + 10));
|
||||
if (!lp)
|
||||
{
|
||||
log_debug_low("FIFO full; cannot expand, no memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_debug_low("FIFO full, expanding by 10 entries");
|
||||
|
||||
/* copy old data new location */
|
||||
for (i = 0; i < (fp->entries - 1); i++)
|
||||
{
|
||||
lp[i] = fp->user_data[fp->rd_ptr++];
|
||||
if (fp->rd_ptr >= fp->entries)
|
||||
fp->rd_ptr = 0;
|
||||
}
|
||||
|
||||
/* update pointers */
|
||||
fp->rd_ptr = 0;
|
||||
fp->wr_ptr = fp->entries - 1;
|
||||
next_val = fp->entries;
|
||||
fp->entries += 10;
|
||||
|
||||
/* free old data */
|
||||
g_free(fp->user_data);
|
||||
fp->user_data = lp;
|
||||
}
|
||||
|
||||
log_debug_low("inserting data at index %d", fp->wr_ptr);
|
||||
|
||||
fp->user_data[fp->wr_ptr] = (long) data;
|
||||
fp->wr_ptr = next_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the head
|
||||
*
|
||||
* @param fp FIFO
|
||||
*
|
||||
* @param data on success, NULL on error
|
||||
*****************************************************************************/
|
||||
void*
|
||||
fifo_remove(FIFO* fp)
|
||||
{
|
||||
long data;
|
||||
|
||||
log_debug_high("entered");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
log_debug_high("FIFO is null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fp->rd_ptr == fp->wr_ptr)
|
||||
{
|
||||
log_debug_high("FIFO is empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug_low("removing data at index %d", fp->rd_ptr);
|
||||
|
||||
data = fp->user_data[fp->rd_ptr++];
|
||||
|
||||
if (fp->rd_ptr >= fp->entries)
|
||||
{
|
||||
log_debug_high("FIFO rd_ptr wrapped around");
|
||||
fp->rd_ptr = 0;
|
||||
}
|
||||
|
||||
return (void *) data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return item from head, but do not remove it
|
||||
*
|
||||
* @param fp FIFO
|
||||
*
|
||||
* @param data on success, NULL on error
|
||||
*****************************************************************************/
|
||||
void*
|
||||
fifo_peek(FIFO* fp)
|
||||
{
|
||||
long data;
|
||||
|
||||
log_debug_high("entered\n");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
log_debug_high("FIFO is null\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fp->rd_ptr == fp->wr_ptr)
|
||||
{
|
||||
log_debug_high("FIFO is empty\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug_low("peeking data at index %d\n", fp->rd_ptr);
|
||||
|
||||
return (void *) fp->user_data[fp->rd_ptr];
|
||||
}
|
35
sesman/chansrv/fifo.h
Normal file
35
sesman/chansrv/fifo.h
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* FIFO implementation to store a pointer to a user struct */
|
||||
|
||||
typedef struct fifo
|
||||
{
|
||||
long* user_data;
|
||||
int rd_ptr;
|
||||
int wr_ptr;
|
||||
int entries;
|
||||
} FIFO;
|
||||
|
||||
int fifo_init(FIFO* fp, int num_entries);
|
||||
int fifo_deinit(FIFO* fp);
|
||||
int fifo_is_empty(FIFO* fp);
|
||||
int fifo_insert(FIFO* fp, void* data);
|
||||
void* fifo_remove(FIFO* fp);
|
||||
void* fifo_peek(FIFO* fp);
|
||||
|
112
sesman/chansrv/mlog.h
Normal file
112
sesman/chansrv/mlog.h
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* module based logging */
|
||||
|
||||
#ifndef _MLOG_H
|
||||
#define _MLOG_H
|
||||
|
||||
/*
|
||||
* Note1: to enable debug messages, in your .c file, #define LOCAL_DEBUG
|
||||
* BEFORE including this file
|
||||
*
|
||||
* Note2: in your .c file, #define MODULE_NAME, 8 chars long, to print each
|
||||
* log entry with your module name
|
||||
*/
|
||||
|
||||
#define LOG_ERROR 0
|
||||
#define LOG_INFO 1
|
||||
#define LOG_DEBUG_LOW 2
|
||||
#define LOG_DEBUG_HIGH 3
|
||||
#define LOG_LEVEL LOG_ERROR
|
||||
|
||||
/*
|
||||
* print always
|
||||
*/
|
||||
|
||||
#define log_error(_params...) \
|
||||
do \
|
||||
{ \
|
||||
g_write("[%10.10u]: %s %s: %d: ERROR: ", g_time3(), \
|
||||
MODULE_NAME, __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define log_always(_params...) \
|
||||
do \
|
||||
{ \
|
||||
g_write("[%10.10u]: %s %s: %d: ALWAYS: ", g_time3(), \
|
||||
MODULE_NAME, __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
/*
|
||||
* print conditionally
|
||||
*/
|
||||
|
||||
#ifdef LOCAL_DEBUG
|
||||
#define log_info(_params...) \
|
||||
do \
|
||||
{ \
|
||||
if (LOG_INFO <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: %s %s: %d: INFO: ", g_time3(), \
|
||||
MODULE_NAME, __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
} \
|
||||
while(0)
|
||||
#else
|
||||
#define log_info(_params...)
|
||||
#endif
|
||||
|
||||
#ifdef LOCAL_DEBUG
|
||||
#define log_debug_low(_params...) \
|
||||
do \
|
||||
{ \
|
||||
if (LOG_DEBUG_LOW <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: %s %s: %d: DEBUG: ", g_time3(), \
|
||||
MODULE_NAME, __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
} \
|
||||
while(0)
|
||||
#else
|
||||
#define log_debug_low(_params...)
|
||||
#endif
|
||||
|
||||
#ifdef LOCAL_DEBUG
|
||||
#define log_debug_high(_params...) \
|
||||
do \
|
||||
{ \
|
||||
if (LOG_DEBUG_HIGH <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: %s %s: %d: DEBUG: ", g_time3(), \
|
||||
MODULE_NAME, __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
} \
|
||||
while(0)
|
||||
#else
|
||||
#define log_debug_high(_params...)
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef _MLOG_H */
|
@ -52,11 +52,22 @@ typedef struct _SCARD_IO_REQUEST
|
||||
#define LLOGLN(_level, _args) \
|
||||
do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
|
||||
|
||||
#define SCARD_ESTABLISH_CONTEXT 0x01
|
||||
#define SCARD_RELEASE_CONTEXT 0x02
|
||||
#define SCARD_LIST_READERS 0x03
|
||||
#define SCARD_CONNECT 0x04
|
||||
#define SCARD_GET_STATUS_CHANGE 0x0C
|
||||
#define SCARD_ESTABLISH_CONTEXT 0x01
|
||||
#define SCARD_RELEASE_CONTEXT 0x02
|
||||
#define SCARD_LIST_READERS 0x03
|
||||
#define SCARD_CONNECT 0x04
|
||||
#define SCARD_RECONNECT 0x05
|
||||
#define SCARD_DISCONNECT 0x06
|
||||
#define SCARD_BEGIN_TRANSACTION 0x07
|
||||
#define SCARD_END_TRANSACTION 0x08
|
||||
#define SCARD_TRANSMIT 0x09
|
||||
#define SCARD_CONTROL 0x0A
|
||||
#define SCARD_STATUS 0x0B
|
||||
#define SCARD_GET_STATUS_CHANGE 0x0C
|
||||
#define SCARD_CANCEL 0x0D
|
||||
#define SCARD_CANCEL_TRANSACTION 0x0E
|
||||
#define SCARD_GET_ATTRIB 0x0F
|
||||
#define SCARD_SET_ATTRIB 0x10
|
||||
|
||||
#define SCARD_S_SUCCESS 0x00000000
|
||||
#define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001)
|
||||
@ -417,7 +428,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
if (code != SCARD_RELEASE_CONTEXT)
|
||||
if (code != SCARD_CONNECT)
|
||||
{
|
||||
LLOGLN(0, ("SCardConnect: error, bad code"));
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
@ -467,6 +478,11 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
|
||||
PCSC_API LONG
|
||||
SCardBeginTransaction(SCARDHANDLE hCard)
|
||||
{
|
||||
char msg[256];
|
||||
int code;
|
||||
int bytes;
|
||||
int status;
|
||||
|
||||
LLOGLN(0, ("SCardBeginTransaction:"));
|
||||
if (g_sck == -1)
|
||||
{
|
||||
@ -474,8 +490,30 @@ SCardBeginTransaction(SCARDHANDLE hCard)
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
pthread_mutex_lock(&g_mutex);
|
||||
SET_UINT32(msg, 0, hCard);
|
||||
if (send_message(SCARD_BEGIN_TRANSACTION, msg, 4) != 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardBeginTransaction: error, send_message"));
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
bytes = 256;
|
||||
if (get_message(&code, msg, &bytes) != 0)
|
||||
{
|
||||
LLOGLN(0, ("SCardBeginTransaction: error, get_message"));
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
if ((code != SCARD_BEGIN_TRANSACTION) || (bytes != 4))
|
||||
{
|
||||
LLOGLN(0, ("SCardBeginTransaction: error, bad code"));
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
pthread_mutex_unlock(&g_mutex);
|
||||
return SCARD_S_SUCCESS;
|
||||
status = GET_UINT32(msg, 0);
|
||||
LLOGLN(10, ("SCardBeginTransaction: got status 0x%8.8x", status));
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1307,6 +1307,8 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
||||
|
||||
/* insert reader name */
|
||||
num_chars = g_mbstowcs(w_reader_name, rs->reader_name, 99);
|
||||
xstream_wr_u32_le(s, 0);
|
||||
xstream_wr_u32_le(s, 0);
|
||||
xstream_wr_u32_le(s, num_chars);
|
||||
if (wide)
|
||||
{
|
||||
@ -1322,6 +1324,7 @@ scard_send_Connect(IRP* irp, tui32 context, int wide, READER_STATE* rs)
|
||||
xstream_wr_u8(s, w_reader_name[index]);
|
||||
}
|
||||
}
|
||||
align_s(s, 4);
|
||||
|
||||
/* insert context */
|
||||
xstream_wr_u32_le(s, 4);
|
||||
@ -2058,6 +2061,7 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
|
||||
tui32 IoStatus)
|
||||
{
|
||||
tui32 len;
|
||||
struct trans *con;
|
||||
|
||||
log_debug("entered");
|
||||
|
||||
@ -2077,7 +2081,9 @@ scard_handle_Connect_Return(struct stream *s, IRP *irp,
|
||||
|
||||
/* get OutputBufferLen */
|
||||
xstream_rd_u32_le(s, len);
|
||||
|
||||
con = (struct trans *) (irp->user_data);
|
||||
scard_function_connect_return(con, s, len);
|
||||
devredir_irp_delete(irp);
|
||||
log_debug("leaving");
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
#define XRDP_PCSC_STATE_GOT_RC (1 << 2) /* release context */
|
||||
#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_BT (1 << 5) /* begin transaction */
|
||||
|
||||
/* TODO: put this in con */
|
||||
static int g_xrdp_pcsc_state = XRDP_PCSC_STATE_NONE;
|
||||
@ -347,6 +348,61 @@ scard_process_connect(struct trans *con, struct stream *in_s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int APP_CC
|
||||
scard_function_connect_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_C) == 0)
|
||||
{
|
||||
LLOGLN(0, ("scard_function_connect_return: opps"));
|
||||
return 1;
|
||||
}
|
||||
g_xrdp_pcsc_state &= ~XRDP_PCSC_STATE_GOT_C;
|
||||
in_uint8s(in_s, 36);
|
||||
in_uint32_le(in_s, dwActiveProtocol);
|
||||
in_uint8s(in_s, 36);
|
||||
in_uint32_le(in_s, hCard);
|
||||
out_s = trans_get_out_s(con, 8192);
|
||||
s_push_layer(out_s, iso_hdr, 8);
|
||||
out_uint32_le(out_s, hCard);
|
||||
out_uint32_le(out_s, dwActiveProtocol);
|
||||
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, 0x04); /* SCARD_CONNECT 0x04 */
|
||||
return trans_force_write(con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
scard_process_begin_transaction(struct trans *con, struct stream *in_s)
|
||||
{
|
||||
int hCard;
|
||||
|
||||
LLOGLN(0, ("scard_process_begin_transaction:"));
|
||||
if (g_xrdp_pcsc_state & XRDP_PCSC_STATE_GOT_BT)
|
||||
{
|
||||
LLOGLN(0, ("scard_process_begin_transaction: opps"));
|
||||
return 1;
|
||||
}
|
||||
g_xrdp_pcsc_state |= XRDP_PCSC_STATE_GOT_BT;
|
||||
in_uint32_le(in_s, hCard);
|
||||
LLOGLN(0, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
|
||||
scard_send_begin_transaction(con, hCard);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int APP_CC
|
||||
@ -495,6 +551,7 @@ scard_process_msg(struct trans *con, struct stream *in_s, int command)
|
||||
|
||||
case 0x07: /* SCARD_BEGIN_TRANSACTION */
|
||||
LLOGLN(0, ("scard_process_msg: SCARD_BEGIN_TRANSACTION"));
|
||||
rv = scard_process_begin_transaction(con, in_s);
|
||||
break;
|
||||
|
||||
case 0x08: /* SCARD_END_TRANSACTION */
|
||||
|
@ -41,5 +41,8 @@ int APP_CC scard_function_list_readers_return(struct trans *con,
|
||||
int APP_CC scard_function_get_status_change_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
int APP_CC scard_function_connect_return(struct trans *con,
|
||||
struct stream *in_s,
|
||||
int len);
|
||||
|
||||
#endif /* end #ifndef _SMARTCARD_PCSC_H */
|
||||
|
@ -769,9 +769,11 @@ rdpDestroyPixmap(PixmapPtr pPixmap)
|
||||
{
|
||||
if (XRDP_IS_OS(priv))
|
||||
{
|
||||
rdpup_remove_os_bitmap(priv->rdpindex);
|
||||
rdpup_delete_os_surface(priv->rdpindex);
|
||||
draw_item_remove_all(priv);
|
||||
if (priv->rdpindex >= 0)
|
||||
{
|
||||
rdpup_remove_os_bitmap(priv->rdpindex);
|
||||
rdpup_delete_os_surface(priv->rdpindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1112,7 +1114,7 @@ rdpCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr pOldRegion)
|
||||
if ((num_clip_rects > 16) && (num_reg_rects > 16))
|
||||
{
|
||||
box3 = RegionExtents(®);
|
||||
rdpup_send_area(10, box3->x1 + dx, box3->y1 + dy,
|
||||
rdpup_send_area(0, box3->x1 + dx, box3->y1 + dy,
|
||||
box3->x2 - box3->x1,
|
||||
box3->y2 - box3->y1);
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ struct rdpup_os_bitmap
|
||||
int stamp;
|
||||
};
|
||||
|
||||
#define USE_MAX_OS_BYTES 1
|
||||
#define MAX_OS_BYTES (16 * 1024 * 1024)
|
||||
static struct rdpup_os_bitmap *g_os_bitmaps = 0;
|
||||
static int g_max_os_bitmaps = 0;
|
||||
@ -232,6 +233,7 @@ rdpup_disconnect(void)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns -1 on error */
|
||||
int
|
||||
rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
|
||||
{
|
||||
@ -241,13 +243,16 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
|
||||
int oldest_index;
|
||||
int this_bytes;
|
||||
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap:"));
|
||||
if (!g_connected)
|
||||
{
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: test error 1"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (g_os_bitmaps == 0)
|
||||
{
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: test error 2"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -255,8 +260,8 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
|
||||
if (this_bytes > MAX_OS_BYTES)
|
||||
{
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: error, too big this_bytes %d "
|
||||
"width %d height %d", this_bytes,
|
||||
pixmap->drawable.height, pixmap->drawable.height));
|
||||
"width %d height %d", this_bytes,
|
||||
pixmap->drawable.height, pixmap->drawable.height));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -297,11 +302,14 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: too many pixmaps removing "
|
||||
"oldest_index %d", oldest_index));
|
||||
rdpup_remove_os_bitmap(oldest_index);
|
||||
g_os_bitmaps[index].used = 1;
|
||||
g_os_bitmaps[index].pixmap = pixmap;
|
||||
g_os_bitmaps[index].priv = priv;
|
||||
g_os_bitmaps[index].stamp = g_os_bitmap_stamp;
|
||||
rdpup_delete_os_surface(oldest_index);
|
||||
g_os_bitmaps[oldest_index].used = 1;
|
||||
g_os_bitmaps[oldest_index].pixmap = pixmap;
|
||||
g_os_bitmaps[oldest_index].priv = priv;
|
||||
g_os_bitmaps[oldest_index].stamp = g_os_bitmap_stamp;
|
||||
g_os_bitmap_stamp++;
|
||||
g_pixmap_num_used++;
|
||||
rv = oldest_index;
|
||||
@ -310,12 +318,14 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
|
||||
|
||||
if (rv < 0)
|
||||
{
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: test error 3"));
|
||||
return rv;
|
||||
}
|
||||
|
||||
g_os_bitmap_alloc_size += this_bytes;
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: this_bytes %d g_os_bitmap_alloc_size %d",
|
||||
this_bytes, g_os_bitmap_alloc_size));
|
||||
#if USE_MAX_OS_BYTES
|
||||
while (g_os_bitmap_alloc_size > MAX_OS_BYTES)
|
||||
{
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: must delete g_pixmap_num_used %d",
|
||||
@ -326,7 +336,7 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
|
||||
index = 0;
|
||||
while (index < g_max_os_bitmaps)
|
||||
{
|
||||
if (g_os_bitmaps[index].used && g_os_bitmaps[index].stamp < oldest)
|
||||
if (g_os_bitmaps[index].used && (g_os_bitmaps[index].stamp < oldest))
|
||||
{
|
||||
oldest = g_os_bitmaps[index].stamp;
|
||||
oldest_index = index;
|
||||
@ -346,6 +356,7 @@ rdpup_add_os_bitmap(PixmapPtr pixmap, rdpPixmapPtr priv)
|
||||
rdpup_remove_os_bitmap(oldest_index);
|
||||
rdpup_delete_os_surface(oldest_index);
|
||||
}
|
||||
#endif
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: new bitmap index %d", rv));
|
||||
LLOGLN(10, ("rdpup_add_os_bitmap: g_pixmap_num_used %d "
|
||||
"g_os_bitmap_stamp 0x%8.8x", g_pixmap_num_used, g_os_bitmap_stamp));
|
||||
@ -365,11 +376,13 @@ rdpup_remove_os_bitmap(int rdpindex)
|
||||
|
||||
if (g_os_bitmaps == 0)
|
||||
{
|
||||
LLOGLN(10, ("rdpup_remove_os_bitmap: test error 1"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((rdpindex < 0) && (rdpindex >= g_max_os_bitmaps))
|
||||
{
|
||||
LLOGLN(10, ("rdpup_remove_os_bitmap: test error 2"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -396,7 +409,8 @@ rdpup_remove_os_bitmap(int rdpindex)
|
||||
LLOGLN(0, ("rdpup_remove_os_bitmap: error"));
|
||||
}
|
||||
|
||||
LLOGLN(10, (" g_pixmap_num_used %d", g_pixmap_num_used));
|
||||
LLOGLN(10, ("rdpup_remove_os_bitmap: g_pixmap_num_used %d",
|
||||
g_pixmap_num_used));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -404,10 +418,6 @@ rdpup_remove_os_bitmap(int rdpindex)
|
||||
int
|
||||
rdpup_update_os_use(int rdpindex)
|
||||
{
|
||||
PixmapPtr pixmap;
|
||||
rdpPixmapPtr priv;
|
||||
int this_bytes;
|
||||
|
||||
LLOGLN(10, ("rdpup_update_use: index %d stamp %d",
|
||||
rdpindex, g_os_bitmaps[rdpindex].stamp));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user