devel

Conflicts:
	libxrdp/xrdp_sec.c
ulab-next-nosound
Idan Freiberg 10 years ago
commit 16929efb05

@ -364,7 +364,7 @@ file_by_name_read_sections(const char *file_name, struct list *names)
fd = g_file_open(file_name);
if (fd < 1)
if (fd < 0)
{
return 1;
}
@ -405,7 +405,7 @@ file_by_name_read_section(const char *file_name, const char *section,
fd = g_file_open(file_name);
if (fd < 1)
if (fd < 0)
{
return 1;
}

@ -284,6 +284,7 @@ internalReadConfiguration(const char *inFilename, const char *applicationName)
if (ret != LOG_STARTUP_OK)
{
g_file_close(fd);
return ret;
}
@ -301,6 +302,7 @@ internalReadConfiguration(const char *inFilename, const char *applicationName)
if (ret != LOG_STARTUP_OK)
{
g_file_close(fd);
return ret;
}

@ -471,8 +471,11 @@ g_tcp_socket(void)
{
option_value = 0;
option_len = sizeof(option_value);
setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&option_value,
option_len);
if (setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&option_value,
option_len) < 0)
{
log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
}
}
}
#endif
@ -484,8 +487,11 @@ g_tcp_socket(void)
{
option_value = 1;
option_len = sizeof(option_value);
setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
option_len);
if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
option_len) < 0)
{
log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
}
}
}
@ -498,8 +504,11 @@ g_tcp_socket(void)
{
option_value = 1024 * 32;
option_len = sizeof(option_value);
setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
option_len);
if (setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
option_len) < 0)
{
log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
}
}
}
@ -785,7 +794,10 @@ g_tcp_set_non_blocking(int sck)
#else
i = fcntl(sck, F_GETFL);
i = i | O_NONBLOCK;
fcntl(sck, F_SETFL, i);
if (fcntl(sck, F_SETFL, i) < 0)
{
log_message(LOG_LEVEL_ERROR, "g_tcp_set_non_blocking: fcntl() failed\n");
}
#endif
return 0;
}
@ -1421,7 +1433,12 @@ g_set_wait_obj(tbus obj)
return 1;
}
sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size);
if (sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size) < 0)
{
close(s);
return 1;
}
close(s);
return 0;
#endif
@ -1934,8 +1951,7 @@ g_mkdir(const char *dirname)
#if defined(_WIN32)
return 0;
#else
mkdir(dirname, S_IRWXU);
return 0;
return mkdir(dirname, S_IRWXU);
#endif
}

@ -122,6 +122,8 @@ struct xrdp_client_info
int mcs_early_capability_flags;
int max_fastpath_frag_bytes;
int capture_code;
int capture_format;
char certificate[1024];
char key_file[1024];

@ -367,11 +367,12 @@ save_all(char *e_data, int e_len, char *n_data, int n_len,
fd = g_file_open(filename);
if (fd > 0)
if (fd != -1)
{
if (g_file_write(fd, "[keys]\n", 7) == -1)
{
g_writeln("problem writing to %s, maybe no rights", filename);
g_file_close(fd);
return 1;
}

@ -1 +0,0 @@
Subproject commit 7b04ca9c54aeddbdaf4bf945cea81f4efb8847e7

@ -310,15 +310,18 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
}
DEBUG(("libxrdp_send_palette sending palette"));
/* clear orders */
libxrdp_orders_force_send(session);
make_stream(s);
init_stream(s, 8192);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
LLOGLN(10, ("libxrdp_send_palette: fastpath"));
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
{
free_stream(s);
return 1;
}
}
@ -347,6 +350,7 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_PALETTE) != 0)
{
free_stream(s);
return 1;
}
}
@ -356,6 +360,7 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
RDP_DATA_PDU_UPDATE);
}
free_stream(s);
/* send the orders palette too */
libxrdp_orders_init(session);
libxrdp_orders_send_palette(session, palette, 0);
@ -777,6 +782,7 @@ libxrdp_set_pointer(struct xrdp_session *session, int cache_idx)
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_CACHED) != 0)
{
free_stream(s);
return 1;
}
}

@ -223,6 +223,7 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
if (trans_force_write_s(self->trans, s) != 0)
{
free_stream(s);
return 1;
}

@ -743,6 +743,7 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
LLOGLN(10, ("xrdp_rdp_send_data_update_sync: fastpath"));
if (xrdp_rdp_init_fastpath(self, s) != 0)
{
free_stream(s);
return 1;
}
}
@ -765,6 +766,7 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
if (xrdp_rdp_send_fastpath(self, s,
FASTPATH_UPDATETYPE_SYNCHRONIZE) != 0)
{
free_stream(s);
return 1;
}
}

@ -1595,6 +1595,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
client_info = &(self->rdp_layer->client_info);
DEBUG(("processing channels, channel_code is %d", client_info->channel_code));
/* this is an option set in xrdp.ini */
@ -1618,16 +1619,19 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
for (index = 0; index < num_channels; index++)
{
struct mcs_channel_item *channel_item;
channel_item = (struct mcs_channel_item *)
g_malloc(sizeof(struct mcs_channel_item), 1);
if (!s_check_rem(s, 12))
{
g_free(channel_item);
return 1;
}
in_uint8a(s, channel_item->name, 8);
in_uint32_le(s, channel_item->flags);
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
list_add_item(self->mcs_layer->channel_list, (tintptr)channel_item);
list_add_item(self->mcs_layer->channel_list, (tintptr) channel_item);
DEBUG(("got channel flags %8.8x name %s", channel_item->flags,
channel_item->name));
}

@ -19,6 +19,7 @@
*/
#include "rdp.h"
#include "common/log.h"
/*****************************************************************************/
struct rdp_mcs *APP_CC
@ -598,7 +599,8 @@ failed"));
int APP_CC
rdp_mcs_init(struct rdp_mcs *self, struct stream *s)
{
rdp_iso_init(self->iso_layer, s);
if (rdp_iso_init(self->iso_layer, s))
log_message(LOG_LEVEL_ERROR, "rdp_mcs.c: rdp_iso_init() failed");
s_push_layer(s, mcs_hdr, 8);
return 0;
}

@ -427,6 +427,12 @@ rdp_rdp_process_color_pointer_pdu(struct rdp_rdp *self, struct stream *s)
return 1;
}
/* there are only 32 cursors */
if (cache_idx > 31)
{
return 1;
}
cursor = self->cursors + cache_idx;
in_uint16_le(s, cursor->x);
in_uint16_le(s, cursor->y);
@ -457,7 +463,7 @@ rdp_rdp_process_cached_pointer_pdu(struct rdp_rdp *self, struct stream *s)
in_uint16_le(s, cache_idx);
if (cache_idx >= sizeof(self->cursors) / sizeof(cursor))
if (cache_idx > 31)
{
return 1;
}

