channels/rail: fixed multithread side effect by creating full orders copy for events.
This commit is contained in:
parent
e701bf1bcf
commit
7744e17ec2
@ -26,6 +26,7 @@
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
#include <freerdp/utils/rail.h>
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
#include "rail_orders.h"
|
||||
@ -44,15 +45,25 @@ void rail_send_channel_data(void* rail_object, void* data, size_t length)
|
||||
|
||||
static void on_free_rail_channel_event(RDP_EVENT* event)
|
||||
{
|
||||
|
||||
if (event->event_class == RDP_EVENT_CLASS_RAIL)
|
||||
{
|
||||
rail_free_cloned_order(event->event_type, event->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void rail_send_channel_event(void* rail_object, uint16 event_type, void* param)
|
||||
{
|
||||
RDP_EVENT* out_event = NULL;
|
||||
railPlugin* plugin = (railPlugin*) rail_object;
|
||||
out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type, on_free_rail_channel_event, param);
|
||||
svc_plugin_send_event((rdpSvcPlugin*) plugin, out_event);
|
||||
void * payload = NULL;
|
||||
|
||||
payload = rail_clone_order(event_type, param);
|
||||
if (payload != NULL)
|
||||
{
|
||||
out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type,
|
||||
on_free_rail_channel_event, payload);
|
||||
svc_plugin_send_event((rdpSvcPlugin*) plugin, out_event);
|
||||
}
|
||||
}
|
||||
|
||||
static void rail_process_connect(rdpSvcPlugin* plugin)
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <freerdp/utils/event.h>
|
||||
#include <freerdp/utils/hexdump.h>
|
||||
#include <freerdp/utils/rail.h>
|
||||
#include <freerdp/rail/rail.h>
|
||||
|
||||
|
||||
@ -128,9 +129,30 @@ void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail)
|
||||
rail->DestroyWindow = xf_rail_DestroyWindow;
|
||||
}
|
||||
|
||||
static void xf_on_free_rail_client_event(RDP_EVENT* event)
|
||||
{
|
||||
if (event->event_class == RDP_EVENT_CLASS_RAIL)
|
||||
{
|
||||
rail_free_cloned_order(event->event_type, event->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void xf_send_rail_client_event(rdpChanMan* chanman, uint16 event_type, void* param)
|
||||
{
|
||||
RDP_EVENT* out_event = NULL;
|
||||
void * payload = NULL;
|
||||
|
||||
payload = rail_clone_order(event_type, param);
|
||||
if (payload != NULL)
|
||||
{
|
||||
out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type,
|
||||
xf_on_free_rail_client_event, payload);
|
||||
freerdp_chanman_send_event(chanman, out_event);
|
||||
}
|
||||
}
|
||||
|
||||
void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event)
|
||||
{
|
||||
RDP_EVENT* new_event;
|
||||
RAIL_SYSPARAM_ORDER* sysparam;
|
||||
|
||||
sysparam = (RAIL_SYSPARAM_ORDER*) event->user_data;
|
||||
@ -150,10 +172,7 @@ void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChanMan* chanman, RDP_E
|
||||
sysparam->taskbarPos.right = 0;
|
||||
sysparam->taskbarPos.bottom = 0;
|
||||
|
||||
new_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL,
|
||||
RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, NULL, sysparam);
|
||||
|
||||
freerdp_chanman_send_event(chanman, new_event);
|
||||
xf_send_rail_client_event(chanman, RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, sysparam);
|
||||
}
|
||||
|
||||
const char* error_code_names[] =
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <freerdp/utils/event.h>
|
||||
#include <freerdp/utils/hexdump.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/rail.h>
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
|
||||
@ -378,8 +379,6 @@ static uint8 server_app_get_resp_app_id[] =
|
||||
};
|
||||
|
||||
|
||||
#define RAIL_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
|
||||
|
||||
#define EMULATE_SERVER_SEND_CHANNEL_DATA(inst, byte_array) \
|
||||
emulate_server_send_channel_data(inst, byte_array, RAIL_ARRAY_SIZE(byte_array))
|
||||
|
||||
@ -477,6 +476,14 @@ int stream_equal_dump(void * dataS, size_t sizeS, void * data, size_t size)
|
||||
return 1;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
static void test_on_free_rail_client_event(RDP_EVENT* event)
|
||||
{
|
||||
if (event->event_class == RDP_EVENT_CLASS_RAIL)
|
||||
{
|
||||
rail_free_cloned_order(event->event_type, event->user_data);
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
static void send_ui_event2plugin(
|
||||
rdpChanMan* chan_man,
|
||||
uint16 event_type,
|
||||
@ -484,10 +491,15 @@ static void send_ui_event2plugin(
|
||||
)
|
||||
{
|
||||
RDP_EVENT* out_event = NULL;
|
||||
out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type,
|
||||
NULL, data);
|
||||
void * payload = NULL;
|
||||
|
||||
freerdp_chanman_send_event(chan_man, out_event);
|
||||
payload = rail_clone_order(event_type, data);
|
||||
if (payload != NULL)
|
||||
{
|
||||
out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type,
|
||||
test_on_free_rail_client_event, payload);
|
||||
freerdp_chanman_send_event(chan_man, out_event);
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
static void emulate_server_send_channel_data(
|
||||
@ -530,9 +542,9 @@ static int emulate_client_send_channel_data(
|
||||
printf("Client send to server (%d packet):\n", counter);
|
||||
freerdp_hexdump(data, size);
|
||||
|
||||
// add to global dumps list
|
||||
save_dump(data, size);
|
||||
|
||||
// add to global dumps list
|
||||
return 0;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -547,9 +559,19 @@ void save_event(RDP_EVENT* event, RAIL_EVENT* rail_event)
|
||||
break;
|
||||
|
||||
case RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS:
|
||||
printf("UI receive Exec Results Event\n");
|
||||
memcpy(&rail_event->order_info.exec_result, event->user_data,
|
||||
sizeof(RAIL_EXEC_ORDER));
|
||||
{
|
||||
RAIL_EXEC_RESULT_ORDER* exec_result = (RAIL_EXEC_RESULT_ORDER*)event->user_data;
|
||||
printf("UI receive Exec Results Event\n");
|
||||
memcpy(&rail_event->order_info.exec_result, event->user_data,
|
||||
sizeof(RAIL_EXEC_RESULT_ORDER));
|
||||
|
||||
rail_unicode_string_alloc(&rail_event->order_info.exec_result.exeOrFile,
|
||||
exec_result->exeOrFile.length);
|
||||
|
||||
memcpy(rail_event->order_info.exec_result.exeOrFile.string,
|
||||
exec_result->exeOrFile.string,
|
||||
exec_result->exeOrFile.length);
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM:
|
||||
@ -574,6 +596,9 @@ void save_event(RDP_EVENT* event, RAIL_EVENT* rail_event)
|
||||
printf("UI receive AppId Response Event\n");
|
||||
memcpy(&rail_event->order_info.get_appid_resp, event->user_data,
|
||||
sizeof(RAIL_GET_APPID_RESP_ORDER));
|
||||
|
||||
rail_event->order_info.get_appid_resp.applicationId.string =
|
||||
&rail_event->order_info.get_appid_resp.applicationIdBuffer[0];
|
||||
break;
|
||||
|
||||
case RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO:
|
||||
@ -605,13 +630,12 @@ static void process_events_and_channel_data_from_plugin(thread_param* param)
|
||||
event->event_type,
|
||||
counter);
|
||||
|
||||
// add to global event list
|
||||
if (param->in_events_number < RAIL_ARRAY_SIZE(param->in_events))
|
||||
{
|
||||
save_event(event, ¶m->in_events[param->in_events_number]);
|
||||
param->in_events_number++;
|
||||
}
|
||||
|
||||
// add to global event list
|
||||
freerdp_event_free(event);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
#define RAIL_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
|
||||
|
||||
FREERDP_API void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString);
|
||||
FREERDP_API void rail_unicode_string_free(UNICODE_STRING* unicode_string);
|
||||
FREERDP_API void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string);
|
||||
@ -31,5 +33,7 @@ FREERDP_API void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_st
|
||||
FREERDP_API void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string);
|
||||
FREERDP_API void rail_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16);
|
||||
FREERDP_API void rail_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16);
|
||||
FREERDP_API void* rail_clone_order(uint32 event_type, void* order);
|
||||
FREERDP_API void rail_free_cloned_order(uint32 event_type, void* order);
|
||||
|
||||
#endif /* __RAIL_UTILS_H */
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#include <freerdp/utils/rail.h>
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString)
|
||||
{
|
||||
@ -80,3 +81,104 @@ void rail_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16)
|
||||
stream_write_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */
|
||||
}
|
||||
|
||||
void* rail_clone_order(uint32 event_type, void* order)
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32 type;
|
||||
uint32 size;
|
||||
} ordersize_table[] =
|
||||
{
|
||||
{RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS, sizeof(RAIL_SYSPARAM_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS, sizeof(RAIL_EXEC_RESULT_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM, sizeof(RAIL_SYSPARAM_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO, sizeof(RAIL_MINMAXINFO_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE, sizeof(RAIL_LOCALMOVESIZE_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP, sizeof(RAIL_GET_APPID_RESP_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO, sizeof(RAIL_LANGBAR_INFO_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, sizeof(RAIL_SYSPARAM_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP, sizeof(RDP_PLUGIN_DATA)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, sizeof(RAIL_ACTIVATE_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU, sizeof(RAIL_SYSMENU_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, sizeof(RAIL_SYSCOMMAND_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT, sizeof(RAIL_NOTIFY_EVENT_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, sizeof(RAIL_WINDOW_MOVE_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ, sizeof(RAIL_GET_APPID_REQ_ORDER)},
|
||||
{RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO, sizeof(RAIL_LANGBAR_INFO_ORDER)},
|
||||
};
|
||||
size_t i = 0;
|
||||
size_t order_size = 0;
|
||||
void* new_order = NULL;
|
||||
|
||||
for (i = 0; i < RAIL_ARRAY_SIZE(ordersize_table); i++)
|
||||
{
|
||||
if (event_type == ordersize_table[i].type)
|
||||
{
|
||||
order_size = ordersize_table[i].size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Event type not found.
|
||||
if (order_size == 0) return NULL;
|
||||
|
||||
new_order = xmalloc(order_size);
|
||||
memcpy(new_order, order, order_size);
|
||||
|
||||
//printf("rail_clone_order: type=%d order=%p\n", event_type, new_order);
|
||||
|
||||
// Create copy of variable data for some orders
|
||||
if ((event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS) ||
|
||||
(event_type == RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS))
|
||||
{
|
||||
RAIL_SYSPARAM_ORDER* new_sysparam = (RAIL_SYSPARAM_ORDER*)new_order;
|
||||
RAIL_SYSPARAM_ORDER* old_sysparam = (RAIL_SYSPARAM_ORDER*)order;
|
||||
|
||||
rail_unicode_string_alloc(&new_sysparam->highContrast.colorScheme,
|
||||
old_sysparam->highContrast.colorScheme.length);
|
||||
|
||||
memcpy(new_sysparam->highContrast.colorScheme.string,
|
||||
old_sysparam->highContrast.colorScheme.string,
|
||||
old_sysparam->highContrast.colorScheme.length);
|
||||
}
|
||||
|
||||
if (event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS)
|
||||
{
|
||||
RAIL_EXEC_RESULT_ORDER* new_exec_result = (RAIL_EXEC_RESULT_ORDER*)new_order;
|
||||
RAIL_EXEC_RESULT_ORDER* old_exec_result = (RAIL_EXEC_RESULT_ORDER*)order;
|
||||
|
||||
rail_unicode_string_alloc(&new_exec_result->exeOrFile,
|
||||
old_exec_result->exeOrFile.length);
|
||||
|
||||
memcpy(new_exec_result->exeOrFile.string,
|
||||
old_exec_result->exeOrFile.string,
|
||||
old_exec_result->exeOrFile.length);
|
||||
}
|
||||
|
||||
if (event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP)
|
||||
{
|
||||
RAIL_GET_APPID_RESP_ORDER* new_app_resp = (RAIL_GET_APPID_RESP_ORDER*)new_order;
|
||||
|
||||
new_app_resp->applicationId.string = &new_app_resp->applicationIdBuffer[0];
|
||||
}
|
||||
|
||||
return new_order;
|
||||
}
|
||||
|
||||
void rail_free_cloned_order(uint32 event_type, void* order)
|
||||
{
|
||||
//printf("rail_free_cloned_order: type=%d order=%p\n", event_type, order);
|
||||
if ((event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS) ||
|
||||
(event_type == RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS))
|
||||
{
|
||||
RAIL_SYSPARAM_ORDER* sysparam = (RAIL_SYSPARAM_ORDER*)order;
|
||||
rail_unicode_string_free(&sysparam->highContrast.colorScheme);
|
||||
}
|
||||
|
||||
if (event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS)
|
||||
{
|
||||
RAIL_EXEC_RESULT_ORDER* exec_result = (RAIL_EXEC_RESULT_ORDER*)order;
|
||||
rail_unicode_string_free(&exec_result->exeOrFile);
|
||||
}
|
||||
xfree(order);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user