diff --git a/channels/rail/rail_channel_orders.c b/channels/rail/rail_channel_orders.c index 163af8c46..f14629a59 100644 --- a/channels/rail/rail_channel_orders.c +++ b/channels/rail/rail_channel_orders.c @@ -54,50 +54,6 @@ void* rail_alloc_order_data(size_t length) return (order_start + RAIL_PDU_HEADER_SIZE); } -void write_rail_unicode_string_content(STREAM* s, RAIL_UNICODE_STRING* string) -{ - if (string->length > 0) - stream_write(s, string->buffer, string->length); -} - -void write_rail_unicode_string(STREAM* s, RAIL_UNICODE_STRING* string) -{ - stream_write_uint16(s, string->length); - - if (string->length > 0) - stream_write(s, string->buffer, string->length); -} - -void write_rail_rect_16(STREAM* s, RAIL_RECT_16* rect) -{ - stream_write_uint16(s, rect->left); /*Left*/ - stream_write_uint16(s, rect->top); /*Top*/ - stream_write_uint16(s, rect->right); /*Right*/ - stream_write_uint16(s, rect->bottom); /*Bottom*/ -} - -void read_rail_unicode_string(STREAM* s, RAIL_UNICODE_STRING * string) -{ - stream_read_uint16(s, string->length); - - string->buffer = NULL; - if (string->length > 0) - { - string->buffer = xmalloc(string->length); - stream_read(s, string->buffer, string->length); - } -} - -void free_rail_unicode_string(RAIL_UNICODE_STRING * string) -{ - if (string->buffer != NULL) - { - xfree(string->buffer); - string->buffer = NULL; - string->length = 0; - } -} - // Used by 'rail_vchannel_send_' routines for sending constructed RAIL PDU to // the 'rail' channel static void rail_vchannel_send_order_data(RAIL_SESSION* session, uint16 order_type, void* allocated_order_data, uint16 data_length) @@ -106,7 +62,6 @@ static void rail_vchannel_send_order_data(RAIL_SESSION* session, uint16 order_ty STREAM* s = &st_stream; uint8* header_start = ((uint8*)allocated_order_data - RAIL_PDU_HEADER_SIZE); - data_length += RAIL_PDU_HEADER_SIZE; stream_init_by_allocated_data(s, header_start, RAIL_PDU_HEADER_SIZE); @@ -135,6 +90,8 @@ void rail_vchannel_send_handshake_order(RAIL_SESSION * session, uint32 build_num uint16 data_length = 4; void* data = rail_alloc_order_data(data_length); + DEBUG_RAIL("Send Handshake Order"); + stream_init_by_allocated_data(s, data, data_length); stream_write_uint32(s, build_number); @@ -166,14 +123,14 @@ void rail_vchannel_send_activate_order(RAIL_SESSION* session, uint32 window_id, * remote application launch on the server. * */ void rail_vchannel_send_exec_order(RAIL_SESSION* session, uint16 flags, - RAIL_UNICODE_STRING* exe_or_file, RAIL_UNICODE_STRING* working_directory, RAIL_UNICODE_STRING* arguments) + UNICODE_STRING* exe_or_file, UNICODE_STRING* working_directory, UNICODE_STRING* arguments) { STREAM st_stream = {0}; STREAM* s = &st_stream; - uint16 exe_or_file_length = exe_or_file->length; - uint16 working_directory_length = working_directory->length; - uint16 arguments_length = arguments->length; + uint16 exe_or_file_length = exe_or_file->cbString; + uint16 working_directory_length = working_directory->cbString; + uint16 arguments_length = arguments->cbString; size_t data_length = 2 + /*Flags (2 bytes)*/ @@ -193,9 +150,9 @@ void rail_vchannel_send_exec_order(RAIL_SESSION* session, uint16 flags, stream_write_uint16(s, working_directory_length); stream_write_uint16(s, arguments_length); - write_rail_unicode_string_content(s, exe_or_file); - write_rail_unicode_string_content(s, working_directory); - write_rail_unicode_string_content(s, arguments); + rail_write_unicode_string_value(s, exe_or_file); + rail_write_unicode_string_value(s, working_directory); + rail_write_unicode_string_value(s, arguments); rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_EXEC, data, data_length); } @@ -204,20 +161,20 @@ size_t get_sysparam_size_in_rdp_stream(RAIL_CLIENT_SYSPARAM * sysparam) { switch (sysparam->type) { - case SPI_SETDRAGFULLWINDOWS: {return 1;} - case SPI_SETKEYBOARDCUES: {return 1;} - case SPI_SETKEYBOARDPREF: {return 1;} - case SPI_SETMOUSEBUTTONSWAP: {return 1;} - case SPI_SETWORKAREA: {return 8;} - case RAIL_SPI_DISPLAYCHANGE: {return 8;} - case RAIL_SPI_TASKBARPOS: {return 8;} - case SPI_SETHIGHCONTRAST: - { - return (4 + /*Flags (4 bytes)*/ - 4 + /*ColorSchemeLength (4 bytes)*/ - 2 + /*UNICODE_STRING.cbString (2 bytes)*/ - sysparam->value.high_contrast_system_info.color_scheme.length); - } + case SPI_SET_DRAG_FULL_WINDOWS: {return 1;} + case SPI_SET_KEYBOARD_CUES: {return 1;} + case SPI_SET_KEYBOARD_PREF: {return 1;} + case SPI_SET_MOUSE_BUTTON_SWAP: {return 1;} + case SPI_SET_WORK_AREA: {return 8;} + case RAIL_SPI_DISPLAY_CHANGE: {return 8;} + case RAIL_SPI_TASKBAR_POS: {return 8;} + case SPI_SET_HIGH_CONTRAST: + { + return (4 + /*Flags (4 bytes)*/ + 4 + /*ColorSchemeLength (4 bytes)*/ + 2 + /*UNICODE_STRING.cbString (2 bytes)*/ + sysparam->value.high_contrast_system_info.color_scheme.cbString); + } }; assert(!"Unknown sysparam type"); @@ -244,38 +201,38 @@ void rail_vchannel_send_client_sysparam_update_order(RAIL_SESSION* session, RAIL switch (sysparam->type) { - case SPI_SETDRAGFULLWINDOWS: + case SPI_SET_DRAG_FULL_WINDOWS: stream_write_uint8(s, sysparam->value.full_window_drag_enabled); break; - case SPI_SETKEYBOARDCUES: + case SPI_SET_KEYBOARD_CUES: stream_write_uint8(s, sysparam->value.menu_access_key_always_underlined); break; - case SPI_SETKEYBOARDPREF: + case SPI_SET_KEYBOARD_PREF: stream_write_uint8(s, sysparam->value.keyboard_for_user_prefered); break; - case SPI_SETMOUSEBUTTONSWAP: + case SPI_SET_MOUSE_BUTTON_SWAP: stream_write_uint8(s, sysparam->value.left_right_mouse_buttons_swapped); break; - case SPI_SETWORKAREA: - write_rail_rect_16(s, &sysparam->value.work_area); + case SPI_SET_WORK_AREA: + rail_write_rectangle_16(s, &sysparam->value.work_area); break; - case RAIL_SPI_DISPLAYCHANGE: - write_rail_rect_16(s, &sysparam->value.display_resolution); + case RAIL_SPI_DISPLAY_CHANGE: + rail_write_rectangle_16(s, &sysparam->value.display_resolution); break; - case RAIL_SPI_TASKBARPOS: - write_rail_rect_16(s, &sysparam->value.taskbar_size); + case RAIL_SPI_TASKBAR_POS: + rail_write_rectangle_16(s, &sysparam->value.taskbar_size); break; - case SPI_SETHIGHCONTRAST: + case SPI_SET_HIGH_CONTRAST: { uint32 color_scheme_length = 2 + - sysparam->value.high_contrast_system_info.color_scheme.length; + sysparam->value.high_contrast_system_info.color_scheme.cbString; stream_write_uint32(s, sysparam->value.high_contrast_system_info.flags); stream_write_uint32(s, color_scheme_length); @@ -338,7 +295,7 @@ void rail_vchannel_send_notify_event_order(RAIL_SESSION * session, uint32 window * when a local window is ending a move or resize. The client communicates the * locally moved or resized window's position to the server by using this packet. * The server uses this information to reposition its window.*/ -void rail_vchannel_send_client_windowmove_order(RAIL_SESSION* session, uint32 window_id, RAIL_RECT_16* new_position) +void rail_vchannel_send_client_windowmove_order(RAIL_SESSION* session, uint32 window_id, RECTANGLE_16* new_position) { STREAM st_stream = {0}; STREAM* s = &st_stream; @@ -367,6 +324,8 @@ void rail_vchannel_send_client_information_order(RAIL_SESSION* session, uint32 f uint16 data_length = 4; void* data = rail_alloc_order_data(data_length); + DEBUG_RAIL("Send Client Information Order"); + stream_init_by_allocated_data(s, data, data_length); stream_write_uint32(s, flags); @@ -458,16 +417,16 @@ void rail_vchannel_process_exec_result_order(RAIL_SESSION* session, STREAM* s) uint16 flags = 0; uint16 exec_result = 0; uint32 raw_result = 0; - RAIL_UNICODE_STRING exe_or_file = {0}; + UNICODE_STRING exe_or_file = {0}; stream_read_uint16(s, flags); /*Flags (2 bytes)*/ stream_read_uint16(s, exec_result); /*ExecResult (2 bytes)*/ stream_read_uint32(s, raw_result); /*RawResult (4 bytes)*/ stream_seek(s, 2); /*Padding (2 bytes)*/ - read_rail_unicode_string(s, &exe_or_file); /*ExeOrFileLength with ExeOrFile (variable)*/ + rail_read_unicode_string(s, &exe_or_file); /*ExeOrFileLength with ExeOrFile (variable)*/ rail_core_handle_exec_result(session, flags, exec_result, raw_result, &exe_or_file); - free_rail_unicode_string(&exe_or_file); + rail_unicode_string_free(&exe_or_file); } /* @@ -482,17 +441,17 @@ void rail_vchannel_process_server_sysparam_update_order(RAIL_SESSION* session, S switch (sysparam.type) { - case SPI_SETSCREENSAVEACTIVE: - stream_read_uint8(s, sysparam.value.screen_saver_enabled); - break; + case SPI_SET_SCREEN_SAVE_ACTIVE: + stream_read_uint8(s, sysparam.value.screen_saver_enabled); + break; - case SPI_SETSCREENSAVESECURE: - stream_read_uint8(s, sysparam.value.screen_saver_lock_enabled); - break; + case SPI_SET_SCREEN_SAVE_SECURE: + stream_read_uint8(s, sysparam.value.screen_saver_lock_enabled); + break; - default: - assert(!"Undocumented RAIL server sysparam type"); - break; + default: + assert(!"Undocumented RAIL server sysparam type"); + break; }; rail_core_handle_server_sysparam(session, &sysparam); @@ -581,16 +540,16 @@ void rail_vchannel_process_server_langbar_info_order(RAIL_SESSION* session, STRE static void rail_vchannel_process_server_get_appid_resp_order(RAIL_SESSION* session, STREAM* s) { uint32 window_id = 0; - RAIL_UNICODE_STRING app_id = {0}; + UNICODE_STRING app_id = {0}; - app_id.length = 256; - app_id.buffer = xmalloc(app_id.length); + app_id.cbString = 256; + app_id.string = xmalloc(app_id.cbString); stream_read_uint32(s, window_id); - stream_read(s, app_id.buffer, app_id.length); + stream_read(s, app_id.string, app_id.cbString); rail_core_handle_server_get_app_resp(session, window_id, &app_id); - free_rail_unicode_string(&app_id); + rail_unicode_string_free(&app_id); } void rail_vchannel_process_received_vchannel_data(RAIL_SESSION * session, STREAM* s) diff --git a/channels/rail/rail_channel_orders.h b/channels/rail/rail_channel_orders.h index c1cc4e494..90e457fe6 100644 --- a/channels/rail/rail_channel_orders.h +++ b/channels/rail/rail_channel_orders.h @@ -26,12 +26,12 @@ void rail_vchannel_send_handshake_order(RAIL_SESSION* session, uint32 build_number); void rail_vchannel_send_client_information_order(RAIL_SESSION* session, uint32 flags); void rail_vchannel_send_activate_order(RAIL_SESSION* session, uint32 window_id, uint8 enabled); -void rail_vchannel_send_exec_order(RAIL_SESSION* session, uint16 flags, RAIL_UNICODE_STRING* exe_or_file, - RAIL_UNICODE_STRING* working_directory, RAIL_UNICODE_STRING* arguments); +void rail_vchannel_send_exec_order(RAIL_SESSION* session, uint16 flags, UNICODE_STRING* exe_or_file, + UNICODE_STRING* working_directory, UNICODE_STRING* arguments); void rail_vchannel_send_client_sysparam_update_order(RAIL_SESSION* session, RAIL_CLIENT_SYSPARAM* sysparam); void rail_vchannel_send_syscommand_order(RAIL_SESSION* session, uint32 window_id, uint16 command); void rail_vchannel_send_notify_event_order(RAIL_SESSION* session, uint32 window_id, uint32 notify_icon_id, uint32 message); -void rail_vchannel_send_client_windowmove_order(RAIL_SESSION* session, uint32 window_id, RAIL_RECT_16* new_position); +void rail_vchannel_send_client_windowmove_order(RAIL_SESSION* session, uint32 window_id, RECTANGLE_16* new_position); void rail_vchannel_send_client_system_menu_order(RAIL_SESSION* session, uint32 window_id, uint16 left, uint16 top); void rail_vchannel_send_client_langbar_information_order(RAIL_SESSION* session, uint32 langbar_status); void rail_vchannel_send_get_appid_req_order(RAIL_SESSION* session, uint32 window_id); diff --git a/channels/rail/rail_core.c b/channels/rail/rail_core.c index 9c52aae36..283fbcab4 100644 --- a/channels/rail/rail_core.c +++ b/channels/rail/rail_core.c @@ -78,32 +78,33 @@ void init_rail_string(RAIL_STRING * rail_string, const char * string) rail_string->length = strlen(string) + 1; } -void rail_string2unicode_string(RAIL_SESSION* session, RAIL_STRING* string, RAIL_UNICODE_STRING* unicode_string) +void rail_string2unicode_string(RAIL_SESSION* session, RAIL_STRING* string, UNICODE_STRING* unicode_string) { size_t result_length = 0; char* result_buffer = NULL; - unicode_string->buffer = NULL; - unicode_string->length = 0; + unicode_string->string = NULL; + unicode_string->cbString = 0; if (string->length == 0) return; result_buffer = freerdp_uniconv_out(session->uniconv, (char*) string->buffer, &result_length); - unicode_string->buffer = (uint8*)result_buffer; - unicode_string->length = (uint16)result_length; + unicode_string->string = (uint8*) result_buffer; + unicode_string->cbString = (uint16) result_length; } -void rail_unicode_string2string(RAIL_SESSION* session, RAIL_UNICODE_STRING* unicode_string, RAIL_STRING* string) +void rail_unicode_string2string(RAIL_SESSION* session, UNICODE_STRING* unicode_string, RAIL_STRING* string) { char* result_buffer = NULL; string->buffer = NULL; string->length = 0; - if (unicode_string->length == 0) return; + if (unicode_string->cbString == 0) + return; - result_buffer = freerdp_uniconv_in(session->uniconv, unicode_string->buffer, unicode_string->length); + result_buffer = freerdp_uniconv_in(session->uniconv, unicode_string->string, unicode_string->cbString); string->buffer = (uint8*)result_buffer; string->length = strlen(result_buffer) + 1; @@ -149,7 +150,7 @@ void rail_core_handle_server_handshake(RAIL_SESSION* session, uint32 build_numbe uint32 client_build_number = 0x00001db0; RAIL_VCHANNEL_EVENT event = {0}; - DEBUG_RAIL("rail_core_handle_server_hadshake: session=0x%p buildNumber=0x%X.", session, build_number); + DEBUG_RAIL("rail_core_handle_server_handshake: session=0x%p buildNumber=0x%X.", session, build_number); // Step 1. Send Handshake PDU (2.2.2.2.1) // Fixed: MS-RDPERP 1.3.2.1 is not correct! @@ -162,19 +163,26 @@ void rail_core_handle_server_handshake(RAIL_SESSION* session, uint32 build_numbe // start UI initialization stage. init_vchannel_event(&event, RAIL_VCHANNEL_EVENT_SESSION_ESTABLISHED); session->event_sender->send_rail_vchannel_event(session->event_sender->event_sender_object, &event); + + // Step 4. Send Client Execute + // FIXME: + // According to "3.1.1.1 Server State Machine" Client Execute + // will be processed after Destop Sync processed. + // So maybe send after receive Destop Sync sequence? + rail_core_send_client_execute(session, False, "||firefox", "", ""); } -void rail_core_handle_exec_result(RAIL_SESSION* session, uint16 flags, uint16 exec_result, uint32 raw_result, RAIL_UNICODE_STRING* exe_or_file) +void rail_core_handle_exec_result(RAIL_SESSION* session, uint16 flags, uint16 exec_result, uint32 raw_result, UNICODE_STRING* exe_or_file) { RAIL_VCHANNEL_EVENT event = {0}; RAIL_STRING exe_or_file_; DEBUG_RAIL("rail_core_handle_exec_result: session=0x%p flags=0x%X " "exec_result=0x%X raw_result=0x%X exe_or_file=(length=%d dump>)", - session, flags, exec_result, raw_result, exe_or_file->length); + session, flags, exec_result, raw_result, exe_or_file->cbString); #ifdef WITH_DEBUG_RAIL - freerdp_hexdump(exe_or_file->buffer, exe_or_file->length); + freerdp_hexdump(exe_or_file->string, exe_or_file->cbString); #endif rail_unicode_string2string(session, exe_or_file, &exe_or_file_); @@ -271,16 +279,16 @@ void rail_core_handle_server_langbar_info(RAIL_SESSION* session, uint32 langbar_ session->event_sender->send_rail_vchannel_event(session->event_sender->event_sender_object, &event); } -void rail_core_handle_server_get_app_resp(RAIL_SESSION* session, uint32 window_id, RAIL_UNICODE_STRING * app_id) +void rail_core_handle_server_get_app_resp(RAIL_SESSION* session, uint32 window_id, UNICODE_STRING * app_id) { RAIL_VCHANNEL_EVENT event = { 0 }; RAIL_STRING app_id_; DEBUG_RAIL("rail_core_handle_server_get_app_resp: session=0x%p " - "window_id=0x%X app_id=(length=%d dump>)", session, window_id, app_id->length); + "window_id=0x%X app_id=(length=%d dump>)", session, window_id, app_id->cbString); #ifdef WITH_DEBUG_RAIL - freerdp_hexdump(app_id->buffer, app_id->length); + freerdp_hexdump(app_id->string, app_id->cbString); #endif rail_unicode_string2string(session, app_id, &app_id_); @@ -300,11 +308,13 @@ void rail_core_send_client_execute(RAIL_SESSION* session, RAIL_STRING exe_or_file_; RAIL_STRING working_directory_; RAIL_STRING arguments_; - RAIL_UNICODE_STRING exe_or_file; - RAIL_UNICODE_STRING working_directory; - RAIL_UNICODE_STRING arguments; + UNICODE_STRING exe_or_file; + UNICODE_STRING working_directory; + UNICODE_STRING arguments; uint16 flags; + DEBUG_RAIL("RAIL_ORDER_EXEC"); + init_rail_string(&exe_or_file_, rail_exe_or_file); init_rail_string(&working_directory_, rail_working_directory); init_rail_string(&arguments_, rail_arguments); @@ -323,9 +333,9 @@ void rail_core_send_client_execute(RAIL_SESSION* session, rail_vchannel_send_exec_order(session, flags, &exe_or_file, &working_directory, &arguments); - free_rail_unicode_string(&exe_or_file); - free_rail_unicode_string(&working_directory); - free_rail_unicode_string(&arguments); + rail_unicode_string_free(&exe_or_file); + rail_unicode_string_free(&working_directory); + rail_unicode_string_free(&arguments); } uint8 boolean2uint8(boolean value) @@ -333,13 +343,13 @@ uint8 boolean2uint8(boolean value) return ((value == True) ? 1 : 0); } -uint8 copy_rail_rect_16(RAIL_RECT_16* src, RAIL_RECT_16* dst) +uint8 copy_rail_rect_16(RECTANGLE_16* src, RECTANGLE_16* dst) { - memcpy(dst, src, sizeof(RAIL_RECT_16)); + memcpy(dst, src, sizeof(RECTANGLE_16)); return 0; } -static void rail_core_handle_ui_update_client_sysparam(RAIL_SESSION* session, RAIL_UI_EVENT* event) +void rail_core_handle_ui_update_client_sysparam(RAIL_SESSION* session, RAIL_UI_EVENT* event) { RAIL_CLIENT_SYSPARAM sys_param; @@ -372,7 +382,7 @@ static void rail_core_handle_ui_update_client_sysparam(RAIL_SESSION* session, RA event->param.sysparam_info.value.high_contrast_system_info.flags; - if (sys_param.type == SPI_SETHIGHCONTRAST) + if (sys_param.type == SPI_SET_HIGH_CONTRAST) { RAIL_STRING color_scheme; @@ -383,7 +393,7 @@ static void rail_core_handle_ui_update_client_sysparam(RAIL_SESSION* session, RA } rail_vchannel_send_client_sysparam_update_order(session, &sys_param); - free_rail_unicode_string(&sys_param.value.high_contrast_system_info.color_scheme); + rail_unicode_string_free(&sys_param.value.high_contrast_system_info.color_scheme); } static void rail_core_handle_ui_execute_remote_app(RAIL_SESSION* session, RAIL_UI_EVENT* event) diff --git a/channels/rail/rail_core.h b/channels/rail/rail_core.h index 027172c19..5578df1c8 100644 --- a/channels/rail/rail_core.h +++ b/channels/rail/rail_core.h @@ -48,7 +48,7 @@ typedef struct _RAIL_STRING typedef struct _RAIL_HIGHCONTRAST { uint32 flags; - RAIL_UNICODE_STRING color_scheme; + UNICODE_STRING color_scheme; } RAIL_HIGHCONTRAST; @@ -62,9 +62,9 @@ typedef struct _RAIL_CLIENT_SYSPARAM uint8 menu_access_key_always_underlined; uint8 keyboard_for_user_prefered; uint8 left_right_mouse_buttons_swapped; - RAIL_RECT_16 work_area; - RAIL_RECT_16 display_resolution; - RAIL_RECT_16 taskbar_size; + RECTANGLE_16 work_area; + RECTANGLE_16 display_resolution; + RECTANGLE_16 taskbar_size; RAIL_HIGHCONTRAST high_contrast_system_info; } value; } RAIL_CLIENT_SYSPARAM; @@ -120,7 +120,7 @@ void rail_core_handle_ui_event(RAIL_SESSION* session, RAIL_UI_EVENT* event); void rail_core_handle_server_handshake(RAIL_SESSION* session, uint32 build_number); void rail_core_handle_exec_result(RAIL_SESSION* session, uint16 flags, - uint16 exec_result, uint32 raw_result, RAIL_UNICODE_STRING* exe_or_file); + uint16 exec_result, uint32 raw_result, UNICODE_STRING* exe_or_file); void rail_core_handle_server_sysparam(RAIL_SESSION* session, RAIL_SERVER_SYSPARAM* sysparam); @@ -132,6 +132,12 @@ void rail_core_handle_server_minmax_info(RAIL_SESSION* session, uint32 window_id uint16 min_track_width, uint16 min_track_height, uint16 max_track_width, uint16 max_track_height); void rail_core_handle_server_langbar_info(RAIL_SESSION* session, uint32 langbar_status); -void rail_core_handle_server_get_app_resp(RAIL_SESSION* session, uint32 window_id, RAIL_UNICODE_STRING* app_id); +void rail_core_handle_server_get_app_resp(RAIL_SESSION* session, uint32 window_id, UNICODE_STRING* app_id); + +void rail_core_send_client_execute(RAIL_SESSION* session, + boolean exec_or_file_is_file_path, const char* rail_exe_or_file, + const char* rail_working_directory, const char* rail_arguments); + +void rail_core_handle_ui_update_client_sysparam(RAIL_SESSION* session, RAIL_UI_EVENT* event); #endif /* __RAIL_CORE_H */ diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index a2c4f6f50..aad529201 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -345,6 +345,11 @@ void xf_process_cb_sync_event(rdpChanMan* chanman, freerdp* instance) freerdp_chanman_send_event(chanman, "cliprdr", event); } +void xf_process_rail_event(rdpChanMan* chanman, freerdp* instance) +{ + +} + void xf_process_channel_event(rdpChanMan* chanman, freerdp* instance) { FRDP_EVENT* event; @@ -357,6 +362,9 @@ void xf_process_channel_event(rdpChanMan* chanman, freerdp* instance) case FRDP_EVENT_TYPE_CB_SYNC: xf_process_cb_sync_event(chanman, instance); break; + case FRDP_EVENT_TYPE_RAIL_VCHANNEL_2_UI: + xf_process_rail_event(chanman, instance); + break; default: printf("xf_process_channel_event: unknown event type %d\n", event->event_type); break; diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h index 10304ea63..6505e2c83 100644 --- a/include/freerdp/rail.h +++ b/include/freerdp/rail.h @@ -21,26 +21,7 @@ #ifndef __RAIL_H #define __RAIL_H -/* RAIL Constants*/ - -enum RDP_RAIL_PDU_TYPE -{ - RDP_RAIL_ORDER_EXEC = 0x0001, - RDP_RAIL_ORDER_ACTIVATE = 0x0002, - RDP_RAIL_ORDER_SYSPARAM = 0x0003, - RDP_RAIL_ORDER_SYSCOMMAND = 0x0004, - RDP_RAIL_ORDER_HANDSHAKE = 0x0005, - RDP_RAIL_ORDER_NOTIFY_EVENT = 0x0006, - RDP_RAIL_ORDER_WINDOWMOVE = 0x0008, - RDP_RAIL_ORDER_LOCALMOVESIZE = 0x0009, - RDP_RAIL_ORDER_MINMAXINFO = 0x000A, - RDP_RAIL_ORDER_CLIENTSTATUS = 0x000B, - RDP_RAIL_ORDER_SYSMENU = 0x000C, - RDP_RAIL_ORDER_LANGBARINFO = 0x000D, - RDP_RAIL_ORDER_EXEC_RESULT = 0x0080, - RDP_RAIL_ORDER_GET_APPID_REQ = 0x000E, - RDP_RAIL_ORDER_GET_APPID_RESP = 0x000F -}; +#include /* RAIL PDU flags */ #define RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY 0x0001 @@ -72,18 +53,18 @@ enum RDP_RAIL_PDU_TYPE #define RAIL_EXEC_E_SESSION_LOCKED 0x0007 /* Client System Parameters Update PDU */ -#define SPI_SETDRAGFULLWINDOWS 0x00000025 -#define SPI_SETKEYBOARDCUES 0x0000100B -#define SPI_SETKEYBOARDPREF 0x00000045 -#define SPI_SETWORKAREA 0x0000002F -#define SPI_SETMOUSEBUTTONSWAP 0x00000021 -#define SPI_SETHIGHCONTRAST 0x00000043 -#define RAIL_SPI_DISPLAYCHANGE 0x0000F001 -#define RAIL_SPI_TASKBARPOS 0x0000F000 +#define SPI_SET_DRAG_FULL_WINDOWS 0x00000025 +#define SPI_SET_KEYBOARD_CUES 0x0000100B +#define SPI_SET_KEYBOARD_PREF 0x00000045 +#define SPI_SET_WORK_AREA 0x0000002F +#define SPI_SET_MOUSE_BUTTON_SWAP 0x00000021 +#define SPI_SET_HIGH_CONTRAST 0x00000043 +#define RAIL_SPI_DISPLAY_CHANGE 0x0000F001 +#define RAIL_SPI_TASKBAR_POS 0x0000F000 /* Server System Parameters Update PDU */ -#define SPI_SETSCREENSAVEACTIVE 0x00000011 -#define SPI_SETSCREENSAVESECURE 0x00000077 +#define SPI_SET_SCREEN_SAVE_ACTIVE 0x00000011 +#define SPI_SET_SCREEN_SAVE_SECURE 0x00000077 /* Client System Command PDU */ #define SC_SIZE 0xF000 @@ -151,23 +132,166 @@ enum RDP_RAIL_PDU_TYPE #define TF_SFT_NOEXTRAICONSONMINIMIZED 0x00000400 #define TF_SFT_DESKBAND 0x00000800 -/* RAIL Common structures */ +struct _UNICODE_STRING +{ + uint16 cbString; + uint8* string; +}; +typedef struct _UNICODE_STRING UNICODE_STRING; -typedef struct _RAIL_RECT_16 +struct _RECTANGLE_16 { uint16 left; uint16 top; uint16 right; uint16 bottom; -} -RAIL_RECT_16; +}; +typedef struct _RECTANGLE_16 RECTANGLE_16; -typedef struct _RAIL_UNICODE_STRING +/* RAIL Orders */ + +struct _RAIL_HANDSHAKE_ORDER { - uint16 length; - uint8 *buffer; -} -RAIL_UNICODE_STRING; + uint32 buildNumber; +}; +typedef struct _RAIL_HANDSHAKE_ORDER RAIL_HANDSHAKE_ORDER; + +struct _RAIL_CLIENT_STATUS_ORDER +{ + uint32 flags; +}; +typedef struct _RAIL_CLIENT_STATUS_ORDER RAIL_CLIENT_STATUS_ORDER; + +struct _RAIL_EXEC_ORDER +{ + uint16 flags; + UNICODE_STRING exeOrFile; + UNICODE_STRING workingDir; + UNICODE_STRING arguments; +}; +typedef struct _RAIL_EXEC_ORDER RAIL_EXEC_ORDER; + +struct _RAIL_EXEC_RESULT_ORDER +{ + uint16 flags; + uint16 execResult; + uint32 rawResult; + UNICODE_STRING exeOrFile; +}; +typedef struct _RAIL_EXEC_RESULT_ORDER RAIL_EXEC_RESULT_ORDER; + +struct _RAIL_SYSPARAM_ORDER +{ + uint32 systemParam; + uint8* body; +}; +typedef struct _RAIL_SYSPARAM_ORDER RAIL_SYSPARAM_ORDER; + +struct _RAIL_ACTIVATE_ORDER +{ + uint32 windowId; + boolean enabled; +}; +typedef struct _RAIL_ACTIVATE_ORDER RAIL_ACTIVATE_ORDER; + +struct _RAIL_SYSMENU_ORDER +{ + uint32 windowId; + uint16 left; + uint16 top; +}; +typedef struct _RAIL_SYSMENU_ORDER RAIL_SYSMENU_ORDER; + +struct _RAIL_SYSCOMMAND_ORDER +{ + uint32 windowId; + uint16 command; +}; +typedef struct _RAIL_SYSCOMMAND_ORDER RAIL_SYSCOMMAND_ORDER; + +struct _RAIL_NOTIFY_EVENT_ORDER +{ + uint32 windowId; + uint32 notifyIconId; + uint32 message; +}; +typedef struct _RAIL_NOTIFY_EVENT_ORDER RAIL_NOTIFY_EVENT_ORDER; + +struct _RAIL_MINMAXINFO_ORDER +{ + uint32 windowId; + uint16 maxWidth; + uint16 maxHeight; + uint16 maxPosX; + uint16 maxPosY; + uint16 minTrackWidth; + uint16 minTrackHeight; + uint16 maxTrackWidth; + uint16 maxTrackHeight; +}; +typedef struct _RAIL_MINMAXINFO_ORDER RAIL_MINMAXINFO_ORDER; + +struct _RAIL_LOCALMOVESIZE_ORDER +{ + uint32 windowId; + uint16 isMoveSizeStart; + uint16 moveSizeType; + uint16 posX; + uint16 posY; +}; +typedef struct _RAIL_LOCALMOVESIZE_ORDER RAIL_LOCALMOVESIZE_ORDER; + +struct _RAIL_WINDOWMOVE_ORDER +{ + uint32 windowId; + uint16 left; + uint16 top; + uint16 right; + uint16 bottom; +}; +typedef struct _RAIL_WINDOWMOVE_ORDER RAIL_WINDOWMOVE_ORDER; + +struct _RAIL_GET_APPID_REQ_ORDER +{ + uint32 windowId; +}; +typedef struct _RAIL_GET_APPID_REQ_ORDER RAIL_GET_APPID_REQ_ORDER; + +struct _RAIL_GET_APPID_RESP_ORDER +{ + uint32 windowId; + UNICODE_STRING applicationId; +}; +typedef struct _RAIL_GET_APPID_RESP_ORDER RAIL_GET_APPID_RESP_ORDER; + +struct _RAIL_LANGBARINFO_ORDER +{ + uint32 languageBarStatus; +}; +typedef struct _RAIL_LANGBARINFO_ORDER RAIL_LANGBARINFO_ORDER; + +/* RAIL Constants */ + +enum RDP_RAIL_PDU_TYPE +{ + RDP_RAIL_ORDER_EXEC = 0x0001, + RDP_RAIL_ORDER_ACTIVATE = 0x0002, + RDP_RAIL_ORDER_SYSPARAM = 0x0003, + RDP_RAIL_ORDER_SYSCOMMAND = 0x0004, + RDP_RAIL_ORDER_HANDSHAKE = 0x0005, + RDP_RAIL_ORDER_NOTIFY_EVENT = 0x0006, + RDP_RAIL_ORDER_WINDOWMOVE = 0x0008, + RDP_RAIL_ORDER_LOCALMOVESIZE = 0x0009, + RDP_RAIL_ORDER_MINMAXINFO = 0x000A, + RDP_RAIL_ORDER_CLIENTSTATUS = 0x000B, + RDP_RAIL_ORDER_SYSMENU = 0x000C, + RDP_RAIL_ORDER_LANGBARINFO = 0x000D, + RDP_RAIL_ORDER_EXEC_RESULT = 0x0080, + RDP_RAIL_ORDER_GET_APPID_REQ = 0x000E, + RDP_RAIL_ORDER_GET_APPID_RESP = 0x000F +}; + +/* RAIL Common structures */ // Events from 'rail' vchannel plugin to UI enum RAIL_VCHANNEL_EVENT @@ -270,9 +394,9 @@ typedef struct _RAIL_UI_EVENT boolean menu_access_key_always_underlined; boolean keyboard_for_user_prefered; boolean left_right_mouse_buttons_swapped; - RAIL_RECT_16 work_area; - RAIL_RECT_16 display_resolution; - RAIL_RECT_16 taskbar_size; + RECTANGLE_16 work_area; + RECTANGLE_16 display_resolution; + RECTANGLE_16 taskbar_size; struct { uint32 flags; @@ -312,7 +436,7 @@ typedef struct _RAIL_UI_EVENT struct { uint32 window_id; - RAIL_RECT_16 new_position; + RECTANGLE_16 new_position; } window_move_info; struct diff --git a/include/freerdp/update.h b/include/freerdp/update.h index 7a1bf1457..b7699c472 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -20,6 +20,7 @@ #ifndef __UPDATE_API_H #define __UPDATE_API_H +#include #include #include @@ -686,22 +687,6 @@ struct _WINDOW_ORDER_INFO }; typedef struct _WINDOW_ORDER_INFO WINDOW_ORDER_INFO; -struct _UNICODE_STRING -{ - uint16 cbString; - uint8* string; -}; -typedef struct _UNICODE_STRING UNICODE_STRING; - -struct _RECTANGLE_16 -{ - uint16 left; - uint16 top; - uint16 right; - uint16 bottom; -}; -typedef struct _RECTANGLE_16 RECTANGLE_16; - struct _ICON_INFO { uint16 cacheEntry; diff --git a/include/freerdp/utils/rail.h b/include/freerdp/utils/rail.h new file mode 100644 index 000000000..e5e22b271 --- /dev/null +++ b/include/freerdp/utils/rail.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_UTILS_H +#define __RAIL_UTILS_H + +#include +#include + +void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString); +void rail_unicode_string_free(UNICODE_STRING* unicode_string); +void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string); +void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string); +void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string); +void rail_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16); +void rail_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16); + +#endif /* __RAIL_UTILS_H */ diff --git a/libfreerdp-core/window.c b/libfreerdp-core/window.c index 388859244..01f097abe 100644 --- a/libfreerdp-core/window.c +++ b/libfreerdp-core/window.c @@ -18,30 +18,11 @@ * limitations under the License. */ +#include #include #include "window.h" -void update_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) -{ - stream_read_uint16(s, unicode_string->cbString); /* cbString (2 bytes) */ - - if (unicode_string->string == NULL) - unicode_string->string = (uint8*) xmalloc(unicode_string->cbString); - else - unicode_string->string = (uint8*) xrealloc(unicode_string->string, unicode_string->cbString); - - stream_read(s, unicode_string->string, unicode_string->cbString); -} - -void update_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) -{ - stream_read_uint16(s, rectangle_16->left); /* left (2 bytes) */ - stream_read_uint16(s, rectangle_16->top); /* top (2 bytes) */ - stream_read_uint16(s, rectangle_16->right); /* right (2 bytes) */ - stream_read_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ -} - void update_read_icon_info(STREAM* s, ICON_INFO* icon_info) { stream_read_uint16(s, icon_info->cacheEntry); /* cacheEntry (2 bytes) */ @@ -85,8 +66,8 @@ void update_read_notify_icon_infotip(STREAM* s, NOTIFY_ICON_INFOTIP* notify_icon { stream_read_uint32(s, notify_icon_infotip->timeout); /* timeout (4 bytes) */ stream_read_uint32(s, notify_icon_infotip->flags); /* infoFlags (4 bytes) */ - update_read_unicode_string(s, ¬ify_icon_infotip->text); /* infoTipText */ - update_read_unicode_string(s, ¬ify_icon_infotip->title); /* title */ + rail_read_unicode_string(s, ¬ify_icon_infotip->text); /* infoTipText */ + rail_read_unicode_string(s, ¬ify_icon_infotip->title); /* title */ } void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) @@ -107,7 +88,7 @@ void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WIN stream_read_uint8(s, window_state->showState); /* showState (1 byte) */ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) - update_read_unicode_string(s, &window_state->titleInfo); /* titleInfo */ + rail_read_unicode_string(s, &window_state->titleInfo); /* titleInfo */ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) { @@ -159,7 +140,7 @@ void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WIN /* windowRects */ for (i = 0; i < window_state->numWindowRects; i++) { - update_read_rectangle_16(s, &window_state->windowRects[i]); + rail_read_rectangle_16(s, &window_state->windowRects[i]); } } @@ -183,7 +164,7 @@ void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WIN /* visibilityRects */ for (i = 0; i < window_state->numVisibilityRects; i++) { - update_read_rectangle_16(s, &window_state->visibilityRects[i]); + rail_read_rectangle_16(s, &window_state->visibilityRects[i]); } } } @@ -235,7 +216,7 @@ void update_read_notification_icon_state_order(STREAM* s, WINDOW_ORDER_INFO* ord stream_read_uint32(s, notify_icon_state->version); /* version (4 bytes) */ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) - update_read_unicode_string(s, ¬ify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */ + rail_read_unicode_string(s, ¬ify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */ if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) update_read_notify_icon_infotip(s, ¬ify_icon_state->infoTip); /* infoTip (NOTIFY_ICON_INFOTIP) */ diff --git a/libfreerdp-utils/CMakeLists.txt b/libfreerdp-utils/CMakeLists.txt index 1cd5c6cb2..adc60f642 100644 --- a/libfreerdp-utils/CMakeLists.txt +++ b/libfreerdp-utils/CMakeLists.txt @@ -29,6 +29,7 @@ set(FREERDP_UTILS_SRCS load_plugin.c memory.c mutex.c + rail.c semaphore.c stream.c svc_plugin.c diff --git a/libfreerdp-utils/rail.c b/libfreerdp-utils/rail.c new file mode 100644 index 000000000..4fae91598 --- /dev/null +++ b/libfreerdp-utils/rail.c @@ -0,0 +1,76 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString) +{ + unicode_string->cbString = cbString; + unicode_string->string = xzalloc(cbString); +} + +void rail_unicode_string_free(UNICODE_STRING* unicode_string) +{ + unicode_string->cbString = 0; + + if (unicode_string->string != NULL) + xfree(unicode_string->string); +} + +void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) +{ + stream_read_uint16(s, unicode_string->cbString); /* cbString (2 bytes) */ + + if (unicode_string->string == NULL) + unicode_string->string = (uint8*) xmalloc(unicode_string->cbString); + else + unicode_string->string = (uint8*) xrealloc(unicode_string->string, unicode_string->cbString); + + stream_read(s, unicode_string->string, unicode_string->cbString); +} + +void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) +{ + stream_write_uint16(s, unicode_string->cbString); /* cbString (2 bytes) */ + stream_write(s, unicode_string->string, unicode_string->cbString); /* string */ +} + +void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string) +{ + stream_write(s, unicode_string->string, unicode_string->cbString); /* string */ +} + +void rail_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) +{ + stream_read_uint16(s, rectangle_16->left); /* left (2 bytes) */ + stream_read_uint16(s, rectangle_16->top); /* top (2 bytes) */ + stream_read_uint16(s, rectangle_16->right); /* right (2 bytes) */ + stream_read_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ +} + +void rail_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) +{ + stream_write_uint16(s, rectangle_16->left); /* left (2 bytes) */ + stream_write_uint16(s, rectangle_16->top); /* top (2 bytes) */ + stream_write_uint16(s, rectangle_16->right); /* right (2 bytes) */ + stream_write_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ +} + diff --git a/libfreerdp-utils/svc_plugin.c b/libfreerdp-utils/svc_plugin.c index 3cdb69a84..aecf84e80 100644 --- a/libfreerdp-utils/svc_plugin.c +++ b/libfreerdp-utils/svc_plugin.c @@ -393,8 +393,8 @@ int svc_plugin_send_event(rdpSvcPlugin* plugin, FRDP_EVENT* event) DEBUG_SVC("event_type %d", event->event_type); - error = plugin->channel_entry_points.pVirtualChannelEventPush(plugin->priv->open_handle, - event); + error = plugin->channel_entry_points.pVirtualChannelEventPush(plugin->priv->open_handle, event); + if (error != CHANNEL_RC_OK) printf("svc_plugin_send_event: VirtualChannelEventPush failed %d\n", error);