@ -812,7 +812,8 @@ my_api_trans_data_in(struct trans *trans)
in_uint8s(s, 12);
in_uint32_le(s, bytes_read);
init_stream(s, bytes_read);
trans_force_read(trans, bytes_read);
if (trans_force_read(trans, bytes_read))
log_message(LOG_LEVEL_ERROR, "chansrv.c: error reading from transport");
}
else if (g_tcp_select(trans->sck, 0) & 1)
{

@ -73,7 +73,7 @@ int xfuse_create_share(tui32 device_id, char *dirname) { r
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId) {}
void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length) {}
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length) {}
void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) {}
int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) {}
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) {}
void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus) {}
void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus) {}
@ -1422,7 +1422,7 @@ static void xfuse_update_xrdpfs_size()
* Add a file or directory to xrdp file system
*****************************************************************************/
void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
{
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
XRDP_INODE *xip = NULL;
@ -1430,13 +1430,14 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
if ((fip == NULL) || (xinode == NULL))
{
log_error("fip or xinode are NULL");
return;
return -1;
}
if (!xfuse_is_inode_valid(fip->inode))
{
log_error("inode %d is not valid", fip->inode);
return;
g_free(xinode);
return -1;
}
log_debug("parent_inode=%d name=%s", fip->inode, xinode->name);
@ -1444,8 +1445,8 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
/* if filename is . or .. don't add it */
if ((strcmp(xinode->name, ".") == 0) || (strcmp(xinode->name, "..") == 0))
{
free(xinode);
return;
g_free(xinode);
return -1;
}
xfuse_dump_fs();
@ -1454,9 +1455,9 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
{
log_debug("inode=%d name=%s already exists in xrdp_fs; not adding it",
fip->inode, xinode->name);
free(xinode);
g_free(xinode);
xip->stale = 0;
return;
return -1;
}
xinode->parent_inode = fip->inode;
@ -1473,6 +1474,7 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
xfuse_update_xrdpfs_size();
xfuse_dump_fs();
return 0;
}
/**
@ -1779,6 +1781,8 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus)
new_xinode = xfuse_get_inode_from_pinode_name(fip->new_inode,
fip->new_name);
if (new_xinode)
{
if (new_xinode->mode & S_IFREG)
xfuse_delete_file_with_xinode(new_xinode);
else
@ -1786,6 +1790,7 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus)
new_xinode = NULL;
}
}
old_xinode = xfuse_get_inode_from_pinode_name(fip->inode, fip->name);
if (old_xinode == NULL)

@ -57,7 +57,7 @@ int xfuse_file_contents_size(int stream_id, int file_size);
int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex);
/* functions that are invoked from devredir */
void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode);
int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode);
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus);
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId);
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length);

@ -1048,8 +1048,11 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
log_debug("clipboard_process_format_announce: formatId 0x%8.8x "
"wszFormatName [%s] clip_msg_len %d", formatId, desc,
clip_msg_len);
if (g_num_formatIds <= 15)
{
g_formatIds[g_num_formatIds] = formatId;
g_num_formatIds++;
}
if (g_num_formatIds > 15)
{
log_debug("clipboard_process_format_announce: max formats");

@ -446,7 +446,13 @@ clipboard_send_file_data(int streamId, int lindex,
full_fn);
return 1;
}
g_file_seek(fd, nPositionLow);
if (g_file_seek(fd, nPositionLow) < 0)
{
log_message(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error "
"in file: %s\n", full_fn);
g_file_close(fd);
return 1;
}
make_stream(s);
init_stream(s, cbRequested + 64);
size = g_file_read(fd, s->data + 12, cbRequested);

@ -790,10 +790,14 @@ dev_redir_proc_device_iocompletion(struct stream *s)
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data == NULL)
{
log_error("fuse_data is NULL");
}
else
{
xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length);
devredir_irp_delete(irp);
}
break;
case CID_WRITE:
@ -802,10 +806,14 @@ dev_redir_proc_device_iocompletion(struct stream *s)
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data == NULL)
{
log_error("fuse_data is NULL");
}
else
{
xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length);
devredir_irp_delete(irp);
}
break;
case CID_CLOSE:
@ -879,7 +887,7 @@ dev_redir_proc_query_dir_response(IRP *irp,
tui32 IoStatus)
{
FUSE_DATA *fuse_data = NULL;
XRDP_INODE *xinode = NULL;
XRDP_INODE *xinode;
tui32 Length;
tui32 NextEntryOffset;
@ -1017,6 +1025,7 @@ dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path)
irp->CompletionId = g_completion_id++;
irp->completion_type = CID_CREATE_DIR_REQ;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
devredir_fuse_data_enqueue(irp, fusep);
@ -1069,6 +1078,7 @@ dev_redir_file_open(void *fusep, tui32 device_id, char *path,
irp->CompletionId = g_completion_id++;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
devredir_fuse_data_enqueue(irp, fusep);
@ -1174,6 +1184,7 @@ devredir_rmdir_or_file(void *fusep, tui32 device_id, char *path, int mode)
irp->CompletionId = g_completion_id++;
irp->completion_type = CID_RMDIR_OR_FILE;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
devredir_fuse_data_enqueue(irp, fusep);
@ -1216,6 +1227,7 @@ devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
{
log_error("no IRP found with FileId = %d", FileId);
xfuse_devredir_cb_read_file(fusep, NULL, 0);
xstream_free(s);
return -1;
}
@ -1224,6 +1236,7 @@ devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
{
/* system out of memory */
xfuse_devredir_cb_read_file(fusep, NULL, 0);
xstream_free(s);
return -1;
}
new_irp->FileId = 0;
@ -1268,6 +1281,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
{
log_error("no IRP found with FileId = %d", FileId);
xfuse_devredir_cb_write_file(fusep, NULL, 0);
xstream_free(s);
return -1;
}
@ -1276,6 +1290,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
{
/* system out of memory */
xfuse_devredir_cb_write_file(fusep, NULL, 0);
xstream_free(s);
return -1;
}
new_irp->FileId = 0;

@ -739,7 +739,7 @@ rail_win_get_state(Window win)
(unsigned char **)&data,
&nitems);
if (data || nitems > 0)
if (data && nitems > 0)
{
rv = *(unsigned long *)data;
XFree(data);
@ -1254,6 +1254,7 @@ rail_win_send_text(Window win)
else
{
LOG(0, ("chansrv::rail_win_send_text: error rail_get_window_data_safe failed"));
g_free(data);
return 1;
}
if (data && len > 0)

@ -861,11 +861,6 @@ scard_make_new_ioctl(IRP *irp, tui32 ioctl)
struct stream *s;
xstream_new(s, 1024 * 4);
if (s == NULL)
{
log_error("system out of memory");
return s;
}
devredir_insert_DeviceIoRequest(s,
irp->DeviceId,

@ -603,6 +603,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
{
LLOGLN(0, ("scard_process_list_readers: "
"get_pcsc_context_by_app_context failed"));
g_free(groups);
return 1;
}
pcscListReaders = g_malloc(sizeof(struct pcsc_list_readers), 1);
@ -1489,6 +1490,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
{
LLOGLN(0, ("scard_process_get_status_change: "
"get_pcsc_context_by_app_context failed"));
g_free(rsa);
return 1;
}
scard_send_get_status_change(user_data,

@ -1132,7 +1132,8 @@ sound_sndsrvr_source_data_in(struct trans *trans)
return 1;
ts = trans_get_in_s(trans);
trans_force_read(trans, 3);
if (trans_force_read(trans, 3))
log_message(LOG_LEVEL_ERROR, "sound.c: error reading from transport");
ts->p = ts->data + 8;
in_uint8(ts, cmd);
@ -1189,7 +1190,6 @@ sound_sndsrvr_source_data_in(struct trans *trans)
s_mark_end(s);
trans_force_write_s(trans, s);
xstream_free(s);
}
else if (cmd == PA_CMD_START_REC)
{
@ -1200,5 +1200,7 @@ sound_sndsrvr_source_data_in(struct trans *trans)
sound_input_stop_recording();
}
xstream_free(s);
return 0;
}

@ -129,7 +129,11 @@ env_set_user(char *username, char *passwd_file, int display,
{
/* if no auth_file_path is set, then we go for
$HOME/.vnc/sesman_username_passwd */
g_mkdir(".vnc");
if (g_mkdir(".vnc") < 0)
{
log_message(LOG_LEVEL_ERROR,
"env_set_user: error creating .vnc dir");
}
g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
}
else

@ -215,6 +215,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount,
if (cmd != 42)
{
g_free(ds);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}

@ -164,6 +164,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
{
log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
g_free(ds);
return SCP_CLIENT_STATE_NETWORK_ERR;
}
@ -180,6 +181,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
if (cmd != SCP_CMD_MNG_LIST) /* session list */
{
log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
g_free(ds);
return SCP_CLIENT_STATE_SEQUENCE_ERR;
}

@ -195,8 +195,6 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
parseCommonStates(e, "scp_v1s_list_sessions()");
break;
}
g_free(slist);
}
/* resource management */
@ -208,6 +206,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
/* cleanup */
scp_session_destroy(s);
auth_end(data);
g_free(slist);
}
static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f)

