2 * FreeRDP: A Remote Desktop Protocol Client
3 * RAIL Virtual Channel Plugin
5 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 * Copyright 2011 Roman Barabanov <romanbarabanov@gmail.com>
7 * Copyright 2011 Vic Lee
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
25 #include <freerdp/constants.h>
26 #include <freerdp/types.h>
27 #include <freerdp/utils/memory.h>
28 #include <freerdp/utils/svc_plugin.h>
29 #include <freerdp/utils/rail.h>
30 #include <freerdp/rail.h>
32 #include "rail_orders.h"
33 #include "rail_main.h"
35 void rail_send_channel_data(void* rail_object, void* data, size_t length)
38 railPlugin* plugin = (railPlugin*) rail_object;
40 s = stream_new(length);
41 stream_write(s, data, length);
43 svc_plugin_send((rdpSvcPlugin*) plugin, s);
46 static void on_free_rail_channel_event(RDP_EVENT* event)
48 if (event->event_class == RDP_EVENT_CLASS_RAIL)
50 rail_free_cloned_order(event->event_type, event->user_data);
54 void rail_send_channel_event(void* rail_object, uint16 event_type, void* param)
56 void * payload = NULL;
57 RDP_EVENT* out_event = NULL;
58 railPlugin* plugin = (railPlugin*) rail_object;
60 payload = rail_clone_order(event_type, param);
64 out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type,
65 on_free_rail_channel_event, payload);
67 svc_plugin_send_event((rdpSvcPlugin*) plugin, out_event);
71 static void rail_process_connect(rdpSvcPlugin* plugin)
73 railPlugin* rail = (railPlugin*) plugin;
75 rail->rail_order = rail_order_new();
76 rail->rail_order->plugin_data = (RDP_PLUGIN_DATA*)plugin->channel_entry_points.pExtendedData;
77 rail->rail_order->plugin = rail;
80 static void rail_process_terminate(rdpSvcPlugin* plugin)
85 static void rail_process_receive(rdpSvcPlugin* plugin, STREAM* s)
87 railPlugin* rail = (railPlugin*) plugin;
88 rail_order_recv(rail->rail_order, s);
92 static void rail_process_plugin_data(rdpRailOrder* rail_order, RDP_PLUGIN_DATA* data)
96 exeOrFile = (char*) data->data[0];
98 if (strlen(exeOrFile) >= 2)
100 if (strncmp(exeOrFile, "||", 2) != 0)
101 rail_order->exec.flags |= RAIL_EXEC_FLAG_FILE;
104 rail_string_to_unicode_string(rail_order, (char*) data->data[0], &rail_order->exec.exeOrFile);
105 rail_string_to_unicode_string(rail_order, (char*) data->data[1], &rail_order->exec.workingDir);
106 rail_string_to_unicode_string(rail_order, (char*) data->data[2], &rail_order->exec.arguments);
108 rail_send_client_exec_order(rail_order);
111 static void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, RDP_EVENT* event)
113 RDP_PLUGIN_DATA* data;
114 RAIL_SYSPARAM_ORDER* sysparam;
116 /* Send System Parameters */
118 sysparam = (RAIL_SYSPARAM_ORDER*)event->user_data;
119 memmove(&rail_order->sysparam, sysparam, sizeof(RAIL_SYSPARAM_ORDER));
121 rail_send_client_sysparams_order(rail_order);
125 rail_order->exec.flags = RAIL_EXEC_FLAG_EXPAND_ARGUMENTS;
127 data = rail_order->plugin_data;
128 while (data && data->size > 0)
130 rail_process_plugin_data(rail_order, data);
131 data = (RDP_PLUGIN_DATA*)(((void*) data) + data->size);
135 static void rail_recv_exec_remote_app_event(rdpRailOrder* rail_order, RDP_EVENT* event)
137 RDP_PLUGIN_DATA* data = (RDP_PLUGIN_DATA*) event->user_data;
139 rail_process_plugin_data(rail_order, data);
142 static void rail_recv_activate_event(rdpRailOrder* rail_order, RDP_EVENT* event)
144 RAIL_ACTIVATE_ORDER* activate = (RAIL_ACTIVATE_ORDER*) event->user_data;
146 memcpy(&rail_order->activate, activate, sizeof(RAIL_ACTIVATE_ORDER));
147 rail_send_client_activate_order(rail_order);
150 static void rail_recv_sysmenu_event(rdpRailOrder* rail_order, RDP_EVENT* event)
152 RAIL_SYSMENU_ORDER* sysmenu = (RAIL_SYSMENU_ORDER*) event->user_data;
154 memcpy(&rail_order->sysmenu, sysmenu, sizeof(RAIL_SYSMENU_ORDER));
155 rail_send_client_sysmenu_order(rail_order);
158 static void rail_recv_syscommand_event(rdpRailOrder* rail_order, RDP_EVENT* event)
160 RAIL_SYSCOMMAND_ORDER* syscommand = (RAIL_SYSCOMMAND_ORDER*) event->user_data;
162 memcpy(&rail_order->syscommand, syscommand, sizeof(RAIL_SYSCOMMAND_ORDER));
163 rail_send_client_syscommand_order(rail_order);
166 static void rail_recv_notify_event(rdpRailOrder* rail_order, RDP_EVENT* event)
168 RAIL_NOTIFY_EVENT_ORDER* notify = (RAIL_NOTIFY_EVENT_ORDER*) event->user_data;
170 memcpy(&rail_order->notify_event, notify, sizeof(RAIL_NOTIFY_EVENT_ORDER));
171 rail_send_client_notify_event_order(rail_order);
174 static void rail_recv_window_move_event(rdpRailOrder* rail_order, RDP_EVENT* event)
176 RAIL_WINDOW_MOVE_ORDER* window_move = (RAIL_WINDOW_MOVE_ORDER*) event->user_data;
178 memcpy(&rail_order->window_move, window_move, sizeof(RAIL_WINDOW_MOVE_ORDER));
179 rail_send_client_window_move_order(rail_order);
182 static void rail_recv_app_req_event(rdpRailOrder* rail_order, RDP_EVENT* event)
184 RAIL_GET_APPID_REQ_ORDER* get_appid_req = (RAIL_GET_APPID_REQ_ORDER*) event->user_data;
186 memcpy(&rail_order->get_appid_req, get_appid_req, sizeof(RAIL_GET_APPID_REQ_ORDER));
187 rail_send_client_get_appid_req_order(rail_order);
190 static void rail_recv_langbarinfo_event(rdpRailOrder* rail_order, RDP_EVENT* event)
192 RAIL_LANGBAR_INFO_ORDER* langbar_info = (RAIL_LANGBAR_INFO_ORDER*) event->user_data;
194 memcpy(&rail_order->langbar_info, langbar_info, sizeof(RAIL_LANGBAR_INFO_ORDER));
195 rail_send_client_langbar_info_order(rail_order);
198 static void rail_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
200 railPlugin* rail = NULL;
201 rail = (railPlugin*) plugin;
203 switch (event->event_type)
205 case RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS:
206 rail_recv_set_sysparams_event(rail->rail_order, event);
209 case RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP:
210 rail_recv_exec_remote_app_event(rail->rail_order, event);
213 case RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE:
214 rail_recv_activate_event(rail->rail_order, event);
217 case RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU:
218 rail_recv_sysmenu_event(rail->rail_order, event);
221 case RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND:
222 rail_recv_syscommand_event(rail->rail_order, event);
225 case RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT:
226 rail_recv_notify_event(rail->rail_order, event);
229 case RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE:
230 rail_recv_window_move_event(rail->rail_order, event);
233 case RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ:
234 rail_recv_app_req_event(rail->rail_order, event);
237 case RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO:
238 rail_recv_langbarinfo_event(rail->rail_order, event);
245 freerdp_event_free(event);
248 DEFINE_SVC_PLUGIN(rail, "rail",
249 CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
250 CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL)