From e5a3355099a952f348a744c3d9cc4f0cab9c5308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 10 Aug 2011 18:08:44 -0400 Subject: [PATCH] rail: fixed sending of actual PDUs --- channels/rail/rail_core.c | 57 ++++++++++++++++++++++++++- channels/rail/rail_core.h | 10 +++-- channels/rail/rail_orders.c | 78 +++++++++++++++++++++++++++++-------- channels/rail/rail_orders.h | 7 +++- libfreerdp-utils/rail.c | 3 +- 5 files changed, 131 insertions(+), 24 deletions(-) diff --git a/channels/rail/rail_core.c b/channels/rail/rail_core.c index 3a518ba75..c0f6e4ce4 100644 --- a/channels/rail/rail_core.c +++ b/channels/rail/rail_core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -76,6 +77,20 @@ void init_rail_string(RAIL_STRING * rail_string, const char * string) rail_string->length = strlen(string) + 1; } +void rail_string_to_unicode_string(rdpRail* rail, char* string, UNICODE_STRING* unicode_string) +{ + char* buffer; + size_t length = 0; + + unicode_string->string = NULL; + unicode_string->length = 0; + + buffer = freerdp_uniconv_out(rail->uniconv, string, &length); + + unicode_string->string = (uint8*) buffer; + unicode_string->length = (uint16) length; +} + void rail_string2unicode_string(RAIL_SESSION* session, RAIL_STRING* string, UNICODE_STRING* unicode_string) { size_t result_length = 0; @@ -119,6 +134,9 @@ RAIL_SESSION* rail_core_session_new(RAIL_VCHANNEL_DATA_SENDER* data_sender, RAIL self->data_sender = data_sender; self->event_sender = event_sender; self->uniconv = freerdp_uniconv_new(); + self->rail = rail_new(); + self->rail->data_sender = data_sender; + self->rail->event_sender = event_sender; } return self; @@ -128,6 +146,7 @@ void rail_core_session_free(RAIL_SESSION* rail_session) { if (rail_session != NULL) { + rail_free(rail_session->rail); freerdp_uniconv_free(rail_session->uniconv); xfree(rail_session); } @@ -150,6 +169,26 @@ void rail_core_handle_server_handshake(RAIL_SESSION* session, uint32 build_numbe DEBUG_RAIL("rail_core_handle_server_handshake: session=0x%p buildNumber=0x%X.", session, build_number); +#if 1 + session->rail->handshake.buildNumber = 0x00001DB0; + rail_send_handshake_order(session->rail); + + session->rail->client_status.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE; + rail_send_client_status_order(session->rail); + + session->rail->exec.flags = + RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY | + RAIL_EXEC_FLAG_EXPAND_ARGUMENTS; + + rail_string_to_unicode_string(session->rail, "||firefox", &session->rail->exec.exeOrFile); + rail_string_to_unicode_string(session->rail, "", &session->rail->exec.workingDir); + rail_string_to_unicode_string(session->rail, "", &session->rail->exec.arguments); + + //rail_send_client_exec_order(session->rail); + + rail_core_send_client_execute(session, False, "||firefox", "", ""); + +#else // Step 1. Send Handshake PDU (2.2.2.2.1) // Fixed: MS-RDPERP 1.3.2.1 is not correct! rail_vchannel_send_handshake_order(session, client_build_number); @@ -168,6 +207,7 @@ void rail_core_handle_server_handshake(RAIL_SESSION* session, uint32 build_numbe // will be processed after Destop Sync processed. // So maybe send after receive Destop Sync sequence? rail_core_send_client_execute(session, False, "||firefox", "", ""); +#endif } void rail_core_handle_exec_result(RAIL_SESSION* session, uint16 flags, uint16 exec_result, uint32 raw_result, UNICODE_STRING* exe_or_file) @@ -203,6 +243,20 @@ void rail_core_handle_server_sysparam(RAIL_SESSION* session, RAIL_SERVER_SYSPARA session, sysparam->type, sysparam->value.screen_saver_enabled, sysparam->value.screen_saver_lock_enabled); +#if 1 + session->rail->sysparam.systemParam = SPI_SET_DRAG_FULL_WINDOWS; + session->rail->sysparam.value = True; + + session->rail->sysparam.systemParam = SPI_SET_KEYBOARD_CUES; + session->rail->sysparam.value = False; + + session->rail->sysparam.systemParam = SPI_SET_KEYBOARD_PREF; + session->rail->sysparam.value = False; + + session->rail->sysparam.systemParam = SPI_SET_MOUSE_BUTTON_SWAP; + session->rail->sysparam.value = False; + +#else init_vchannel_event(&event, RAIL_VCHANNEL_EVENT_SERVER_SYSPARAM_RECEIVED); event.param.server_param_info.param_type = sysparam->type; event.param.server_param_info.screen_saver_enabled = @@ -212,6 +266,7 @@ void rail_core_handle_server_sysparam(RAIL_SESSION* session, RAIL_SERVER_SYSPARA ((sysparam->value.screen_saver_lock_enabled != 0) ? True: False); session->event_sender->send_rail_vchannel_event(session->event_sender->event_sender_object, &event); +#endif } void rail_core_handle_server_movesize(RAIL_SESSION* session, uint32 window_id, @@ -311,8 +366,6 @@ void rail_core_send_client_execute(RAIL_SESSION* session, 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); diff --git a/channels/rail/rail_core.h b/channels/rail/rail_core.h index f38346913..0dc0c3ae9 100644 --- a/channels/rail/rail_core.h +++ b/channels/rail/rail_core.h @@ -29,6 +29,12 @@ #include #include +typedef struct _RAIL_SESSION RAIL_SESSION; +typedef struct _RAIL_VCHANNEL_DATA_SENDER RAIL_VCHANNEL_DATA_SENDER; +typedef struct _RAIL_VCHANNEL_EVENT_SENDER RAIL_VCHANNEL_EVENT_SENDER; + +#include "rail_orders.h" + #define WITH_DEBUG_RAIL 1 #ifdef WITH_DEBUG_RAIL @@ -86,22 +92,20 @@ struct _RAIL_VCHANNEL_DATA_SENDER void* data_sender_object; void (*send_rail_vchannel_data)(void* sender_object, void* data, size_t length); }; -typedef struct _RAIL_VCHANNEL_DATA_SENDER RAIL_VCHANNEL_DATA_SENDER; struct _RAIL_VCHANNEL_EVENT_SENDER { void * event_sender_object; void (*send_rail_vchannel_event)(void* ui_event_sender_object, RAIL_VCHANNEL_EVENT* event); }; -typedef struct _RAIL_VCHANNEL_EVENT_SENDER RAIL_VCHANNEL_EVENT_SENDER; struct _RAIL_SESSION { + rdpRail* rail; UNICONV* uniconv; RAIL_VCHANNEL_DATA_SENDER* data_sender; RAIL_VCHANNEL_EVENT_SENDER* event_sender; }; -typedef struct _RAIL_SESSION RAIL_SESSION; RAIL_SESSION* rail_core_session_new(RAIL_VCHANNEL_DATA_SENDER *data_sender, RAIL_VCHANNEL_EVENT_SENDER *event_sender); void rail_core_session_free(RAIL_SESSION * rail_session); diff --git a/channels/rail/rail_orders.c b/channels/rail/rail_orders.c index 9ec0317a9..c37132e84 100644 --- a/channels/rail/rail_orders.c +++ b/channels/rail/rail_orders.c @@ -22,6 +22,43 @@ #include "rail_orders.h" +#define RAIL_ORDER_TYPE_EXEC 0x0001 +#define RAIL_ORDER_TYPE_ACTIVATE 0x0002 +#define RAIL_ORDER_TYPE_SYSPARAM 0x0003 +#define RAIL_ORDER_TYPE_SYSCOMMAND 0x0004 +#define RAIL_ORDER_TYPE_HANDSHAKE 0x0005 +#define RAIL_ORDER_TYPE_NOTIFY_EVENT 0x0006 +#define RAIL_ORDER_TYPE_WINDOW_MOVE 0x0008 +#define RAIL_ORDER_TYPE_LOCALMOVESIZE 0x0009 +#define RAIL_ORDER_TYPE_MINMAXINFO 0x000A +#define RAIL_ORDER_TYPE_CLIENT_STATUS 0x000B +#define RAIL_ORDER_TYPE_SYSMENU 0x000C +#define RAIL_ORDER_TYPE_LANGBAR_INFO 0x000D +#define RAIL_ORDER_TYPE_EXEC_RESULT 0x0080 +#define RAIL_ORDER_TYPE_GET_APPID_REQ 0x000E +#define RAIL_ORDER_TYPE_GET_APPID_RESP 0x000F + +uint8 RAIL_ORDER_TYPE_STRINGS[][32] = +{ + "", + "Execute", + "Activate", + "System Parameters Update", + "System Command", + "Handshake", + "Notify Event", + "", + "Window Move", + "Local Move/Size", + "Min Max Info", + "Client Status", + "System Menu", + "Language Bar Info", + "Get Application ID Request", + "Get Application ID Response", + "Execute Result" +}; + void rail_read_pdu_header(STREAM* s, uint16* orderType, uint16* orderLength) { stream_read_uint16(s, *orderType); /* orderType (2 bytes) */ @@ -42,7 +79,7 @@ STREAM* rail_pdu_init(int length) return s; } -void rail_send_pdu(STREAM* s, uint16 orderType) +void rail_send_pdu(rdpRail* rail, STREAM* s, uint16 orderType) { uint16 orderLength; @@ -53,6 +90,10 @@ void rail_send_pdu(STREAM* s, uint16 orderType) stream_set_pos(s, orderLength); /* send */ + printf("Sending %s PDU, length:%d\n", + RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + orderType], orderLength); + + rail->data_sender->send_rail_vchannel_data(rail->data_sender->data_sender_object, s->data, orderLength); } void rail_write_high_contrast(STREAM* s, HIGH_CONTRAST* high_contrast) @@ -139,9 +180,9 @@ void rail_write_client_exec_order(STREAM* s, RAIL_EXEC_ORDER* exec) stream_write_uint16(s, exec->exeOrFile.length); /* exeOrFileLength (2 bytes) */ stream_write_uint16(s, exec->workingDir.length); /* workingDirLength (2 bytes) */ stream_write_uint16(s, exec->arguments.length); /* argumentsLength (2 bytes) */ - rail_write_unicode_string_value(s, exec->exeOrFile); /* exeOrFile */ - rail_write_unicode_string_value(s, exec->workingDir); /* workingDir */ - rail_write_unicode_string_value(s, exec->arguments); /* arguments */ + rail_write_unicode_string_value(s, &exec->exeOrFile); /* exeOrFile */ + rail_write_unicode_string_value(s, &exec->workingDir); /* workingDir */ + rail_write_unicode_string_value(s, &exec->arguments); /* arguments */ } void rail_write_client_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam) @@ -227,6 +268,9 @@ void rail_order_recv(rdpRail* rail, STREAM* s) rail_read_pdu_header(s, &orderType, &orderLength); + printf("Received %s PDU, length:%d\n", + RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + orderType], orderLength); + switch (orderType) { case RDP_RAIL_ORDER_HANDSHAKE: @@ -267,7 +311,7 @@ void rail_send_handshake_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH); rail_write_handshake_order(s, &rail->handshake); - rail_send_pdu(s, RAIL_ORDER_TYPE_HANDSHAKE); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_HANDSHAKE); } void rail_send_client_status_order(rdpRail* rail) @@ -275,7 +319,7 @@ void rail_send_client_status_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_CLIENT_STATUS_ORDER_LENGTH); rail_write_client_status_order(s, &rail->client_status); - rail_send_pdu(s, RAIL_ORDER_TYPE_CLIENT_STATUS); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_CLIENT_STATUS); } void rail_send_client_exec_order(rdpRail* rail) @@ -285,12 +329,12 @@ void rail_send_client_exec_order(rdpRail* rail) length = RAIL_EXEC_ORDER_LENGTH + rail->exec.exeOrFile.length + - rail->exec.workingDir.length; + rail->exec.workingDir.length + rail->exec.arguments.length; s = rail_pdu_init(RAIL_EXEC_ORDER_LENGTH); - rail_write_exec_order(s, &rail->exec); - rail_send_pdu(s, RAIL_ORDER_TYPE_EXEC); + rail_write_client_exec_order(s, &rail->exec); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_EXEC); } void rail_send_client_sysparam_order(rdpRail* rail) @@ -322,7 +366,7 @@ void rail_send_client_sysparam_order(rdpRail* rail) s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH); rail_write_sysparam_order(s, &rail->sysparam); - rail_send_pdu(s, RAIL_ORDER_TYPE_SYSPARAM); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_SYSPARAM); } void rail_send_client_activate_order(rdpRail* rail) @@ -330,7 +374,7 @@ void rail_send_client_activate_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_ACTIVATE_ORDER_LENGTH); rail_write_activate_order(s, &rail->activate); - rail_send_pdu(s, RAIL_ORDER_TYPE_ACTIVATE); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_ACTIVATE); } void rail_send_client_sysmenu_order(rdpRail* rail) @@ -338,7 +382,7 @@ void rail_send_client_sysmenu_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_SYSMENU_ORDER_LENGTH); rail_write_sysmenu_order(s, &rail->sysmenu); - rail_send_pdu(s, RAIL_ORDER_TYPE_SYSMENU); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_SYSMENU); } void rail_send_client_syscommand_order(rdpRail* rail) @@ -346,7 +390,7 @@ void rail_send_client_syscommand_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_SYSCOMMAND_ORDER_LENGTH); rail_write_syscommand_order(s, &rail->syscommand); - rail_send_pdu(s, RAIL_ORDER_TYPE_SYSCOMMAND); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_SYSCOMMAND); } void rail_send_client_notify_event_order(rdpRail* rail) @@ -354,7 +398,7 @@ void rail_send_client_notify_event_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_NOTIFY_EVENT_ORDER_LENGTH); rail_write_notify_event_order(s, &rail->notify_event); - rail_send_pdu(s, RAIL_ORDER_TYPE_NOTIFY_EVENT); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_NOTIFY_EVENT); } void rail_send_client_window_move_order(rdpRail* rail) @@ -362,7 +406,7 @@ void rail_send_client_window_move_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_WINDOW_MOVE_ORDER_LENGTH); rail_write_window_move_order(s, &rail->window_move); - rail_send_pdu(s, RAIL_ORDER_TYPE_WINDOW_MOVE); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_WINDOW_MOVE); } void rail_send_client_get_appid_req_order(rdpRail* rail) @@ -370,7 +414,7 @@ void rail_send_client_get_appid_req_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_GET_APPID_REQ_ORDER_LENGTH); rail_write_window_move_order(s, &rail->get_appid_req); - rail_send_pdu(s, RAIL_ORDER_TYPE_GET_APPID_REQ); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_GET_APPID_REQ); } void rail_send_client_langbar_info_order(rdpRail* rail) @@ -378,7 +422,7 @@ void rail_send_client_langbar_info_order(rdpRail* rail) STREAM* s; s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH); rail_write_window_move_order(s, &rail->langbar_info); - rail_send_pdu(s, RAIL_ORDER_TYPE_LANGBAR_INFO); + rail_send_pdu(rail, s, RAIL_ORDER_TYPE_LANGBAR_INFO); } rdpRail* rail_new() diff --git a/channels/rail/rail_orders.h b/channels/rail/rail_orders.h index 2225eafe2..79439e77c 100644 --- a/channels/rail/rail_orders.h +++ b/channels/rail/rail_orders.h @@ -21,6 +21,10 @@ #ifndef __RAIL_ORDERS_H #define __RAIL_ORDERS_H +typedef struct rdp_rail rdpRail; + +#include "rail_core.h" + #include #include @@ -42,8 +46,9 @@ struct rdp_rail RAIL_LANGBAR_INFO_ORDER langbar_info; RAIL_GET_APPID_REQ_ORDER get_appid_req; RAIL_GET_APPID_RESP_ORDER get_appid_resp; + RAIL_VCHANNEL_DATA_SENDER* data_sender; + RAIL_VCHANNEL_EVENT_SENDER* event_sender; }; -typedef struct rdp_rail rdpRail; #define RAIL_ORDER_TYPE_EXEC 0x0001 #define RAIL_ORDER_TYPE_ACTIVATE 0x0002 diff --git a/libfreerdp-utils/rail.c b/libfreerdp-utils/rail.c index a8a9c2f53..14e90dde4 100644 --- a/libfreerdp-utils/rail.c +++ b/libfreerdp-utils/rail.c @@ -55,7 +55,8 @@ void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string) { - stream_write(s, unicode_string->string, unicode_string->length); /* string */ + if (unicode_string->length > 0) + stream_write(s, unicode_string->string, unicode_string->length); /* string */ } void rail_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16)