@ -308,9 +308,17 @@ main(int argc, char **argv)
g_file_close(1);
g_file_close(2);
g_file_open("/dev/null");
g_file_open("/dev/null");
g_file_open("/dev/null");
if (g_file_open("/dev/null") < 0)
{
}
if (g_file_open("/dev/null") < 0)
{
}
if (g_file_open("/dev/null") < 0)
{
}
}
/* initializing locks */
@ -361,7 +369,11 @@ main(int argc, char **argv)
/* make sure the /tmp/.X11-unix directory exist */
if (!g_directory_exist("/tmp/.X11-unix"))
{
g_create_dir("/tmp/.X11-unix");
if (!g_create_dir("/tmp/.X11-unix"))
{
log_message(LOG_LEVEL_ERROR,
"sesman.c: error creating dir /tmp/.X11-unix");
}
g_chmod_hex("/tmp/.X11-unix", 0x1777);
}

@ -759,8 +759,12 @@ session_start_fork(int width, int height, int bpp, char *username,
/*THREAD-FIX release chain lock */
lock_chain_release();
return display;
}
g_free(temp->item);
g_free(temp);
return display;
}
@ -1003,6 +1007,7 @@ session_get_bypid(int pid)
"pid %d is null!", pid);
/*THREAD-FIX release chain lock */
lock_chain_release();
g_free(dummy);
return 0;
}
@ -1021,6 +1026,7 @@ session_get_bypid(int pid)
/*THREAD-FIX release chain lock */
lock_chain_release();
g_free(dummy);
return 0;
}

@ -86,6 +86,7 @@ sig_sesman_reload_cfg(int sig)
if (config_read(cfg) != 0)
{
log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
g_free(cfg);
return;
}

@ -179,16 +179,16 @@ void cmndList(struct SCP_CONNECTION *c)
(dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \
(dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute);
}
if (0 != dsl)
{
g_free(dsl);
}
}
else
{
printf("No sessions.\n");
}
if (0 != dsl)
{
g_free(dsl);
}
}
void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s)

