libfreerdp-utils: added RAIL utils

This commit is contained in:
Marc-André Moreau 2011-08-10 02:24:06 -04:00
parent 95642fd33f
commit 21aa8ad9a8
12 changed files with 402 additions and 218 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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 */

View File

@ -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;

View File

@ -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 <freerdp/types.h>
/* 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

View File

@ -20,6 +20,7 @@
#ifndef __UPDATE_API_H
#define __UPDATE_API_H
#include <freerdp/rail.h>
#include <freerdp/types.h>
#include <freerdp/utils/stream.h>
@ -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;

View File

@ -0,0 +1,34 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Remote Applications Integrated Locally (RAIL) Utils
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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 <freerdp/rail.h>
#include <freerdp/utils/stream.h>
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 */

View File

@ -18,30 +18,11 @@
* limitations under the License.
*/
#include <freerdp/utils/rail.h>
#include <freerdp/utils/memory.h>
#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, &notify_icon_infotip->text); /* infoTipText */
update_read_unicode_string(s, &notify_icon_infotip->title); /* title */
rail_read_unicode_string(s, &notify_icon_infotip->text); /* infoTipText */
rail_read_unicode_string(s, &notify_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, &notify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */
rail_read_unicode_string(s, &notify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
update_read_notify_icon_infotip(s, &notify_icon_state->infoTip); /* infoTip (NOTIFY_ICON_INFOTIP) */

View File

@ -29,6 +29,7 @@ set(FREERDP_UTILS_SRCS
load_plugin.c
memory.c
mutex.c
rail.c
semaphore.c
stream.c
svc_plugin.c

76
libfreerdp-utils/rail.c Normal file
View File

@ -0,0 +1,76 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Remote Applications Integrated Locally (RAIL) Utils
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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 <freerdp/utils/memory.h>
#include <freerdp/utils/rail.h>
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) */
}

View File

@ -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);