diff options
Diffstat (limited to 'src/rdp/rdp_module.c')
-rw-r--r-- | src/rdp/rdp_module.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/rdp/rdp_module.c b/src/rdp/rdp_module.c new file mode 100644 index 0000000..a315325 --- /dev/null +++ b/src/rdp/rdp_module.c @@ -0,0 +1,168 @@ +/* BSD-2-Clause license + * + * Copyright (c) 2018-2023 NST <www.newinfosec.ru>, sss <sss at dark-alexandr dot net>. + * + */ + +#include <unistd.h> + +#include <freerdp/freerdp.h> +#include <freerdp/gdi/gdi.h> + +#include <webrdp_core_api.h> +#include <webrdp_module_api.h> + +#include "rdp_backend_api.h" +#include "rdp_impl.h" +#include "rdp_display_output.h" +#include "rdp_user_input.h" +#include "rdp_clipboard.h" +#include "rdp_ft.h" +#include "rdp_module.h" +#include "rdp_settings.h" + +/* static void +send_termination_message (rdp_internals* i) +{ + i->core->send_termination_msg (i->task_info); +} */ + +static bool +rdp_init(void *internals) +{ + bool ret = true; + if (!rdp_init_internals(internals)) + { + /* TODO: handle error */ + return false; + } + if (!((rdp_internals *)internals)->instance) + { + /* TODO: handle error */ + ret = false; + } + if (!rdp_init_settings(internals)) + { + /* TODO: handle error */ + ret = false; + } + if (!rdp_connect(internals)) + { + /* TODO: handle error */ + ret = false; + } + if (!ret) + { + rdp_internals *i = internals; + i->core->api_msgs->send_error_msg( + "rdp_module_internal_error", i->task_info); + /*send_termination_message (i);*/ + i->core->api_core->task_finished(false, i->task_info); + } + return ret; +} + +static void +destroy_rdp(void *internals) +{ + rdp_internals *_i = internals; + /* stop all rdp fd's watchers */ + int i; + for (i = 0; i < _i->rdp_fd_count; ++i) + { + if (ev_is_active(&(_i->rdp_fd[i]))) + { + ev_io_stop( + _i->core->api_core->get_libev_loop(_i->task_info), + &(_i->rdp_fd[i])); + } + } + if (_i->conn_state == rdp_conn_state_connected) + { + freerdp_disconnect(_i->instance); + _i->conn_state = rdp_conn_state_offline; + } + _i->rdp_fd_count = 0; + if (_i->context) + { + if (_i->context->clipboard && _i->context->clipboard->srv_fmts + && _i->context->clipboard->srv_fmts_count) + { + for (i = 0; i < _i->context->clipboard->srv_fmts_count; + ++i) + { + if (_i->context->clipboard->srv_fmts[i] + .rdp_fmt.formatName) + { + free(_i->context->clipboard->srv_fmts[i] + .rdp_fmt.formatName); + } + } + free(_i->context->clipboard->srv_fmts); + } + if (_i->context->clipboard && _i->context->clipboard->clipboard) + { + ClipboardDestroy(_i->context->clipboard->clipboard); + } + if (_i->context->clipboard + && _i->context->clipboard->client_filelist_cache) + { + free(_i->context->clipboard->client_filelist_cache); + _i->context->clipboard->client_filelist_cache = 0; + } + free(_i->context->ft_to_client); + free(_i->context->ft_to_server); + } + if (_i->instance) + { + freerdp_context_free(_i->instance); + freerdp_free(_i->instance); + _i->instance = 0; + } + if (internals) + { + rdp_settings_free(internals); + internals = 0; + } +} + +static void +rdp_set_task_info(void *task_info, void *internals) +{ + rdp_internals *i = internals; + i->task_info = task_info; +} + +bool +rdp_create(wrdp_core_exports *core, wrdp_backend_module *module) +{ + wrdp_backend_module *backend = module; + if (!backend) + { + return false; + } + backend->callbacks_module->init = rdp_init; + backend->callbacks_module->destroy = destroy_rdp; + backend->callbacks_module->set_setting_int = rdp_set_setting_int; + backend->callbacks_module->set_setting_str = rdp_set_setting_str; + backend->callbacks_module->set_task_info = rdp_set_task_info; + register_input(backend); + register_clipboard(backend); + register_ft(backend); + backend->backend_internals = calloc(1, sizeof(rdp_internals)); + if (!backend->backend_internals) + { + perror("calloc"); + return false; + } + memset(&(((rdp_internals *)backend->backend_internals)->my_settings), 0, + sizeof(my_rdp_settings)); + /* TODO: do we need to zero each option structure in settings ? */ + { + rdp_internals *i = backend->backend_internals; + i->core = core; + i->backend = backend; + } + + return true; +} |