@ -39,9 +39,216 @@
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#define RDP_MAX_TILES 1024
/******************************************************************************/
static int
rdpLimitRects(RegionPtr reg, int max_rects, BoxPtr *rects)
{
int nrects;
nrects = REGION_NUM_RECTS(reg);
if (nrects > max_rects)
{
nrects = 1;
*rects = rdpRegionExtents(reg);
}
else
{
*rects = REGION_RECTS(reg);
}
return nrects;
}
/******************************************************************************/
/* copy rects with no error checking */
static int
rdpCopyBox_a8r8g8b8_to_a8r8g8b8(void *src, int src_stride, int srcx, int srcy,
void *dst, int dst_stride, int dstx, int dsty,
BoxPtr rects, int num_rects)
{
char *s8;
char *d8;
int index;
int jndex;
int bytes;
int height;
BoxPtr box;
for (index = 0; index < num_rects; index++)
{
box = rects + index;
s8 = ((char *) src) + (box->y1 - srcy) * src_stride;
s8 += (box->x1 - srcx) * 4;
d8 = ((char *) dst) + (box->y1 - dsty) * dst_stride;
d8 += (box->x1 - dstx) * 4;
bytes = box->x2 - box->x1;
bytes *= 4;
height = box->y2 - box->y1;
for (jndex = 0; jndex < height; jndex++)
{
memcpy(d8, s8, bytes);
d8 += dst_stride;
s8 += src_stride;
}
}
return 0;
}
/******************************************************************************/
static int
rdpFillBox_yuvalp(int ax, int ay,
void *dst, int dst_stride)
{
dst = ((char *) dst) + (ay << 8) * (dst_stride >> 8) + (ax << 8);
memset(dst, 0, 64 * 64 * 4);
return 0;
}
/******************************************************************************/
/* copy rects with no error checking
* convert ARGB32 to 64x64 linear planar YUVA */
/* http://msdn.microsoft.com/en-us/library/ff635643.aspx
* 0.299 -0.168935 0.499813
* 0.587 -0.331665 -0.418531
* 0.114 0.50059 -0.081282
y = r * 0.299000 + g * 0.587000 + b * 0.114000;
u = r * -0.168935 + g * -0.331665 + b * 0.500590;
v = r * 0.499813 + g * -0.418531 + b * -0.081282; */
/* 19595 38470 7471
-11071 -21736 32807
32756 -27429 -5327 */
static int
rdpCopyBox_a8r8g8b8_to_yuvalp(int ax, int ay,
void *src, int src_stride,
void *dst, int dst_stride,
BoxPtr rects, int num_rects)
{
char *s8;
char *d8;
char *yptr;
char *uptr;
char *vptr;
char *aptr;
int *s32;
int index;
int jndex;
int kndex;
int width;
int height;
int pixel;
int a;
int r;
int g;
int b;
int y;
int u;
int v;
BoxPtr box;
dst = ((char *) dst) + (ay << 8) * (dst_stride >> 8) + (ax << 8);
for (index = 0; index < num_rects; index++)
{
box = rects + index;
s8 = ((char *) src) + box->y1 * src_stride;
s8 += box->x1 * 4;
d8 = ((char *) dst) + (box->y1 - ay) * 64;
d8 += box->x1 - ax;
width = box->x2 - box->x1;
height = box->y2 - box->y1;
for (jndex = 0; jndex < height; jndex++)
{
s32 = (int *) s8;
yptr = d8;
uptr = yptr + 64 * 64;
vptr = uptr + 64 * 64;
aptr = vptr + 64 * 64;
kndex = 0;
while (kndex < width)
{
pixel = *(s32++);
a = (pixel >> 24) & 0xff;
r = (pixel >> 16) & 0xff;
g = (pixel >> 8) & 0xff;
b = (pixel >> 0) & 0xff;
y = (r * 19595 + g * 38470 + b * 7471) >> 16;
u = (r * -11071 + g * -21736 + b * 32807) >> 16;
v = (r * 32756 + g * -27429 + b * -5327) >> 16;
y = y - 128;
y = max(y, -128);
u = max(u, -128);
v = max(v, -128);
y = min(y, 127);
u = min(u, 127);
v = min(v, 127);
*(yptr++) = y;
*(uptr++) = u;
*(vptr++) = v;
*(aptr++) = a;
kndex++;
}
d8 += 64;
s8 += src_stride;
}
}
return 0;
}
/******************************************************************************/
/* copy rects with no error checking */
static int
rdpCopyBox_a8r8g8b8_to_a8b8g8r8(void *src, int src_stride,
void *dst, int dst_stride,
BoxPtr rects, int num_rects)
{
char *s8;
char *d8;
int index;
int jndex;
int kndex;
int bytes;
int width;
int height;
int red;
int green;
int blue;
BoxPtr box;
unsigned int *s32;
unsigned int *d32;
for (index = 0; index < num_rects; index++)
{
box = rects + index;
s8 = ((char *) src) + box->y1 * src_stride;
s8 += box->x1 * 4;
d8 = ((char *) dst) + box->y1 * dst_stride;
d8 += box->x1 * 4;
bytes = box->x2 - box->x1;
bytes *= 4;
width = box->x2 - box->x1;
height = box->y2 - box->y1;
for (jndex = 0; jndex < height; jndex++)
{
s32 = (unsigned int *) s8;
d32 = (unsigned int *) d8;
for (kndex = 0; kndex < width; kndex++)
{
SPLITCOLOR32(red, green, blue, *s32);
*d32 = COLOR24(red, green, blue);
s32++;
d32++;
}
d8 += dst_stride;
s8 += src_stride;
}
}
return 0;
}
/******************************************************************************/
static Bool
rdpCapture0(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
rdpCapture0(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
@ -52,15 +259,13 @@ rdpCapture0(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
RegionRec reg;
char *src_rect;
char *dst_rect;
int num_regions;
int bytespp;
int num_rects;
int src_bytespp;
int dst_bytespp;
int width;
int height;
int src_offset;
int dst_offset;
int bytes;
int i;
int j;
int k;
@ -69,7 +274,6 @@ rdpCapture0(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
int blue;
Bool rv;
unsigned int *s32;
unsigned int *d32;
unsigned short *d16;
unsigned char *d8;
@ -84,27 +288,18 @@ rdpCapture0(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
rdpRegionInit(&reg, &rect, 0);
rdpRegionIntersect(&reg, in_reg, &reg);
num_regions = REGION_NUM_RECTS(&reg);
if (num_regions > max_rects)
{
num_regions = 1;
psrc_rects = rdpRegionExtents(&reg);
}
else
{
psrc_rects = REGION_RECTS(&reg);
}
if (num_regions < 1)
psrc_rects = 0;
num_rects = rdpLimitRects(&reg, max_rects, &psrc_rects);
if (num_rects < 1)
{
rdpRegionUninit(&reg);
return FALSE;
}
*num_out_rects = num_regions;
*num_out_rects = num_rects;
*out_rects = (BoxPtr) g_malloc(sizeof(BoxRec) * num_regions, 0);
for (i = 0; i < num_regions; i++)
*out_rects = (BoxPtr) g_malloc(sizeof(BoxRec) * num_rects, 0);
for (i = 0; i < num_rects; i++)
{
rect = psrc_rects[i];
(*out_rects)[i] = rect;
@ -112,78 +307,22 @@ rdpCapture0(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8r8g8b8))
{
bytespp = 4;
for (i = 0; i < num_regions; i++)
{
/* get rect to copy */
rect = (*out_rects)[i];
/* get rect dimensions */
width = rect.x2 - rect.x1;
height = rect.y2 - rect.y1;
/* point to start of each rect in respective memory */
src_offset = rect.y1 * src_stride + rect.x1 * bytespp;
dst_offset = rect.y1 * dst_stride + rect.x1 * bytespp;
src_rect = src + src_offset;
dst_rect = dst + dst_offset;
/* bytes per line */
bytes = width * bytespp;
/* copy one line at a time */
for (j = 0; j < height; j++)
{
memcpy(dst_rect, src_rect, bytes);
src_rect += src_stride;
dst_rect += dst_stride;
}
}
rdpCopyBox_a8r8g8b8_to_a8r8g8b8(src, src_stride, 0, 0,
dst, dst_stride, 0, 0,
psrc_rects, num_rects);
}
else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8b8g8r8))
{
src_bytespp = 4;
dst_bytespp = 4;
for (i = 0; i < num_regions; i++)
{
/* get rect to copy */
rect = (*out_rects)[i];
/* get rect dimensions */
width = rect.x2 - rect.x1;
height = rect.y2 - rect.y1;
/* point to start of each rect in respective memory */
src_offset = rect.y1 * src_stride + rect.x1 * src_bytespp;
dst_offset = rect.y1 * dst_stride + rect.x1 * dst_bytespp;
src_rect = src + src_offset;
dst_rect = dst + dst_offset;
/* copy one line at a time */
for (j = 0; j < height; j++)
{
s32 = (unsigned int *) src_rect;
d32 = (unsigned int *) dst_rect;
for (k = 0; k < width; k++)
{
SPLITCOLOR32(red, green, blue, *s32);
*d32 = COLOR24(red, green, blue);
s32++;
d32++;
}
src_rect += src_stride;
dst_rect += dst_stride;
}
}
rdpCopyBox_a8r8g8b8_to_a8b8g8r8(src, src_stride,
dst, dst_stride,
psrc_rects, num_rects);
}
else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_r5g6b5))
{
src_bytespp = 4;
dst_bytespp = 2;
for (i = 0; i < num_regions; i++)
for (i = 0; i < num_rects; i++)
{
/* get rect to copy */
rect = (*out_rects)[i];
@ -220,7 +359,7 @@ rdpCapture0(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
src_bytespp = 4;
dst_bytespp = 2;
for (i = 0; i < num_regions; i++)
for (i = 0; i < num_rects; i++)
{
/* get rect to copy */
rect = (*out_rects)[i];
@ -257,7 +396,7 @@ rdpCapture0(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
src_bytespp = 4;
dst_bytespp = 1;
for (i = 0; i < num_regions; i++)
for (i = 0; i < num_rects; i++)
{
/* get rect to copy */
rect = (*out_rects)[i];
@ -300,7 +439,8 @@ rdpCapture0(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
/******************************************************************************/
/* make out_rects always multiple of 16 width and height */
static Bool
rdpCapture1(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
rdpCapture1(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
@ -475,11 +615,124 @@ rdpCapture1(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
return rv;
}
/******************************************************************************/
static Bool
rdpCapture2(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
int dst_stride, int dst_format, int max_rects)
{
int x;
int y;
int out_rect_index;
int num_rects;
int rcode;
BoxRec rect;
BoxRec extents_rect;
BoxPtr rects;
RegionRec tile_reg;
RegionRec lin_reg;
RegionRec temp_reg;
RegionPtr pin_reg;
LLOGLN(10, ("rdpCapture2:"));
*out_rects = (BoxPtr) g_malloc(sizeof(BoxRec) * RDP_MAX_TILES, 0);
if (*out_rects == NULL)
{
return FALSE;
}
out_rect_index = 0;
/* clip for smaller of 2 */
rect.x1 = 0;
rect.y1 = 0;
rect.x2 = min(dst_width, src_width);
rect.y2 = min(dst_height, src_height);
rdpRegionInit(&temp_reg, &rect, 0);
rdpRegionIntersect(&temp_reg, in_reg, &temp_reg);
/* limit the numer of rects */
num_rects = REGION_NUM_RECTS(&temp_reg);
if (num_rects > max_rects)
{
LLOGLN(10, ("rdpCapture2: too many rects"));
rdpRegionInit(&lin_reg, rdpRegionExtents(&temp_reg), 0);
pin_reg = &lin_reg;
}
else
{
LLOGLN(10, ("rdpCapture2: not too many rects"));
rdpRegionInit(&lin_reg, NullBox, 0);
pin_reg = &temp_reg;
}
extents_rect = *rdpRegionExtents(pin_reg);
y = extents_rect.y1 & ~63;
while (y < extents_rect.y2)
{
x = extents_rect.x1 & ~63;
while (x < extents_rect.x2)
{
rect.x1 = x;
rect.y1 = y;
rect.x2 = rect.x1 + 64;
rect.y2 = rect.y1 + 64;
rcode = rdpRegionContainsRect(pin_reg, &rect);
LLOGLN(10, ("rdpCapture2: rcode %d", rcode));
if (rcode != rgnOUT)
{
if (rcode == rgnPART)
{
LLOGLN(10, ("rdpCapture2: rgnPART"));
rdpFillBox_yuvalp(x, y, dst, dst_stride);
rdpRegionInit(&tile_reg, &rect, 0);
rdpRegionIntersect(&tile_reg, pin_reg, &tile_reg);
rects = REGION_RECTS(&tile_reg);
num_rects = REGION_NUM_RECTS(&tile_reg);
rdpCopyBox_a8r8g8b8_to_yuvalp(x, y,
src, src_stride,
dst, dst_stride,
rects, num_rects);
rdpRegionUninit(&tile_reg);
}
else /* rgnIN */
{
LLOGLN(10, ("rdpCapture2: rgnIN"));
rdpCopyBox_a8r8g8b8_to_yuvalp(x, y,
src, src_stride,
dst, dst_stride,
&rect, 1);
}
(*out_rects)[out_rect_index] = rect;
out_rect_index++;
if (out_rect_index >= RDP_MAX_TILES)
{
g_free(*out_rects);
*out_rects = NULL;
rdpRegionUninit(&temp_reg);
rdpRegionUninit(&lin_reg);
return FALSE;
}
}
x += 64;
}
y += 64;
}
*num_out_rects = out_rect_index;
rdpRegionUninit(&temp_reg);
rdpRegionUninit(&lin_reg);
return TRUE;
}
/**
* Copy an array of rectangles from one memory area to another
*****************************************************************************/
Bool
rdpCapture(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
rdpCapture(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
@ -489,13 +742,19 @@ rdpCapture(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
switch (mode)
{
case 0:
return rdpCapture0(in_reg, out_rects, num_out_rects,
return rdpCapture0(clientCon, in_reg, out_rects, num_out_rects,
src, src_width, src_height,
src_stride, src_format,
dst, dst_width, dst_height,
dst_stride, dst_format, 15);
case 1:
return rdpCapture1(in_reg, out_rects, num_out_rects,
return rdpCapture1(clientCon, in_reg, out_rects, num_out_rects,
src, src_width, src_height,
src_stride, src_format,
dst, dst_width, dst_height,
dst_stride, dst_format, 15);
case 2:
return rdpCapture2(clientCon, in_reg, out_rects, num_out_rects,
src, src_width, src_height,
src_stride, src_format,
dst, dst_width, dst_height,

@ -19,7 +19,8 @@
*/
Bool
rdpCapture(RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
rdpCapture(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,

@ -523,6 +523,8 @@ rdpClientConProcessMsgVersion(rdpPtr dev, rdpClientCon *clientCon,
return 0;
}
#define LALIGN(_num, _po2) ((_num + ((_po2) - 1)) & ~((_po2) - 1))
/******************************************************************************/
/*
this from miScreenInit
@ -544,6 +546,8 @@ rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon,
clientCon->rdp_width = width;
clientCon->rdp_height = height;
clientCon->rdp_bpp = bpp;
clientCon->cap_width = width;
clientCon->cap_height = height;
if (bpp < 15)
{
@ -649,7 +653,8 @@ rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
}
else if (msg == 300) /* resize desktop */
{
rdpClientConProcessScreenSizeMsg(dev, clientCon, param1, param2, param3);
rdpClientConProcessScreenSizeMsg(dev, clientCon, param1,
param2, param3);
}
else if (msg == 301) /* version */
{
@ -691,11 +696,30 @@ rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon)
i1 = clientCon->client_info.offscreen_cache_entries;
LLOGLN(0, (" offscreen entries %d", i1));
if ((clientCon->client_info.mcs_connection_type == 6) && /* LAN */
(clientCon->client_info.jpeg_codec_id == 2))
if (clientCon->client_info.capture_format != 0)
{
clientCon->rdp_format = clientCon->client_info.capture_format;
}
if (clientCon->client_info.capture_code == 2) /* RFX */
{
LLOGLN(0, ("rdpClientConProcessMsgClientInfo: got RFX capture"));
clientCon->cap_width = LALIGN(clientCon->rdp_width, 64);
clientCon->cap_height = LALIGN(clientCon->rdp_height, 64);
LLOGLN(0, (" cap_width %d cap_height %d",
clientCon->cap_width, clientCon->cap_height));
if (clientCon->shmemptr != 0)
{
/* jpeg capture needs swap */
clientCon->rdp_format = XRDP_a8b8g8r8;
shmdt(clientCon->shmemptr);
}
bytes = clientCon->cap_width * clientCon->cap_height *
clientCon->rdp_Bpp;
clientCon->shmemid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777);
clientCon->shmemptr = shmat(clientCon->shmemid, 0, 0);
shmctl(clientCon->shmemid, IPC_RMID, NULL);
LLOGLN(0, ("rdpClientConProcessMsgClientInfo: shmemid %d shmemptr %p "
"bytes %d", clientCon->shmemid, clientCon->shmemptr, bytes));
clientCon->shmem_lineBytes = clientCon->rdp_Bpp * clientCon->cap_width;
}
if (clientCon->client_info.offscreen_support_level > 0)
@ -1944,8 +1968,8 @@ rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon,
out_uint32_le(s, clientCon->rect_id);
out_uint32_le(s, id->shmem_id);
out_uint32_le(s, id->shmem_offset);
out_uint16_le(s, clientCon->rdp_width);
out_uint16_le(s, clientCon->rdp_height);
out_uint16_le(s, clientCon->cap_width);
out_uint16_le(s, clientCon->cap_height);
rdpClientConEndUpdate(dev, clientCon);
@ -1964,7 +1988,9 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
LLOGLN(10, ("rdpDeferredUpdateCallback:"));
clientCon = (rdpClientCon *) arg;
if (clientCon->rect_id > clientCon->rect_id_ack)
if ((clientCon->rect_id > clientCon->rect_id_ack) ||
/* do not allow captures until we have the client_info */
clientCon->client_info.size == 0)
{
LLOGLN(0, ("rdpDeferredUpdateCallback: reschedual rect_id %d "
"rect_id_ack %d",
@ -1986,13 +2012,16 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
clientCon->updateSchedualed = FALSE;
rects = 0;
num_rects = 0;
if (rdpCapture(clientCon->dirtyRegion, &rects, &num_rects,
LLOGLN(10, ("rdpDeferredUpdateCallback: capture_code %d",
clientCon->client_info.capture_code));
if (rdpCapture(clientCon, clientCon->dirtyRegion, &rects, &num_rects,
id.pixels, id.width, id.height,
id.lineBytes, XRDP_a8r8g8b8, id.shmem_pixels,
clientCon->rdp_width, clientCon->rdp_height,
clientCon->rdp_width * clientCon->rdp_Bpp,
clientCon->rdp_format, 0))
clientCon->cap_width, clientCon->cap_height,
clientCon->cap_width * clientCon->rdp_Bpp,
clientCon->rdp_format, clientCon->client_info.capture_code))
{
LLOGLN(10, ("rdpDeferredUpdateCallback: num_rects %d", num_rects));
rdpClientConSendPaintRectShmEx(clientCon->dev, clientCon, &id,
clientCon->dirtyRegion,
rects, num_rects);

@ -80,6 +80,8 @@ struct _rdpClientCon
int rdp_width;
int rdp_height;
int rdp_format; /* XRDP_a8r8g8b8, XRDP_r5g6b5, ... */
int cap_width;
int cap_height;
int rdpIndex; /* current os target */

@ -231,7 +231,7 @@ get_keymaps(int keylayout, struct xrdp_keymap *keymap)
{
fd = g_file_open(filename);
if (fd > 0)
if (fd != -1)
{
lkeymap = (struct xrdp_keymap *)g_malloc(sizeof(struct xrdp_keymap), 0);
/* make a copy of the build in kaymap */

@ -64,6 +64,7 @@ m 0x32 50 0000 8000
, 0x33 51 0000 8000
. 0x34 52 0000 8000
/ 0x35 53 0000 8000
/(keypad) 0x35 53 0100 8100
right shift 0x36 54 0000/4000 c000
*(keypad) 0x37 55 0000 8000
print scrn 0x37 55 0100 8100
@ -87,7 +88,7 @@ scroll lock 0x46 70 0000/4000 c000
home 0x47 71 0100 8100
8(keypad) 0x48 72 0000 8000
up arrow 0x48 72 0100 8100
9(kaypad) 0x49 73 0000 8000
9(keypad) 0x49 73 0000 8000
pg up 0x49 73 0100 8100
-(keypad) 0x4a 74 0000 8000
4(keypad) 0x4b 75 0000 8000
@ -102,7 +103,7 @@ end 0x4f 79 0100 8100
down arrow 0x50 80 0100 8100
3(keypad) 0x51 81 0000 8000
pg down 0x51 81 0100 8100
o(keypad) 0x52 82 0000 8000
0(keypad) 0x52 82 0000 8000
insert 0x52 82 0100 8100
.(keypad) 0x53 83 0000 8000
delete 0x53 83 0100 8100

@ -538,9 +538,19 @@ main(int argc, char **argv)
g_file_close(0);
g_file_close(1);
g_file_close(2);
g_file_open("/dev/null");
g_file_open("/dev/null");
g_file_open("/dev/null");
if (g_file_open("/dev/null") < 0)
{
}
if (g_file_open("/dev/null") < 0)
{
}
if (g_file_open("/dev/null") < 0)
{
}
/* end of daemonizing code */
}

@ -441,7 +441,13 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
g_file_read(fd, s->data, 4);
in_uint32_le(s, size);
/* read bmp header */
g_file_seek(fd, 14);
if (g_file_seek(fd, 14) < 0)
{
log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
filename);
g_file_close(fd);
return 1;
}
init_stream(s, 8192);
g_file_read(fd, s->data, 40); /* size better be 40 */
in_uint32_le(s, header.size);
@ -468,7 +474,11 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
if (header.bit_count == 24) /* 24 bit bitmap */
{
g_file_seek(fd, 14 + header.size);
if (g_file_seek(fd, 14 + header.size) < 0)
{
log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
filename);
}
xrdp_bitmap_resize(self, header.image_width, header.image_height);
size = header.image_width * header.image_height * 3;
init_stream(s, size);
@ -521,7 +531,11 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
else if (header.bit_count == 8) /* 8 bit bitmap */
{
/* read palette */
g_file_seek(fd, 14 + header.size);
if (g_file_seek(fd, 14 + header.size) < 0)
{
log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
filename);
}
init_stream(s, 8192);
g_file_read(fd, s->data, header.clr_used * sizeof(int));
@ -578,7 +592,11 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
else if (header.bit_count == 4) /* 4 bit bitmap */
{
/* read palette */
g_file_seek(fd, 14 + header.size);
if (g_file_seek(fd, 14 + header.size) < 0)
{
log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
filename);
}
init_stream(s, 8192);
g_file_read(fd, s->data, header.clr_used * sizeof(int));
@ -1746,7 +1764,6 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg,
if (self->child_list != 0)
{
i = list_index_of(self->child_list, (long)self->focused_control);
}
if (shift)
{
@ -1805,6 +1822,7 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg,
b = (struct xrdp_bitmap *)list_get_item(self->child_list, i);
}
}
}
else if (scan_code == 28) /* enter */
{
if (self->default_button != 0)

@ -39,25 +39,34 @@
} \
while (0)
#define JPG_CODEC 0
#define RFX_CODEC 1
/*****************************************************************************/
static int
process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
static int
process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
/**
* Init encoder
*
* @return 0 on success, -1 on failure
*****************************************************************************/
/* called from main thread */
int APP_CC
init_xrdp_encoder(struct xrdp_mm *self)
{
char buf[1024];
int pid;
LLOGLN(0, ("init_xrdp_encoder: initing encoder"));
if (self == 0)
{
return -1;
}
LLOGLN(0, ("init_xrdp_encoder: initing encoder codec_id %d", self->codec_id));
/* setup required FIFOs */
self->fifo_to_proc = fifo_create();
self->fifo_processed = fifo_create();
@ -72,6 +81,28 @@ init_xrdp_encoder(struct xrdp_mm *self)
g_snprintf(buf, 1024, "xrdp_%8.8x_encoder_term", pid);
self->xrdp_encoder_term = g_create_wait_obj(buf);
switch (self->codec_id)
{
case 2:
self->process_enc = process_enc_jpg;
break;
case 3:
self->process_enc = process_enc_rfx;
#ifdef XRDP_RFXCODEC
self->codec_handle =
rfxcodec_encode_create(self->wm->screen->width,
self->wm->screen->height,
RFX_FORMAT_YUV, 0);
//RFX_FORMAT_BGRA, 0);
#endif
break;
default:
LLOGLN(0, ("init_xrdp_encoder: unknown codec_id %d",
self->codec_id));
break;
}
/* create thread to process messages */
tc_thread_create(proc_enc_msg, self);
@ -104,6 +135,13 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
g_set_wait_obj(self->xrdp_encoder_term);
g_sleep(1000);
if (self->codec_id == 3)
{
#ifdef XRDP_RFXCODEC
rfxcodec_encode_destroy(self->codec_handle);
#endif
}
/* destroy wait objects used for signalling */
g_delete_wait_obj(self->xrdp_encoder_event_to_proc);
g_delete_wait_obj(self->xrdp_encoder_event_processed);
@ -147,8 +185,9 @@ deinit_xrdp_encoder(struct xrdp_mm *self)
}
/*****************************************************************************/
/* called from encoder thread */
static int
process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
{
int index;
int x;
@ -165,7 +204,7 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
tbus mutex;
tbus event_processed;
LLOGLN(10, ("process_enc:"));
LLOGLN(10, ("process_enc_jpg:"));
quality = self->codec_quality;
fifo_processed = self->fifo_processed;
mutex = self->mutex;
@ -179,19 +218,22 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
cy = enc->crects[index * 4 + 3];
if (cx < 1 || cy < 1)
{
LLOGLN(0, ("process_enc: error 1"));
LLOGLN(0, ("process_enc_jpg: error 1"));
continue;
}
LLOGLN(10, ("process_enc_jpg: x %d y %d cx %d cy %d", x, y, cx, cy));
out_data_bytes = MAX((cx + 4) * cy * 4, 8192);
if ((out_data_bytes < 1) || (out_data_bytes > 16 * 1024 * 1024))
{
LLOGLN(0, ("process_enc: error 2"));
LLOGLN(0, ("process_enc_jpg: error 2"));
return 1;
}
out_data = (char *) g_malloc(out_data_bytes + 256 + 2, 0);
if (out_data == 0)
{
LLOGLN(0, ("process_enc: error 3"));
LLOGLN(0, ("process_enc_jpg: error 3"));
return 1;
}
out_data[256] = 0; /* header bytes */
@ -203,7 +245,7 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
out_data + 256 + 2, &out_data_bytes);
if (error < 0)
{
LLOGLN(0, ("process_enc: jpeg error %d bytes %d",
LLOGLN(0, ("process_enc_jpg: jpeg error %d bytes %d",
error, out_data_bytes));
g_free(out_data);
return 1;
@ -216,7 +258,10 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
enc_done->comp_pad_data = out_data;
enc_done->enc = enc;
enc_done->last = index == (enc->num_crects - 1);
enc_done->index = index;
enc_done->x = x;
enc_done->y = y;
enc_done->cx = cx;
enc_done->cy = cy;
/* done with msg */
/* inform main thread done */
tc_mutex_lock(mutex);
@ -228,10 +273,125 @@ process_enc(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
return 0;
}
#ifdef XRDP_RFXCODEC
/*****************************************************************************/
/* called from encoder thread */
static int
process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
{
int index;
int x;
int y;
int cx;
int cy;
int out_data_bytes;
int count;
int error;
char *out_data;
XRDP_ENC_DATA_DONE *enc_done;
FIFO *fifo_processed;
tbus mutex;
tbus event_processed;
struct rfx_tile *tiles;
struct rfx_rect *rfxrects;
LLOGLN(10, ("process_enc_rfx:"));
LLOGLN(10, ("process_enc_rfx: num_crects %d num_drects %d",
enc->num_crects, enc->num_drects));
fifo_processed = self->fifo_processed;
mutex = self->mutex;
event_processed = self->xrdp_encoder_event_processed;
if ((enc->num_crects > 512) || (enc->num_drects > 512))
{
return 0;
}
out_data_bytes = 16 * 1024 * 1024;
index = 256 + sizeof(struct rfx_tile) * 512 +
sizeof(struct rfx_rect) * 512;
out_data = (char *) g_malloc(out_data_bytes + index, 0);
if (out_data == 0)
{
return 0;
}
tiles = (struct rfx_tile *) (out_data + out_data_bytes + 256);
rfxrects = (struct rfx_rect *) (tiles + 512);
count = enc->num_crects;
for (index = 0; index < count; index++)
{
x = enc->crects[index * 4 + 0];
y = enc->crects[index * 4 + 1];
cx = enc->crects[index * 4 + 2];
cy = enc->crects[index * 4 + 3];
LLOGLN(10, ("process_enc_rfx:"));
tiles[index].x = x;
tiles[index].y = y;
tiles[index].cx = cx;
tiles[index].cy = cy;
LLOGLN(10, ("x %d y %d cx %d cy %d", x, y, cx, cy));
tiles[index].quant_y = 0;
tiles[index].quant_cb = 0;
tiles[index].quant_cr = 0;
}
count = enc->num_drects;
for (index = 0; index < count; index++)
{
x = enc->drects[index * 4 + 0];
y = enc->drects[index * 4 + 1];
cx = enc->drects[index * 4 + 2];
cy = enc->drects[index * 4 + 3];
LLOGLN(10, ("process_enc_rfx:"));
rfxrects[index].x = x;
rfxrects[index].y = y;
rfxrects[index].cx = cx;
rfxrects[index].cy = cy;
}
error = rfxcodec_encode(self->codec_handle, out_data + 256, &out_data_bytes,
enc->data, enc->width, enc->height, enc->width * 4,
rfxrects, enc->num_drects,
tiles, enc->num_crects, 0, 0);
LLOGLN(10, ("process_enc_rfx: rfxcodec_encode rv %d", error));
enc_done = (XRDP_ENC_DATA_DONE *)
g_malloc(sizeof(XRDP_ENC_DATA_DONE), 1);
enc_done->comp_bytes = out_data_bytes;
enc_done->pad_bytes = 256;
enc_done->comp_pad_data = out_data;
enc_done->enc = enc;
enc_done->last = 1;
enc_done->cx = self->wm->screen->width;
enc_done->cy = self->wm->screen->height;
/* done with msg */
/* inform main thread done */
tc_mutex_lock(mutex);
fifo_add_item(fifo_processed, enc_done);
tc_mutex_unlock(mutex);
/* signal completion for main thread */
g_set_wait_obj(event_processed);
return 0;
}
#else
/*****************************************************************************/
/* called from encoder thread */
static int
process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
{
return 0;
}
#endif
/**
* Init encoder
*
* @return 0 on success, -1 on failure
* Encoder thread main loop
*****************************************************************************/
THREAD_RV THREAD_CC
proc_enc_msg(void *arg)
@ -305,7 +465,7 @@ proc_enc_msg(void *arg)
while (enc != 0)
{
/* do work */
process_enc(self, enc);
self->process_enc(self, enc);
/* get next msg */
tc_mutex_lock(mutex);
enc = (XRDP_ENC_DATA *) fifo_remove_item(fifo_to_proc);

@ -169,7 +169,7 @@ xrdp_listen_get_port_address(char *port, int port_bytes,
*tcp_nodelay = 0 ;
*tcp_keepalive = 0 ;
if (fd > 0)
if (fd != -1)
{
names = list_create();
names->auto_free = 1;
@ -242,9 +242,10 @@ xrdp_listen_get_port_address(char *port, int port_bytes,
list_delete(names);
list_delete(values);
g_file_close(fd);
}
g_file_close(fd);
/* startup_param overrides */
if (startup_param->port[0] != 0)
{
@ -448,7 +449,7 @@ xrdp_listen_main_loop(struct xrdp_listen *self)
robjs[robjs_count++] = done_obj;
timeout = -1;
if (self->listen_trans != 0)
/* if (self->listen_trans != 0) */
{
if (trans_get_wait_objs(self->listen_trans, robjs,
&robjs_count) != 0)

@ -55,7 +55,13 @@ xrdp_mm_create(struct xrdp_wm *owner)
self->login_values = list_create();
self->login_values->auto_free = 1;
LLOGLN(10, ("xrdp_mm_create: bpp %d", self->wm->client_info->bpp));
LLOGLN(0, ("xrdp_mm_create: bpp %d mcs_connection_type %d "
"jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d",
self->wm->client_info->bpp,
self->wm->client_info->mcs_connection_type,
self->wm->client_info->jpeg_codec_id,
self->wm->client_info->v3_codec_id,
self->wm->client_info->rfx_codec_id));
/* go into jpeg codec mode if jpeg set, lan set */
if (self->wm->client_info->mcs_connection_type == 6) /* LAN */
{
@ -67,6 +73,20 @@ xrdp_mm_create(struct xrdp_wm *owner)
self->codec_id = 2;
self->in_codec_mode = 1;
self->codec_quality = self->wm->client_info->jpeg_prop[0];
self->wm->client_info->capture_code = 0;
self->wm->client_info->capture_format =
/* PIXMAN_a8b8g8r8 */
(32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8;
}
}
else if (self->wm->client_info->rfx_codec_id == 3) /* RFX */
{
if (self->wm->client_info->bpp > 16)
{
LLOGLN(0, ("xrdp_mm_create: starting rfx codec session"));
self->codec_id = 3;
self->in_codec_mode = 1;
self->wm->client_info->capture_code = 2;
}
}
}
@ -1287,9 +1307,9 @@ xrdp_mm_get_sesman_port(char *port, int port_bytes)
list_delete(names);
list_delete(values);
g_file_close(fd);
}
g_file_close(fd);
return 0;
}
@ -1414,7 +1434,7 @@ access_control(char *username, char *password, char *srv)
int index;
int socket = g_tcp_socket();
if (socket > 0)
if (socket != -1)
{
/* we use a blocking socket here */
reply = g_tcp_connect(socket, srv, "3350");
@ -1507,6 +1527,9 @@ access_control(char *username, char *password, char *srv)
log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control");
}
if (socket != -1)
g_tcp_close(socket);
return rec;
}
#endif
@ -2064,27 +2087,31 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
LLOGLN(10, ("xrdp_mm_check_wait_objs: message back bytes %d",
enc_done->comp_bytes));
x = enc_done->enc->crects[enc_done->index * 4 + 0];
y = enc_done->enc->crects[enc_done->index * 4 + 1];
cx = enc_done->enc->crects[enc_done->index * 4 + 2];
cy = enc_done->enc->crects[enc_done->index * 4 + 3];
x = enc_done->x;
y = enc_done->y;
cx = enc_done->cx;
cy = enc_done->cy;
#if DUMP_JPEG
xrdp_mm_dump_jpeg(self, enc_done);
#endif
if (enc_done->comp_bytes > 0)
{
libxrdp_fastpath_send_surface(self->wm->session,
enc_done->comp_pad_data,
enc_done->pad_bytes,
enc_done->comp_bytes,
x, y, x + cx, y + cy,
32, 2, cx, cy);
32, self->codec_id, cx, cy);
}
/* free enc_done */
if (enc_done->last)
{
LLOGLN(10, ("xrdp_mm_check_wait_objs: last set"));
self->mod->mod_frame_ack(self->mod, enc_done->enc->flags, enc_done->enc->frame_id);
self->mod->mod_frame_ack(self->mod,
enc_done->enc->flags, enc_done->enc->frame_id);
g_free(enc_done->enc->drects);
g_free(enc_done->enc->crects);
g_free(enc_done->enc);
@ -2719,10 +2746,11 @@ int read_allowed_channel_names(struct list *names, struct list *values)
int ret = 0;
char cfg_file[256];
int pos;
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file);
if (fd > 0)
if (fd != -1)
{
names->auto_free = 1;
values->auto_free = 1;

@ -70,7 +70,6 @@ xrdp_process_loop(struct xrdp_process *self, struct stream *s)
if (self->session != 0)
{
rv = libxrdp_process_data(self->session, s);
}
if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0))
{
@ -80,6 +79,7 @@ xrdp_process_loop(struct xrdp_process *self, struct stream *s)
zero and login_mode_event is set so xrdp_wm_init should be called by
xrdp_wm_check_wait_objs */
}
}
return rv;
}

@ -268,6 +268,9 @@ struct xrdp_cache
struct list* xrdp_os_del_list;
};
/* defined later */
struct xrdp_enc_data;
struct xrdp_mm
{
struct xrdp_wm* wm; /* owner */
@ -300,6 +303,8 @@ struct xrdp_mm
FIFO *fifo_to_proc;
FIFO *fifo_processed;
tbus mutex;
int (*process_enc)(struct xrdp_mm *self, struct xrdp_enc_data *enc);
void *codec_handle;
};
struct xrdp_key_info
@ -641,7 +646,10 @@ struct xrdp_enc_data_done
char *comp_pad_data;
struct xrdp_enc_data *enc;
int last; /* true is this is last message for enc */
int index; /* depends on codec */
int x;
int y;
int cx;
int cy;
};
typedef struct xrdp_enc_data_done XRDP_ENC_DATA_DONE;

@ -236,10 +236,11 @@ xrdp_wm_load_pointer(struct xrdp_wm *self, char *file_name, char *data,
init_stream(fs, 8192);
fd = g_file_open(file_name);
if (fd < 1)
if (fd < 0)
{
log_message(LOG_LEVEL_ERROR,"xrdp_wm_load_pointer: error loading pointer from file [%s]",
file_name);
xstream_free(fs);
return 1;
}
@ -567,7 +568,7 @@ xrdp_wm_init(struct xrdp_wm *self)
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file); /* xrdp.ini */
if (fd > 0)
if (fd != -1)
{
names = list_create();
names->auto_free = 1;
@ -1744,13 +1745,13 @@ callback(long id, int msg, long param1, long param2, long param3, long param4)
static int APP_CC
xrdp_wm_login_mode_changed(struct xrdp_wm *self)
{
g_writeln("xrdp_wm_login_mode_changed: login_mode is %d", self->login_mode);
if (self == 0)
{
return 0;
}
g_writeln("xrdp_wm_login_mode_changed: login_mode is %d", self->login_mode);
if (self->login_mode == 0)
{
/* this is the inital state of the login window */

@ -129,7 +129,10 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, const char *pVirtualName,
/* set non blocking */
llong = fcntl(wts->fd, F_GETFL);
llong = llong | O_NONBLOCK;
fcntl(wts->fd, F_SETFL, llong);
if (fcntl(wts->fd, F_SETFL, llong) < 0)
{
LLOGLN(10, ("WTSVirtualChannelOpenEx: set non-block mode failed"));
}
/* connect to chansrv session */
memset(&s, 0, sizeof(struct sockaddr_un));

@ -1380,6 +1380,7 @@ lib_send_client_info(struct mod *mod)
struct stream *s;
int len;
g_writeln("lib_send_client_info:");
make_stream(s);
init_stream(s, 8192);
s_push_layer(s, iso_hdr, 4);

Loading…
Cancel
Save