diff options
Diffstat (limited to 'sesman/chansrv')
-rw-r--r-- | sesman/chansrv/Makefile.am | 10 | ||||
-rw-r--r-- | sesman/chansrv/chansrv.c | 135 | ||||
-rw-r--r-- | sesman/chansrv/chansrv_fuse.c | 86 | ||||
-rw-r--r-- | sesman/chansrv/chansrv_fuse.h | 4 | ||||
-rw-r--r-- | sesman/chansrv/clipboard.c | 7 | ||||
-rw-r--r-- | sesman/chansrv/clipboard_file.c | 8 | ||||
-rw-r--r-- | sesman/chansrv/devredir.c | 39 | ||||
-rw-r--r-- | sesman/chansrv/pcsc/xrdp_pcsc.c | 129 | ||||
-rw-r--r-- | sesman/chansrv/pulse/module-xrdp-sink.c | 28 | ||||
-rw-r--r-- | sesman/chansrv/pulse/module-xrdp-source.c | 22 | ||||
-rw-r--r-- | sesman/chansrv/rail.c | 93 | ||||
-rw-r--r-- | sesman/chansrv/smartcard.c | 5 | ||||
-rw-r--r-- | sesman/chansrv/smartcard_pcsc.c | 2 | ||||
-rw-r--r-- | sesman/chansrv/sound.c | 410 | ||||
-rw-r--r-- | sesman/chansrv/sound.h | 20 |
15 files changed, 487 insertions, 511 deletions
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am index 9aa3ebe7..81218db1 100644 --- a/sesman/chansrv/Makefile.am +++ b/sesman/chansrv/Makefile.am @@ -16,21 +16,11 @@ EXTRA_INCLUDES = EXTRA_LIBS = EXTRA_FLAGS = -if XRDP_SIMPLESOUND -EXTRA_DEFINES += -DXRDP_SIMPLESOUND -EXTRA_LIBS += -lpthread -lpulse -lpulse-simple -endif - if XRDP_FUSE EXTRA_DEFINES += -DXRDP_FUSE EXTRA_LIBS += -lfuse endif -if XRDP_LOAD_PULSE_MODULES -EXTRA_DEFINES += -DXRDP_LOAD_PULSE_MODULES -EXTRA_LIBS += -lpulse -endif - AM_CFLAGS = \ -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \ -DXRDP_SBIN_PATH=\"${sbindir}\" \ diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index a89957ba..af2f6957 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -38,7 +38,7 @@ static struct trans *g_lis_trans = 0; static struct trans *g_con_trans = 0; static struct trans *g_api_lis_trans = 0; -static struct trans *g_api_con_trans = 0; +static struct list *g_api_con_trans_list = 0; /* list of apps using api functions */ static struct chan_item g_chan_items[32]; static int g_num_chan_items = 0; static int g_cliprdr_index = -1; @@ -608,7 +608,10 @@ process_message_channel_data(struct stream *s) int rv = 0; int length = 0; int total_length = 0; + int index; struct stream *ls; + struct trans *ltran; + struct xrdp_api_data *api_data; in_uint16_le(s, chan_id); in_uint16_le(s, chan_flags); @@ -641,29 +644,36 @@ process_message_channel_data(struct stream *s) { rv = drdynvc_data_in(s, chan_id, chan_flags, length, total_length); } - else if ((g_api_con_trans != 0) && - (chan_id == ((struct xrdp_api_data *) - (g_api_con_trans->callback_data))->chan_id)) + else if (g_api_con_trans_list != 0) { - LOG(10, ("process_message_channel_data length %d total_length %d " - "chan_flags 0x%8.8x", length, total_length, chan_flags)); - ls = g_api_con_trans->out_s; - - if (chan_flags & 1) /* first */ - { - init_stream(ls, total_length); - } - - out_uint8a(ls, s->p, length); - - if (chan_flags & 2) /* last */ + for (index = 0; index < g_api_con_trans_list->count; index++) { - s_mark_end(ls); - rv = trans_force_write(g_api_con_trans); + ltran = (struct trans *) list_get_item(g_api_con_trans_list, index); + if (ltran != 0) + { + api_data = (struct xrdp_api_data *) (ltran->callback_data); + if (api_data != 0) + { + if (api_data->chan_id == chan_id) + { + ls = ltran->out_s; + if (chan_flags & 1) /* first */ + { + init_stream(ls, total_length); + } + out_uint8a(ls, s->p, length); + if (chan_flags & 2) /* last */ + { + s_mark_end(ls); + rv = trans_force_write(ltran); + } + break; + } + } + } } } } - return rv; } @@ -796,9 +806,12 @@ my_api_trans_data_in(struct trans *trans) return 0; } - if (trans != g_api_con_trans) + if (g_api_con_trans_list != 0) { - return 1; + if (list_index_of(g_api_con_trans_list, (tintptr) trans) == -1) + { + return 1; + } } LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:")); @@ -812,7 +825,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) { @@ -932,6 +946,7 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans) { LOG(0, ("my_api_trans_conn_in: trans_force_read failed")); trans_delete(new_trans); + return 1; } s->end = s->data; @@ -987,10 +1002,13 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans) new_trans->callback_data = ad; - trans_delete(g_api_con_trans); - g_api_con_trans = new_trans; - g_api_con_trans->trans_data_in = my_api_trans_data_in; - g_api_con_trans->header_size = 0; + if (g_api_con_trans_list == 0) + { + g_api_con_trans_list = list_create(); + } + new_trans->trans_data_in = my_api_trans_data_in; + new_trans->header_size = 0; + list_add_item(g_api_con_trans_list, (tintptr) new_trans); return 0; } @@ -1011,8 +1029,7 @@ setup_listen(void) { g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192); g_lis_trans->is_term = g_is_term; - g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", - 7200 + g_display_num); + g_snprintf(port, 255, XRDP_CHANSRV_STR, g_display_num); } else { @@ -1043,7 +1060,7 @@ setup_api_listen(void) g_api_lis_trans = trans_create(TRANS_MODE_UNIX, 8192 * 4, 8192 * 4); g_api_lis_trans->is_term = g_is_term; - g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num); + g_snprintf(port, 255, CHANSRV_API_STR, g_display_num); g_api_lis_trans->trans_conn_in = my_api_trans_conn_in; error = trans_listen(g_api_lis_trans, port); @@ -1067,7 +1084,9 @@ channel_thread_loop(void *in_val) int num_wobjs; int timeout; int error; + int index; THREAD_RV rv; + struct trans *ltran; LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); rv = 0; @@ -1137,19 +1156,20 @@ channel_thread_loop(void *in_val) } } - LOG(10, ("0 %p", g_api_con_trans)); - - if (g_api_con_trans != 0) + if (g_api_con_trans_list != 0) { - LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0))); - - if (trans_check_wait_objs(g_api_con_trans) != 0) + for (index = g_api_con_trans_list->count - 1; index >= 0; index--) { - LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, " - "or disconnected")); - g_free(g_api_con_trans->callback_data); - trans_delete(g_api_con_trans); - g_api_con_trans = 0; + ltran = (struct trans *) list_get_item(g_api_con_trans_list, index); + if (ltran != 0) + { + if (trans_check_wait_objs(ltran) != 0) + { + list_remove_item(g_api_con_trans_list, index); + g_free(ltran->callback_data); + trans_delete(ltran); + } + } } } @@ -1166,7 +1186,19 @@ channel_thread_loop(void *in_val) trans_get_wait_objs_rw(g_con_trans, objs, &num_objs, wobjs, &num_wobjs); trans_get_wait_objs(g_api_lis_trans, objs, &num_objs); - trans_get_wait_objs(g_api_con_trans, objs, &num_objs); + + if (g_api_con_trans_list != 0) + { + for (index = g_api_con_trans_list->count - 1; index >= 0; index--) + { + ltran = (struct trans *) list_get_item(g_api_con_trans_list, index); + if (ltran != 0) + { + trans_get_wait_objs(ltran, objs, &num_objs); + } + } + } + xcommon_get_wait_objs(objs, &num_objs, &timeout); sound_get_wait_objs(objs, &num_objs, &timeout); dev_redir_get_wait_objs(objs, &num_objs, &timeout); @@ -1181,8 +1213,20 @@ channel_thread_loop(void *in_val) g_con_trans = 0; trans_delete(g_api_lis_trans); g_api_lis_trans = 0; - trans_delete(g_api_con_trans); - g_api_con_trans = 0; + if (g_api_con_trans_list != 0) + { + for (index = g_api_con_trans_list->count - 1; index >= 0; index--) + { + ltran = (struct trans *) list_get_item(g_api_con_trans_list, index); + if (ltran != 0) + { + list_remove_item(g_api_con_trans_list, index); + g_free(ltran->callback_data); + trans_delete(ltran); + } + } + list_delete(g_api_con_trans_list); + } LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); g_set_wait_obj(g_thread_done_event); return rv; @@ -1599,11 +1643,6 @@ remove_struct_with_chan_id(tui32 dvc_chan_id) { int i; - if (dvc_chan_id < 0) - { - return -1; - } - for (i = 0; i < MAX_DVC_CHANNELS; i++) { if (g_dvc_channels[i]->dvc_chan_id == dvc_chan_id) diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 2eb78ea0..c4532ead 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -39,6 +39,8 @@ //#define USE_SYNC_FLAG +static char g_fuse_mount_name[256] = "xrdp_client"; + /* FUSE mount point */ char g_fuse_root_path[256] = ""; char g_fuse_clipboard_path[256] = ""; /* for clipboard use */ @@ -71,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) {} @@ -369,6 +371,37 @@ int clipboard_request_file_data(int stream_id, int lindex, int offset, static void xfuse_mark_as_stale(int pinode); static void xfuse_delete_stale_entries(int pinode); +/*****************************************************************************/ +int APP_CC +load_fuse_config(void) +{ + int index; + char cfg_file[256]; + struct list *items; + struct list *values; + char *item; + char *value; + + items = list_create(); + items->auto_free = 1; + values = list_create(); + values->auto_free = 1; + g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); + file_by_name_read_section(cfg_file, "Chansrv", items, values); + for (index = 0; index < items->count; index++) + { + item = (char *)list_get_item(items, index); + value = (char *)list_get_item(values, index); + if (g_strcasecmp(item, "FuseMountName") == 0) + { + g_strncpy(g_fuse_mount_name, value, 255); + } + } + list_delete(items); + list_delete(values); + return 0; +} + /***************************************************************************** ** ** ** public functions - can be called from any code path ** @@ -381,7 +414,8 @@ static void xfuse_delete_stale_entries(int pinode); * @return 0 on success, -1 on failure *****************************************************************************/ -int xfuse_init() +int APP_CC +xfuse_init(void) { struct fuse_args args = FUSE_ARGS_INIT(0, NULL); @@ -398,8 +432,10 @@ int xfuse_init() return -1; } - /* define FUSE mount point to ~/xrdp_client */ - g_snprintf(g_fuse_root_path, 255, "%s/xrdp_client", g_getenv("HOME")); + load_fuse_config(); + + /* define FUSE mount point to ~/xrdp_client, ~/thinclient_drives */ + g_snprintf(g_fuse_root_path, 255, "%s/%s", g_getenv("HOME"), g_fuse_mount_name); g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path); /* if FUSE mount point does not exist, create it */ @@ -460,7 +496,8 @@ int xfuse_init() * @return 0 on success, -1 on failure *****************************************************************************/ -int xfuse_deinit() +int APP_CC +xfuse_deinit(void) { xfuse_deinit_xrdp_fs(); fifo_deinit(&g_fifo_opendir); @@ -1385,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; @@ -1393,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); @@ -1407,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(); @@ -1417,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; @@ -1436,6 +1474,7 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) xfuse_update_xrdpfs_size(); xfuse_dump_fs(); + return 0; } /** @@ -1742,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); @@ -1759,7 +1801,8 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus) } old_xinode->parent_inode = fip->new_inode; - strcpy(old_xinode->name, fip->new_name); + strncpy(old_xinode->name, fip->new_name, 1023); + old_xinode->name[1023] = 0; if (fip->inode != fip->new_inode) { @@ -1987,7 +2030,7 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, return; } - di = (struct dir_info *) fi->fh; + di = (struct dir_info *) (tintptr) (fi->fh); if (di == NULL) { /* something seriously wrong somewhere! */ @@ -2142,7 +2185,7 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent, } strcat(full_path, "/"); - strcat(full_path, name); + strncat(full_path, name, sizeof(full_path) - strlen(full_path)); if (xinode->is_loc_resource) { @@ -2583,7 +2626,6 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct fip, fip->fi, fip->fi->fh); FileId = handle->FileId; - free(handle); fip->fi->fh = 0; xinode->close_in_progress = 1; @@ -2592,6 +2634,8 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct log_error("failed to send devredir_close_file() cmd"); fuse_reply_err(req, EREMOTEIO); } + + free(handle); } /** diff --git a/sesman/chansrv/chansrv_fuse.h b/sesman/chansrv/chansrv_fuse.h index 09011452..4638add5 100644 --- a/sesman/chansrv/chansrv_fuse.h +++ b/sesman/chansrv/chansrv_fuse.h @@ -34,7 +34,7 @@ struct xrdp_inode time_t atime; /* Time of last access. */ time_t mtime; /* Time of last modification. */ time_t ctime; /* Time of last status change. */ - char name[256]; /* Dir or filename */ + char name[1024]; /* Dir or filename */ tui32 device_id; /* for file system redirection */ char is_synced; /* dir struct has been read from */ /* remote device, done just once */ @@ -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..cea42c81 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -118,7 +118,7 @@ dev_redir_init(void) } u; /* get a random number that will act as a unique clientID */ - if ((fd = open("/dev/urandom", O_RDONLY))) + if ((fd = open("/dev/urandom", O_RDONLY)) != -1) { if (read(fd, u.buf, 4) != 4) { @@ -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,7 +1025,8 @@ 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); + + strncpy(irp->pathname, path, 255); devredir_fuse_data_enqueue(irp, fusep); DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE; @@ -1060,7 +1069,7 @@ dev_redir_file_open(void *fusep, tui32 device_id, char *path, if (type & OP_RENAME_FILE) { irp->completion_type = CID_RENAME_FILE; - strcpy(irp->gen_buf, gen_buf); + strncpy(irp->gen_buf, gen_buf, 1023); } else { @@ -1069,7 +1078,8 @@ dev_redir_file_open(void *fusep, tui32 device_id, char *path, irp->CompletionId = g_completion_id++; irp->DeviceId = device_id; - strcpy(irp->pathname, path); + + strncpy(irp->pathname, path, 255); devredir_fuse_data_enqueue(irp, fusep); if (mode & O_CREAT) @@ -1174,7 +1184,8 @@ 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); + + strncpy(irp->pathname, path, 255); devredir_fuse_data_enqueue(irp, fusep); //DesiredAccess = DA_DELETE | DA_FILE_READ_ATTRIBUTES | DA_SYNCHRONIZE; @@ -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/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c index f4aaba14..3b830d60 100644 --- a/sesman/chansrv/pcsc/xrdp_pcsc.c +++ b/sesman/chansrv/pcsc/xrdp_pcsc.c @@ -15,8 +15,13 @@ typedef unsigned char BYTE; typedef BYTE *LPBYTE; -typedef unsigned int LONG; +#ifdef __APPLE__ +typedef int LONG; typedef unsigned int DWORD; +#else +typedef long LONG; +typedef unsigned long DWORD; +#endif typedef DWORD *LPDWORD; typedef const void *LPCVOID; typedef const char *LPCSTR; @@ -59,6 +64,8 @@ PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 }; #define LLOG_LEVEL 5 #define LLOGLN(_level, _args) \ do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0) +#define LHEXDUMP(_level, _args) \ + do { if (_level < LLOG_LEVEL) { lhexdump _args ; } } while (0) #define SCARD_ESTABLISH_CONTEXT 0x01 #define SCARD_RELEASE_CONTEXT 0x02 @@ -103,6 +110,50 @@ static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; static char g_error_str[512]; /*****************************************************************************/ +/* produce a hex dump */ +static void +lhexdump(void *p, int len) +{ + unsigned char *line; + int i; + int thisline; + int offset; + + line = (unsigned char *)p; + offset = 0; + + while (offset < len) + { + printf("%04x ", offset); + thisline = len - offset; + + if (thisline > 16) + { + thisline = 16; + } + + for (i = 0; i < thisline; i++) + { + printf("%02x ", line[i]); + } + + for (; i < 16; i++) + { + printf(" "); + } + + for (i = 0; i < thisline; i++) + { + printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); + } + + printf("\n"); + offset += thisline; + line += thisline; + } +} + +/*****************************************************************************/ static int get_display_num_from_display(const char *display_text) { @@ -156,7 +207,7 @@ get_display_num_from_display(const char *display_text) host[host_index] = 0; disp[disp_index] = 0; scre[scre_index] = 0; - LLOGLN(0, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]", + LLOGLN(10, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]", host, disp, scre)); rv = atoi(disp); return rv; @@ -219,7 +270,7 @@ connect_to_chansrv(void) bytes = sizeof(saddr.sun_path); snprintf(saddr.sun_path, bytes, "%s/.pcsc%d/pcscd.comm", home_str, dis); saddr.sun_path[bytes - 1] = 0; - LLOGLN(0, ("connect_to_chansrv: connecting to %s", saddr.sun_path)); + LLOGLN(10, ("connect_to_chansrv: connecting to %s", saddr.sun_path)); psaddr = (struct sockaddr *) &saddr; bytes = sizeof(struct sockaddr_un); error = connect(g_sck, psaddr, bytes); @@ -256,6 +307,8 @@ send_message(int code, char *data, int bytes) pthread_mutex_unlock(&g_mutex); return 1; } + LLOGLN(10, ("send_message:")); + LHEXDUMP(10, (data, bytes)); pthread_mutex_unlock(&g_mutex); return 0; } @@ -392,7 +445,7 @@ SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, } context = GET_UINT32(msg, 0); status = GET_UINT32(msg, 4); - LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", context)); + LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", (int)context)); *phContext = context; return status; } @@ -463,7 +516,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, LLOGLN(10, ("SCardConnect:")); LLOGLN(10, ("SCardConnect: hContext 0x%8.8x szReader %s dwShareMode %d " "dwPreferredProtocols %d", - hContext, szReader, dwShareMode, dwPreferredProtocols)); + (int)hContext, szReader, (int)dwShareMode, (int)dwPreferredProtocols)); if (g_sck == -1) { LLOGLN(0, ("SCardConnect: error, not connected")); @@ -507,7 +560,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, status = GET_UINT32(msg, 8); LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard 0x%8.8x " "dwActiveProtocol %d", - status, *phCard, *pdwActiveProtocol)); + status, (int)*phCard, (int)*pdwActiveProtocol)); return status; } @@ -536,7 +589,7 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition) int status; LLOGLN(10, ("SCardDisconnect: hCard 0x%8.8x dwDisposition %d", - hCard, dwDisposition)); + (int)hCard, (int)dwDisposition)); if (g_sck == -1) { LLOGLN(0, ("SCardDisconnect: error, not connected")); @@ -575,7 +628,7 @@ SCardBeginTransaction(SCARDHANDLE hCard) int bytes; int status; - LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", hCard)); + LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", (int)hCard)); if (hCard == 0) { LLOGLN(0, ("SCardBeginTransaction: error, bad hCard")); @@ -665,7 +718,7 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LLOGLN(10, ("SCardStatus:")); if (hCard == 0) { - LLOGLN(0, ("SCardStatus: error, bad hCard")); + LLOGLN(10, ("SCardStatus: error, bad hCard")); return SCARD_F_INTERNAL_ERROR; } if (g_sck == -1) @@ -673,9 +726,9 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LLOGLN(0, ("SCardStatus: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - LLOGLN(10, (" hCard 0x%8.8x", hCard)); - LLOGLN(10, (" cchReaderLen %d", *pcchReaderLen)); - LLOGLN(10, (" cbAtrLen %d", *pcbAtrLen)); + LLOGLN(10, (" hCard 0x%8.8x", (int)hCard)); + LLOGLN(10, (" cchReaderLen %d", (int)*pcchReaderLen)); + LLOGLN(10, (" cbAtrLen %d", (int)*pcbAtrLen)); cchReaderLen = *pcchReaderLen; msg = (char *) malloc(8192); @@ -703,10 +756,10 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, return SCARD_F_INTERNAL_ERROR; } - LLOGLN(10, ("SCardStatus: cchReaderLen in %d", *pcchReaderLen)); + LLOGLN(10, ("SCardStatus: cchReaderLen in %d", (int)*pcchReaderLen)); offset = 0; *pcchReaderLen = GET_UINT32(msg, offset); - LLOGLN(10, ("SCardStatus: cchReaderLen out %d", *pcchReaderLen)); + LLOGLN(10, ("SCardStatus: cchReaderLen out %d", (int)*pcchReaderLen)); offset += 4; if (cchReaderLen > 0) { @@ -721,14 +774,18 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen, LLOGLN(10, ("SCardStatus: mszReaderName out %s", mszReaderName)); offset += *pcchReaderLen; *pdwState = GET_UINT32(msg, offset); - LLOGLN(10, ("SCardStatus: dwState %d", *pdwState)); + if (*pdwState == 1) + { + *pdwState = 0x34; + } + LLOGLN(10, ("SCardStatus: dwState %d", (int)*pdwState)); offset += 4; *pdwProtocol = GET_UINT32(msg, offset); - LLOGLN(10, ("SCardStatus: dwProtocol %d", *pdwProtocol)); + LLOGLN(10, ("SCardStatus: dwProtocol %d", (int)*pdwProtocol)); offset += 4; *pcbAtrLen = GET_UINT32(msg, offset); offset += 4; - LLOGLN(10, ("SCardStatus: cbAtrLen %d", *pcbAtrLen)); + LLOGLN(10, ("SCardStatus: cbAtrLen %d", (int)*pcbAtrLen)); memcpy(pbAtr, msg + offset, *pcbAtrLen); offset += *pcbAtrLen; status = GET_UINT32(msg, offset); @@ -757,7 +814,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, char atr[36]; LLOGLN(10, ("SCardGetStatusChange:")); - LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders)); + LLOGLN(10, (" dwTimeout %d cReaders %d", (int)dwTimeout, (int)cReaders)); if (g_sck == -1) { LLOGLN(0, ("SCardGetStatusChange: error, not connected")); @@ -829,7 +886,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout, } cReaders = GET_UINT32(msg, 0); offset = 4; - LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", cReaders)); + LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", (int)cReaders)); for (index = 0; index < cReaders; index++) { rname = rgReaderStates[index].szReader; @@ -897,10 +954,10 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, LLOGLN(0, ("SCardControl: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - LLOGLN(10, (" hCard 0x%8.8x", hCard)); - LLOGLN(10, (" dwControlCode 0x%8.8x", dwControlCode)); - LLOGLN(10, (" cbSendLength %d", cbSendLength)); - LLOGLN(10, (" cbRecvLength %d", cbRecvLength)); + LLOGLN(10, (" hCard 0x%8.8x", (int)hCard)); + LLOGLN(10, (" dwControlCode 0x%8.8x", (int)dwControlCode)); + LLOGLN(10, (" cbSendLength %d", (int)cbSendLength)); + LLOGLN(10, (" cbRecvLength %d", (int)cbRecvLength)); /* #define SCARD_CTL_CODE(code) (0x42000000 + (code)) control_code = (control_code & 0x3ffc) >> 2; @@ -910,7 +967,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, dwControlCode = dwControlCode - 0x42000000; dwControlCode = dwControlCode << 2; dwControlCode = dwControlCode | (49 << 16); - LLOGLN(10, (" MS dwControlCode 0x%8.8x", dwControlCode)); + LLOGLN(10, (" MS dwControlCode 0x%8.8d", (int)dwControlCode)); msg = (char *) malloc(8192); offset = 0; @@ -946,7 +1003,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer, } offset = 0; *lpBytesReturned = GET_UINT32(msg, offset); - LLOGLN(10, (" cbRecvLength %d", *lpBytesReturned)); + LLOGLN(10, (" cbRecvLength %d", (int)*lpBytesReturned)); offset += 4; memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned); offset += *lpBytesReturned; @@ -976,9 +1033,10 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, LLOGLN(0, ("SCardTransmit: error, not connected")); return SCARD_F_INTERNAL_ERROR; } - LLOGLN(10, (" hCard 0x%8.8x", hCard)); - LLOGLN(10, (" cbSendLength %d", cbSendLength)); - LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength)); + + LLOGLN(10, (" hCard 0x%8.8x", (int)hCard)); + LLOGLN(10, (" cbSendLength %d", (int)cbSendLength)); + LLOGLN(10, (" cbRecvLength %d", (int)*pcbRecvLength)); LLOGLN(10, (" pioSendPci->dwProtocol %d", (int)(pioSendPci->dwProtocol))); LLOGLN(10, (" pioSendPci->cbPciLength %d", (int)(pioSendPci->cbPciLength))); LLOGLN(10, (" pioRecvPci %p", pioRecvPci)); @@ -993,9 +1051,11 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, offset += 4; SET_UINT32(msg, offset, pioSendPci->dwProtocol); offset += 4; - SET_UINT32(msg, offset, pioSendPci->cbPciLength); +/* SET_UINT32(msg, offset, pioSendPci->cbPciLength); */ + SET_UINT32(msg, offset, 8); offset += 4; - extra_len = pioSendPci->cbPciLength - 8; +/* extra_len = pioSendPci->cbPciLength - 8; */ + extra_len = 0; SET_UINT32(msg, offset, extra_len); offset += 4; memcpy(msg + offset, pioSendPci + 1, extra_len); @@ -1070,8 +1130,9 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci, } *pcbRecvLength = GET_UINT32(msg, offset); offset += 4; - LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength)); + LLOGLN(10, (" cbRecvLength %d", (int)*pcbRecvLength)); memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength); + LHEXDUMP(10, (pbRecvBuffer, *pcbRecvLength)); offset += *pcbRecvLength; status = GET_UINT32(msg, offset); free(msg); @@ -1113,12 +1174,16 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LLOGLN(10, ("SCardListReaders:")); LLOGLN(10, ("SCardListReaders: mszGroups %s", mszGroups)); - LLOGLN(10, ("SCardListReaders: *pcchReaders %d", *pcchReaders)); + LLOGLN(10, ("SCardListReaders: *pcchReaders %d", (int)*pcchReaders)); if (g_sck == -1) { LLOGLN(0, ("SCardListReaders: error, not connected")); return SCARD_F_INTERNAL_ERROR; } + if ((mszGroups == NULL) && (mszReaders == NULL)) + { + *pcchReaders = 0; + } msg = (char *) malloc(8192); offset = 0; SET_UINT32(msg, offset, hContext); diff --git a/sesman/chansrv/pulse/module-xrdp-sink.c b/sesman/chansrv/pulse/module-xrdp-sink.c index d56a4883..8606f412 100644 --- a/sesman/chansrv/pulse/module-xrdp-sink.c +++ b/sesman/chansrv/pulse/module-xrdp-sink.c @@ -58,6 +58,15 @@ #include <pulsecore/thread-mq.h> #include <pulsecore/rtpoll.h> +/* defined in pulse/version.h */ +#if PA_PROTOCOL_VERSION > 28 +/* these used to be defined in pulsecore/macro.h */ +typedef bool pa_bool_t; +#define FALSE ((pa_bool_t) 0) +#define TRUE (!FALSE) +#else +#endif + #include "module-xrdp-sink-symdef.h" PA_MODULE_AUTHOR("Jay Sorg"); @@ -268,6 +277,19 @@ static int get_display_num_from_display(char *display_text) { return display_num; } +static int lsend(int fd, char *data, int bytes) { + int sent = 0; + int error; + while (sent < bytes) { + error = send(fd, data + sent, bytes - sent, 0); + if (error < 1) { + return error; + } + sent += error; + } + return sent; +} + static int data_send(struct userdata *u, pa_memchunk *chunk) { char *data; int bytes; @@ -316,7 +338,7 @@ static int data_send(struct userdata *u, pa_memchunk *chunk) { h.code = 0; h.bytes = bytes + 8; - if (send(u->fd, &h, 8, 0) != 8) { + if (lsend(u->fd, (char*)(&h), 8) != 8) { pa_log("data_send: send failed"); close(u->fd); u->fd = 0; @@ -327,7 +349,7 @@ static int data_send(struct userdata *u, pa_memchunk *chunk) { data = (char*)pa_memblock_acquire(chunk->memblock); data += chunk->index; - sent = send(u->fd, data, bytes, 0); + sent = lsend(u->fd, data, bytes); pa_memblock_release(chunk->memblock); if (sent != bytes) { @@ -349,7 +371,7 @@ static int close_send(struct userdata *u) { } h.code = 1; h.bytes = 8; - if (send(u->fd, &h, 8, 0) != 8) { + if (lsend(u->fd, (char*)(&h), 8) != 8) { pa_log("close_send: send failed"); close(u->fd); u->fd = 0; diff --git a/sesman/chansrv/pulse/module-xrdp-source.c b/sesman/chansrv/pulse/module-xrdp-source.c index 2d7ec4fa..1c03b069 100644 --- a/sesman/chansrv/pulse/module-xrdp-source.c +++ b/sesman/chansrv/pulse/module-xrdp-source.c @@ -45,6 +45,15 @@ #include <pulsecore/thread-mq.h> #include <pulsecore/thread.h> +/* defined in pulse/version.h */ +#if PA_PROTOCOL_VERSION > 28 +/* these used to be defined in pulsecore/macro.h */ +typedef bool pa_bool_t; +#define FALSE ((pa_bool_t) 0) +#define TRUE (!FALSE) +#else +#endif + #include "module-xrdp-source-symdef.h" PA_MODULE_AUTHOR("Laxmikant Rashinkar"); @@ -329,8 +338,7 @@ int pa__init(pa_module *m) { pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME)); pa_source_new_data_set_sample_spec(&data, &ss); pa_source_new_data_set_channel_map(&data, &map); - //pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "Null Input")); - pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "xrdp Input")); + pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "xrdp source")); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "abstract"); u->source = pa_source_new(m->core, &data, PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY); @@ -361,7 +369,15 @@ int pa__init(pa_module *m) { u->source->thread_info.max_rewind = pa_usec_to_bytes(u->block_usec, &u->source->sample_spec); - if (!(u->thread = pa_thread_new("null-source", thread_func, u))) { + #if defined(PA_CHECK_VERSION) + #if PA_CHECK_VERSION(0, 9, 22) + if (!(u->thread = pa_thread_new("xrdp-source", thread_func, u))) { + #else + if (!(u->thread = pa_thread_new(thread_func, u))) { + #endif + #else + if (!(u->thread = pa_thread_new(thread_func, u))) + #endif pa_log("Failed to create thread."); goto fail; } diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index 4bfeef7e..f3777970 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -71,6 +71,8 @@ static int g_xrr_event_base = 0; /* non zero means we got extension */ static Cursor g_default_cursor = 0; +static char *g_override_window_title = 0; + /* used in valid field of struct rail_window_data */ #define RWD_X (1 << 0) #define RWD_Y (1 << 1) @@ -621,6 +623,18 @@ rail_process_activate(struct stream *s, int size) } /*****************************************************************************/ +static int +rail_select_input(Window window_id) +{ + XSelectInput(g_display, window_id, + PropertyChangeMask | StructureNotifyMask | + SubstructureNotifyMask | FocusChangeMask | + EnterWindowMask | LeaveWindowMask); + XSync(g_display, 0); + return 0; +} + +/*****************************************************************************/ static int APP_CC rail_restore_windows(void) { @@ -637,6 +651,7 @@ rail_restore_windows(void) XGetWindowAttributes(g_display, children[i], &window_attributes); if (!window_attributes.override_redirect) { + rail_select_input(children[i]); if (window_attributes.map_state == IsViewable) { rail_win_set_state(children[i], 0x0); /* WithdrawnState */ @@ -724,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); @@ -760,31 +775,40 @@ rail_win_set_state(Window win, unsigned long state) } /*****************************************************************************/ +/* *data pointer that needs g_free */ static int APP_CC rail_win_get_text(Window win, char **data) { int ret = 0; int i = 0; unsigned long nitems = 0; + unsigned char *ldata = 0; + char *lldata = 0; + if (g_override_window_title != 0) + { + *data = g_strdup(g_override_window_title); + return g_strlen(*data); + } ret = rail_get_property(g_display, win, g_utf8_string, g_net_wm_name, - (unsigned char **)data, &nitems); + &ldata, &nitems); if (ret != 0) { /* _NET_WM_NAME isn't set, use WM_NAME (XFetchName) instead */ - XFetchName(g_display, win, data); + XFetchName(g_display, win, &lldata); + *data = g_strdup(lldata); + i = g_strlen(*data); + XFree(lldata); + return i; } - if (data) + *data = 0; + if (ldata) { - char *ptr = *data; - for (; ptr != NULL; i++) - { - if (ptr[i] == '\0') - { - break; - } - } + *data = g_strdup((char *)ldata); + i = g_strlen(*data); + XFree(ldata); + return i; } return i; @@ -1207,6 +1231,7 @@ rail_win_send_text(Window win) int crc; struct rail_window_data* rwd; + LOG(10, ("chansrv::rail_win_send_text:")); len = rail_win_get_text(win, &data); rwd = rail_get_window_data_safe(win); if (rwd != 0) @@ -1219,7 +1244,7 @@ rail_win_send_text(Window win) if (rwd->title_crc == crc) { LOG(10, ("chansrv::rail_win_send_text: skipping, title not changed")); - XFree(data); + g_free(data); XFree(rwd); return 0; } @@ -1229,13 +1254,15 @@ 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) { + if (data && len > 0) + { LOG(10, ("chansrv::rail_win_send_text: 0x%8.8x text %s length %d", win, data, len)); make_stream(s); - init_stream(s, 1024); + init_stream(s, len + 1024); flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_FIELD_TITLE; out_uint32_le(s, 8); /* update title info */ out_uint32_le(s, win); /* window id */ @@ -1251,10 +1278,7 @@ rail_win_send_text(Window win) rwd->title_crc = crc; rail_set_window_data(win, rwd); } - if (data != 0) - { - XFree(data); - } + g_free(data); XFree(rwd); return 0; } @@ -1355,7 +1379,8 @@ rail_create_window(Window window_id, Window owner_id) flags = WINDOW_ORDER_TYPE_WINDOW; } - title_size = rail_win_get_text(window_id, &title_bytes); + title_size = 0; + title_bytes = 0; XGetTransientForHint(g_display, window_id, &transient_for); @@ -1363,21 +1388,24 @@ rail_create_window(Window window_id, Window owner_id) { style = RAIL_STYLE_TOOLTIP; ext_style = RAIL_EXT_STYLE_TOOLTIP; + /* for tooltips, we don't grab the window text */ } else if (transient_for > 0) { style = RAIL_STYLE_DIALOG; ext_style = RAIL_EXT_STYLE_DIALOG; owner_id = transient_for; + title_size = rail_win_get_text(window_id, &title_bytes); } else { style = RAIL_STYLE_NORMAL; ext_style = RAIL_EXT_STYLE_NORMAL; + title_size = rail_win_get_text(window_id, &title_bytes); } make_stream(s); - init_stream(s, 1024); + init_stream(s, title_size + 1024 + num_window_rects * 8 + num_visibility_rects * 8); out_uint32_le(s, 2); /* create_window */ out_uint32_le(s, window_id); /* window_id */ @@ -1387,6 +1415,7 @@ rail_create_window(Window window_id, Window owner_id) out_uint32_le(s, ext_style); /* extended_style */ flags |= WINDOW_ORDER_FIELD_STYLE; out_uint32_le(s, 0x05); /* show_state */ + LOG(10, (" title %s", title_bytes)); flags |= WINDOW_ORDER_FIELD_SHOW; if (title_size > 0) { @@ -1449,7 +1478,7 @@ rail_create_window(Window window_id, Window owner_id) s_mark_end(s); send_rail_drawing_orders(s->data, (int)(s->end - s->data)); free_stream(s); - XFree(title_bytes); + g_free(title_bytes); rail_set_window_data(window_id, rwd); XFree(rwd); return 0; @@ -1608,7 +1637,7 @@ rail_configure_request_window(XConfigureRequestEvent* config) flags = WINDOW_ORDER_TYPE_WINDOW; make_stream(s); - init_stream(s, 1024); + init_stream(s, 1024 + num_window_rects * 8 + num_visibility_rects * 8); out_uint32_le(s, 10); /* configure_window */ out_uint32_le(s, window_id); /* window_id */ @@ -1692,7 +1721,7 @@ rail_configure_window(XConfigureEvent *config) flags = WINDOW_ORDER_TYPE_WINDOW; make_stream(s); - init_stream(s, 1024); + init_stream(s, 1024 + num_window_rects * 8 + num_visibility_rects * 8); out_uint32_le(s, 10); /* configure_window */ out_uint32_le(s, window_id); /* window_id */ @@ -1822,10 +1851,7 @@ rail_xevent(void *xevent) case CreateNotify: LOG(10, (" got CreateNotify window 0x%8.8x parent 0x%8.8x", lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent)); - XSelectInput(g_display, lxevent->xcreatewindow.window, - PropertyChangeMask | StructureNotifyMask | - SubstructureNotifyMask | FocusChangeMask | - EnterWindowMask | LeaveWindowMask); + rail_select_input(lxevent->xcreatewindow.window); break; case DestroyNotify: @@ -1865,7 +1891,7 @@ rail_xevent(void *xevent) XGetWindowAttributes(g_display, lxevent->xmap.window, &wnd_attributes); if (wnd_attributes.map_state == IsViewable) { - rail_create_window(lxevent->xmap.window, lxevent->xmap.event); + rail_create_window(lxevent->xmap.window, g_root_window); if (!wnd_attributes.override_redirect) { rail_win_set_state(lxevent->xmap.window, 0x1); /* NormalState */ @@ -1887,7 +1913,16 @@ rail_xevent(void *xevent) LOG(10, (" window 0x%8.8x is unmapped", lxevent->xunmap.window)); if (index >= 0) { + XGetWindowAttributes(g_display, lxevent->xunmap.window, &wnd_attributes); + if (wnd_attributes.override_redirect) + { + // remove popups + rail_destroy_window(lxevent->xunmap.window); + list_remove_item(g_window_list, index); + } else { rail_show_window(lxevent->xunmap.window, 0x0); + } + rv = 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 8c76c9bc..f5e17fef 100644 --- a/sesman/chansrv/sound.c +++ b/sesman/chansrv/sound.c @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2009-2013 + * Copyright (C) Jay Sorg 2009-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,14 +23,11 @@ #include <signal.h> #include <sys/un.h> -#ifdef XRDP_LOAD_PULSE_MODULES -#include <pulse/util.h> -#endif - #include "sound.h" #include "thread_calls.h" #include "defines.h" #include "fifo.h" +#include "file_loc.h" extern int g_rdpsnd_chan_id; /* in chansrv.c */ extern int g_display_num; /* in chansrv.c */ @@ -56,14 +53,6 @@ int g_buf_index = 0; int g_sent_time[256]; int g_sent_flag[256]; -#if defined(XRDP_SIMPLESOUND) -static void *DEFAULT_CC -read_raw_audio_data(void *arg); -#endif - -#define CHANSRV_PORT_OUT_STR "/tmp/.xrdp/xrdp_chansrv_audio_out_socket_%d" -#define CHANSRV_PORT_IN_STR "/tmp/.xrdp/xrdp_chansrv_audio_in_socket_%d" - struct xr_wave_format_ex { int wFormatTag; @@ -155,6 +144,25 @@ static struct xr_wave_format_ex *g_wave_inp_formats[SND_NUM_INP_FORMATS] = static int g_client_input_format_index = 0; static int g_server_input_format_index = 0; +/* microphone related */ +static int APP_CC +sound_send_server_input_formats(void); +static int APP_CC +sound_process_input_format(int aindex, int wFormatTag, + int nChannels, int nSamplesPerSec, + int nAvgBytesPerSec, int nBlockAlign, + int wBitsPerSample, int cbSize, char *data); +static int APP_CC +sound_process_input_formats(struct stream *s, int size); +static int APP_CC +sound_input_start_recording(void); +static int APP_CC +sound_input_stop_recording(void); +static int APP_CC +sound_process_input_data(struct stream *s, int bytes); +static int DEFAULT_CC +sound_sndsrvr_source_data_in(struct trans *trans); + /*****************************************************************************/ static int APP_CC sound_send_server_output_formats(void) @@ -224,7 +232,6 @@ sound_send_server_output_formats(void) } /*****************************************************************************/ - static int sound_send_training(void) { @@ -365,13 +372,15 @@ sound_send_wave_data_chunk(char *data, int data_bytes) if ((data_bytes < 4) || (data_bytes > 128 * 1024)) { LOG(0, ("sound_send_wave_data_chunk: bad data_bytes %d", data_bytes)); - return 0; + return 1; } + LOG(20, ("sound_send_wave_data_chunk: g_sent_flag[%d] = %d", + g_cBlockNo + 1, g_sent_flag[(g_cBlockNo + 1) & 0xff])); if (g_sent_flag[(g_cBlockNo + 1) & 0xff] & 1) { LOG(10, ("sound_send_wave_data_chunk: no room")); - return 0; + return 2; } else { @@ -430,9 +439,12 @@ sound_send_wave_data(char *data, int data_bytes) int space_left; int chunk_bytes; int data_index; + int error; + int res; LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes)); data_index = 0; + error = 0; while (data_bytes > 0) { space_left = BBUF_SIZE - g_buf_index; @@ -440,19 +452,33 @@ sound_send_wave_data(char *data, int data_bytes) if (chunk_bytes < 1) { LOG(10, ("sound_send_wave_data: error")); + error = 1; break; } g_memcpy(g_buffer + g_buf_index, data + data_index, chunk_bytes); g_buf_index += chunk_bytes; if (g_buf_index >= BBUF_SIZE) { - sound_send_wave_data_chunk(g_buffer, BBUF_SIZE); g_buf_index = 0; + res = sound_send_wave_data_chunk(g_buffer, BBUF_SIZE); + if (res == 2) + { + /* don't need to error on this */ + LOG(0, ("sound_send_wave_data: dropped, no room")); + break; + } + else if (res != 0) + { + LOG(10, ("sound_send_wave_data: error")); + error = 1; + break; + } } data_bytes -= chunk_bytes; data_index += chunk_bytes; } - return 0; + + return error; } /*****************************************************************************/ @@ -467,9 +493,18 @@ sound_send_close(void) LOG(10, ("sound_send_close:")); /* send any left over data */ - sound_send_wave_data_chunk(g_buffer, g_buf_index); + if (g_buf_index) + { + if (sound_send_wave_data_chunk(g_buffer, g_buf_index) != 0) + { + LOG(10, ("sound_send_close: sound_send_wave_data_chunk failed")); + return 1; + } + } g_buf_index = 0; + g_memset(g_sent_flag, 0, sizeof(g_sent_flag)); + /* send close msg */ make_stream(s); init_stream(s, 8182); out_uint16_le(s, SNDC_CLOSE); @@ -522,23 +557,23 @@ sound_process_wave_confirm(struct stream *s, int size) /*****************************************************************************/ /* process message in from the audio source, eg pulse, alsa - on it's way to the client */ + on it's way to the client. returns error */ static int APP_CC process_pcm_message(int id, int size, struct stream *s) { switch (id) { case 0: - sound_send_wave_data(s->p, size); + return sound_send_wave_data(s->p, size); break; case 1: - sound_send_close(); + return sound_send_close(); break; default: LOG(10, ("process_pcm_message: unknown id %d", id)); break; } - return 0; + return 1; } /*****************************************************************************/ @@ -652,11 +687,6 @@ sound_init(void) g_memset(g_sent_flag, 0, sizeof(g_sent_flag)); -#ifdef XRDP_LOAD_PULSE_MODULES - if (load_pulse_modules()) - LOG(0, ("Audio and microphone redirection will not work!")); -#endif - /* init sound output */ sound_send_server_output_formats(); @@ -682,13 +712,6 @@ sound_init(void) /* save data from sound_server_source */ fifo_init(&in_fifo, 100); -#if defined(XRDP_SIMPLESOUND) - - /* start thread to read raw audio data from pulseaudio device */ - tc_thread_create(read_raw_audio_data, 0); - -#endif - return 0; } @@ -696,6 +719,7 @@ sound_init(void) int APP_CC sound_deinit(void) { + LOG(10, ("sound_deinit:")); if (g_audio_l_trans_out != 0) { trans_delete(g_audio_l_trans_out); @@ -722,10 +746,6 @@ sound_deinit(void) fifo_deinit(&in_fifo); -#ifdef XRDP_LOAD_PULSE_MODULES - system("pulseaudio --kill"); -#endif - return 0; } @@ -814,180 +834,49 @@ sound_get_wait_objs(tbus *objs, int *count, int *timeout) int APP_CC sound_check_wait_objs(void) { + if (g_audio_l_trans_out != 0) { - trans_check_wait_objs(g_audio_l_trans_out); + if (trans_check_wait_objs(g_audio_l_trans_out) != 0) + { + LOG(10, ("sound_check_wait_objs: g_audio_l_trans_out returned non-zero")); + trans_delete(g_audio_l_trans_out); + g_audio_l_trans_out = 0; + } } if (g_audio_c_trans_out != 0) { - trans_check_wait_objs(g_audio_c_trans_out); - } - - if (g_audio_l_trans_in != 0) - { - trans_check_wait_objs(g_audio_l_trans_in); - } - - if (g_audio_c_trans_in != 0) - { - trans_check_wait_objs(g_audio_c_trans_in); - } - - return 0; -} - -/** - * Load xrdp pulseaudio sink and source modules - * - * @return 0 on success, -1 on failure - *****************************************************************************/ - -#ifdef XRDP_LOAD_PULSE_MODULES - -static int APP_CC -load_pulse_modules() -{ - struct sockaddr_un sa; - - pid_t pid; - char* cli; - int fd; - int i; - int rv; - char buf[1024]; - - /* is pulse audio daemon running? */ - if (pa_pid_file_check_running(&pid, "pulseaudio") < 0) - { - LOG(0, ("load_pulse_modules: No PulseAudio daemon running, " - "or not running as session daemon")); - } - - /* get name of unix domain socket used by pulseaudio for CLI */ - if ((cli = (char *) pa_runtime_path("cli")) == NULL) - { - LOG(0, ("load_pulse_modules: Error getting PulesAudio runtime path")); - return -1; - } - - /* open a socket */ - if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) - { - pa_xfree(cli); - LOG(0, ("load_pulse_modules: Socket open error")); - return -1; - } - - /* set it up */ - memset(&sa, 0, sizeof(struct sockaddr_un)); - sa.sun_family = AF_UNIX; - pa_strlcpy(sa.sun_path, cli, sizeof(sa.sun_path)); - pa_xfree(cli); - - for (i = 0; i < 20; i++) - { - if (pa_pid_file_kill(SIGUSR2, NULL, "pulseaudio") < 0) - LOG(0, ("load_pulse_modules: Failed to kill PulseAudio daemon")); - - if ((rv = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 && - (errno != ECONNREFUSED && errno != ENOENT)) + if (trans_check_wait_objs(g_audio_c_trans_out) != 0) { - LOG(0, ("load_pulse_modules: connect() failed with error: %s", - strerror(errno))); - return -1; + LOG(10, ("sound_check_wait_objs: g_audio_c_trans_out returned non-zero")); + trans_delete(g_audio_c_trans_out); + g_audio_c_trans_out = 0; } - - if (rv >= 0) - break; - - pa_msleep(300); } - if (i >= 20) - { - LOG(0, ("load_pulse_modules: Daemon not responding")); - return -1; - } - - LOG(0, ("load_pulse_modules: connected to pulseaudio daemon")); - - /* read back PulseAudio sign on message */ - memset(buf, 0, 1024); - recv(fd, buf, 1024, 0); - - /* send cmd to load source module */ - memset(buf, 0, 1024); - sprintf(buf, "load-module module-xrdp-source\n"); - send(fd, buf, strlen(buf), 0); - - /* read back response */ - memset(buf, 0, 1024); - recv(fd, buf, 1024, 0); - if (strcasestr(buf, "Module load failed") != 0) - { - LOG(0, ("load_pulse_modules: Error loading module-xrdp-source")); - } - else + if (g_audio_l_trans_in != 0) { - LOG(0, ("load_pulse_modules: Loaded module-xrdp-source")); - - /* success, set it as the default source */ - memset(buf, 0, 1024); - sprintf(buf, "set-default-source xrdp-source\n"); - send(fd, buf, strlen(buf), 0); - - memset(buf, 0, 1024); - recv(fd, buf, 1024, 0); - - if (strcasestr(buf, "does not exist") != 0) - { - LOG(0, ("load_pulse_modules: Error setting default source")); - } - else + if (trans_check_wait_objs(g_audio_l_trans_in) != 0) { - LOG(0, ("load_pulse_modules: set default source")); + LOG(10, ("sound_check_wait_objs: g_audio_l_trans_in returned non-zero")); + trans_delete(g_audio_l_trans_in); + g_audio_l_trans_in = 0; } } - /* send cmd to load sink module */ - memset(buf, 0, 1024); - sprintf(buf, "load-module module-xrdp-sink\n"); - send(fd, buf, strlen(buf), 0); - - /* read back response */ - memset(buf, 0, 1024); - recv(fd, buf, 1024, 0); - if (strcasestr(buf, "Module load failed") != 0) - { - LOG(0, ("load_pulse_modules: Error loading module-xrdp-sink")); - } - else + if (g_audio_c_trans_in != 0) { - LOG(0, ("load_pulse_modules: Loaded module-xrdp-sink")); - - /* success, set it as the default sink */ - memset(buf, 0, 1024); - sprintf(buf, "set-default-sink xrdp-sink\n"); - send(fd, buf, strlen(buf), 0); - - memset(buf, 0, 1024); - recv(fd, buf, 1024, 0); - - if (strcasestr(buf, "does not exist") != 0) - { - LOG(0, ("load_pulse_modules: Error setting default sink")); - } - else + if (trans_check_wait_objs(g_audio_c_trans_in) != 0) { - LOG(0, ("load_pulse_modules: set default sink")); + LOG(10, ("sound_check_wait_objs: g_audio_c_trans_in returned non-zero")); + trans_delete(g_audio_c_trans_in); + g_audio_c_trans_in = 0; } } - close(fd); return 0; } -#endif /****************************************************************************** ** ** @@ -1152,7 +1041,7 @@ sound_process_input_formats(struct stream *s, int size) *****************************************************************************/ static int APP_CC -sound_input_start_recording() +sound_input_start_recording(void) { struct stream* s; @@ -1186,7 +1075,7 @@ sound_input_start_recording() *****************************************************************************/ static int APP_CC -sound_input_stop_recording() +sound_input_stop_recording(void) { struct stream* s; @@ -1252,14 +1141,14 @@ 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); in_uint16_le(ts, bytes_req); - if (bytes_req != 0) - xstream_new(s, bytes_req + 2); + xstream_new(s, bytes_req + 2); if (cmd == PA_CMD_SEND_DATA) { @@ -1309,7 +1198,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) { @@ -1320,133 +1208,7 @@ sound_sndsrvr_source_data_in(struct trans *trans) sound_input_stop_recording(); } - return 0; -} - -/*****************************************************************************/ - -#if defined(XRDP_SIMPLESOUND) - -#define AUDIO_BUF_SIZE 2048 + xstream_free(s); -static int DEFAULT_CC -sttrans_data_in(struct trans *self) -{ - LOG(0, ("sttrans_data_in:\n")); return 0; } - -/** - * read raw audio data from pulseaudio device and write it - * to a unix domain socket on which trans server is listening - */ - -static void *DEFAULT_CC -read_raw_audio_data(void *arg) -{ - pa_sample_spec samp_spec; - pa_simple *simple = NULL; - uint32_t bytes_read; - char *cptr; - int i; - int error; - struct trans *strans; - char path[256]; - struct stream *outs; - - strans = trans_create(TRANS_MODE_UNIX, 8192, 8192); - - if (strans == 0) - { - LOG(0, ("read_raw_audio_data: trans_create failed\n")); - return 0; - } - - strans->trans_data_in = sttrans_data_in; - g_snprintf(path, 255, CHANSRV_PORT_OUT_STR, g_display_num); - - if (trans_connect(strans, "", path, 100) != 0) - { - LOG(0, ("read_raw_audio_data: trans_connect failed\n")); - trans_delete(strans); - return 0; - } - - /* setup audio format */ - samp_spec.format = PA_SAMPLE_S16LE; - samp_spec.rate = 44100; - samp_spec.channels = 2; - - /* if we are root, then for first 8 seconds connection to pulseaudo server - fails; if we are non-root, then connection succeeds on first attempt; - for now we have changed code to be non-root, but this may change in the - future - so pretend we are root and try connecting to pulseaudio server - for upto one minute */ - for (i = 0; i < 60; i++) - { - simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL, - "record", &samp_spec, NULL, NULL, &error); - - if (simple) - { - /* connected to pulseaudio server */ - LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n")); - break; - } - - LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n")); - LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); - g_sleep(1000); - } - - if (i == 60) - { - /* failed to connect to audio server */ - trans_delete(strans); - return NULL; - } - - /* insert header just once */ - outs = trans_get_out_s(strans, 8192); - out_uint32_le(outs, 0); - out_uint32_le(outs, AUDIO_BUF_SIZE + 8); - cptr = outs->p; - out_uint8s(outs, AUDIO_BUF_SIZE); - s_mark_end(outs); - - while (1) - { - /* read a block of raw audio data... */ - g_memset(cptr, 0, 4); - bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error); - - if (bytes_read < 0) - { - LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n")); - LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error))); - break; - } - - /* bug workaround: - even when there is no audio data, pulseaudio is returning without - errors but the data itself is zero; we use this zero data to - determine that there is no audio data present */ - if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0) - { - g_sleep(10); - continue; - } - - if (trans_force_write_s(strans, outs) != 0) - { - LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n")); - break; - } - } - - pa_simple_free(simple); - trans_delete(strans); - return NULL; -} - -#endif diff --git a/sesman/chansrv/sound.h b/sesman/chansrv/sound.h index c26d0913..f3563dab 100644 --- a/sesman/chansrv/sound.h +++ b/sesman/chansrv/sound.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2009-2013 + * Copyright (C) Jay Sorg 2009-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,6 @@ #ifndef _SOUND_H_ #define _SOUND_H_ -#if defined(XRDP_SIMPLESOUND) -#include <pulse/simple.h> -#include <pulse/error.h> -#endif - #include "arch.h" #include "parse.h" #include "os_calls.h" @@ -63,17 +58,4 @@ int APP_CC sound_check_wait_objs(void); int APP_CC sound_data_in(struct stream* s, int chan_id, int chan_flags, int length, int total_length); -/* microphone related */ -static int APP_CC sound_send_server_input_formats(void); - -static int APP_CC sound_process_input_format(int aindex, int wFormatTag, - int nChannels, int nSamplesPerSec, int nAvgBytesPerSec, - int nBlockAlign, int wBitsPerSample, int cbSize, char *data); - -static int APP_CC sound_process_input_formats(struct stream *s, int size); -static int APP_CC sound_input_start_recording(); -static int APP_CC sound_input_stop_recording(); -static int APP_CC sound_process_input_data(struct stream *s, int bytes); -static int DEFAULT_CC sound_sndsrvr_source_data_in(struct trans *trans); -static int APP_CC load_pulse_modules(); #endif |