mirror of https://github.com/FreeRDP/FreeRDP
rail: removing older code
This commit is contained in:
parent
53981e9dba
commit
91326a4f65
|
@ -19,14 +19,9 @@
|
|||
|
||||
set(RAIL_SRCS
|
||||
rail_main.c
|
||||
rail_main.h
|
||||
rail_core.c
|
||||
rail_core.h
|
||||
rail_main.h
|
||||
rail_orders.c
|
||||
rail_orders.h
|
||||
rail_channel_orders.c
|
||||
rail_channel_orders.h
|
||||
)
|
||||
rail_orders.h)
|
||||
|
||||
add_library(rail SHARED ${RAIL_SRCS})
|
||||
set_target_properties(rail PROPERTIES PREFIX "")
|
||||
|
|
|
@ -1,610 +0,0 @@
|
|||
/*
|
||||
FreeRDP: A Remote Desktop Protocol client.
|
||||
Remote Applications Integrated Locally (RAIL)
|
||||
|
||||
Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
Copyright 2011 Roman Barabanov <romanbarabanov@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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
#include <freerdp/utils/rail.h>
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
#include "rail_core.h"
|
||||
#include "rail_main.h"
|
||||
|
||||
/*
|
||||
* RAIL_PDU_HEADER
|
||||
* begin
|
||||
* orderType = 2 bytes
|
||||
* orderLength = 2 bytes
|
||||
end
|
||||
*/
|
||||
|
||||
static size_t RAIL_PDU_HEADER_SIZE = 4;
|
||||
|
||||
void stream_init_by_allocated_data(STREAM* s, void* data, size_t size)
|
||||
{
|
||||
s->data = data;
|
||||
s->size = size;
|
||||
s->p = s->data;
|
||||
}
|
||||
|
||||
void* rail_alloc_order_data(size_t length)
|
||||
{
|
||||
uint8 * order_start = xmalloc(length + RAIL_PDU_HEADER_SIZE);
|
||||
return (order_start + RAIL_PDU_HEADER_SIZE);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
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);
|
||||
|
||||
stream_write_uint16(s, order_type);
|
||||
stream_write_uint16(s, data_length);
|
||||
|
||||
session->data_sender->send_rail_vchannel_data(
|
||||
session->data_sender->data_sender_object,
|
||||
header_start, data_length);
|
||||
|
||||
// In there we free memory which we allocated in rail_alloc_order_data(..)
|
||||
xfree(header_start);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Handshake PDU is exchanged between the server and the client to
|
||||
* establish that both endpoints are ready to begin RAIL mode.
|
||||
* The server sends the Handshake PDU and the client responds
|
||||
* with the Handshake PDU.
|
||||
*/
|
||||
void rail_vchannel_send_handshake_order(RAIL_SESSION * session, uint32 build_number)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
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);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_HANDSHAKE, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Client Activate PDU is sent from client to server
|
||||
* when a local RAIL window on the client is activated or deactivated.
|
||||
*/
|
||||
void rail_vchannel_send_activate_order(RAIL_SESSION* session, uint32 window_id, uint8 enabled)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
uint16 data_length = 5;
|
||||
void* data = rail_alloc_order_data(data_length);
|
||||
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint32(s, window_id);
|
||||
stream_write_uint8(s, enabled);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_ACTIVATE, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicates a Client Execute PDU from client to server to request that a
|
||||
* remote application launch on the server.
|
||||
* */
|
||||
void rail_vchannel_send_exec_order(RAIL_SESSION* session, uint16 flags,
|
||||
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;
|
||||
|
||||
size_t data_length =
|
||||
2 + /*Flags (2 bytes)*/
|
||||
2 + /*ExeOrFileLength (2 bytes)*/
|
||||
2 + /*WorkingDirLength (2 bytes)*/
|
||||
2 + /*ArgumentsLen (2 bytes)*/
|
||||
exe_or_file_length + /*ExeOrFile (variable)*/
|
||||
working_directory_length + /*WorkingDir (variable)*/
|
||||
arguments_length; /*Arguments (variable):*/
|
||||
|
||||
void* data = rail_alloc_order_data(data_length);
|
||||
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint16(s, flags);
|
||||
stream_write_uint16(s, exe_or_file_length);
|
||||
stream_write_uint16(s, working_directory_length);
|
||||
stream_write_uint16(s, arguments_length);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
size_t get_sysparam_size_in_rdp_stream(RAIL_CLIENT_SYSPARAM * sysparam)
|
||||
{
|
||||
switch (sysparam->type)
|
||||
{
|
||||
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 SPI_DISPLAY_CHANGE: {return 8;}
|
||||
case 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.length);
|
||||
}
|
||||
};
|
||||
|
||||
assert(!"Unknown sysparam type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicates a Client System Parameters Update PDU from client to server to
|
||||
* synchronize system parameters on the server with those on the client.
|
||||
*/
|
||||
void rail_vchannel_send_client_sysparam_update_order(RAIL_SESSION* session, RAIL_CLIENT_SYSPARAM* sysparam)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
size_t data_length = 4; /*SystemParam (4 bytes)*/
|
||||
void* data = 0;
|
||||
|
||||
data_length += get_sysparam_size_in_rdp_stream(sysparam);
|
||||
|
||||
data = rail_alloc_order_data(data_length);
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint32(s, sysparam->type);
|
||||
|
||||
switch (sysparam->type)
|
||||
{
|
||||
case SPI_SET_DRAG_FULL_WINDOWS:
|
||||
stream_write_uint8(s, sysparam->value.full_window_drag_enabled);
|
||||
break;
|
||||
|
||||
case SPI_SET_KEYBOARD_CUES:
|
||||
stream_write_uint8(s, sysparam->value.menu_access_key_always_underlined);
|
||||
break;
|
||||
|
||||
case SPI_SET_KEYBOARD_PREF:
|
||||
stream_write_uint8(s, sysparam->value.keyboard_for_user_prefered);
|
||||
break;
|
||||
|
||||
case SPI_SET_MOUSE_BUTTON_SWAP:
|
||||
stream_write_uint8(s, sysparam->value.left_right_mouse_buttons_swapped);
|
||||
break;
|
||||
|
||||
case SPI_SET_WORK_AREA:
|
||||
rail_write_rectangle_16(s, &sysparam->value.work_area);
|
||||
break;
|
||||
|
||||
case SPI_DISPLAY_CHANGE:
|
||||
rail_write_rectangle_16(s, &sysparam->value.display_resolution);
|
||||
break;
|
||||
|
||||
case SPI_TASKBAR_POS:
|
||||
rail_write_rectangle_16(s, &sysparam->value.taskbar_size);
|
||||
break;
|
||||
|
||||
case SPI_SET_HIGH_CONTRAST:
|
||||
{
|
||||
uint32 color_scheme_length = 2 +
|
||||
sysparam->value.high_contrast_system_info.color_scheme.length;
|
||||
|
||||
stream_write_uint32(s, sysparam->value.high_contrast_system_info.flags);
|
||||
stream_write_uint32(s, color_scheme_length);
|
||||
rail_write_unicode_string_value(s, &sysparam->value.high_contrast_system_info.color_scheme);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(!"Unknown sysparam type");
|
||||
break;
|
||||
}
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_SYSPARAM, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Indicates a Client System Command PDU from client to server when a local
|
||||
* RAIL window on the client receives a command to perform an action on the
|
||||
* window, such as minimize or maximize.
|
||||
*/
|
||||
void rail_vchannel_send_syscommand_order(RAIL_SESSION* session, uint32 window_id, uint16 command)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
uint16 data_length = 4 + 2;
|
||||
void* data = rail_alloc_order_data(data_length);
|
||||
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint32(s, window_id);
|
||||
stream_write_uint16(s, command);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_SYSCOMMAND, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Client Notify Event PDU packet is sent from a client to a server when
|
||||
* a local RAIL Notification Icon on the client receives a keyboard or mouse
|
||||
* message from the user. This notification is forwarded to the server via
|
||||
* the Notify Event PDU.
|
||||
* */
|
||||
void rail_vchannel_send_notify_event_order(RAIL_SESSION * session, uint32 window_id, uint32 notify_icon_id, uint32 message)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
uint16 data_length = 4 * 3;
|
||||
void* data = rail_alloc_order_data(data_length);
|
||||
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint32(s, window_id);
|
||||
stream_write_uint32(s, notify_icon_id);
|
||||
stream_write_uint32(s, message);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_NOTIFY_EVENT, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Client Window Move PDU packet is sent from the client to the server
|
||||
* 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, RECTANGLE_16* new_position)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
uint16 data_length = 4 + 2 * 4;
|
||||
void* data = rail_alloc_order_data(data_length);
|
||||
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint32(s, window_id);
|
||||
stream_write_uint16(s, new_position->left);
|
||||
stream_write_uint16(s, new_position->top);
|
||||
stream_write_uint16(s, new_position->right);
|
||||
stream_write_uint16(s, new_position->bottom);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_WINDOWMOVE, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Client Information PDU is sent from client to server and contains
|
||||
* information about RAIL client state and features supported by the client.
|
||||
* */
|
||||
void rail_vchannel_send_client_information_order(RAIL_SESSION* session, uint32 flags)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
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);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_CLIENTSTATUS, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Client System Menu PDU packet is sent from the client to the server
|
||||
* when a local RAIL window on the client receives a command to display its
|
||||
* System menu. This command is forwarded to the server via
|
||||
* the System menu PDU.
|
||||
*/
|
||||
void rail_vchannel_send_client_system_menu_order(RAIL_SESSION* session, uint32 window_id, uint16 left, uint16 top)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
uint16 data_length = 4 + 2 * 2;
|
||||
void* data = rail_alloc_order_data(data_length);
|
||||
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint32(s, window_id);
|
||||
stream_write_uint16(s, left);
|
||||
stream_write_uint16(s, top);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_SYSMENU, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Language Bar Information PDU is used to set the language bar status.
|
||||
* It is sent from a client to a server or a server to a client, but only when
|
||||
* both support the Language Bar docking capability
|
||||
* (TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED).
|
||||
* This PDU contains information about the language bar status.
|
||||
* */
|
||||
void rail_vchannel_send_client_langbar_information_order(RAIL_SESSION* session, uint32 langbar_status)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
uint16 data_length = 4;
|
||||
void* data = rail_alloc_order_data(data_length);
|
||||
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint32(s, langbar_status);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_LANGBARINFO, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Client Get Application ID PDU is sent from a client to a server.
|
||||
* This PDU requests information from the server about the Application ID
|
||||
* that the window SHOULD <15> have on the client.
|
||||
* */
|
||||
void rail_vchannel_send_get_appid_req_order(RAIL_SESSION* session, uint32 window_id)
|
||||
{
|
||||
STREAM st_stream = {0};
|
||||
STREAM* s = &st_stream;
|
||||
uint16 data_length = 4;
|
||||
void* data = rail_alloc_order_data(data_length);
|
||||
|
||||
stream_init_by_allocated_data(s, data, data_length);
|
||||
|
||||
stream_write_uint32(s, window_id);
|
||||
|
||||
rail_vchannel_send_order_data(session, RDP_RAIL_ORDER_GET_APPID_REQ, data, data_length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look at rail_vchannel_send_handshake_order(...)
|
||||
*/
|
||||
void rail_vchannel_process_handshake_order(RAIL_SESSION* session, STREAM* s)
|
||||
{
|
||||
uint32 build_number = 0;
|
||||
|
||||
stream_read_uint32(s, build_number);
|
||||
rail_core_handle_server_handshake(session, build_number);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Server Execute Result PDU is sent from server to client in response to
|
||||
* a Client Execute PDU request, and contains the result of the server's
|
||||
* attempt to launch the requested executable.
|
||||
*/
|
||||
void rail_vchannel_process_exec_result_order(RAIL_SESSION* session, STREAM* s)
|
||||
{
|
||||
uint16 flags = 0;
|
||||
uint16 exec_result = 0;
|
||||
uint32 raw_result = 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)*/
|
||||
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);
|
||||
rail_unicode_string_free(&exe_or_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Server System Parameters Update PDU is sent from the server to client to
|
||||
* synchronize system parameters on the client with those on the server.
|
||||
*/
|
||||
void rail_vchannel_process_server_sysparam_update_order(RAIL_SESSION* session, STREAM* s)
|
||||
{
|
||||
RAIL_SERVER_SYSPARAM sysparam = {0};
|
||||
|
||||
stream_read_uint32(s, sysparam.type);
|
||||
|
||||
switch (sysparam.type)
|
||||
{
|
||||
case SPI_SET_SCREEN_SAVE_ACTIVE:
|
||||
stream_read_uint8(s, sysparam.value.screen_saver_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;
|
||||
};
|
||||
|
||||
rail_core_handle_server_sysparam(session, &sysparam);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Server Move/Size Start PDU packet is sent by the server when a window on
|
||||
* the server is beginning a move or resize.
|
||||
* The client uses this information to initiate a local move or resize of the
|
||||
* corresponding local window.
|
||||
*
|
||||
* The Server Move/Size End PDU is sent by the server when a window on the
|
||||
* server is completing a move or resize.
|
||||
* The client uses this information to end a local move/resize of the
|
||||
* corresponding local window.
|
||||
*
|
||||
*/
|
||||
void rail_vchannel_process_server_movesize_order(RAIL_SESSION* session, STREAM* s)
|
||||
{
|
||||
uint32 window_id = 0;
|
||||
uint16 move_size_started = 0;
|
||||
uint16 move_size_type = 0;
|
||||
uint16 pos_x = 0;
|
||||
uint16 pos_y = 0;
|
||||
|
||||
stream_read_uint32(s, window_id);
|
||||
stream_read_uint16(s, move_size_started);
|
||||
stream_read_uint16(s, move_size_type);
|
||||
stream_read_uint16(s, pos_x);
|
||||
stream_read_uint16(s, pos_y);
|
||||
|
||||
rail_core_handle_server_movesize(session, window_id, move_size_started, move_size_type, pos_x, pos_y);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Server Min Max Info PDU is sent from a server to a client when a window
|
||||
* move or resize on the server is being initiated.
|
||||
* This PDU contains information about the minimum and maximum extents to
|
||||
* which the window can be moved or sized.
|
||||
*/
|
||||
void rail_vchannel_process_server_minmax_info_order(RAIL_SESSION* session, STREAM* s)
|
||||
{
|
||||
uint32 window_id = 0;
|
||||
uint16 max_width = 0;
|
||||
uint16 max_height = 0;
|
||||
uint16 max_pos_x = 0;
|
||||
uint16 max_pos_y = 0;
|
||||
uint16 min_track_width = 0;
|
||||
uint16 min_track_height = 0;
|
||||
uint16 max_track_width = 0;
|
||||
uint16 max_track_height = 0;
|
||||
|
||||
stream_read_uint32(s, window_id);
|
||||
stream_read_uint16(s, max_width);
|
||||
stream_read_uint16(s, max_height);
|
||||
stream_read_uint16(s, max_pos_x);
|
||||
stream_read_uint16(s, max_pos_y);
|
||||
stream_read_uint16(s, min_track_width);
|
||||
stream_read_uint16(s, min_track_height);
|
||||
stream_read_uint16(s, max_track_width);
|
||||
stream_read_uint16(s, max_track_height);
|
||||
|
||||
rail_core_handle_server_minmax_info(session, window_id, max_width,
|
||||
max_height, max_pos_x, max_pos_y, min_track_width, min_track_height,
|
||||
max_track_width, max_track_height);
|
||||
}
|
||||
|
||||
/*
|
||||
*The Language Bar Information PDU is used to set the language bar status.
|
||||
*/
|
||||
void rail_vchannel_process_server_langbar_info_order(RAIL_SESSION* session, STREAM* s)
|
||||
{
|
||||
uint32 langbar_status = 0;
|
||||
|
||||
stream_read_uint32(s, langbar_status);
|
||||
|
||||
rail_core_handle_server_langbar_info(session, langbar_status);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Server Get Application ID Response PDU is sent from a server to a client.
|
||||
* This PDU MAY be sent to the client as a response to a Client Get Application
|
||||
* ID PDU. This PDU specifies the Application ID that the specified window
|
||||
* SHOULD have on the client. The client MAY ignore this PDU.
|
||||
*/
|
||||
static void rail_vchannel_process_server_get_appid_resp_order(RAIL_SESSION* session, STREAM* s)
|
||||
{
|
||||
uint32 window_id = 0;
|
||||
UNICODE_STRING app_id = {0};
|
||||
|
||||
app_id.length = 256;
|
||||
app_id.string = xmalloc(app_id.length);
|
||||
|
||||
stream_read_uint32(s, window_id);
|
||||
stream_read(s, app_id.string, app_id.length);
|
||||
|
||||
rail_core_handle_server_get_app_resp(session, window_id, &app_id);
|
||||
rail_unicode_string_free(&app_id);
|
||||
}
|
||||
|
||||
extern uint8 RAIL_ORDER_TYPE_STRINGS[][32];
|
||||
|
||||
void rail_vchannel_process_received_vchannel_data(RAIL_SESSION * session, STREAM* s)
|
||||
{
|
||||
size_t length = 0;
|
||||
uint16 order_type = 0;
|
||||
uint16 order_length = 0;
|
||||
|
||||
length = ((s->data + s->size) - s->p);
|
||||
|
||||
stream_read_uint16(s, order_type); /* orderType */
|
||||
stream_read_uint16(s, order_length); /* orderLength */
|
||||
|
||||
DEBUG_RAIL("rail_on_channel_data_received: session=0x%p data_size=%d "
|
||||
"orderType=0x%X orderLength=%d", session, (int) length, order_type, order_length);
|
||||
|
||||
printf("Received %s PDU, length:%d\n",
|
||||
RAIL_ORDER_TYPE_STRINGS[((order_type & 0xF0) >> 3) + (order_type & 0x0F)], order_length);
|
||||
|
||||
switch (order_type)
|
||||
{
|
||||
case RDP_RAIL_ORDER_HANDSHAKE:
|
||||
rail_vchannel_process_handshake_order(session, s);
|
||||
break;
|
||||
|
||||
case RDP_RAIL_ORDER_EXEC_RESULT:
|
||||
rail_vchannel_process_exec_result_order(session, s);
|
||||
break;
|
||||
|
||||
case RDP_RAIL_ORDER_SYSPARAM:
|
||||
rail_vchannel_process_server_sysparam_update_order(session, s);
|
||||
break;
|
||||
|
||||
case RDP_RAIL_ORDER_LOCALMOVESIZE:
|
||||
rail_vchannel_process_server_movesize_order(session, s);
|
||||
break;
|
||||
|
||||
case RDP_RAIL_ORDER_MINMAXINFO:
|
||||
rail_vchannel_process_server_minmax_info_order(session, s);
|
||||
break;
|
||||
|
||||
case RDP_RAIL_ORDER_LANGBARINFO:
|
||||
rail_vchannel_process_server_langbar_info_order(session, s);
|
||||
break;
|
||||
|
||||
case RDP_RAIL_ORDER_GET_APPID_RESP:
|
||||
rail_vchannel_process_server_get_appid_resp_order(session, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_RAIL("rail_on_channel_data_received: "
|
||||
"Undocumented RAIL server PDU: order_type=0x%X",order_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
FreeRDP: A Remote Desktop Protocol client.
|
||||
Remote Applications Integrated Locally (RAIL)
|
||||
|
||||
Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
Copyright 2011 Roman Barabanov <romanbarabanov@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_CHANNEL_ORDERS_H
|
||||
#define __RAIL_CHANNEL_ORDERS_H
|
||||
|
||||
#include "rail_core.h"
|
||||
|
||||
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, 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, 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);
|
||||
void rail_vchannel_process_received_vchannel_data(RAIL_SESSION* session, STREAM* s);
|
||||
|
||||
#endif /* __RAIL_CHANNEL_ORDERS_H */
|
|
@ -1,570 +0,0 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Remote Applications Integrated Locally (RAIL)
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2011 Roman Barabanov <romanbarabanov@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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/hexdump.h>
|
||||
#include <freerdp/utils/unicode.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
#include <freerdp/utils/rail.h>
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
#include "rail_core.h"
|
||||
#include "rail_channel_orders.h"
|
||||
|
||||
/*
|
||||
// Initialization stage in UI for RAIL:
|
||||
// 1) create a sequence of rail_notify_client_sysparam_update()
|
||||
// calls with all current client system parameters
|
||||
//
|
||||
// 2) if Language Bar capability enabled - call updating Language Bar PDU
|
||||
//
|
||||
// 3) prepare and call rail_client_execute(exe_or_file, working_dir, args)
|
||||
//
|
||||
*/
|
||||
|
||||
/*
|
||||
Flow of init stage over channel;
|
||||
|
||||
Client notify UI about session start
|
||||
and go to RAIL_ESTABLISHING state.
|
||||
|
||||
Client wait for Server Handshake PDU
|
||||
Server send Handshake request
|
||||
Client check Handshake response.
|
||||
If NOT OK - exit with specified reason
|
||||
Client send Handshake response
|
||||
Server send Server System
|
||||
Parameters Update (in parallel)
|
||||
Client send Client Information
|
||||
Client send Client System Parameters Update
|
||||
Client send Client Execute
|
||||
Server send Server Execute Result
|
||||
Client check Server Execute Result. If NOT OK - exit with specified reason
|
||||
|
||||
Client notify UI about success session establishing and go to
|
||||
RAIL_ESTABLISHED state.
|
||||
*/
|
||||
|
||||
void init_vchannel_event(RAIL_VCHANNEL_EVENT* event, uint32 event_id)
|
||||
{
|
||||
memset(event, 0, sizeof(RAIL_VCHANNEL_EVENT));
|
||||
event->event_id = event_id;
|
||||
}
|
||||
|
||||
void init_rail_string(RAIL_STRING * rail_string, const char * string)
|
||||
{
|
||||
rail_string->buffer = (uint8*)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;
|
||||
|
||||
if (strlen(string) < 1)
|
||||
return;
|
||||
|
||||
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;
|
||||
char* result_buffer = NULL;
|
||||
|
||||
unicode_string->string = NULL;
|
||||
unicode_string->length = 0;
|
||||
|
||||
if (string->length == 0) return;
|
||||
|
||||
result_buffer = freerdp_uniconv_out(session->uniconv, (char*) string->buffer, &result_length);
|
||||
|
||||
unicode_string->string = (uint8*) result_buffer;
|
||||
unicode_string->length = (uint16) result_length;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
result_buffer = freerdp_uniconv_in(session->uniconv, unicode_string->string, unicode_string->length);
|
||||
|
||||
string->buffer = (uint8*)result_buffer;
|
||||
string->length = strlen(result_buffer) + 1;
|
||||
}
|
||||
|
||||
RAIL_SESSION* rail_core_session_new(RAIL_VCHANNEL_DATA_SENDER* data_sender, RAIL_VCHANNEL_EVENT_SENDER* event_sender)
|
||||
{
|
||||
RAIL_SESSION* self;
|
||||
|
||||
self = (RAIL_SESSION*) xzalloc(sizeof(RAIL_SESSION));
|
||||
|
||||
if (self != NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void rail_core_on_channel_connected(RAIL_SESSION* session)
|
||||
{
|
||||
DEBUG_RAIL("RAIL channel connected.");
|
||||
}
|
||||
|
||||
void rail_core_on_channel_terminated(RAIL_SESSION* session)
|
||||
{
|
||||
DEBUG_RAIL("RAIL channel terminated.");
|
||||
}
|
||||
|
||||
void rail_core_handle_server_handshake(RAIL_SESSION* session, uint32 build_number)
|
||||
{
|
||||
#if 1
|
||||
DEBUG_RAIL("Server Handshake");
|
||||
|
||||
session->rail->handshake.buildNumber = 0x00001DB1;
|
||||
rail_send_handshake_order(session->rail);
|
||||
|
||||
session->rail->client_status.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
|
||||
rail_send_client_status_order(session->rail);
|
||||
|
||||
/* sysparam update */
|
||||
|
||||
session->rail->sysparam.systemParam = SPI_SET_HIGH_CONTRAST;
|
||||
session->rail->sysparam.highContrast.colorScheme.string = NULL;
|
||||
session->rail->sysparam.highContrast.colorScheme.length = 0;
|
||||
session->rail->sysparam.highContrast.flags = 0x7E;
|
||||
rail_send_client_sysparam_order(session->rail);
|
||||
|
||||
session->rail->sysparam.systemParam = SPI_TASKBAR_POS;
|
||||
session->rail->sysparam.rectangle.left = 0;
|
||||
session->rail->sysparam.rectangle.top = 0;
|
||||
session->rail->sysparam.rectangle.right = 1024;
|
||||
session->rail->sysparam.rectangle.bottom = 29;
|
||||
rail_send_client_sysparam_order(session->rail);
|
||||
|
||||
session->rail->sysparam.systemParam = SPI_SET_MOUSE_BUTTON_SWAP;
|
||||
session->rail->sysparam.value = False;
|
||||
rail_send_client_sysparam_order(session->rail);
|
||||
|
||||
session->rail->sysparam.systemParam = SPI_SET_KEYBOARD_PREF;
|
||||
session->rail->sysparam.value = False;
|
||||
rail_send_client_sysparam_order(session->rail);
|
||||
|
||||
session->rail->sysparam.systemParam = SPI_SET_DRAG_FULL_WINDOWS;
|
||||
session->rail->sysparam.value = True;
|
||||
rail_send_client_sysparam_order(session->rail);
|
||||
|
||||
session->rail->sysparam.systemParam = SPI_SET_KEYBOARD_CUES;
|
||||
session->rail->sysparam.value = False;
|
||||
rail_send_client_sysparam_order(session->rail);
|
||||
|
||||
session->rail->sysparam.systemParam = SPI_SET_WORK_AREA;
|
||||
session->rail->sysparam.rectangle.left = 0;
|
||||
session->rail->sysparam.rectangle.top = 0;
|
||||
session->rail->sysparam.rectangle.right = 1024;
|
||||
session->rail->sysparam.rectangle.bottom = 768;
|
||||
rail_send_client_sysparam_order(session->rail);
|
||||
|
||||
/* execute */
|
||||
|
||||
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
|
||||
uint32 client_build_number = 0x00001db0;
|
||||
RAIL_VCHANNEL_EVENT event = {0};
|
||||
|
||||
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!
|
||||
rail_vchannel_send_handshake_order(session, client_build_number);
|
||||
|
||||
// Step 2. Send Client Information PDU (2.2.2.2.1)
|
||||
rail_vchannel_send_client_information_order(session, RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE);
|
||||
|
||||
// Step 3. Notify UI about session establishing and about requirements to
|
||||
// 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", "", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
void rail_core_handle_exec_result(RAIL_SESSION* session, uint16 flags, uint16 exec_result, uint32 raw_result, UNICODE_STRING* exe_or_file)
|
||||
{
|
||||
DEBUG_RAIL("EXEC_RESULT");
|
||||
#if 0
|
||||
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);
|
||||
|
||||
#ifdef WITH_DEBUG_RAIL
|
||||
freerdp_hexdump(exe_or_file->string, exe_or_file->length);
|
||||
#endif
|
||||
|
||||
rail_unicode_string2string(session, exe_or_file, &exe_or_file_);
|
||||
|
||||
init_vchannel_event(&event, RAIL_VCHANNEL_EVENT_EXEC_RESULT_RETURNED);
|
||||
event.param.exec_result_info.flags = flags;
|
||||
event.param.exec_result_info.exec_result = exec_result;
|
||||
event.param.exec_result_info.raw_result = raw_result;
|
||||
event.param.exec_result_info.exe_or_file = exe_or_file_.buffer;
|
||||
|
||||
session->event_sender->send_rail_vchannel_event(session->event_sender->event_sender_object, &event);
|
||||
#endif
|
||||
}
|
||||
|
||||
void rail_core_handle_server_sysparam(RAIL_SESSION* session, RAIL_SERVER_SYSPARAM* sysparam)
|
||||
{
|
||||
#if 0
|
||||
RAIL_VCHANNEL_EVENT event = {0};
|
||||
|
||||
DEBUG_RAIL("rail_core_handle_server_sysparam: session=0x%p "
|
||||
"type=0x%X scr_enabled=%d scr_lock_enabled=%d",
|
||||
session, sysparam->type, sysparam->value.screen_saver_enabled,
|
||||
sysparam->value.screen_saver_lock_enabled);
|
||||
|
||||
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 =
|
||||
((sysparam->value.screen_saver_enabled != 0) ? True: False);
|
||||
|
||||
event.param.server_param_info.screen_saver_lock_enabled =
|
||||
((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,
|
||||
uint16 move_size_started, uint16 move_size_type, uint16 pos_x, uint16 pos_y)
|
||||
{
|
||||
RAIL_VCHANNEL_EVENT event = {0};
|
||||
|
||||
DEBUG_RAIL("rail_core_handle_server_movesize: session=0x%p "
|
||||
"window_id=0x%X started=%d move_size_type=%d pos_x=%d pos_y=%d",
|
||||
session, window_id, move_size_started, move_size_type, pos_x, pos_y);
|
||||
|
||||
init_vchannel_event(&event, ((move_size_started != 0) ?
|
||||
RAIL_VCHANNEL_EVENT_MOVESIZE_STARTED:
|
||||
RAIL_VCHANNEL_EVENT_MOVESIZE_FINISHED));
|
||||
|
||||
event.param.movesize_info.window_id = window_id;
|
||||
event.param.movesize_info.move_size_type = move_size_type;
|
||||
event.param.movesize_info.pos_x = pos_x;
|
||||
event.param.movesize_info.pos_y = pos_y;
|
||||
|
||||
session->event_sender->send_rail_vchannel_event(session->event_sender->event_sender_object, &event);
|
||||
}
|
||||
|
||||
void rail_core_handle_server_minmax_info(RAIL_SESSION* session,
|
||||
uint32 window_id, uint16 max_width, uint16 max_height, uint16 max_pos_x, uint16 max_pos_y,
|
||||
uint16 min_track_width, uint16 min_track_height, uint16 max_track_width, uint16 max_track_height)
|
||||
{
|
||||
RAIL_VCHANNEL_EVENT event = {0};
|
||||
|
||||
DEBUG_RAIL("rail_core_handle_server_minmax_info: session=0x%p "
|
||||
"window_id=0x%X max_width=%d max_height=%d max_pos_x=%d max_pos_y=%d "
|
||||
"min_track_width=%d min_track_height=%d max_track_width=%d max_track_height=%d",
|
||||
session, window_id, max_width, max_height, max_pos_x, max_pos_y,
|
||||
min_track_width, min_track_height, max_track_width, max_track_height);
|
||||
|
||||
init_vchannel_event(&event, RAIL_VCHANNEL_EVENT_MINMAX_INFO_UPDATED);
|
||||
|
||||
event.param.minmax_info.window_id = window_id;
|
||||
|
||||
event.param.minmax_info.max_width = max_width;
|
||||
event.param.minmax_info.max_height = max_height;
|
||||
event.param.minmax_info.max_pos_x = max_pos_x;
|
||||
event.param.minmax_info.max_pos_y = max_pos_y;
|
||||
event.param.minmax_info.min_track_width = min_track_width;
|
||||
event.param.minmax_info.min_track_height = min_track_height;
|
||||
event.param.minmax_info.max_track_width = max_track_width;
|
||||
event.param.minmax_info.max_track_height = max_track_height;
|
||||
|
||||
session->event_sender->send_rail_vchannel_event(session->event_sender->event_sender_object, &event);
|
||||
}
|
||||
|
||||
void rail_core_handle_server_langbar_info(RAIL_SESSION* session, uint32 langbar_status)
|
||||
{
|
||||
RAIL_VCHANNEL_EVENT event = {0};
|
||||
|
||||
DEBUG_RAIL("rail_core_handle_server_langbar_info: session=0x%p "
|
||||
"langbar_status=0x%X", session, langbar_status);
|
||||
|
||||
init_vchannel_event(&event, RAIL_VCHANNEL_EVENT_LANGBAR_STATUS_UPDATED);
|
||||
|
||||
event.param.langbar_info.status = langbar_status;
|
||||
|
||||
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, 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);
|
||||
|
||||
#ifdef WITH_DEBUG_RAIL
|
||||
freerdp_hexdump(app_id->string, app_id->length);
|
||||
#endif
|
||||
|
||||
rail_unicode_string2string(session, app_id, &app_id_);
|
||||
|
||||
init_vchannel_event(&event, RAIL_VCHANNEL_EVENT_LANGBAR_STATUS_UPDATED);
|
||||
|
||||
event.param.app_response_info.window_id= window_id;
|
||||
event.param.app_response_info.application_id = app_id_.buffer;
|
||||
|
||||
session->event_sender->send_rail_vchannel_event(session->event_sender->event_sender_object, &event);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
RAIL_STRING exe_or_file_;
|
||||
RAIL_STRING working_directory_;
|
||||
RAIL_STRING arguments_;
|
||||
UNICODE_STRING exe_or_file;
|
||||
UNICODE_STRING working_directory;
|
||||
UNICODE_STRING arguments;
|
||||
uint16 flags;
|
||||
|
||||
init_rail_string(&exe_or_file_, rail_exe_or_file);
|
||||
init_rail_string(&working_directory_, rail_working_directory);
|
||||
init_rail_string(&arguments_, rail_arguments);
|
||||
|
||||
rail_string2unicode_string(session, &exe_or_file_, &exe_or_file);
|
||||
rail_string2unicode_string(session, &working_directory_, &working_directory);
|
||||
rail_string2unicode_string(session, &arguments_, &arguments);
|
||||
|
||||
flags = (RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY | RAIL_EXEC_FLAG_EXPAND_ARGUMENTS);
|
||||
|
||||
if (exec_or_file_is_file_path)
|
||||
{
|
||||
flags |= (RAIL_EXEC_FLAG_TRANSLATE_FILES | RAIL_EXEC_FLAG_FILE);
|
||||
}
|
||||
|
||||
rail_vchannel_send_exec_order(session, flags, &exe_or_file,
|
||||
&working_directory, &arguments);
|
||||
|
||||
rail_unicode_string_free(&exe_or_file);
|
||||
rail_unicode_string_free(&working_directory);
|
||||
rail_unicode_string_free(&arguments);
|
||||
}
|
||||
|
||||
uint8 boolean2uint8(boolean value)
|
||||
{
|
||||
return ((value == True) ? 1 : 0);
|
||||
}
|
||||
|
||||
uint8 copy_rail_rect_16(RECTANGLE_16* src, RECTANGLE_16* dst)
|
||||
{
|
||||
memcpy(dst, src, sizeof(RECTANGLE_16));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rail_core_handle_ui_update_client_sysparam(RAIL_SESSION* session, RAIL_UI_EVENT* event)
|
||||
{
|
||||
RAIL_CLIENT_SYSPARAM sys_param;
|
||||
|
||||
memset(&sys_param, 0, sizeof(sys_param));
|
||||
|
||||
sys_param.type = event->param.sysparam_info.param;
|
||||
|
||||
sys_param.value.full_window_drag_enabled =
|
||||
boolean2uint8(event->param.sysparam_info.value.full_window_drag_enabled);
|
||||
|
||||
sys_param.value.menu_access_key_always_underlined =
|
||||
boolean2uint8(event->param.sysparam_info.value.menu_access_key_always_underlined);
|
||||
|
||||
sys_param.value.keyboard_for_user_prefered =
|
||||
boolean2uint8(event->param.sysparam_info.value.keyboard_for_user_prefered);
|
||||
|
||||
sys_param.value.left_right_mouse_buttons_swapped =
|
||||
boolean2uint8(event->param.sysparam_info.value.left_right_mouse_buttons_swapped);
|
||||
|
||||
copy_rail_rect_16(&event->param.sysparam_info.value.work_area,
|
||||
&sys_param.value.work_area);
|
||||
|
||||
copy_rail_rect_16(&event->param.sysparam_info.value.display_resolution,
|
||||
&sys_param.value.display_resolution);
|
||||
|
||||
copy_rail_rect_16(&event->param.sysparam_info.value.taskbar_size,
|
||||
&sys_param.value.taskbar_size);
|
||||
|
||||
sys_param.value.high_contrast_system_info.flags =
|
||||
event->param.sysparam_info.value.high_contrast_system_info.flags;
|
||||
|
||||
|
||||
if (sys_param.type == SPI_SET_HIGH_CONTRAST)
|
||||
{
|
||||
RAIL_STRING color_scheme;
|
||||
|
||||
init_rail_string(&color_scheme,
|
||||
event->param.sysparam_info.value.high_contrast_system_info.color_scheme);
|
||||
|
||||
rail_string2unicode_string(session, &color_scheme, &sys_param.value.high_contrast_system_info.color_scheme);
|
||||
}
|
||||
|
||||
rail_vchannel_send_client_sysparam_update_order(session, &sys_param);
|
||||
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)
|
||||
{
|
||||
rail_core_send_client_execute(session,
|
||||
event->param.execute_info.exec_or_file_is_file_path,
|
||||
event->param.execute_info.exe_or_file,
|
||||
event->param.execute_info.working_directory,
|
||||
event->param.execute_info.arguments);
|
||||
}
|
||||
|
||||
static void rail_core_handle_ui_activate(RAIL_SESSION* session, RAIL_UI_EVENT* event)
|
||||
{
|
||||
rail_vchannel_send_activate_order(
|
||||
session, event->param.activate_info.window_id,
|
||||
((event->param.activate_info.enabled == True) ? 1 : 0));
|
||||
}
|
||||
|
||||
static void rail_core_handle_ui_sys_command(RAIL_SESSION* session, RAIL_UI_EVENT* event)
|
||||
{
|
||||
rail_vchannel_send_syscommand_order(session,
|
||||
event->param.syscommand_info.window_id,
|
||||
event->param.syscommand_info.syscommand);
|
||||
}
|
||||
|
||||
static void rail_core_handle_ui_notify(RAIL_SESSION* session, RAIL_UI_EVENT* event)
|
||||
{
|
||||
rail_vchannel_send_notify_event_order(session,
|
||||
event->param.notify_info.window_id,
|
||||
event->param.notify_info.notify_icon_id,
|
||||
event->param.notify_info.message);
|
||||
}
|
||||
|
||||
static void rail_core_handle_ui_window_move(RAIL_SESSION* session, RAIL_UI_EVENT* event)
|
||||
{
|
||||
rail_vchannel_send_client_windowmove_order(session,
|
||||
event->param.window_move_info.window_id,
|
||||
&event->param.window_move_info.new_position);
|
||||
}
|
||||
|
||||
static void rail_core_handle_ui_system_menu(RAIL_SESSION* session, RAIL_UI_EVENT* event)
|
||||
{
|
||||
rail_vchannel_send_client_system_menu_order(session,
|
||||
event->param.system_menu_info.window_id,
|
||||
event->param.system_menu_info.left,
|
||||
event->param.system_menu_info.top);
|
||||
}
|
||||
|
||||
static void rail_core_handle_ui_get_app_id(RAIL_SESSION* session, RAIL_UI_EVENT* event)
|
||||
{
|
||||
rail_vchannel_send_get_appid_req_order(session, event->param.get_app_id_info.window_id);
|
||||
}
|
||||
|
||||
void rail_core_handle_ui_event(RAIL_SESSION* session, RAIL_UI_EVENT* event)
|
||||
{
|
||||
return;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 event_id;
|
||||
void (*event_handler)(RAIL_SESSION* session, RAIL_UI_EVENT* event);
|
||||
} handlers_table[] =
|
||||
{
|
||||
{RAIL_UI_EVENT_UPDATE_CLIENT_SYSPARAM, rail_core_handle_ui_update_client_sysparam},
|
||||
{RAIL_UI_EVENT_EXECUTE_REMOTE_APP, rail_core_handle_ui_execute_remote_app},
|
||||
{RAIL_UI_EVENT_ACTIVATE, rail_core_handle_ui_activate},
|
||||
{RAIL_UI_EVENT_SYS_COMMAND, rail_core_handle_ui_sys_command},
|
||||
{RAIL_UI_EVENT_NOTIFY, rail_core_handle_ui_notify},
|
||||
{RAIL_UI_EVENT_WINDOW_MOVE, rail_core_handle_ui_window_move},
|
||||
{RAIL_UI_EVENT_SYSTEM_MENU, rail_core_handle_ui_system_menu},
|
||||
{RAIL_UI_EVENT_LANGBAR_INFO, rail_core_handle_ui_system_menu},
|
||||
{RAIL_UI_EVENT_GET_APP_ID, rail_core_handle_ui_get_app_id}
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < RAIL_ARRAY_SIZE(handlers_table); i++)
|
||||
{
|
||||
if ((event->event_id == handlers_table[i].event_id) &&
|
||||
(handlers_table[i].event_handler != NULL))
|
||||
{
|
||||
(handlers_table[i].event_handler)(session, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Remote Applications Integrated Locally (RAIL)
|
||||
*
|
||||
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2011 Roman Barabanov <romanbarabanov@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_CORE_H
|
||||
#define __RAIL_CORE_H
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/unicode.h>
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
|
||||
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
|
||||
#define DEBUG_RAIL(fmt, ...) DEBUG_CLASS(RAIL, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_RAIL(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define RAIL_ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
typedef struct _RAIL_STRING
|
||||
{
|
||||
uint16 length;
|
||||
uint8 *buffer;
|
||||
} RAIL_STRING;
|
||||
|
||||
typedef struct _RAIL_HIGHCONTRAST
|
||||
{
|
||||
uint32 flags;
|
||||
UNICODE_STRING color_scheme;
|
||||
|
||||
} RAIL_HIGHCONTRAST;
|
||||
|
||||
typedef struct _RAIL_CLIENT_SYSPARAM
|
||||
{
|
||||
uint32 type;
|
||||
|
||||
union
|
||||
{
|
||||
uint8 full_window_drag_enabled;
|
||||
uint8 menu_access_key_always_underlined;
|
||||
uint8 keyboard_for_user_prefered;
|
||||
uint8 left_right_mouse_buttons_swapped;
|
||||
RECTANGLE_16 work_area;
|
||||
RECTANGLE_16 display_resolution;
|
||||
RECTANGLE_16 taskbar_size;
|
||||
RAIL_HIGHCONTRAST high_contrast_system_info;
|
||||
} value;
|
||||
} RAIL_CLIENT_SYSPARAM;
|
||||
|
||||
struct _RAIL_SERVER_SYSPARAM
|
||||
{
|
||||
uint32 type;
|
||||
|
||||
union
|
||||
{
|
||||
uint8 screen_saver_enabled;
|
||||
uint8 screen_saver_lock_enabled;
|
||||
} value;
|
||||
};
|
||||
typedef struct _RAIL_SERVER_SYSPARAM RAIL_SERVER_SYSPARAM;
|
||||
|
||||
struct _RAIL_VCHANNEL_DATA_SENDER
|
||||
{
|
||||
void* data_sender_object;
|
||||
void (*send_rail_vchannel_data)(void* sender_object, void* data, size_t length);
|
||||
};
|
||||
|
||||
struct _RAIL_VCHANNEL_EVENT_SENDER
|
||||
{
|
||||
void * event_sender_object;
|
||||
void (*send_rail_vchannel_event)(void* ui_event_sender_object, RAIL_VCHANNEL_EVENT* event);
|
||||
};
|
||||
|
||||
struct _RAIL_SESSION
|
||||
{
|
||||
rdpRail* rail;
|
||||
UNICONV* uniconv;
|
||||
RAIL_VCHANNEL_DATA_SENDER* data_sender;
|
||||
RAIL_VCHANNEL_EVENT_SENDER* event_sender;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
// RAIL Core Handlers for events from channel plugin interface
|
||||
|
||||
void rail_core_on_channel_connected(RAIL_SESSION* rail_session);
|
||||
void rail_core_on_channel_terminated(RAIL_SESSION* rail_session);
|
||||
void rail_core_on_channel_data_received(RAIL_SESSION* rail_session, void* data, size_t length);
|
||||
|
||||
// RAIL Core Handlers for events from UI
|
||||
|
||||
void rail_core_handle_ui_event(RAIL_SESSION* session, RAIL_UI_EVENT* event);
|
||||
|
||||
// RAIL Core Handlers for events from channel orders reader
|
||||
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, UNICODE_STRING* exe_or_file);
|
||||
|
||||
void rail_core_handle_server_sysparam(RAIL_SESSION* session, RAIL_SERVER_SYSPARAM* sysparam);
|
||||
|
||||
void rail_core_handle_server_movesize(RAIL_SESSION* session, uint32 window_id,
|
||||
uint16 move_size_started, uint16 move_size_type, uint16 pos_x, uint16 pos_y);
|
||||
|
||||
void rail_core_handle_server_minmax_info(RAIL_SESSION* session, uint32 window_id,
|
||||
uint16 max_width, uint16 max_height, uint16 max_pos_x, uint16 max_pos_y,
|
||||
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, 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 */
|
|
@ -28,22 +28,17 @@
|
|||
#include <freerdp/utils/svc_plugin.h>
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
#include "rail_core.h"
|
||||
#include "rail_channel_orders.h"
|
||||
#include "rail_orders.h"
|
||||
#include "rail_main.h"
|
||||
|
||||
static void rail_plugin_process_connect(rdpSvcPlugin* plugin)
|
||||
{
|
||||
railPlugin* rail_plugin = (railPlugin*)plugin;
|
||||
|
||||
DEBUG_RAIL("rail_plugin_process_connect() called.");
|
||||
rail_core_on_channel_connected(rail_plugin->session);
|
||||
}
|
||||
|
||||
static void rail_plugin_process_terminate(rdpSvcPlugin* plugin)
|
||||
{
|
||||
DEBUG_RAIL("rail_plugin_process_terminate\n");
|
||||
xfree(plugin);
|
||||
}
|
||||
|
||||
static void rail_plugin_send_vchannel_data(void* rail_plugin_object, void* data, size_t length)
|
||||
|
@ -51,35 +46,27 @@ static void rail_plugin_send_vchannel_data(void* rail_plugin_object, void* data,
|
|||
STREAM* s = NULL;
|
||||
railPlugin* plugin = (railPlugin*) rail_plugin_object;
|
||||
|
||||
DEBUG_RAIL("rail_plugin_send_vchannel_data\n");
|
||||
|
||||
s = stream_new(length);
|
||||
stream_write(s, data, length);
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) plugin, s);
|
||||
}
|
||||
|
||||
static void rail_plugin_process_received_vchannel_data(rdpSvcPlugin* plugin, STREAM* data_in)
|
||||
static void rail_plugin_process_received_vchannel_data(rdpSvcPlugin* plugin, STREAM* s)
|
||||
{
|
||||
railPlugin* rail_plugin = (railPlugin*) plugin;
|
||||
|
||||
DEBUG_RAIL("rail_plugin_process_receive: size=%d", stream_get_size(data_in));
|
||||
DEBUG_RAIL("rail_plugin_process_received_vchannel_data\n");
|
||||
|
||||
rail_vchannel_process_received_vchannel_data(rail_plugin->session, data_in);
|
||||
stream_free(data_in);
|
||||
rail_order_recv(rail_plugin->rail, s);
|
||||
stream_free(s);
|
||||
}
|
||||
|
||||
static void on_free_rail_vchannel_event(FRDP_EVENT* event)
|
||||
{
|
||||
assert(event->event_type == FRDP_EVENT_TYPE_RAIL_VCHANNEL_2_UI);
|
||||
|
||||
RAIL_VCHANNEL_EVENT* rail_event = (RAIL_VCHANNEL_EVENT*)event->user_data;
|
||||
|
||||
if (rail_event->event_id == RAIL_VCHANNEL_EVENT_APP_RESPONSE_RECEIVED)
|
||||
xfree((void*)rail_event->param.app_response_info.application_id);
|
||||
|
||||
if (rail_event->event_id == RAIL_VCHANNEL_EVENT_EXEC_RESULT_RETURNED)
|
||||
xfree((void*)rail_event->param.exec_result_info.exe_or_file);
|
||||
|
||||
xfree(rail_event);
|
||||
}
|
||||
|
||||
static void rail_plugin_send_vchannel_event(void* rail_plugin_object, RAIL_VCHANNEL_EVENT* event)
|
||||
|
@ -88,6 +75,8 @@ static void rail_plugin_send_vchannel_event(void* rail_plugin_object, RAIL_VCHAN
|
|||
RAIL_VCHANNEL_EVENT* payload = NULL;
|
||||
FRDP_EVENT* out_event = NULL;
|
||||
|
||||
DEBUG_RAIL("rail_plugin_send_vchannel_event\n");
|
||||
|
||||
payload = xnew(RAIL_VCHANNEL_EVENT);
|
||||
memset(payload, 0, sizeof(RAIL_VCHANNEL_EVENT));
|
||||
memcpy(payload, event, sizeof(RAIL_VCHANNEL_EVENT));
|
||||
|
@ -107,41 +96,42 @@ static void rail_plugin_process_event(rdpSvcPlugin* plugin, FRDP_EVENT* event)
|
|||
rail_plugin = (railPlugin*)plugin;
|
||||
rail_ui_event = (RAIL_UI_EVENT*)event->user_data;
|
||||
|
||||
if (event->event_type == FRDP_EVENT_TYPE_RAIL_UI_2_VCHANNEL)
|
||||
rail_core_handle_ui_event(rail_plugin->session, rail_ui_event);
|
||||
//if (event->event_type == FRDP_EVENT_TYPE_RAIL_UI_2_VCHANNEL)
|
||||
//rail_core_handle_ui_event(rail_plugin->session, rail_ui_event);
|
||||
|
||||
freerdp_event_free(event);
|
||||
}
|
||||
|
||||
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
railPlugin* rail;
|
||||
railPlugin* rail_plugin;
|
||||
|
||||
DEBUG_RAIL("RAIL plugin VirtualChannelEntry started.");
|
||||
|
||||
rail = (railPlugin*) xzalloc(sizeof(railPlugin));
|
||||
rail_plugin = (railPlugin*) xzalloc(sizeof(railPlugin));
|
||||
|
||||
rail->plugin.channel_def.options = CHANNEL_OPTION_INITIALIZED |
|
||||
rail_plugin->plugin.channel_def.options = CHANNEL_OPTION_INITIALIZED |
|
||||
CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP |
|
||||
CHANNEL_OPTION_SHOW_PROTOCOL;
|
||||
strcpy(rail->plugin.channel_def.name, "rail");
|
||||
strcpy(rail_plugin->plugin.channel_def.name, "rail");
|
||||
|
||||
rail->plugin.connect_callback = rail_plugin_process_connect;
|
||||
rail->plugin.terminate_callback = rail_plugin_process_terminate;
|
||||
rail_plugin->plugin.connect_callback = rail_plugin_process_connect;
|
||||
rail_plugin->plugin.terminate_callback = rail_plugin_process_terminate;
|
||||
|
||||
rail->plugin.receive_callback = rail_plugin_process_received_vchannel_data;
|
||||
rail->plugin.event_callback = rail_plugin_process_event;
|
||||
rail_plugin->plugin.receive_callback = rail_plugin_process_received_vchannel_data;
|
||||
rail_plugin->plugin.event_callback = rail_plugin_process_event;
|
||||
|
||||
rail->rail_event_sender.event_sender_object = rail;
|
||||
rail->rail_event_sender.send_rail_vchannel_event = rail_plugin_send_vchannel_event;
|
||||
rail_plugin->rail_event_sender.event_sender_object = rail_plugin;
|
||||
rail_plugin->rail_event_sender.send_rail_vchannel_event = rail_plugin_send_vchannel_event;
|
||||
|
||||
rail->rail_data_sender.data_sender_object = rail;
|
||||
rail->rail_data_sender.send_rail_vchannel_data =
|
||||
rail_plugin_send_vchannel_data;
|
||||
rail_plugin->rail_data_sender.data_sender_object = rail_plugin;
|
||||
rail_plugin->rail_data_sender.send_rail_vchannel_data = rail_plugin_send_vchannel_data;
|
||||
|
||||
rail->session = rail_core_session_new(&rail->rail_data_sender, &rail->rail_event_sender);
|
||||
rail_plugin->rail = rail_new();
|
||||
rail_plugin->rail->data_sender = &(rail_plugin->rail_data_sender);
|
||||
rail_plugin->rail->event_sender = &(rail_plugin->rail_event_sender);
|
||||
|
||||
svc_plugin_init((rdpSvcPlugin*) rail, pEntryPoints);
|
||||
svc_plugin_init((rdpSvcPlugin*) rail_plugin, pEntryPoints);
|
||||
|
||||
DEBUG_RAIL("RAIL plugin VirtualChannelEntry finished.");
|
||||
|
||||
|
|
|
@ -22,13 +22,63 @@
|
|||
#ifndef __RAIL_MAIN_H
|
||||
#define __RAIL_MAIN_H
|
||||
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
typedef struct _RAIL_VCHANNEL_DATA_SENDER RAIL_VCHANNEL_DATA_SENDER;
|
||||
typedef struct _RAIL_VCHANNEL_EVENT_SENDER RAIL_VCHANNEL_EVENT_SENDER;
|
||||
|
||||
struct _RAIL_VCHANNEL_DATA_SENDER
|
||||
{
|
||||
void* data_sender_object;
|
||||
void (*send_rail_vchannel_data)(void* sender_object, void* data, size_t length);
|
||||
};
|
||||
|
||||
struct _RAIL_VCHANNEL_EVENT_SENDER
|
||||
{
|
||||
void * event_sender_object;
|
||||
void (*send_rail_vchannel_event)(void* ui_event_sender_object, RAIL_VCHANNEL_EVENT* event);
|
||||
};
|
||||
|
||||
struct rdp_rail
|
||||
{
|
||||
UNICONV* uniconv;
|
||||
RAIL_HANDSHAKE_ORDER handshake;
|
||||
RAIL_CLIENT_STATUS_ORDER client_status;
|
||||
RAIL_EXEC_ORDER exec;
|
||||
RAIL_EXEC_RESULT_ORDER exec_result;
|
||||
RAIL_SYSPARAM_ORDER sysparam;
|
||||
RAIL_ACTIVATE_ORDER activate;
|
||||
RAIL_SYSMENU_ORDER sysmenu;
|
||||
RAIL_SYSCOMMAND_ORDER syscommand;
|
||||
RAIL_NOTIFY_EVENT_ORDER notify_event;
|
||||
RAIL_MINMAXINFO_ORDER minmaxinfo;
|
||||
RAIL_LOCALMOVESIZE_ORDER localmovesize;
|
||||
RAIL_WINDOW_MOVE_ORDER window_move;
|
||||
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;
|
||||
|
||||
struct rail_plugin
|
||||
{
|
||||
rdpSvcPlugin plugin;
|
||||
RAIL_VCHANNEL_DATA_SENDER rail_data_sender;
|
||||
RAIL_VCHANNEL_EVENT_SENDER rail_event_sender;
|
||||
RAIL_SESSION * session;
|
||||
rdpRail* rail;
|
||||
};
|
||||
typedef struct rail_plugin railPlugin;
|
||||
|
||||
#define WITH_DEBUG_RAIL 1
|
||||
|
||||
#ifdef WITH_DEBUG_RAIL
|
||||
#define DEBUG_RAIL(fmt, ...) DEBUG_CLASS(RAIL, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_RAIL(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif /* __RAIL_MAIN_H */
|
||||
|
|
|
@ -60,6 +60,23 @@ uint8 RAIL_ORDER_TYPE_STRINGS[][32] =
|
|||
"Execute Result"
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
if (strlen(string) < 1)
|
||||
return;
|
||||
|
||||
buffer = freerdp_uniconv_out(rail->uniconv, string, &length);
|
||||
|
||||
unicode_string->string = (uint8*) buffer;
|
||||
unicode_string->length = (uint16) length;
|
||||
}
|
||||
|
||||
void rail_read_pdu_header(STREAM* s, uint16* orderType, uint16* orderLength)
|
||||
{
|
||||
stream_read_uint16(s, *orderType); /* orderType (2 bytes) */
|
||||
|
@ -263,6 +280,67 @@ void rail_write_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_i
|
|||
stream_write_uint32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */
|
||||
}
|
||||
|
||||
void rail_recv_handshake_order(rdpRail* rail, STREAM* s)
|
||||
{
|
||||
rail_read_handshake_order(s, &rail->handshake);
|
||||
|
||||
rail->handshake.buildNumber = 0x00001DB1;
|
||||
rail_send_handshake_order(rail);
|
||||
|
||||
rail->client_status.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
|
||||
rail_send_client_status_order(rail);
|
||||
|
||||
/* sysparam update */
|
||||
|
||||
rail->sysparam.systemParam = SPI_SET_HIGH_CONTRAST;
|
||||
rail->sysparam.highContrast.colorScheme.string = NULL;
|
||||
rail->sysparam.highContrast.colorScheme.length = 0;
|
||||
rail->sysparam.highContrast.flags = 0x7E;
|
||||
rail_send_client_sysparam_order(rail);
|
||||
|
||||
rail->sysparam.systemParam = SPI_TASKBAR_POS;
|
||||
rail->sysparam.rectangle.left = 0;
|
||||
rail->sysparam.rectangle.top = 0;
|
||||
rail->sysparam.rectangle.right = 1024;
|
||||
rail->sysparam.rectangle.bottom = 29;
|
||||
rail_send_client_sysparam_order(rail);
|
||||
|
||||
rail->sysparam.systemParam = SPI_SET_MOUSE_BUTTON_SWAP;
|
||||
rail->sysparam.value = False;
|
||||
rail_send_client_sysparam_order(rail);
|
||||
|
||||
rail->sysparam.systemParam = SPI_SET_KEYBOARD_PREF;
|
||||
rail->sysparam.value = False;
|
||||
rail_send_client_sysparam_order(rail);
|
||||
|
||||
rail->sysparam.systemParam = SPI_SET_DRAG_FULL_WINDOWS;
|
||||
rail->sysparam.value = False;
|
||||
rail_send_client_sysparam_order(rail);
|
||||
|
||||
rail->sysparam.systemParam = SPI_SET_KEYBOARD_CUES;
|
||||
rail->sysparam.value = False;
|
||||
rail_send_client_sysparam_order(rail);
|
||||
|
||||
rail->sysparam.systemParam = SPI_SET_WORK_AREA;
|
||||
rail->sysparam.rectangle.left = 0;
|
||||
rail->sysparam.rectangle.top = 0;
|
||||
rail->sysparam.rectangle.right = 1024;
|
||||
rail->sysparam.rectangle.bottom = 768;
|
||||
rail_send_client_sysparam_order(rail);
|
||||
|
||||
/* execute */
|
||||
|
||||
rail->exec.flags =
|
||||
RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY |
|
||||
RAIL_EXEC_FLAG_EXPAND_ARGUMENTS;
|
||||
|
||||
rail_string_to_unicode_string(rail, "||cmd", &rail->exec.exeOrFile);
|
||||
rail_string_to_unicode_string(rail, "", &rail->exec.workingDir);
|
||||
rail_string_to_unicode_string(rail, "", &rail->exec.arguments);
|
||||
|
||||
rail_send_client_exec_order(rail);
|
||||
}
|
||||
|
||||
void rail_order_recv(rdpRail* rail, STREAM* s)
|
||||
{
|
||||
uint16 orderType;
|
||||
|
@ -276,7 +354,7 @@ void rail_order_recv(rdpRail* rail, STREAM* s)
|
|||
switch (orderType)
|
||||
{
|
||||
case RDP_RAIL_ORDER_HANDSHAKE:
|
||||
rail_read_handshake_order(s, &rail->handshake);
|
||||
rail_recv_handshake_order(rail, s);
|
||||
break;
|
||||
|
||||
case RDP_RAIL_ORDER_EXEC_RESULT:
|
||||
|
|
|
@ -21,34 +21,7 @@
|
|||
#ifndef __RAIL_ORDERS_H
|
||||
#define __RAIL_ORDERS_H
|
||||
|
||||
typedef struct rdp_rail rdpRail;
|
||||
|
||||
#include "rail_core.h"
|
||||
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
struct rdp_rail
|
||||
{
|
||||
UNICONV* uniconv;
|
||||
RAIL_HANDSHAKE_ORDER handshake;
|
||||
RAIL_CLIENT_STATUS_ORDER client_status;
|
||||
RAIL_EXEC_ORDER exec;
|
||||
RAIL_EXEC_RESULT_ORDER exec_result;
|
||||
RAIL_SYSPARAM_ORDER sysparam;
|
||||
RAIL_ACTIVATE_ORDER activate;
|
||||
RAIL_SYSMENU_ORDER sysmenu;
|
||||
RAIL_SYSCOMMAND_ORDER syscommand;
|
||||
RAIL_NOTIFY_EVENT_ORDER notify_event;
|
||||
RAIL_MINMAXINFO_ORDER minmaxinfo;
|
||||
RAIL_LOCALMOVESIZE_ORDER localmovesize;
|
||||
RAIL_WINDOW_MOVE_ORDER window_move;
|
||||
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;
|
||||
};
|
||||
#include "rail_main.h"
|
||||
|
||||
#define RAIL_ORDER_TYPE_EXEC 0x0001
|
||||
#define RAIL_ORDER_TYPE_ACTIVATE 0x0002
|
||||
|
|
Loading…
Reference in New Issue