diff --git a/common/file.c b/common/file.c index a9a06de9..b51a37cc 100644 --- a/common/file.c +++ b/common/file.c @@ -233,7 +233,7 @@ l_file_read_section(int fd, int max_file_size, const char *section, int len; int index; int file_size; - + data = (char *) g_malloc(FILE_MAX_LINE_BYTES * 3, 0); text = data; name = text + FILE_MAX_LINE_BYTES; @@ -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; } diff --git a/common/log.c b/common/log.c index 54dfaa29..d7594d67 100644 --- a/common/log.c +++ b/common/log.c @@ -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; } diff --git a/common/os_calls.c b/common/os_calls.c index 1d3a71b1..68a6a5b0 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -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 } diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 954595d8..59915f37 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -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]; diff --git a/keygen/keygen.c b/keygen/keygen.c index bd47f73a..0cd1427d 100644 --- a/keygen/keygen.c +++ b/keygen/keygen.c @@ -217,7 +217,7 @@ sign_key(char *e_data, int e_len, char *n_data, int n_len, { return 1; } - + if (n_len == 64) { key = (char *)g_malloc(184, 0); @@ -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; } diff --git a/librfxcodec b/librfxcodec deleted file mode 160000 index 7b04ca9c..00000000 --- a/librfxcodec +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7b04ca9c54aeddbdaf4bf945cea81f4efb8847e7 diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 3b781f70..876d9473 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -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; } } diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 90bfebce..ee490839 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -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; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 6891bb97..b4ef19a8 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -743,7 +743,8 @@ 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) { - return 1; + free_stream(s); + return 1; } } else /* slowpath */ @@ -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; } } diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 0bb2688c..7ac68b14 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -730,7 +730,7 @@ xrdp_sec_send_media_lic_response(struct xrdp_sec *self) /*****************************************************************************/ static void APP_CC -xrdp_sec_rsa_op(struct xrdp_sec *self, char *out, char *in, int in_bytes, +xrdp_sec_rsa_op(struct xrdp_sec *self, char *out, char *in, int in_bytes, char *mod, char *exp) { ssl_mod_exp(out, self->rsa_key_bytes, in, in_bytes, @@ -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)); } @@ -1926,20 +1930,20 @@ xrdp_sec_incoming(struct xrdp_sec *self) /* initialize selected security layer */ if (iso->requestedProtocol > PROTOCOL_RDP) { - /* init tls security */ - DEBUG((" in xrdp_sec_incoming: init tls security")); + /* init tls security */ + DEBUG((" in xrdp_sec_incoming: init tls security")); - if (trans_set_tls_mode(self->mcs_layer->iso_layer->trans, - self->rdp_layer->client_info.key_file, - self->rdp_layer->client_info.certificate) != 0) - { - g_writeln("xrdp_sec_incoming: trans_set_tls_mode failed"); - return 1; - } + if (trans_set_tls_mode(self->mcs_layer->iso_layer->trans, + self->rdp_layer->client_info.key_file, + self->rdp_layer->client_info.certificate) != 0) + { + g_writeln("xrdp_sec_incoming: trans_set_tls_mode failed"); + return 1; + } - self->crypt_level = CRYPT_LEVEL_NONE; - self->crypt_method = CRYPT_METHOD_NONE; - self->rsa_key_bytes = 0; + self->crypt_level = CRYPT_LEVEL_NONE; + self->crypt_method = CRYPT_METHOD_NONE; + self->rsa_key_bytes = 0; } else diff --git a/rdp/rdp_mcs.c b/rdp/rdp_mcs.c index 55067b1f..18c33ac4 100644 --- a/rdp/rdp_mcs.c +++ b/rdp/rdp_mcs.c @@ -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; } diff --git a/rdp/rdp_rdp.c b/rdp/rdp_rdp.c index 973b8fe9..70155c60 100644 --- a/rdp/rdp_rdp.c +++ b/rdp/rdp_rdp.c @@ -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; } diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index a89957ba..6aa5c8e8 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -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) { diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 3ec00b6e..e80f93a9 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -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,12 +1781,15 @@ 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->mode & S_IFREG) - xfuse_delete_file_with_xinode(new_xinode); - else - xfuse_delete_dir_with_xinode(new_xinode); + if (new_xinode) + { + if (new_xinode->mode & S_IFREG) + xfuse_delete_file_with_xinode(new_xinode); + else + xfuse_delete_dir_with_xinode(new_xinode); - new_xinode = NULL; + new_xinode = NULL; + } } old_xinode = xfuse_get_inode_from_pinode_name(fip->inode, fip->name); diff --git a/sesman/chansrv/chansrv_fuse.h b/sesman/chansrv/chansrv_fuse.h index 09011452..41a73062 100644 --- a/sesman/chansrv/chansrv_fuse.h +++ b/sesman/chansrv/chansrv_fuse.h @@ -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); diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 6d52da85..310e2093 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -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); - g_formatIds[g_num_formatIds] = formatId; - g_num_formatIds++; + 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"); diff --git a/sesman/chansrv/clipboard_file.c b/sesman/chansrv/clipboard_file.c index 96f1b0e8..ff95b0a0 100644 --- a/sesman/chansrv/clipboard_file.c +++ b/sesman/chansrv/clipboard_file.c @@ -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); diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index cdcc9e94..121c1190 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -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"); - - xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length); - devredir_irp_delete(irp); + } + 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"); - - xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length); - devredir_irp_delete(irp); + } + 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; diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index 4888d2e0..f3777970 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -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) diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c index 0d6d5405..a07e36eb 100644 --- a/sesman/chansrv/smartcard.c +++ b/sesman/chansrv/smartcard.c @@ -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, diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c index 1d1618dc..9824432e 100644 --- a/sesman/chansrv/smartcard_pcsc.c +++ b/sesman/chansrv/smartcard_pcsc.c @@ -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, diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c index cc64a558..c699ffde 100644 --- a/sesman/chansrv/sound.c +++ b/sesman/chansrv/sound.c @@ -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; } diff --git a/sesman/env.c b/sesman/env.c index 26d1a4f7..227f6bbf 100644 --- a/sesman/env.c +++ b/sesman/env.c @@ -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 diff --git a/sesman/libscp/libscp_v1c.c b/sesman/libscp/libscp_v1c.c index 7d1b9db8..848b3437 100644 --- a/sesman/libscp/libscp_v1c.c +++ b/sesman/libscp/libscp_v1c.c @@ -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; } diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c index 59762e36..dc1016db 100644 --- a/sesman/libscp/libscp_v1c_mng.c +++ b/sesman/libscp/libscp_v1c_mng.c @@ -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; } diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index 12115929..2324b750 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -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) diff --git a/sesman/sesman.c b/sesman/sesman.c index 83db5961..964bc740 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -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); } diff --git a/sesman/session.c b/sesman/session.c index 091ce013..130ca26c 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -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; } diff --git a/sesman/sig.c b/sesman/sig.c index 7bb881ce..72892fb2 100644 --- a/sesman/sig.c +++ b/sesman/sig.c @@ -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; } diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c index 25af850b..979a22f9 100644 --- a/sesman/tools/sesadmin.c +++ b/sesman/tools/sesadmin.c @@ -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) diff --git a/xorg/server/module/rdpCapture.c b/xorg/server/module/rdpCapture.c index e9fef483..5163e6ae 100644 --- a/xorg/server/module/rdpCapture.c +++ b/xorg/server/module/rdpCapture.c @@ -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(®, &rect, 0); rdpRegionIntersect(®, in_reg, ®); - num_regions = REGION_NUM_RECTS(®); - - if (num_regions > max_rects) - { - num_regions = 1; - psrc_rects = rdpRegionExtents(®); - } - else - { - psrc_rects = REGION_RECTS(®); - } - - if (num_regions < 1) + psrc_rects = 0; + num_rects = rdpLimitRects(®, max_rects, &psrc_rects); + if (num_rects < 1) { + rdpRegionUninit(®); 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, diff --git a/xorg/server/module/rdpCapture.h b/xorg/server/module/rdpCapture.h index 5810e3b6..4dff1eea 100644 --- a/xorg/server/module/rdpCapture.h +++ b/xorg/server/module/rdpCapture.h @@ -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, diff --git a/xorg/server/module/rdpClientCon.c b/xorg/server/module/rdpClientCon.c index 24870557..622a3f8a 100644 --- a/xorg/server/module/rdpClientCon.c +++ b/xorg/server/module/rdpClientCon.c @@ -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,12 +653,13 @@ 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 */ { rdpClientConProcessMsgVersion(dev, clientCon, - param1, param2, param3, param4); + param1, param2, param3, param4); } else { @@ -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) { - /* jpeg capture needs swap */ - clientCon->rdp_format = XRDP_a8b8g8r8; + 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) + { + 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); diff --git a/xorg/server/module/rdpClientCon.h b/xorg/server/module/rdpClientCon.h index 2b5ec00a..a66abbcd 100644 --- a/xorg/server/module/rdpClientCon.h +++ b/xorg/server/module/rdpClientCon.h @@ -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 */ diff --git a/xrdp/lang.c b/xrdp/lang.c index 2f2a3da5..5ffff0eb 100644 --- a/xrdp/lang.c +++ b/xrdp/lang.c @@ -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 */ diff --git a/xrdp/rdp-scan-codes.txt b/xrdp/rdp-scan-codes.txt index 649bc5eb..938ce4c5 100644 --- a/xrdp/rdp-scan-codes.txt +++ b/xrdp/rdp-scan-codes.txt @@ -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 diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index ba9d02a3..02e94d41 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -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 */ } diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index 87fb0ebc..3bbebfd9 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -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,42 +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) - { - i--; - - if (i < 0) - { - i = self->child_list->count - 1; - } - } - else - { - i++; - - if (i >= self->child_list->count) - { - i = 0; - } - } - - n = self->child_list->count; - b = (struct xrdp_bitmap *)list_get_item(self->child_list, i); - - while (b != self->focused_control && b != 0 && n > 0) - { - n--; - - if (b->tab_stop) - { - focus_out_control = self->focused_control; - self->focused_control = b; - xrdp_bitmap_invalidate(focus_out_control, 0); - xrdp_bitmap_invalidate(b, 0); - break; - } if (shift) { @@ -1802,7 +1784,43 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg, } } + n = self->child_list->count; b = (struct xrdp_bitmap *)list_get_item(self->child_list, i); + + while (b != self->focused_control && b != 0 && n > 0) + { + n--; + + if (b->tab_stop) + { + focus_out_control = self->focused_control; + self->focused_control = b; + xrdp_bitmap_invalidate(focus_out_control, 0); + xrdp_bitmap_invalidate(b, 0); + break; + } + + if (shift) + { + i--; + + if (i < 0) + { + i = self->child_list->count - 1; + } + } + else + { + i++; + + if (i >= self->child_list->count) + { + i = 0; + } + } + + b = (struct xrdp_bitmap *)list_get_item(self->child_list, i); + } } } else if (scan_code == 28) /* enter */ diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c index 5ed1a5c0..78d1b52e 100644 --- a/xrdp/xrdp_encoder.c +++ b/xrdp/xrdp_encoder.c @@ -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); diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 2a706b91..fb4d9aec 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -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) diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 1054ba2e..2bdd821d 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -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 - 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); + 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, 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; diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index af56a4e1..5a7cd1d8 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -70,15 +70,15 @@ 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)) - { - DEBUG(("calling xrdp_wm_init and creating wm")); - self->wm = xrdp_wm_create(self, self->session->client_info); - /* at this point the wm(window manager) is create and wm::login_mode is - zero and login_mode_event is set so xrdp_wm_init should be called by - xrdp_wm_check_wait_objs */ + if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0)) + { + DEBUG(("calling xrdp_wm_init and creating wm")); + self->wm = xrdp_wm_create(self, self->session->client_info); + /* at this point the wm(window manager) is create and wm::login_mode is + zero and login_mode_event is set so xrdp_wm_init should be called by + xrdp_wm_check_wait_objs */ + } } return rv; diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 0e31dd59..89a7ce93 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -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; diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index caf55a7d..6179d2e8 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -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 */ diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c index 4cf8db71..23630804 100644 --- a/xrdpapi/xrdpapi.c +++ b/xrdpapi/xrdpapi.c @@ -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)); diff --git a/xup/xup.c b/xup/xup.c index 5429e5f3..294500be 100644 --- a/xup/xup.c +++ b/xup/xup.c @@ -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);