/* BSD-2-Clause license * * Copyright (c) 2018-2023 NST , sss . * */ #include #include #include #include #include #include #include #include "ws_session.h" #include "ws_protocol.h" #include "webrdp_module_api.h" #include "wrdp_thpool_internals.h" #include "globals.h" #include "task.h" #include "thread_impl.h" #include "utilities.h" #include "log.h" void send_text_msg(const char *msg, void *_task_info) { ws_send_text((uint8_t *)msg, strlen(msg), _task_info); } static void send_typed_text_msg(const char *type, const char *msg, void *_task_info) { size_t len = strlen(msg) + strlen(type); uint8_t *buf = malloc(len); #ifdef DEBUG log_msg((const uint8_t *)msg, strlen(msg), wrdp_log_level_trace, 0); #endif if (!buf) { perror("malloc"); return; } memset(buf, 0, len); memcpy(buf, type, strlen(type)); memcpy(buf + strlen(type), msg, len - strlen(type)); ws_send_text(buf, len, _task_info); free(buf); } void send_text_info_msg(const char *msg, void *task_info) { send_typed_text_msg("I:", msg, task_info); } void send_text_warning_msg(const char *msg, void *task_info) { send_typed_text_msg("W:", msg, task_info); } void send_text_debug_msg(const char *msg, void *task_info) { send_typed_text_msg("D:", msg, task_info); } void send_error_msg(const char *msg, void *task_info) { send_typed_text_msg("E:", msg, task_info); } void send_ctl_msg(const char *msg, void *task_info) { send_typed_text_msg("0:", msg, task_info); } static void send_termination_msg(void *task_info) { ws_send_text((uint8_t *)"T:", 2, task_info); } static void send_typed_proto_msg( uint8_t *buf, size_t size, ws_output_codes type, void *task_info) { uint8_t *msg = ws_pack_msg(buf, size, type); ws_send_binary(msg, size + 4, task_info); free(msg); } static void send_begin_paint(void *task_info) { send_typed_proto_msg(0, 0, ws_out_beginpaint, task_info); } static void send_end_paint(void *task_info) { send_typed_proto_msg(0, 0, ws_out_endpaint, task_info); } static void send_bitmap( const wrdp_core_display_bmp *bmp, uint8_t *bmp_data, void *task_info) { size_t buf_size = sizeof(wrdp_core_display_bmp) + bmp->size; uint8_t *buf = malloc(buf_size); if (!buf) { perror("malloc"); return; } memcpy(buf, bmp, sizeof(wrdp_core_display_bmp)); memcpy(buf + sizeof(wrdp_core_display_bmp), bmp_data, bmp->size); send_typed_proto_msg(buf, buf_size, ws_out_bitmap, task_info); free(buf); } static void send_opaque_rect_order( const wrdp_core_display_opaque_rect_order *oro, void *task_info) { send_typed_proto_msg((uint8_t *)oro, sizeof(wrdp_core_display_opaque_rect_order), ws_out_opaquerect, task_info); } static void send_set_bounds(const wrdp_core_display_bounds *bounds, void *task_info) { send_typed_proto_msg((uint8_t *)bounds, sizeof(wrdp_core_display_bounds), ws_out_setbounds, task_info); } static void send_pat_blt(const wrdp_core_display_patblt_order *patblt, void *task_info) { send_typed_proto_msg((uint8_t *)patblt, sizeof(wrdp_core_display_patblt_order), ws_out_patblt, task_info); } static void send_multi_opaque_rect( const wrdp_core_display_m_opaque_rect *mrect, void *task_info) { size_t buf_size = (sizeof(uint32_t) * 2) + (sizeof(wrdp_core_display_delta_rect) * mrect->num_rect); uint8_t *buf = malloc(buf_size); if (!buf) { perror("malloc"); return; } memcpy(buf, (uint8_t *)&(mrect->color), 4); memcpy(buf + 4, (uint8_t *)&(mrect->num_rect), 4); memcpy(buf + 4 + 4, (uint8_t *)mrect->rects, mrect->num_rect * sizeof(wrdp_core_display_delta_rect)); send_typed_proto_msg(buf, buf_size, ws_out_multi_opaquerect, task_info); free(buf); } static void send_scr_blt(const wrdp_core_display_scr_blt *scr_blt, void *task_info) { send_typed_proto_msg((uint8_t *)&scr_blt, sizeof(wrdp_core_display_scr_blt), ws_out_scr_btl, task_info); } static void send_ptr_new(const wrdp_core_display_cursor_info *ptr, void *task_info) { size_t buf_size = sizeof(wrdp_core_display_cursor) - sizeof(uint8_t *) + sizeof(wrdp_core_display_cursor_info) - sizeof(uint32_t) - sizeof(wrdp_core_display_cursor *) + ptr->data_size; uint8_t *buf = malloc(buf_size); if (!buf) { perror("malloc"); return; } memcpy(buf, ptr, sizeof(wrdp_core_display_cursor_info) - sizeof(uint32_t) - sizeof(wrdp_core_display_cursor *)); memcpy(buf + sizeof(wrdp_core_display_cursor_info) - sizeof(uint32_t) - sizeof(wrdp_core_display_cursor *), ptr->cur, sizeof(wrdp_core_display_cursor) - sizeof(uint8_t *)); memcpy(buf + sizeof(wrdp_core_display_cursor_info) - sizeof(uint32_t) - sizeof(wrdp_core_display_cursor *) + sizeof(wrdp_core_display_cursor) - sizeof(uint8_t *), ptr->cur->data, ptr->data_size); send_typed_proto_msg(buf, buf_size, ws_out_ptr_new, task_info); free(buf); } static void send_ptr_free(uint32_t ptr_id, void *task_info) { send_typed_proto_msg( (uint8_t *)&ptr_id, sizeof(uint32_t), ws_out_ptr_free, task_info); } static void send_ptr_set(uint32_t ptr_id, void *task_info) { send_typed_proto_msg( (uint8_t *)&ptr_id, sizeof(uint32_t), ws_out_ptr_set, task_info); } static void send_ptr_set_null(void *task_info) { send_typed_proto_msg(0, 0, ws_out_ptr_set_null, task_info); } static void send_ptr_set_default(void *task_info) { send_typed_proto_msg(0, 0, ws_out_ptr_set_default, task_info); } static void clipboard_changed(uint8_t *fmts, size_t fmts_count, void *task_info) { send_typed_proto_msg( fmts, fmts_count, ws_out_clpbrd_changed, task_info); } static void clipboard_send_data(uint8_t *buf, size_t buf_size, void *task_info) { send_typed_proto_msg(buf, buf_size, ws_out_clpbrd_data, task_info); } static void clipboard_request_data(uint8_t data_fmt, void *task_info) { send_typed_proto_msg( &data_fmt, 1, ws_out_clpbrd_request_data, task_info); } static void ft_request(const wrdp_backend_ft_file_request *req, void *task_info) { send_typed_proto_msg((uint8_t *)req, sizeof(wrdp_backend_ft_file_request), ws_out_ft_request, task_info); } static void ft_send_chunk( const wrdp_backend_ft_chunk *chunk, uint8_t *data, void *task_info) { size_t buf_size = sizeof(wrdp_backend_ft_chunk) + chunk->size; uint8_t *buf = malloc(buf_size); if (!buf) { perror("malloc"); return; } memcpy(buf, chunk, sizeof(wrdp_backend_ft_chunk)); memcpy(buf + sizeof(wrdp_backend_ft_chunk), data, chunk->size); send_typed_proto_msg(buf, buf_size, ws_out_ft_chunk, task_info); free(buf); } static void ft_finish(const wrdp_backend_ft_status *status, void *task_info) { send_typed_proto_msg((uint8_t *)status, sizeof(wrdp_backend_ft_status), ws_out_ft_finish, task_info); } static void * get_libev_loop(void *_task_info) { task_info *t = _task_info; wrdp_thpool_task *pt = t->wrdp_thpool_task; return pt->thread->ev_th_loop; } static void task_finished(bool success, void *_task_info) { /* TODO: handle task failure */ destroy_task(_task_info); } static void reset_idle(void *_task_info) { task_info *t = _task_info; t->idle_time = 0; } bool init_exports() { g_globals.exports = calloc(1, sizeof(wrdp_core_exports)); if (!g_globals.exports) { perror("calloc"); exit(EXIT_FAILURE); } g_globals.exports->api_core = calloc(1, sizeof(wrdp_core_cb_core)); if (!g_globals.exports->api_core) { perror("calloc"); exit(EXIT_FAILURE); } g_globals.exports->api_msgs = calloc(1, sizeof(wrdp_core_cb_msgs)); if (!g_globals.exports->api_msgs) { perror("calloc"); exit(EXIT_FAILURE); } g_globals.exports->api_paint = calloc(1, sizeof(wrdp_core_cb_paint)); if (!g_globals.exports->api_paint) { perror("calloc"); exit(EXIT_FAILURE); } g_globals.exports->api_clipboard = calloc(1, sizeof(wrdp_core_cb_clipboard)); if (!g_globals.exports->api_clipboard) { perror("calloc"); exit(EXIT_FAILURE); } g_globals.exports->api_filetransfers = calloc(1, sizeof(wrdp_core_cb_filetransfer)); if (!g_globals.exports->api_filetransfers) { perror("calloc"); exit(EXIT_FAILURE); } g_globals.exports->api_utils = calloc(1, sizeof(wrdp_core_cb_utils)); if (!g_globals.exports->api_utils) { perror("calloc"); exit(EXIT_FAILURE); } g_globals.exports->api_paint->send_begin_paint = send_begin_paint; g_globals.exports->api_paint->send_bitmap = send_bitmap; g_globals.exports->api_paint->send_end_paint = send_end_paint; g_globals.exports->api_paint->send_multi_opaque_rect = send_multi_opaque_rect; g_globals.exports->api_paint->send_opaque_rect_order = send_opaque_rect_order; g_globals.exports->api_paint->send_pat_blt = send_pat_blt; g_globals.exports->api_paint->send_ptr_free = send_ptr_free; g_globals.exports->api_paint->send_ptr_new = send_ptr_new; g_globals.exports->api_paint->send_ptr_set = send_ptr_set; g_globals.exports->api_paint->send_ptr_set_default = send_ptr_set_default; g_globals.exports->api_paint->send_ptr_set_null = send_ptr_set_null; g_globals.exports->api_paint->send_scr_blt = send_scr_blt; g_globals.exports->api_paint->send_set_bounds = send_set_bounds; g_globals.exports->api_msgs->send_text_msg = send_text_msg; g_globals.exports->api_msgs->send_text_info_msg = send_text_info_msg; g_globals.exports->api_msgs->send_text_warning_msg = send_text_warning_msg; g_globals.exports->api_msgs->send_text_debug_msg = send_text_debug_msg; g_globals.exports->api_msgs->send_ctl_msg = send_ctl_msg; g_globals.exports->api_msgs->send_error_msg = send_error_msg; g_globals.exports->api_msgs->send_termination_msg = send_termination_msg; g_globals.exports->api_core->get_libev_loop = get_libev_loop; g_globals.exports->api_core->task_finished = task_finished; g_globals.exports->api_core->reset_idle = reset_idle; g_globals.exports->api_clipboard->send_data = clipboard_send_data; g_globals.exports->api_clipboard->clipboard_changed = clipboard_changed; g_globals.exports->api_clipboard->request_data = clipboard_request_data; g_globals.exports->api_filetransfers->ft_finish = ft_finish; g_globals.exports->api_filetransfers->ft_request = ft_request; g_globals.exports->api_filetransfers->ft_send_chunk = ft_send_chunk; g_globals.exports->api_utils->hex_print = hex_print; g_globals.exports->api_utils->log_msg = log_msg; g_globals.exports->api_utils->log_msg_ex = log_msg_ex; return true; }