Merge branch 'master' into remotefx
Conflicts: libfreerdp-utils/CMakeLists.txt
This commit is contained in:
commit
00b2b135a8
@ -21,4 +21,5 @@ add_subdirectory(cliprdr)
|
|||||||
add_subdirectory(drdynvc)
|
add_subdirectory(drdynvc)
|
||||||
add_subdirectory(rdpdbg)
|
add_subdirectory(rdpdbg)
|
||||||
add_subdirectory(rdpdr)
|
add_subdirectory(rdpdr)
|
||||||
|
add_subdirectory(rail)
|
||||||
|
|
||||||
|
35
channels/rail/CMakeLists.txt
Normal file
35
channels/rail/CMakeLists.txt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# FreeRDP: A Remote Desktop Protocol Client
|
||||||
|
# FreeRDP cmake build script
|
||||||
|
#
|
||||||
|
# Copyright 2011 O.S. Systems Software Ltda.
|
||||||
|
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
set(RAIL_SRCS
|
||||||
|
rail_main.c
|
||||||
|
rail_main.h
|
||||||
|
rail_core.c
|
||||||
|
rail_core.h
|
||||||
|
rail_channel_orders.c
|
||||||
|
rail_channel_orders.h
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(rail SHARED ${RAIL_SRCS})
|
||||||
|
set_target_properties(rail PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
target_link_libraries(rail freerdp-utils)
|
||||||
|
|
||||||
|
install(TARGETS rail DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||||
|
|
605
channels/rail/rail_channel_orders.c
Normal file
605
channels/rail/rail_channel_orders.c
Normal file
@ -0,0 +1,605 @@
|
|||||||
|
/*
|
||||||
|
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/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->cbString;
|
||||||
|
uint16 working_directory_length = working_directory->cbString;
|
||||||
|
uint16 arguments_length = arguments->cbString;
|
||||||
|
|
||||||
|
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 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");
|
||||||
|
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 RAIL_SPI_DISPLAY_CHANGE:
|
||||||
|
rail_write_rectangle_16(s, &sysparam->value.display_resolution);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RAIL_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.cbString;
|
||||||
|
|
||||||
|
stream_write_uint32(s, sysparam->value.high_contrast_system_info.flags);
|
||||||
|
stream_write_uint32(s, color_scheme_length);
|
||||||
|
write_rail_unicode_string(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.cbString = 256;
|
||||||
|
app_id.string = xmalloc(app_id.cbString);
|
||||||
|
|
||||||
|
stream_read_uint32(s, window_id);
|
||||||
|
stream_read(s, app_id.string, app_id.cbString);
|
||||||
|
|
||||||
|
rail_core_handle_server_get_app_resp(session, window_id, &app_id);
|
||||||
|
rail_unicode_string_free(&app_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
40
channels/rail/rail_channel_orders.h
Normal file
40
channels/rail/rail_channel_orders.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
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 */
|
481
channels/rail/rail_core.c
Normal file
481
channels/rail/rail_core.c
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
/**
|
||||||
|
* 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/svc_plugin.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_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->cbString = 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->cbString = (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->cbString == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
result_buffer = freerdp_uniconv_in(session->uniconv, unicode_string->string, unicode_string->cbString);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rail_core_session_free(RAIL_SESSION* rail_session)
|
||||||
|
{
|
||||||
|
if (rail_session != NULL)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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", "", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
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->cbString);
|
||||||
|
|
||||||
|
#ifdef WITH_DEBUG_RAIL
|
||||||
|
freerdp_hexdump(exe_or_file->string, exe_or_file->cbString);
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rail_core_handle_server_sysparam(RAIL_SESSION* session, RAIL_SERVER_SYSPARAM* sysparam)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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->cbString);
|
||||||
|
|
||||||
|
#ifdef WITH_DEBUG_RAIL
|
||||||
|
freerdp_hexdump(app_id->string, app_id->cbString);
|
||||||
|
#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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
143
channels/rail/rail_core.h
Normal file
143
channels/rail/rail_core.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
};
|
||||||
|
typedef struct _RAIL_VCHANNEL_DATA_SENDER RAIL_VCHANNEL_DATA_SENDER;
|
||||||
|
|
||||||
|
struct _RAIL_VCHANNEL_EVENT_SENDER
|
||||||
|
{
|
||||||
|
void * event_sender_object;
|
||||||
|
void (*send_rail_vchannel_event)(void* ui_event_sender_object, RAIL_VCHANNEL_EVENT* event);
|
||||||
|
};
|
||||||
|
typedef struct _RAIL_VCHANNEL_EVENT_SENDER RAIL_VCHANNEL_EVENT_SENDER;
|
||||||
|
|
||||||
|
struct _RAIL_SESSION
|
||||||
|
{
|
||||||
|
UNICONV * uniconv;
|
||||||
|
RAIL_VCHANNEL_DATA_SENDER* data_sender;
|
||||||
|
RAIL_VCHANNEL_EVENT_SENDER* event_sender;
|
||||||
|
};
|
||||||
|
typedef struct _RAIL_SESSION RAIL_SESSION;
|
||||||
|
|
||||||
|
RAIL_SESSION* rail_core_session_new(RAIL_VCHANNEL_DATA_SENDER *data_sender, RAIL_VCHANNEL_EVENT_SENDER *event_sender);
|
||||||
|
void rail_core_session_free(RAIL_SESSION * rail_session);
|
||||||
|
|
||||||
|
// 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 */
|
149
channels/rail/rail_main.c
Normal file
149
channels/rail/rail_main.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/**
|
||||||
|
* FreeRDP: A Remote Desktop Protocol Client
|
||||||
|
* RAIL Virtual Channel Plugin
|
||||||
|
*
|
||||||
|
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||||
|
* Copyright 2011 Roman Barabanov <romanbarabanov@gmail.com>
|
||||||
|
* Copyright 2011 Vic Lee
|
||||||
|
*
|
||||||
|
* 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/svc_plugin.h>
|
||||||
|
#include <freerdp/rail.h>
|
||||||
|
|
||||||
|
#include "rail_core.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)
|
||||||
|
{
|
||||||
|
STREAM* s = NULL;
|
||||||
|
railPlugin* plugin = (railPlugin*) rail_plugin_object;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
railPlugin* rail_plugin = (railPlugin*) plugin;
|
||||||
|
|
||||||
|
DEBUG_RAIL("rail_plugin_process_receive: size=%d", stream_get_size(data_in));
|
||||||
|
|
||||||
|
rail_vchannel_process_received_vchannel_data(rail_plugin->session, data_in);
|
||||||
|
stream_free(data_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
railPlugin* plugin = (railPlugin*) rail_plugin_object;
|
||||||
|
RAIL_VCHANNEL_EVENT* payload = NULL;
|
||||||
|
FRDP_EVENT* out_event = NULL;
|
||||||
|
|
||||||
|
payload = xnew(RAIL_VCHANNEL_EVENT);
|
||||||
|
memset(payload, 0, sizeof(RAIL_VCHANNEL_EVENT));
|
||||||
|
memcpy(payload, event, sizeof(RAIL_VCHANNEL_EVENT));
|
||||||
|
|
||||||
|
out_event = freerdp_event_new(FRDP_EVENT_TYPE_RAIL_VCHANNEL_2_UI, on_free_rail_vchannel_event, payload);
|
||||||
|
|
||||||
|
svc_plugin_send_event((rdpSvcPlugin*) plugin, out_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rail_plugin_process_event(rdpSvcPlugin* plugin, FRDP_EVENT* event)
|
||||||
|
{
|
||||||
|
RAIL_UI_EVENT* rail_ui_event = NULL;
|
||||||
|
railPlugin* rail_plugin = NULL;
|
||||||
|
|
||||||
|
DEBUG_RAIL("rail_plugin_process_event: event_type=%d\n", event->event_type);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
freerdp_event_free(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||||
|
{
|
||||||
|
railPlugin* rail;
|
||||||
|
|
||||||
|
DEBUG_RAIL("RAIL plugin VirtualChannelEntry started.");
|
||||||
|
|
||||||
|
rail = (railPlugin*) xzalloc(sizeof(railPlugin));
|
||||||
|
|
||||||
|
rail->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");
|
||||||
|
|
||||||
|
rail->plugin.connect_callback = rail_plugin_process_connect;
|
||||||
|
rail->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->rail_event_sender.event_sender_object = rail;
|
||||||
|
rail->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->session = rail_core_session_new(&rail->rail_data_sender, &rail->rail_event_sender);
|
||||||
|
|
||||||
|
svc_plugin_init((rdpSvcPlugin*) rail, pEntryPoints);
|
||||||
|
|
||||||
|
DEBUG_RAIL("RAIL plugin VirtualChannelEntry finished.");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
34
channels/rail/rail_main.h
Normal file
34
channels/rail/rail_main.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* FreeRDP: A Remote Desktop Protocol Client
|
||||||
|
* RAIL Virtual Channel Plugin
|
||||||
|
*
|
||||||
|
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||||
|
* Copyright 2011 Roman Barabanov <romanbarabanov@gmail.com>
|
||||||
|
* Copyright 2011 Vic Lee
|
||||||
|
*
|
||||||
|
* 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_MAIN_H
|
||||||
|
#define __RAIL_MAIN_H
|
||||||
|
|
||||||
|
struct rail_plugin
|
||||||
|
{
|
||||||
|
rdpSvcPlugin plugin;
|
||||||
|
RAIL_VCHANNEL_DATA_SENDER rail_data_sender;
|
||||||
|
RAIL_VCHANNEL_EVENT_SENDER rail_event_sender;
|
||||||
|
RAIL_SESSION * session;
|
||||||
|
};
|
||||||
|
typedef struct rail_plugin railPlugin;
|
||||||
|
|
||||||
|
#endif /* __RAIL_MAIN_H */
|
@ -407,7 +407,8 @@ boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, ui
|
|||||||
case FileAllocationInformation:
|
case FileAllocationInformation:
|
||||||
/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
|
/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
|
||||||
stream_read_uint64(input, size);
|
stream_read_uint64(input, size);
|
||||||
ftruncate(file->fd, size);
|
if (ftruncate(file->fd, size) != 0)
|
||||||
|
return False;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FileDispositionInformation:
|
case FileDispositionInformation:
|
||||||
|
@ -257,7 +257,7 @@ boolean xf_post_connect(freerdp* instance)
|
|||||||
if (xf_get_pixmap_info(xfi) != True)
|
if (xf_get_pixmap_info(xfi) != True)
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
gdi_init(instance, CLRCONV_ALPHA | CLRBUF_16BPP | CLRBUF_32BPP);
|
gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP);
|
||||||
gdi = GET_GDI(instance->update);
|
gdi = GET_GDI(instance->update);
|
||||||
|
|
||||||
if (xfi->fullscreen)
|
if (xfi->fullscreen)
|
||||||
@ -345,6 +345,11 @@ void xf_process_cb_sync_event(rdpChanMan* chanman, freerdp* instance)
|
|||||||
freerdp_chanman_send_event(chanman, "cliprdr", event);
|
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)
|
void xf_process_channel_event(rdpChanMan* chanman, freerdp* instance)
|
||||||
{
|
{
|
||||||
FRDP_EVENT* event;
|
FRDP_EVENT* event;
|
||||||
@ -357,6 +362,9 @@ void xf_process_channel_event(rdpChanMan* chanman, freerdp* instance)
|
|||||||
case FRDP_EVENT_TYPE_CB_SYNC:
|
case FRDP_EVENT_TYPE_CB_SYNC:
|
||||||
xf_process_cb_sync_event(chanman, instance);
|
xf_process_cb_sync_event(chanman, instance);
|
||||||
break;
|
break;
|
||||||
|
case FRDP_EVENT_TYPE_RAIL_VCHANNEL_2_UI:
|
||||||
|
xf_process_rail_event(chanman, instance);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("xf_process_channel_event: unknown event type %d\n", event->event_type);
|
printf("xf_process_channel_event: unknown event type %d\n", event->event_type);
|
||||||
break;
|
break;
|
||||||
|
@ -88,7 +88,10 @@ enum FRDP_EVENT_TYPE
|
|||||||
FRDP_EVENT_TYPE_CB_SYNC = 3,
|
FRDP_EVENT_TYPE_CB_SYNC = 3,
|
||||||
FRDP_EVENT_TYPE_CB_FORMAT_LIST = 4,
|
FRDP_EVENT_TYPE_CB_FORMAT_LIST = 4,
|
||||||
FRDP_EVENT_TYPE_CB_DATA_REQUEST = 5,
|
FRDP_EVENT_TYPE_CB_DATA_REQUEST = 5,
|
||||||
FRDP_EVENT_TYPE_CB_DATA_RESPONSE = 6
|
FRDP_EVENT_TYPE_CB_DATA_RESPONSE = 6,
|
||||||
|
|
||||||
|
FRDP_EVENT_TYPE_RAIL_UI_2_VCHANNEL = 100,
|
||||||
|
FRDP_EVENT_TYPE_RAIL_VCHANNEL_2_UI = 101
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
465
include/freerdp/rail.h
Normal file
465
include/freerdp/rail.h
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
/**
|
||||||
|
* 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_H
|
||||||
|
#define __RAIL_H
|
||||||
|
|
||||||
|
#include <freerdp/types.h>
|
||||||
|
|
||||||
|
/* RAIL PDU flags */
|
||||||
|
#define RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY 0x0001
|
||||||
|
#define RAIL_EXEC_FLAG_TRANSLATE_FILES 0x0002
|
||||||
|
#define RAIL_EXEC_FLAG_FILE 0x0004
|
||||||
|
#define RAIL_EXEC_FLAG_EXPAND_ARGUMENTS 0x0008
|
||||||
|
|
||||||
|
/* Notification Icon Balloon Tooltip */
|
||||||
|
#define NIIF_NONE 0x00000000
|
||||||
|
#define NIIF_INFO 0x00000001
|
||||||
|
#define NIIF_WARNING 0x00000002
|
||||||
|
#define NIIF_ERROR 0x00000003
|
||||||
|
#define NIIF_NOSOUND 0x00000010
|
||||||
|
#define NIIF_LARGE_ICON 0x00000020
|
||||||
|
|
||||||
|
/* Client Execute PDU Flags */
|
||||||
|
#define RAIL_EXEC_FLAG_EXPAND_WORKING_DIRECTORY 0x0001
|
||||||
|
#define RAIL_EXEC_FLAG_TRANSLATE_FILES 0x0002
|
||||||
|
#define RAIL_EXEC_FLAG_FILE 0x0004
|
||||||
|
#define RAIL_EXEC_FLAG_EXPAND_ARGUMENTS 0x0008
|
||||||
|
|
||||||
|
/* Server Execute Result PDU */
|
||||||
|
#define RAIL_EXEC_S_OK 0x0000
|
||||||
|
#define RAIL_EXEC_E_HOOK_NOT_LOADED 0x0001
|
||||||
|
#define RAIL_EXEC_E_DECODE_FAILED 0x0002
|
||||||
|
#define RAIL_EXEC_E_NOT_IN_ALLOWLIST 0x0003
|
||||||
|
#define RAIL_EXEC_E_FILE_NOT_FOUND 0x0005
|
||||||
|
#define RAIL_EXEC_E_FAIL 0x0006
|
||||||
|
#define RAIL_EXEC_E_SESSION_LOCKED 0x0007
|
||||||
|
|
||||||
|
/* Client System Parameters Update PDU */
|
||||||
|
#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_SET_SCREEN_SAVE_ACTIVE 0x00000011
|
||||||
|
#define SPI_SET_SCREEN_SAVE_SECURE 0x00000077
|
||||||
|
|
||||||
|
/* Client System Command PDU */
|
||||||
|
#define SC_SIZE 0xF000
|
||||||
|
#define SC_MOVE 0xF010
|
||||||
|
#define SC_MINIMIZE 0xF020
|
||||||
|
#define SC_MAXIMIZE 0xF030
|
||||||
|
#define SC_CLOSE 0xF060
|
||||||
|
#define SC_KEYMENU 0xF100
|
||||||
|
#define SC_RESTORE 0xF120
|
||||||
|
#define SC_DEFAULT 0xF160
|
||||||
|
|
||||||
|
/* Client Notify Event PDU */
|
||||||
|
#define WM_LBUTTONDOWN 0x00000201
|
||||||
|
#define WM_LBUTTONUP 0x00000202
|
||||||
|
#define WM_RBUTTONDOWN 0x00000204
|
||||||
|
#define WM_RBUTTONUP 0x00000205
|
||||||
|
#define WM_CONTEXTMENU 0x0000007B
|
||||||
|
#define WM_LBUTTONDBLCLK 0x00000203
|
||||||
|
#define WM_RBUTTONDBLCLK 0x00000206
|
||||||
|
|
||||||
|
#define NIN_SELECT 0x00000400
|
||||||
|
#define NIN_KEYSELECT 0x00000401
|
||||||
|
#define NIN_BALLOONSHOW 0x00000402
|
||||||
|
#define NIN_BALLOONHIDE 0x00000403
|
||||||
|
#define NIN_BALLOONTIMEOUT 0x00000404
|
||||||
|
#define NIN_BALLOONUSERCLICK 0x00000405
|
||||||
|
|
||||||
|
/* Client Information PDU */
|
||||||
|
#define RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE 0x00000001
|
||||||
|
#define RAIL_CLIENTSTATUS_AUTORECONNECT 0x00000002
|
||||||
|
|
||||||
|
/*HIGHCONTRAST flags values */
|
||||||
|
#define HCF_AVAILABLE 0x00000002
|
||||||
|
#define HCF_CONFIRMHOTKEY 0x00000008
|
||||||
|
#define HCF_HIGHCONTRASTON 0x00000001
|
||||||
|
#define HCF_HOTKEYACTIVE 0x00000004
|
||||||
|
#define HCF_HOTKEYAVAILABLE 0x00000040
|
||||||
|
#define HCF_HOTKEYSOUND 0x00000010
|
||||||
|
#define HCF_INDICATOR 0x00000020
|
||||||
|
|
||||||
|
/* Server Move/Size Start PDU */
|
||||||
|
#define RAIL_WMSZ_LEFT 0x0001
|
||||||
|
#define RAIL_WMSZ_RIGHT 0x0002
|
||||||
|
#define RAIL_WMSZ_TOP 0x0003
|
||||||
|
#define RAIL_WMSZ_TOPLEFT 0x0004
|
||||||
|
#define RAIL_WMSZ_TOPRIGHT 0x0005
|
||||||
|
#define RAIL_WMSZ_BOTTOM 0x0006
|
||||||
|
#define RAIL_WMSZ_BOTTOMLEFT 0x0007
|
||||||
|
#define RAIL_WMSZ_BOTTOMRIGHT 0x0008
|
||||||
|
#define RAIL_WMSZ_MOVE 0x0009
|
||||||
|
#define RAIL_WMSZ_KEYMOVE 0x000A
|
||||||
|
#define RAIL_WMSZ_KEYSIZE 0x000B
|
||||||
|
|
||||||
|
/* Language Bar Information PDU */
|
||||||
|
#define TF_SFT_SHOWNORMAL 0x00000001
|
||||||
|
#define TF_SFT_DOCK 0x00000002
|
||||||
|
#define TF_SFT_MINIMIZED 0x00000004
|
||||||
|
#define TF_SFT_HIDDEN 0x00000008
|
||||||
|
#define TF_SFT_NOTRANSPARENCY 0x00000010
|
||||||
|
#define TF_SFT_LOWTRANSPARENCY 0x00000020
|
||||||
|
#define TF_SFT_HIGHTRANSPARENCY 0x00000040
|
||||||
|
#define TF_SFT_LABELS 0x00000080
|
||||||
|
#define TF_SFT_NOLABELS 0x00000100
|
||||||
|
#define TF_SFT_EXTRAICONSONMINIMIZED 0x00000200
|
||||||
|
#define TF_SFT_NOEXTRAICONSONMINIMIZED 0x00000400
|
||||||
|
#define TF_SFT_DESKBAND 0x00000800
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* RAIL Orders */
|
||||||
|
|
||||||
|
struct _RAIL_HANDSHAKE_ORDER
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
RAIL_VCHANNEL_EVENT_SESSION_ESTABLISHED = 1,
|
||||||
|
RAIL_VCHANNEL_EVENT_EXEC_RESULT_RETURNED,
|
||||||
|
RAIL_VCHANNEL_EVENT_SERVER_SYSPARAM_RECEIVED,
|
||||||
|
RAIL_VCHANNEL_EVENT_MOVESIZE_STARTED,
|
||||||
|
RAIL_VCHANNEL_EVENT_MOVESIZE_FINISHED,
|
||||||
|
RAIL_VCHANNEL_EVENT_MINMAX_INFO_UPDATED,
|
||||||
|
RAIL_VCHANNEL_EVENT_LANGBAR_STATUS_UPDATED,
|
||||||
|
RAIL_VCHANNEL_EVENT_APP_RESPONSE_RECEIVED
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _RAIL_VCHANNEL_EVENT
|
||||||
|
{
|
||||||
|
uint32 event_id;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint16 flags;
|
||||||
|
uint16 exec_result;
|
||||||
|
uint32 raw_result;
|
||||||
|
const char* exe_or_file;
|
||||||
|
} exec_result_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 param_type;
|
||||||
|
boolean screen_saver_enabled;
|
||||||
|
boolean screen_saver_lock_enabled;
|
||||||
|
} server_param_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 window_id;
|
||||||
|
uint16 move_size_type;
|
||||||
|
uint16 pos_x;
|
||||||
|
uint16 pos_y;
|
||||||
|
} movesize_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
} minmax_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 status;
|
||||||
|
} langbar_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 window_id;
|
||||||
|
const char* application_id;
|
||||||
|
|
||||||
|
} app_response_info;
|
||||||
|
|
||||||
|
}param;
|
||||||
|
}
|
||||||
|
RAIL_VCHANNEL_EVENT;
|
||||||
|
|
||||||
|
// Events from UI to 'rail' vchannel plugin
|
||||||
|
enum RAIL_UI_EVENT
|
||||||
|
{
|
||||||
|
RAIL_UI_EVENT_UPDATE_CLIENT_SYSPARAM = 1,
|
||||||
|
RAIL_UI_EVENT_EXECUTE_REMOTE_APP,
|
||||||
|
RAIL_UI_EVENT_ACTIVATE,
|
||||||
|
RAIL_UI_EVENT_SYS_COMMAND,
|
||||||
|
RAIL_UI_EVENT_NOTIFY,
|
||||||
|
RAIL_UI_EVENT_WINDOW_MOVE,
|
||||||
|
RAIL_UI_EVENT_SYSTEM_MENU,
|
||||||
|
RAIL_UI_EVENT_LANGBAR_INFO,
|
||||||
|
RAIL_UI_EVENT_GET_APP_ID
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _RAIL_UI_EVENT
|
||||||
|
{
|
||||||
|
uint32 event_id;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 param;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
boolean full_window_drag_enabled;
|
||||||
|
boolean menu_access_key_always_underlined;
|
||||||
|
boolean keyboard_for_user_prefered;
|
||||||
|
boolean left_right_mouse_buttons_swapped;
|
||||||
|
RECTANGLE_16 work_area;
|
||||||
|
RECTANGLE_16 display_resolution;
|
||||||
|
RECTANGLE_16 taskbar_size;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 flags;
|
||||||
|
const char* color_scheme;
|
||||||
|
} high_contrast_system_info;
|
||||||
|
} value;
|
||||||
|
|
||||||
|
} sysparam_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
boolean exec_or_file_is_file_path;
|
||||||
|
const char* exe_or_file;
|
||||||
|
const char* working_directory;
|
||||||
|
const char* arguments;
|
||||||
|
} execute_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 window_id;
|
||||||
|
boolean enabled;
|
||||||
|
} activate_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 window_id;
|
||||||
|
uint32 syscommand;
|
||||||
|
} syscommand_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 window_id;
|
||||||
|
uint32 notify_icon_id;
|
||||||
|
uint32 message;
|
||||||
|
} notify_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 window_id;
|
||||||
|
RECTANGLE_16 new_position;
|
||||||
|
} window_move_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 window_id;
|
||||||
|
uint16 left;
|
||||||
|
uint16 top;
|
||||||
|
} system_menu_info;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 status;
|
||||||
|
} langbar_info;
|
||||||
|
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 window_id;
|
||||||
|
} get_app_id_info;
|
||||||
|
} param;
|
||||||
|
}
|
||||||
|
RAIL_UI_EVENT;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __RAIL_H */
|
||||||
|
|
@ -20,6 +20,7 @@
|
|||||||
#ifndef __UPDATE_API_H
|
#ifndef __UPDATE_API_H
|
||||||
#define __UPDATE_API_H
|
#define __UPDATE_API_H
|
||||||
|
|
||||||
|
#include <freerdp/rail.h>
|
||||||
#include <freerdp/types.h>
|
#include <freerdp/types.h>
|
||||||
|
|
||||||
/* Common */
|
/* Common */
|
||||||
@ -685,22 +686,6 @@ struct _WINDOW_ORDER_INFO
|
|||||||
};
|
};
|
||||||
typedef struct _WINDOW_ORDER_INFO 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
|
struct _ICON_INFO
|
||||||
{
|
{
|
||||||
uint16 cacheEntry;
|
uint16 cacheEntry;
|
||||||
|
34
include/freerdp/utils/rail.h
Normal file
34
include/freerdp/utils/rail.h
Normal 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 */
|
@ -18,30 +18,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <freerdp/utils/rail.h>
|
||||||
#include <freerdp/utils/memory.h>
|
#include <freerdp/utils/memory.h>
|
||||||
|
|
||||||
#include "window.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)
|
void update_read_icon_info(STREAM* s, ICON_INFO* icon_info)
|
||||||
{
|
{
|
||||||
stream_read_uint16(s, icon_info->cacheEntry); /* cacheEntry (2 bytes) */
|
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->timeout); /* timeout (4 bytes) */
|
||||||
stream_read_uint32(s, notify_icon_infotip->flags); /* infoFlags (4 bytes) */
|
stream_read_uint32(s, notify_icon_infotip->flags); /* infoFlags (4 bytes) */
|
||||||
update_read_unicode_string(s, ¬ify_icon_infotip->text); /* infoTipText */
|
rail_read_unicode_string(s, ¬ify_icon_infotip->text); /* infoTipText */
|
||||||
update_read_unicode_string(s, ¬ify_icon_infotip->title); /* title */
|
rail_read_unicode_string(s, ¬ify_icon_infotip->title); /* title */
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state)
|
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) */
|
stream_read_uint8(s, window_state->showState); /* showState (1 byte) */
|
||||||
|
|
||||||
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
|
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)
|
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 */
|
/* windowRects */
|
||||||
for (i = 0; i < window_state->numWindowRects; i++)
|
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 */
|
/* visibilityRects */
|
||||||
for (i = 0; i < window_state->numVisibilityRects; i++)
|
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) */
|
stream_read_uint32(s, notify_icon_state->version); /* version (4 bytes) */
|
||||||
|
|
||||||
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
|
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
|
||||||
update_read_unicode_string(s, ¬ify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */
|
rail_read_unicode_string(s, ¬ify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */
|
||||||
|
|
||||||
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
|
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
|
||||||
update_read_notify_icon_infotip(s, ¬ify_icon_state->infoTip); /* infoTip (NOTIFY_ICON_INFOTIP) */
|
update_read_notify_icon_infotip(s, ¬ify_icon_state->infoTip); /* infoTip (NOTIFY_ICON_INFOTIP) */
|
||||||
|
@ -30,6 +30,7 @@ set(FREERDP_UTILS_SRCS
|
|||||||
memory.c
|
memory.c
|
||||||
mutex.c
|
mutex.c
|
||||||
profiler.c
|
profiler.c
|
||||||
|
rail.c
|
||||||
semaphore.c
|
semaphore.c
|
||||||
stopwatch.c
|
stopwatch.c
|
||||||
stream.c
|
stream.c
|
||||||
|
@ -50,6 +50,10 @@ FRDP_EVENT* freerdp_event_new(uint32 event_type, FRDP_EVENT_CALLBACK on_event_fr
|
|||||||
case FRDP_EVENT_TYPE_CB_DATA_RESPONSE:
|
case FRDP_EVENT_TYPE_CB_DATA_RESPONSE:
|
||||||
event = (FRDP_EVENT*)xnew(FRDP_CB_DATA_RESPONSE_EVENT);
|
event = (FRDP_EVENT*)xnew(FRDP_CB_DATA_RESPONSE_EVENT);
|
||||||
break;
|
break;
|
||||||
|
case FRDP_EVENT_TYPE_RAIL_UI_2_VCHANNEL:
|
||||||
|
case FRDP_EVENT_TYPE_RAIL_VCHANNEL_2_UI:
|
||||||
|
event = xnew(FRDP_EVENT);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (event != NULL)
|
if (event != NULL)
|
||||||
{
|
{
|
||||||
|
76
libfreerdp-utils/rail.c
Normal file
76
libfreerdp-utils/rail.c
Normal 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) */
|
||||||
|
}
|
||||||
|
|
@ -393,8 +393,8 @@ int svc_plugin_send_event(rdpSvcPlugin* plugin, FRDP_EVENT* event)
|
|||||||
|
|
||||||
DEBUG_SVC("event_type %d", event->event_type);
|
DEBUG_SVC("event_type %d", event->event_type);
|
||||||
|
|
||||||
error = plugin->channel_entry_points.pVirtualChannelEventPush(plugin->priv->open_handle,
|
error = plugin->channel_entry_points.pVirtualChannelEventPush(plugin->priv->open_handle, event);
|
||||||
event);
|
|
||||||
if (error != CHANNEL_RC_OK)
|
if (error != CHANNEL_RC_OK)
|
||||||
printf("svc_plugin_send_event: VirtualChannelEventPush failed %d\n", error);
|
printf("svc_plugin_send_event: VirtualChannelEventPush failed %d\n", error);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user