1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * RAIL Virtual Channel Plugin
4  *
5  * Copyright 2019 Mati Shabtay <matishabtay@gmail.com>
6  *
7 
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #include <freerdp/types.h>
22 #include <freerdp/constants.h>
23 
24 #include <freerdp/channels/log.h>
25 
26 #include <winpr/crt.h>
27 #include <winpr/synch.h>
28 #include <winpr/thread.h>
29 #include <winpr/stream.h>
30 
31 #include "rail_main.h"
32 
33 #define TAG CHANNELS_TAG("rail.server")
34 
35 /**
36  * Sends a single rail PDU on the channel
37  *
38  * @return 0 on success, otherwise a Win32 error code
39  */
rail_send(RailServerContext * context,wStream * s,ULONG length)40 static UINT rail_send(RailServerContext* context, wStream* s, ULONG length)
41 {
42 	UINT status = CHANNEL_RC_OK;
43 	ULONG written;
44 
45 	if (!context)
46 		return CHANNEL_RC_BAD_INIT_HANDLE;
47 
48 	if (!WTSVirtualChannelWrite(context->priv->rail_channel, (PCHAR)Stream_Buffer(s), length,
49 	                            &written))
50 	{
51 		WLog_ERR(TAG, "WTSVirtualChannelWrite failed!");
52 		status = ERROR_INTERNAL_ERROR;
53 	}
54 
55 	return status;
56 }
57 
58 /**
59  * Function description
60  *
61  * @return 0 on success, otherwise a Win32 error code
62  */
rail_server_send_pdu(RailServerContext * context,wStream * s,UINT16 orderType)63 static UINT rail_server_send_pdu(RailServerContext* context, wStream* s, UINT16 orderType)
64 {
65 	UINT16 orderLength;
66 
67 	if (!context || !s)
68 		return ERROR_INVALID_PARAMETER;
69 
70 	orderLength = (UINT16)Stream_GetPosition(s);
71 	Stream_SetPosition(s, 0);
72 	rail_write_pdu_header(s, orderType, orderLength);
73 	Stream_SetPosition(s, orderLength);
74 	WLog_DBG(TAG, "Sending %s PDU, length: %" PRIu16 "", rail_get_order_type_string(orderType),
75 	         orderLength);
76 	return rail_send(context, s, orderLength);
77 }
78 
79 /**
80  * Function description
81  *
82  * @return 0 on success, otherwise a Win32 error code
83  */
rail_write_local_move_size_order(wStream * s,const RAIL_LOCALMOVESIZE_ORDER * localMoveSize)84 static UINT rail_write_local_move_size_order(wStream* s,
85                                              const RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
86 {
87 	if (!s || !localMoveSize)
88 		return ERROR_INVALID_PARAMETER;
89 
90 	Stream_Write_UINT32(s, localMoveSize->windowId);                /* WindowId (4 bytes) */
91 	Stream_Write_UINT16(s, localMoveSize->isMoveSizeStart ? 1 : 0); /* IsMoveSizeStart (2 bytes) */
92 	Stream_Write_UINT16(s, localMoveSize->moveSizeType);            /* MoveSizeType (2 bytes) */
93 	Stream_Write_UINT16(s, localMoveSize->posX);                    /* PosX (2 bytes) */
94 	Stream_Write_UINT16(s, localMoveSize->posY);                    /* PosY (2 bytes) */
95 	return ERROR_SUCCESS;
96 }
97 
98 /**
99  * Function description
100  *
101  * @return 0 on success, otherwise a Win32 error code
102  */
rail_write_min_max_info_order(wStream * s,const RAIL_MINMAXINFO_ORDER * minMaxInfo)103 static UINT rail_write_min_max_info_order(wStream* s, const RAIL_MINMAXINFO_ORDER* minMaxInfo)
104 {
105 	if (!s || !minMaxInfo)
106 		return ERROR_INVALID_PARAMETER;
107 
108 	Stream_Write_UINT32(s, minMaxInfo->windowId);      /* WindowId (4 bytes) */
109 	Stream_Write_INT16(s, minMaxInfo->maxWidth);       /* MaxWidth (2 bytes) */
110 	Stream_Write_INT16(s, minMaxInfo->maxHeight);      /* MaxHeight (2 bytes) */
111 	Stream_Write_INT16(s, minMaxInfo->maxPosX);        /* MaxPosX (2 bytes) */
112 	Stream_Write_INT16(s, minMaxInfo->maxPosY);        /* MaxPosY (2 bytes) */
113 	Stream_Write_INT16(s, minMaxInfo->minTrackWidth);  /* MinTrackWidth (2 bytes) */
114 	Stream_Write_INT16(s, minMaxInfo->minTrackHeight); /* MinTrackHeight (2 bytes) */
115 	Stream_Write_INT16(s, minMaxInfo->maxTrackWidth);  /* MaxTrackWidth (2 bytes) */
116 	Stream_Write_INT16(s, minMaxInfo->maxTrackHeight); /* MaxTrackHeight (2 bytes) */
117 	return ERROR_SUCCESS;
118 }
119 
120 /**
121  * Function description
122  *
123  * @return 0 on success, otherwise a Win32 error code
124  */
rail_write_taskbar_info_order(wStream * s,const RAIL_TASKBAR_INFO_ORDER * taskbarInfo)125 static UINT rail_write_taskbar_info_order(wStream* s, const RAIL_TASKBAR_INFO_ORDER* taskbarInfo)
126 {
127 	if (!s || !taskbarInfo)
128 		return ERROR_INVALID_PARAMETER;
129 
130 	Stream_Write_UINT32(s, taskbarInfo->TaskbarMessage); /* TaskbarMessage (4 bytes) */
131 	Stream_Write_UINT32(s, taskbarInfo->WindowIdTab);    /* WindowIdTab (4 bytes) */
132 	Stream_Write_UINT32(s, taskbarInfo->Body);           /* Body (4 bytes) */
133 	return ERROR_SUCCESS;
134 }
135 
136 /**
137  * Function description
138  *
139  * @return 0 on success, otherwise a Win32 error code
140  */
rail_write_langbar_info_order(wStream * s,const RAIL_LANGBAR_INFO_ORDER * langbarInfo)141 static UINT rail_write_langbar_info_order(wStream* s, const RAIL_LANGBAR_INFO_ORDER* langbarInfo)
142 {
143 	if (!s || !langbarInfo)
144 		return ERROR_INVALID_PARAMETER;
145 
146 	Stream_Write_UINT32(s, langbarInfo->languageBarStatus); /* LanguageBarStatus (4 bytes) */
147 	return ERROR_SUCCESS;
148 }
149 
150 /**
151  * Function description
152  *
153  * @return 0 on success, otherwise a Win32 error code
154  */
rail_write_exec_result_order(wStream * s,const RAIL_EXEC_RESULT_ORDER * execResult)155 static UINT rail_write_exec_result_order(wStream* s, const RAIL_EXEC_RESULT_ORDER* execResult)
156 {
157 	if (!s || !execResult)
158 		return ERROR_INVALID_PARAMETER;
159 
160 	if (execResult->exeOrFile.length > 520 || execResult->exeOrFile.length < 1)
161 		return ERROR_INVALID_DATA;
162 
163 	Stream_Write_UINT16(s, execResult->flags);            /* Flags (2 bytes) */
164 	Stream_Write_UINT16(s, execResult->execResult);       /* ExecResult (2 bytes) */
165 	Stream_Write_UINT32(s, execResult->rawResult);        /* RawResult (4 bytes) */
166 	Stream_Write_UINT16(s, 0);                            /* Padding (2 bytes) */
167 	Stream_Write_UINT16(s, execResult->exeOrFile.length); /* ExeOrFileLength (2 bytes) */
168 	Stream_Write(s, execResult->exeOrFile.string,
169 	             execResult->exeOrFile.length); /* ExeOrFile (variable) */
170 	return ERROR_SUCCESS;
171 }
172 
173 /**
174  * Function description
175  *
176  * @return 0 on success, otherwise a Win32 error code
177  */
rail_write_z_order_sync_order(wStream * s,const RAIL_ZORDER_SYNC * zOrderSync)178 static UINT rail_write_z_order_sync_order(wStream* s, const RAIL_ZORDER_SYNC* zOrderSync)
179 {
180 	if (!s || !zOrderSync)
181 		return ERROR_INVALID_PARAMETER;
182 
183 	Stream_Write_UINT32(s, zOrderSync->windowIdMarker); /* WindowIdMarker (4 bytes) */
184 	return ERROR_SUCCESS;
185 }
186 
187 /**
188  * Function description
189  *
190  * @return 0 on success, otherwise a Win32 error code
191  */
rail_write_cloak_order(wStream * s,const RAIL_CLOAK * cloak)192 static UINT rail_write_cloak_order(wStream* s, const RAIL_CLOAK* cloak)
193 {
194 	if (!s || !cloak)
195 		return ERROR_INVALID_PARAMETER;
196 
197 	Stream_Write_UINT32(s, cloak->windowId);     /* WindowId (4 bytes) */
198 	Stream_Write_UINT8(s, cloak->cloak ? 1 : 0); /* Cloaked (1 byte) */
199 	return ERROR_SUCCESS;
200 }
201 
202 /**
203  * Function description
204  *
205  * @return 0 on success, otherwise a Win32 error code
206  */
207 static UINT
rail_write_power_display_request_order(wStream * s,const RAIL_POWER_DISPLAY_REQUEST * powerDisplayRequest)208 rail_write_power_display_request_order(wStream* s,
209                                        const RAIL_POWER_DISPLAY_REQUEST* powerDisplayRequest)
210 {
211 	if (!s || !powerDisplayRequest)
212 		return ERROR_INVALID_PARAMETER;
213 
214 	Stream_Write_UINT32(s, powerDisplayRequest->active ? 1 : 0); /* Active (4 bytes) */
215 	return ERROR_SUCCESS;
216 }
217 
218 /**
219  * Function description
220  *
221  * @return 0 on success, otherwise a Win32 error code
222  */
rail_write_get_app_id_resp_order(wStream * s,const RAIL_GET_APPID_RESP_ORDER * getAppidResp)223 static UINT rail_write_get_app_id_resp_order(wStream* s,
224                                              const RAIL_GET_APPID_RESP_ORDER* getAppidResp)
225 {
226 	if (!s || !getAppidResp)
227 		return ERROR_INVALID_PARAMETER;
228 
229 	Stream_Write_UINT32(s, getAppidResp->windowId); /* WindowId (4 bytes) */
230 	Stream_Write_UTF16_String(
231 	    s, getAppidResp->applicationId,
232 	    ARRAYSIZE(getAppidResp->applicationId)); /* ApplicationId (512 bytes) */
233 	return ERROR_SUCCESS;
234 }
235 
236 /**
237  * Function description
238  *
239  * @return 0 on success, otherwise a Win32 error code
240  */
rail_write_get_appid_resp_ex_order(wStream * s,const RAIL_GET_APPID_RESP_EX * getAppidRespEx)241 static UINT rail_write_get_appid_resp_ex_order(wStream* s,
242                                                const RAIL_GET_APPID_RESP_EX* getAppidRespEx)
243 {
244 	if (!s || !getAppidRespEx)
245 		return ERROR_INVALID_PARAMETER;
246 
247 	Stream_Write_UINT32(s, getAppidRespEx->windowID); /* WindowId (4 bytes) */
248 	Stream_Write_UTF16_String(
249 	    s, getAppidRespEx->applicationID,
250 	    ARRAYSIZE(getAppidRespEx->applicationID));     /* ApplicationId (520 bytes) */
251 	Stream_Write_UINT32(s, getAppidRespEx->processId); /* ProcessId (4 bytes) */
252 	Stream_Write_UTF16_String(
253 	    s, getAppidRespEx->processImageName,
254 	    ARRAYSIZE(getAppidRespEx->processImageName)); /* ProcessImageName (520 bytes) */
255 	return ERROR_SUCCESS;
256 }
257 
258 /**
259  * Function description
260  *
261  * @return 0 on success, otherwise a Win32 error code
262  */
rail_send_server_handshake(RailServerContext * context,const RAIL_HANDSHAKE_ORDER * handshake)263 static UINT rail_send_server_handshake(RailServerContext* context,
264                                        const RAIL_HANDSHAKE_ORDER* handshake)
265 {
266 	wStream* s;
267 	UINT error;
268 
269 	if (!context || !handshake)
270 		return ERROR_INVALID_PARAMETER;
271 
272 	s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH);
273 
274 	if (!s)
275 	{
276 		WLog_ERR(TAG, "rail_pdu_init failed!");
277 		return CHANNEL_RC_NO_MEMORY;
278 	}
279 
280 	rail_write_handshake_order(s, handshake);
281 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_HANDSHAKE);
282 	Stream_Free(s, TRUE);
283 	return error;
284 }
285 
286 /**
287  * Function description
288  *
289  * @return 0 on success, otherwise a Win32 error code
290  */
rail_send_server_handshake_ex(RailServerContext * context,const RAIL_HANDSHAKE_EX_ORDER * handshakeEx)291 static UINT rail_send_server_handshake_ex(RailServerContext* context,
292                                           const RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
293 {
294 	wStream* s;
295 	UINT error;
296 
297 	if (!context || !handshakeEx || !context->priv)
298 		return ERROR_INVALID_PARAMETER;
299 
300 	s = rail_pdu_init(RAIL_HANDSHAKE_EX_ORDER_LENGTH);
301 
302 	if (!s)
303 	{
304 		WLog_ERR(TAG, "rail_pdu_init failed!");
305 		return CHANNEL_RC_NO_MEMORY;
306 	}
307 
308 	rail_server_set_handshake_ex_flags(context, handshakeEx->railHandshakeFlags);
309 
310 	rail_write_handshake_ex_order(s, handshakeEx);
311 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_HANDSHAKE_EX);
312 	Stream_Free(s, TRUE);
313 	return error;
314 }
315 
316 /**
317  * Function description
318  *
319  * @return 0 on success, otherwise a Win32 error code
320  */
rail_send_server_sysparam(RailServerContext * context,const RAIL_SYSPARAM_ORDER * sysparam)321 static UINT rail_send_server_sysparam(RailServerContext* context,
322                                       const RAIL_SYSPARAM_ORDER* sysparam)
323 {
324 	wStream* s;
325 	UINT error;
326 	RailServerPrivate* priv;
327 	BOOL extendedSpiSupported;
328 
329 	if (!context || !sysparam)
330 		return ERROR_INVALID_PARAMETER;
331 
332 	priv = context->priv;
333 
334 	if (!priv)
335 		return ERROR_INVALID_PARAMETER;
336 
337 	extendedSpiSupported = rail_is_extended_spi_supported(context->priv->channelFlags);
338 	s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH);
339 
340 	if (!s)
341 	{
342 		WLog_ERR(TAG, "rail_pdu_init failed!");
343 		return CHANNEL_RC_NO_MEMORY;
344 	}
345 
346 	rail_write_sysparam_order(s, sysparam, extendedSpiSupported);
347 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_SYSPARAM);
348 	Stream_Free(s, TRUE);
349 	return error;
350 }
351 
352 /**
353  * Function description
354  *
355  * @return 0 on success, otherwise a Win32 error code
356  */
rail_send_server_local_move_size(RailServerContext * context,const RAIL_LOCALMOVESIZE_ORDER * localMoveSize)357 static UINT rail_send_server_local_move_size(RailServerContext* context,
358                                              const RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
359 {
360 	wStream* s;
361 	UINT error;
362 
363 	if (!context || !localMoveSize)
364 		return ERROR_INVALID_PARAMETER;
365 
366 	s = rail_pdu_init(RAIL_LOCALMOVESIZE_ORDER_LENGTH);
367 
368 	if (!s)
369 	{
370 		WLog_ERR(TAG, "rail_pdu_init failed!");
371 		return CHANNEL_RC_NO_MEMORY;
372 	}
373 
374 	rail_write_local_move_size_order(s, localMoveSize);
375 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_LOCALMOVESIZE);
376 	Stream_Free(s, TRUE);
377 	return error;
378 }
379 
380 /**
381  * Function description
382  *
383  * @return 0 on success, otherwise a Win32 error code
384  */
rail_send_server_min_max_info(RailServerContext * context,const RAIL_MINMAXINFO_ORDER * minMaxInfo)385 static UINT rail_send_server_min_max_info(RailServerContext* context,
386                                           const RAIL_MINMAXINFO_ORDER* minMaxInfo)
387 {
388 	wStream* s;
389 	UINT error;
390 
391 	if (!context || !minMaxInfo)
392 		return ERROR_INVALID_PARAMETER;
393 
394 	s = rail_pdu_init(RAIL_MINMAXINFO_ORDER_LENGTH);
395 
396 	if (!s)
397 	{
398 		WLog_ERR(TAG, "rail_pdu_init failed!");
399 		return CHANNEL_RC_NO_MEMORY;
400 	}
401 
402 	rail_write_min_max_info_order(s, minMaxInfo);
403 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_MINMAXINFO);
404 	Stream_Free(s, TRUE);
405 	return error;
406 }
407 
408 /**
409  * Function description
410  *
411  * @return 0 on success, otherwise a Win32 error code
412  */
rail_send_server_taskbar_info(RailServerContext * context,const RAIL_TASKBAR_INFO_ORDER * taskbarInfo)413 static UINT rail_send_server_taskbar_info(RailServerContext* context,
414                                           const RAIL_TASKBAR_INFO_ORDER* taskbarInfo)
415 {
416 	wStream* s;
417 	UINT error;
418 
419 	if (!context || !taskbarInfo)
420 		return ERROR_INVALID_PARAMETER;
421 
422 	s = rail_pdu_init(RAIL_TASKBAR_INFO_ORDER_LENGTH);
423 
424 	if (!s)
425 	{
426 		WLog_ERR(TAG, "rail_pdu_init failed!");
427 		return CHANNEL_RC_NO_MEMORY;
428 	}
429 
430 	rail_write_taskbar_info_order(s, taskbarInfo);
431 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_TASKBARINFO);
432 	Stream_Free(s, TRUE);
433 	return error;
434 }
435 
436 /**
437  * Function description
438  *
439  * @return 0 on success, otherwise a Win32 error code
440  */
rail_send_server_langbar_info(RailServerContext * context,const RAIL_LANGBAR_INFO_ORDER * langbarInfo)441 static UINT rail_send_server_langbar_info(RailServerContext* context,
442                                           const RAIL_LANGBAR_INFO_ORDER* langbarInfo)
443 {
444 	wStream* s;
445 	UINT error;
446 
447 	if (!context || !langbarInfo)
448 		return ERROR_INVALID_PARAMETER;
449 
450 	s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH);
451 
452 	if (!s)
453 	{
454 		WLog_ERR(TAG, "rail_pdu_init failed!");
455 		return CHANNEL_RC_NO_MEMORY;
456 	}
457 
458 	rail_write_langbar_info_order(s, langbarInfo);
459 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_LANGBARINFO);
460 	Stream_Free(s, TRUE);
461 	return error;
462 }
463 
464 /**
465  * Function description
466  *
467  * @return 0 on success, otherwise a Win32 error code
468  */
rail_send_server_exec_result(RailServerContext * context,const RAIL_EXEC_RESULT_ORDER * execResult)469 static UINT rail_send_server_exec_result(RailServerContext* context,
470                                          const RAIL_EXEC_RESULT_ORDER* execResult)
471 {
472 	wStream* s;
473 	UINT error;
474 
475 	if (!context || !execResult)
476 		return ERROR_INVALID_PARAMETER;
477 
478 	s = rail_pdu_init(RAIL_EXEC_RESULT_ORDER_LENGTH + execResult->exeOrFile.length);
479 
480 	if (!s)
481 	{
482 		WLog_ERR(TAG, "rail_pdu_init failed!");
483 		return CHANNEL_RC_NO_MEMORY;
484 	}
485 
486 	rail_write_exec_result_order(s, execResult);
487 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_EXEC_RESULT);
488 	Stream_Free(s, TRUE);
489 	return error;
490 }
491 
492 /**
493  * Function description
494  *
495  * @return 0 on success, otherwise a Win32 error code
496  */
rail_send_server_z_order_sync(RailServerContext * context,const RAIL_ZORDER_SYNC * zOrderSync)497 static UINT rail_send_server_z_order_sync(RailServerContext* context,
498                                           const RAIL_ZORDER_SYNC* zOrderSync)
499 {
500 	wStream* s;
501 	UINT error;
502 
503 	if (!context || !zOrderSync)
504 		return ERROR_INVALID_PARAMETER;
505 
506 	s = rail_pdu_init(RAIL_Z_ORDER_SYNC_ORDER_LENGTH);
507 
508 	if (!s)
509 	{
510 		WLog_ERR(TAG, "rail_pdu_init failed!");
511 		return CHANNEL_RC_NO_MEMORY;
512 	}
513 
514 	rail_write_z_order_sync_order(s, zOrderSync);
515 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_ZORDER_SYNC);
516 	Stream_Free(s, TRUE);
517 	return error;
518 }
519 
520 /**
521  * Function description
522  *
523  * @return 0 on success, otherwise a Win32 error code
524  */
rail_send_server_cloak(RailServerContext * context,const RAIL_CLOAK * cloak)525 static UINT rail_send_server_cloak(RailServerContext* context, const RAIL_CLOAK* cloak)
526 {
527 	wStream* s;
528 	UINT error;
529 
530 	if (!context || !cloak)
531 		return ERROR_INVALID_PARAMETER;
532 
533 	s = rail_pdu_init(RAIL_CLOAK_ORDER_LENGTH);
534 
535 	if (!s)
536 	{
537 		WLog_ERR(TAG, "rail_pdu_init failed!");
538 		return CHANNEL_RC_NO_MEMORY;
539 	}
540 
541 	rail_write_cloak_order(s, cloak);
542 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_CLOAK);
543 	Stream_Free(s, TRUE);
544 	return error;
545 }
546 
547 /**
548  * Function description
549  *
550  * @return 0 on success, otherwise a Win32 error code
551  */
552 static UINT
rail_send_server_power_display_request(RailServerContext * context,const RAIL_POWER_DISPLAY_REQUEST * powerDisplayRequest)553 rail_send_server_power_display_request(RailServerContext* context,
554                                        const RAIL_POWER_DISPLAY_REQUEST* powerDisplayRequest)
555 {
556 	wStream* s;
557 	UINT error;
558 
559 	if (!context || !powerDisplayRequest)
560 		return ERROR_INVALID_PARAMETER;
561 
562 	s = rail_pdu_init(RAIL_POWER_DISPLAY_REQUEST_ORDER_LENGTH);
563 
564 	if (!s)
565 	{
566 		WLog_ERR(TAG, "rail_pdu_init failed!");
567 		return CHANNEL_RC_NO_MEMORY;
568 	}
569 
570 	rail_write_power_display_request_order(s, powerDisplayRequest);
571 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_POWER_DISPLAY_REQUEST);
572 	Stream_Free(s, TRUE);
573 	return error;
574 }
575 
576 /**
577  * Function description
578  *
579  * @return 0 on success, otherwise a Win32 error coie
580  */
rail_send_server_get_app_id_resp(RailServerContext * context,const RAIL_GET_APPID_RESP_ORDER * getAppidResp)581 static UINT rail_send_server_get_app_id_resp(RailServerContext* context,
582                                              const RAIL_GET_APPID_RESP_ORDER* getAppidResp)
583 {
584 	wStream* s;
585 	UINT error;
586 
587 	if (!context || !getAppidResp)
588 		return ERROR_INVALID_PARAMETER;
589 
590 	s = rail_pdu_init(RAIL_GET_APPID_RESP_ORDER_LENGTH);
591 
592 	if (!s)
593 	{
594 		WLog_ERR(TAG, "rail_pdu_init failed!");
595 		return CHANNEL_RC_NO_MEMORY;
596 	}
597 
598 	rail_write_get_app_id_resp_order(s, getAppidResp);
599 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_GET_APPID_RESP);
600 	Stream_Free(s, TRUE);
601 	return error;
602 }
603 
604 /**
605  * Function description
606  *
607  * @return 0 on success, otherwise a Win32 error code
608  */
rail_send_server_get_appid_resp_ex(RailServerContext * context,const RAIL_GET_APPID_RESP_EX * getAppidRespEx)609 static UINT rail_send_server_get_appid_resp_ex(RailServerContext* context,
610                                                const RAIL_GET_APPID_RESP_EX* getAppidRespEx)
611 {
612 	wStream* s;
613 	UINT error;
614 
615 	if (!context || !getAppidRespEx)
616 		return ERROR_INVALID_PARAMETER;
617 
618 	s = rail_pdu_init(RAIL_GET_APPID_RESP_EX_ORDER_LENGTH);
619 
620 	if (!s)
621 	{
622 		WLog_ERR(TAG, "rail_pdu_init failed!");
623 		return CHANNEL_RC_NO_MEMORY;
624 	}
625 
626 	rail_write_get_appid_resp_ex_order(s, getAppidRespEx);
627 	error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_GET_APPID_RESP_EX);
628 	Stream_Free(s, TRUE);
629 	return error;
630 }
631 
632 /**
633  * Function description
634  *
635  * @return 0 on success, otherwise a Win32 error code
636  */
rail_read_client_status_order(wStream * s,RAIL_CLIENT_STATUS_ORDER * clientStatus)637 static UINT rail_read_client_status_order(wStream* s, RAIL_CLIENT_STATUS_ORDER* clientStatus)
638 {
639 	if (Stream_GetRemainingLength(s) < RAIL_CLIENT_STATUS_ORDER_LENGTH)
640 		return ERROR_INVALID_DATA;
641 
642 	Stream_Read_UINT32(s, clientStatus->flags); /* Flags (4 bytes) */
643 	return CHANNEL_RC_OK;
644 }
645 
646 /**
647  * Function description
648  *
649  * @return 0 on success, otherwise a Win32 error code
650  */
rail_read_exec_order(wStream * s,RAIL_EXEC_ORDER * exec)651 static UINT rail_read_exec_order(wStream* s, RAIL_EXEC_ORDER* exec)
652 {
653 	RAIL_EXEC_ORDER order = { 0 };
654 	UINT16 exeLen, workLen, argLen;
655 
656 	if (Stream_GetRemainingLength(s) < RAIL_EXEC_ORDER_LENGTH)
657 		return ERROR_INVALID_DATA;
658 
659 	Stream_Read_UINT16(s, exec->flags); /* Flags (2 bytes) */
660 	Stream_Read_UINT16(s, exeLen);      /* ExeOrFileLength (2 bytes) */
661 	Stream_Read_UINT16(s, workLen);     /* WorkingDirLength (2 bytes) */
662 	Stream_Read_UINT16(s, argLen);      /* ArgumentsLength (2 bytes) */
663 
664 	if (Stream_GetRemainingLength(s) < (size_t)exeLen + workLen + argLen)
665 		return ERROR_INVALID_DATA;
666 
667 	{
668 		const int len = exeLen / sizeof(WCHAR);
669 		int rc;
670 		const WCHAR* str = (const WCHAR*)Stream_Pointer(s);
671 		rc = ConvertFromUnicode(CP_UTF8, 0, str, len, &exec->RemoteApplicationProgram, 0, NULL,
672 		                        NULL);
673 		if (rc != len)
674 			goto fail;
675 		Stream_Seek(s, exeLen);
676 	}
677 	{
678 		const int len = workLen / sizeof(WCHAR);
679 		int rc;
680 
681 		const WCHAR* str = (const WCHAR*)Stream_Pointer(s);
682 		rc = ConvertFromUnicode(CP_UTF8, 0, str, len, &exec->RemoteApplicationProgram, 0, NULL,
683 		                        NULL);
684 		if (rc != len)
685 			goto fail;
686 		Stream_Seek(s, workLen);
687 	}
688 	{
689 		const int len = argLen / sizeof(WCHAR);
690 		int rc;
691 		const WCHAR* str = (const WCHAR*)Stream_Pointer(s);
692 		rc = ConvertFromUnicode(CP_UTF8, 0, str, len, &exec->RemoteApplicationProgram, 0, NULL,
693 		                        NULL);
694 		if (rc != len)
695 			goto fail;
696 		Stream_Seek(s, argLen);
697 	}
698 
699 	return CHANNEL_RC_OK;
700 fail:
701 	free(exec->RemoteApplicationProgram);
702 	free(exec->RemoteApplicationArguments);
703 	free(exec->RemoteApplicationWorkingDir);
704 	*exec = order;
705 	return ERROR_INTERNAL_ERROR;
706 }
707 
708 /**
709  * Function description
710  *
711  * @return 0 on success, otherwise a Win32 error code
712  */
rail_read_activate_order(wStream * s,RAIL_ACTIVATE_ORDER * activate)713 static UINT rail_read_activate_order(wStream* s, RAIL_ACTIVATE_ORDER* activate)
714 {
715 	BYTE enabled;
716 
717 	if (Stream_GetRemainingLength(s) < RAIL_ACTIVATE_ORDER_LENGTH)
718 		return ERROR_INVALID_DATA;
719 
720 	Stream_Read_UINT32(s, activate->windowId); /* WindowId (4 bytes) */
721 	Stream_Read_UINT8(s, enabled);             /* Enabled (1 byte) */
722 	activate->enabled = (enabled != 0) ? TRUE : FALSE;
723 	return CHANNEL_RC_OK;
724 }
725 
726 /**
727  * Function description
728  *
729  * @return 0 on success, otherwise a Win32 error code
730  */
rail_read_sysmenu_order(wStream * s,RAIL_SYSMENU_ORDER * sysmenu)731 static UINT rail_read_sysmenu_order(wStream* s, RAIL_SYSMENU_ORDER* sysmenu)
732 {
733 	if (Stream_GetRemainingLength(s) < RAIL_SYSMENU_ORDER_LENGTH)
734 		return ERROR_INVALID_DATA;
735 
736 	Stream_Read_UINT32(s, sysmenu->windowId); /* WindowId (4 bytes) */
737 	Stream_Read_INT16(s, sysmenu->left);      /* Left (2 bytes) */
738 	Stream_Read_INT16(s, sysmenu->top);       /* Top (2 bytes) */
739 	return CHANNEL_RC_OK;
740 }
741 
742 /**
743  * Function description
744  *
745  * @return 0 on success, otherwise a Win32 error code
746  */
rail_read_syscommand_order(wStream * s,RAIL_SYSCOMMAND_ORDER * syscommand)747 static UINT rail_read_syscommand_order(wStream* s, RAIL_SYSCOMMAND_ORDER* syscommand)
748 {
749 	if (Stream_GetRemainingLength(s) < RAIL_SYSCOMMAND_ORDER_LENGTH)
750 		return ERROR_INVALID_DATA;
751 
752 	Stream_Read_UINT32(s, syscommand->windowId); /* WindowId (4 bytes) */
753 	Stream_Read_UINT16(s, syscommand->command);  /* Command (2 bytes) */
754 	return CHANNEL_RC_OK;
755 }
756 
757 /**
758  * Function description
759  *
760  * @return 0 on success, otherwise a Win32 error code
761  */
rail_read_notify_event_order(wStream * s,RAIL_NOTIFY_EVENT_ORDER * notifyEvent)762 static UINT rail_read_notify_event_order(wStream* s, RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
763 {
764 	if (Stream_GetRemainingLength(s) < RAIL_NOTIFY_EVENT_ORDER_LENGTH)
765 		return ERROR_INVALID_DATA;
766 
767 	Stream_Read_UINT32(s, notifyEvent->windowId);     /* WindowId (4 bytes) */
768 	Stream_Read_UINT32(s, notifyEvent->notifyIconId); /* NotifyIconId (4 bytes) */
769 	Stream_Read_UINT32(s, notifyEvent->message);      /* Message (4 bytes) */
770 	return CHANNEL_RC_OK;
771 }
772 
773 /**
774  * Function description
775  *
776  * @return 0 on success, otherwise a Win32 error code
777  */
rail_read_get_appid_req_order(wStream * s,RAIL_GET_APPID_REQ_ORDER * getAppidReq)778 static UINT rail_read_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ_ORDER* getAppidReq)
779 {
780 	if (Stream_GetRemainingLength(s) < RAIL_GET_APPID_REQ_ORDER_LENGTH)
781 		return ERROR_INVALID_DATA;
782 
783 	Stream_Read_UINT32(s, getAppidReq->windowId); /* WindowId (4 bytes) */
784 	return CHANNEL_RC_OK;
785 }
786 
787 /**
788  * Function description
789  *
790  * @return 0 on success, otherwise a Win32 error code
791  */
rail_read_window_move_order(wStream * s,RAIL_WINDOW_MOVE_ORDER * windowMove)792 static UINT rail_read_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORDER* windowMove)
793 {
794 	if (Stream_GetRemainingLength(s) < RAIL_WINDOW_MOVE_ORDER_LENGTH)
795 		return ERROR_INVALID_DATA;
796 
797 	Stream_Read_UINT32(s, windowMove->windowId); /* WindowId (4 bytes) */
798 	Stream_Read_INT16(s, windowMove->left);      /* Left (2 bytes) */
799 	Stream_Read_INT16(s, windowMove->top);       /* Top (2 bytes) */
800 	Stream_Read_INT16(s, windowMove->right);     /* Right (2 bytes) */
801 	Stream_Read_INT16(s, windowMove->bottom);    /* Bottom (2 bytes) */
802 	return CHANNEL_RC_OK;
803 }
804 
805 /**
806  * Function description
807  *
808  * @return 0 on success, otherwise a Win32 error code
809  */
rail_read_snap_arange_order(wStream * s,RAIL_SNAP_ARRANGE * snapArrange)810 static UINT rail_read_snap_arange_order(wStream* s, RAIL_SNAP_ARRANGE* snapArrange)
811 {
812 	if (Stream_GetRemainingLength(s) < RAIL_SNAP_ARRANGE_ORDER_LENGTH)
813 		return ERROR_INVALID_DATA;
814 
815 	Stream_Read_UINT32(s, snapArrange->windowId); /* WindowId (4 bytes) */
816 	Stream_Read_INT16(s, snapArrange->left);      /* Left (2 bytes) */
817 	Stream_Read_INT16(s, snapArrange->top);       /* Top (2 bytes) */
818 	Stream_Read_INT16(s, snapArrange->right);     /* Right (2 bytes) */
819 	Stream_Read_INT16(s, snapArrange->bottom);    /* Bottom (2 bytes) */
820 	return CHANNEL_RC_OK;
821 }
822 
823 /**
824  * Function description
825  *
826  * @return 0 on success, otherwise a Win32 error code
827  */
rail_read_langbar_info_order(wStream * s,RAIL_LANGBAR_INFO_ORDER * langbarInfo)828 static UINT rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbarInfo)
829 {
830 	if (Stream_GetRemainingLength(s) < RAIL_LANGBAR_INFO_ORDER_LENGTH)
831 		return ERROR_INVALID_DATA;
832 
833 	Stream_Read_UINT32(s, langbarInfo->languageBarStatus); /* LanguageBarStatus (4 bytes) */
834 	return CHANNEL_RC_OK;
835 }
836 
837 /**
838  * Function description
839  *
840  * @return 0 on success, otherwise a Win32 error code
841  */
rail_read_language_ime_info_order(wStream * s,RAIL_LANGUAGEIME_INFO_ORDER * languageImeInfo)842 static UINT rail_read_language_ime_info_order(wStream* s,
843                                               RAIL_LANGUAGEIME_INFO_ORDER* languageImeInfo)
844 {
845 	if (Stream_GetRemainingLength(s) < RAIL_LANGUAGEIME_INFO_ORDER_LENGTH)
846 		return ERROR_INVALID_DATA;
847 
848 	Stream_Read_UINT32(s, languageImeInfo->ProfileType); /* ProfileType (4 bytes) */
849 	Stream_Read_UINT16(s, languageImeInfo->LanguageID);  /* LanguageID (2 bytes) */
850 	Stream_Read(
851 	    s, &languageImeInfo->LanguageProfileCLSID,
852 	    sizeof(languageImeInfo->LanguageProfileCLSID)); /* LanguageProfileCLSID (16 bytes) */
853 	Stream_Read(s, &languageImeInfo->ProfileGUID,
854 	            sizeof(languageImeInfo->ProfileGUID));      /* ProfileGUID (16 bytes) */
855 	Stream_Read_UINT32(s, languageImeInfo->KeyboardLayout); /* KeyboardLayout (4 bytes) */
856 	return CHANNEL_RC_OK;
857 }
858 
859 /**
860  * Function description
861  *
862  * @return 0 on success, otherwise a Win32 error code
863  */
rail_read_compartment_info_order(wStream * s,RAIL_COMPARTMENT_INFO_ORDER * compartmentInfo)864 static UINT rail_read_compartment_info_order(wStream* s,
865                                              RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo)
866 {
867 	if (Stream_GetRemainingLength(s) < RAIL_COMPARTMENT_INFO_ORDER_LENGTH)
868 		return ERROR_INVALID_DATA;
869 
870 	Stream_Read_UINT32(s, compartmentInfo->ImeState);        /* ImeState (4 bytes) */
871 	Stream_Read_UINT32(s, compartmentInfo->ImeConvMode);     /* ImeConvMode (4 bytes) */
872 	Stream_Read_UINT32(s, compartmentInfo->ImeSentenceMode); /* ImeSentenceMode (4 bytes) */
873 	Stream_Read_UINT32(s, compartmentInfo->KanaMode);        /* KANAMode (4 bytes) */
874 	return CHANNEL_RC_OK;
875 }
876 
877 /**
878  * Function description
879  *
880  * @return 0 on success, otherwise a Win32 error code
881  */
rail_read_cloak_order(wStream * s,RAIL_CLOAK * cloak)882 static UINT rail_read_cloak_order(wStream* s, RAIL_CLOAK* cloak)
883 {
884 	BYTE cloaked;
885 
886 	if (Stream_GetRemainingLength(s) < RAIL_CLOAK_ORDER_LENGTH)
887 		return ERROR_INVALID_DATA;
888 
889 	Stream_Read_UINT32(s, cloak->windowId); /* WindowId (4 bytes) */
890 	Stream_Read_UINT8(s, cloaked);          /* Cloaked (1 byte) */
891 	cloak->cloak = (cloaked != 0) ? TRUE : FALSE;
892 	return CHANNEL_RC_OK;
893 }
894 
895 /**
896  * Function description
897  *
898  * @return 0 on success, otherwise a Win32 error code
899  */
rail_recv_client_handshake_order(RailServerContext * context,RAIL_HANDSHAKE_ORDER * handshake,wStream * s)900 static UINT rail_recv_client_handshake_order(RailServerContext* context,
901                                              RAIL_HANDSHAKE_ORDER* handshake, wStream* s)
902 {
903 	UINT error;
904 
905 	if (!context || !handshake || !s)
906 		return ERROR_INVALID_PARAMETER;
907 
908 	if ((error = rail_read_handshake_order(s, handshake)))
909 	{
910 		WLog_ERR(TAG, "rail_read_handshake_order failed with error %" PRIu32 "!", error);
911 		return error;
912 	}
913 
914 	IFCALLRET(context->ClientHandshake, error, context, handshake);
915 
916 	if (error)
917 		WLog_ERR(TAG, "context.ClientHandshake failed with error %" PRIu32 "", error);
918 
919 	return error;
920 }
921 
922 /**
923  * Function description
924  *
925  * @return 0 on success, otherwise a Win32 error code
926  */
rail_recv_client_client_status_order(RailServerContext * context,RAIL_CLIENT_STATUS_ORDER * clientStatus,wStream * s)927 static UINT rail_recv_client_client_status_order(RailServerContext* context,
928                                                  RAIL_CLIENT_STATUS_ORDER* clientStatus, wStream* s)
929 {
930 	UINT error;
931 
932 	if (!context || !clientStatus || !s)
933 		return ERROR_INVALID_PARAMETER;
934 
935 	if ((error = rail_read_client_status_order(s, clientStatus)))
936 	{
937 		WLog_ERR(TAG, "rail_read_client_status_order failed with error %" PRIu32 "!", error);
938 		return error;
939 	}
940 
941 	IFCALLRET(context->ClientClientStatus, error, context, clientStatus);
942 
943 	if (error)
944 		WLog_ERR(TAG, "context.ClientClientStatus failed with error %" PRIu32 "", error);
945 
946 	return error;
947 }
948 
949 /**
950  * Function description
951  *
952  * @return 0 on success, otherwise a Win32 error code
953  */
rail_recv_client_exec_order(RailServerContext * context,wStream * s)954 static UINT rail_recv_client_exec_order(RailServerContext* context, wStream* s)
955 {
956 	UINT error;
957 	RAIL_EXEC_ORDER exec = { 0 };
958 
959 	if (!context || !s)
960 		return ERROR_INVALID_PARAMETER;
961 
962 	if ((error = rail_read_exec_order(s, &exec)))
963 	{
964 		WLog_ERR(TAG, "rail_read_client_status_order failed with error %" PRIu32 "!", error);
965 		return error;
966 	}
967 
968 	IFCALLRET(context->ClientExec, error, context, &exec);
969 
970 	if (error)
971 		WLog_ERR(TAG, "context.Exec failed with error %" PRIu32 "", error);
972 
973 	free(exec.RemoteApplicationProgram);
974 	free(exec.RemoteApplicationArguments);
975 	free(exec.RemoteApplicationWorkingDir);
976 	return error;
977 }
978 
979 /**
980  * Function description
981  *
982  * @return 0 on success, otherwise a Win32 error code
983  */
rail_recv_client_sysparam_order(RailServerContext * context,RAIL_SYSPARAM_ORDER * sysparam,wStream * s)984 static UINT rail_recv_client_sysparam_order(RailServerContext* context,
985                                             RAIL_SYSPARAM_ORDER* sysparam, wStream* s)
986 {
987 	UINT error;
988 	BOOL extendedSpiSupported;
989 
990 	if (!context || !sysparam || !s)
991 		return ERROR_INVALID_PARAMETER;
992 
993 	extendedSpiSupported = rail_is_extended_spi_supported(context->priv->channelFlags);
994 	if ((error = rail_read_sysparam_order(s, sysparam, extendedSpiSupported)))
995 	{
996 		WLog_ERR(TAG, "rail_read_sysparam_order failed with error %" PRIu32 "!", error);
997 		return error;
998 	}
999 
1000 	IFCALLRET(context->ClientSysparam, error, context, sysparam);
1001 
1002 	if (error)
1003 		WLog_ERR(TAG, "context.ClientSysparam failed with error %" PRIu32 "", error);
1004 
1005 	return error;
1006 }
1007 
1008 /**
1009  * Function description
1010  *
1011  * @return 0 on success, otherwise a Win32 error code
1012  */
rail_recv_client_activate_order(RailServerContext * context,RAIL_ACTIVATE_ORDER * activate,wStream * s)1013 static UINT rail_recv_client_activate_order(RailServerContext* context,
1014                                             RAIL_ACTIVATE_ORDER* activate, wStream* s)
1015 {
1016 	UINT error;
1017 
1018 	if (!context || !activate || !s)
1019 		return ERROR_INVALID_PARAMETER;
1020 
1021 	if ((error = rail_read_activate_order(s, activate)))
1022 	{
1023 		WLog_ERR(TAG, "rail_read_activate_order failed with error %" PRIu32 "!", error);
1024 		return error;
1025 	}
1026 
1027 	IFCALLRET(context->ClientActivate, error, context, activate);
1028 
1029 	if (error)
1030 		WLog_ERR(TAG, "context.ClientActivate failed with error %" PRIu32 "", error);
1031 
1032 	return error;
1033 }
1034 
1035 /**
1036  * Function description
1037  *
1038  * @return 0 on success, otherwise a Win32 error code
1039  */
rail_recv_client_sysmenu_order(RailServerContext * context,RAIL_SYSMENU_ORDER * sysmenu,wStream * s)1040 static UINT rail_recv_client_sysmenu_order(RailServerContext* context, RAIL_SYSMENU_ORDER* sysmenu,
1041                                            wStream* s)
1042 {
1043 	UINT error;
1044 
1045 	if (!context || !sysmenu || !s)
1046 		return ERROR_INVALID_PARAMETER;
1047 
1048 	if ((error = rail_read_sysmenu_order(s, sysmenu)))
1049 	{
1050 		WLog_ERR(TAG, "rail_read_sysmenu_order failed with error %" PRIu32 "!", error);
1051 		return error;
1052 	}
1053 
1054 	IFCALLRET(context->ClientSysmenu, error, context, sysmenu);
1055 
1056 	if (error)
1057 		WLog_ERR(TAG, "context.ClientSysmenu failed with error %" PRIu32 "", error);
1058 
1059 	return error;
1060 }
1061 
1062 /**
1063  * Function description
1064  *
1065  * @return 0 on success, otherwise a Win32 error code
1066  */
rail_recv_client_syscommand_order(RailServerContext * context,RAIL_SYSCOMMAND_ORDER * syscommand,wStream * s)1067 static UINT rail_recv_client_syscommand_order(RailServerContext* context,
1068                                               RAIL_SYSCOMMAND_ORDER* syscommand, wStream* s)
1069 {
1070 	UINT error;
1071 
1072 	if (!context || !syscommand || !s)
1073 		return ERROR_INVALID_PARAMETER;
1074 
1075 	if ((error = rail_read_syscommand_order(s, syscommand)))
1076 	{
1077 		WLog_ERR(TAG, "rail_read_syscommand_order failed with error %" PRIu32 "!", error);
1078 		return error;
1079 	}
1080 
1081 	IFCALLRET(context->ClientSyscommand, error, context, syscommand);
1082 
1083 	if (error)
1084 		WLog_ERR(TAG, "context.ClientSyscommand failed with error %" PRIu32 "", error);
1085 
1086 	return error;
1087 }
1088 
1089 /**
1090  * Function description
1091  *
1092  * @return 0 on success, otherwise a Win32 error code
1093  */
rail_recv_client_notify_event_order(RailServerContext * context,RAIL_NOTIFY_EVENT_ORDER * notifyEvent,wStream * s)1094 static UINT rail_recv_client_notify_event_order(RailServerContext* context,
1095                                                 RAIL_NOTIFY_EVENT_ORDER* notifyEvent, wStream* s)
1096 {
1097 	UINT error;
1098 
1099 	if (!context || !notifyEvent || !s)
1100 		return ERROR_INVALID_PARAMETER;
1101 
1102 	if ((error = rail_read_notify_event_order(s, notifyEvent)))
1103 	{
1104 		WLog_ERR(TAG, "rail_read_notify_event_order failed with error %" PRIu32 "!", error);
1105 		return error;
1106 	}
1107 
1108 	IFCALLRET(context->ClientNotifyEvent, error, context, notifyEvent);
1109 
1110 	if (error)
1111 		WLog_ERR(TAG, "context.ClientNotifyEvent failed with error %" PRIu32 "", error);
1112 
1113 	return error;
1114 }
1115 
1116 /**
1117  * Function description
1118  *
1119  * @return 0 on success, otherwise a Win32 error code
1120  */
rail_recv_client_window_move_order(RailServerContext * context,RAIL_WINDOW_MOVE_ORDER * windowMove,wStream * s)1121 static UINT rail_recv_client_window_move_order(RailServerContext* context,
1122                                                RAIL_WINDOW_MOVE_ORDER* windowMove, wStream* s)
1123 {
1124 	UINT error;
1125 
1126 	if (!context || !windowMove || !s)
1127 		return ERROR_INVALID_PARAMETER;
1128 
1129 	if ((error = rail_read_window_move_order(s, windowMove)))
1130 	{
1131 		WLog_ERR(TAG, "rail_read_window_move_order failed with error %" PRIu32 "!", error);
1132 		return error;
1133 	}
1134 
1135 	IFCALLRET(context->ClientWindowMove, error, context, windowMove);
1136 
1137 	if (error)
1138 		WLog_ERR(TAG, "context.ClientWindowMove failed with error %" PRIu32 "", error);
1139 
1140 	return error;
1141 }
1142 
1143 /**
1144  * Function description
1145  *
1146  * @return 0 on success, otherwise a Win32 error code
1147  */
rail_recv_client_snap_arrange_order(RailServerContext * context,RAIL_SNAP_ARRANGE * snapArrange,wStream * s)1148 static UINT rail_recv_client_snap_arrange_order(RailServerContext* context,
1149                                                 RAIL_SNAP_ARRANGE* snapArrange, wStream* s)
1150 {
1151 	UINT error;
1152 
1153 	if (!context || !snapArrange || !s)
1154 		return ERROR_INVALID_PARAMETER;
1155 
1156 	if ((error = rail_read_snap_arange_order(s, snapArrange)))
1157 	{
1158 		WLog_ERR(TAG, "rail_read_snap_arange_order failed with error %" PRIu32 "!", error);
1159 		return error;
1160 	}
1161 
1162 	IFCALLRET(context->ClientSnapArrange, error, context, snapArrange);
1163 
1164 	if (error)
1165 		WLog_ERR(TAG, "context.ClientSnapArrange failed with error %" PRIu32 "", error);
1166 
1167 	return error;
1168 }
1169 
1170 /**
1171  * Function description
1172  *
1173  * @return 0 on success, otherwise a Win32 error code
1174  */
rail_recv_client_get_appid_req_order(RailServerContext * context,RAIL_GET_APPID_REQ_ORDER * getAppidReq,wStream * s)1175 static UINT rail_recv_client_get_appid_req_order(RailServerContext* context,
1176                                                  RAIL_GET_APPID_REQ_ORDER* getAppidReq, wStream* s)
1177 {
1178 	UINT error;
1179 
1180 	if (!context || !getAppidReq || !s)
1181 		return ERROR_INVALID_PARAMETER;
1182 
1183 	if ((error = rail_read_get_appid_req_order(s, getAppidReq)))
1184 	{
1185 		WLog_ERR(TAG, "rail_read_get_appid_req_order failed with error %" PRIu32 "!", error);
1186 		return error;
1187 	}
1188 
1189 	IFCALLRET(context->ClientGetAppidReq, error, context, getAppidReq);
1190 
1191 	if (error)
1192 		WLog_ERR(TAG, "context.ClientGetAppidReq failed with error %" PRIu32 "", error);
1193 
1194 	return error;
1195 }
1196 
1197 /**
1198  * Function description
1199  *
1200  * @return 0 on success, otherwise a Win32 error code
1201  */
rail_recv_client_langbar_info_order(RailServerContext * context,RAIL_LANGBAR_INFO_ORDER * langbarInfo,wStream * s)1202 static UINT rail_recv_client_langbar_info_order(RailServerContext* context,
1203                                                 RAIL_LANGBAR_INFO_ORDER* langbarInfo, wStream* s)
1204 {
1205 	UINT error;
1206 
1207 	if (!context || !langbarInfo || !s)
1208 		return ERROR_INVALID_PARAMETER;
1209 
1210 	if ((error = rail_read_langbar_info_order(s, langbarInfo)))
1211 	{
1212 		WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %" PRIu32 "!", error);
1213 		return error;
1214 	}
1215 
1216 	IFCALLRET(context->ClientLangbarInfo, error, context, langbarInfo);
1217 
1218 	if (error)
1219 		WLog_ERR(TAG, "context.ClientLangbarInfo failed with error %" PRIu32 "", error);
1220 
1221 	return error;
1222 }
1223 
1224 /**
1225  * Function description
1226  *
1227  * @return 0 on success, otherwise a Win32 error code
1228  */
rail_recv_client_language_ime_info_order(RailServerContext * context,RAIL_LANGUAGEIME_INFO_ORDER * languageImeInfo,wStream * s)1229 static UINT rail_recv_client_language_ime_info_order(RailServerContext* context,
1230                                                      RAIL_LANGUAGEIME_INFO_ORDER* languageImeInfo,
1231                                                      wStream* s)
1232 {
1233 	UINT error;
1234 
1235 	if (!context || !languageImeInfo || !s)
1236 		return ERROR_INVALID_PARAMETER;
1237 
1238 	if ((error = rail_read_language_ime_info_order(s, languageImeInfo)))
1239 	{
1240 		WLog_ERR(TAG, "rail_read_language_ime_info_order failed with error %" PRIu32 "!", error);
1241 		return error;
1242 	}
1243 
1244 	IFCALLRET(context->ClientLanguageImeInfo, error, context, languageImeInfo);
1245 
1246 	if (error)
1247 		WLog_ERR(TAG, "context.ClientLanguageImeInfo failed with error %" PRIu32 "", error);
1248 
1249 	return error;
1250 }
1251 
1252 /**
1253  * Function description
1254  *
1255  * @return 0 on success, otherwise a Win32 error code
1256  */
rail_recv_client_compartment_info(RailServerContext * context,RAIL_COMPARTMENT_INFO_ORDER * compartmentInfo,wStream * s)1257 static UINT rail_recv_client_compartment_info(RailServerContext* context,
1258                                               RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo,
1259                                               wStream* s)
1260 {
1261 	UINT error;
1262 
1263 	if (!context || !compartmentInfo || !s)
1264 		return ERROR_INVALID_PARAMETER;
1265 
1266 	if ((error = rail_read_compartment_info_order(s, compartmentInfo)))
1267 	{
1268 		WLog_ERR(TAG, "rail_read_compartment_info_order failed with error %" PRIu32 "!", error);
1269 		return error;
1270 	}
1271 
1272 	IFCALLRET(context->ClientCompartmentInfo, error, context, compartmentInfo);
1273 
1274 	if (error)
1275 		WLog_ERR(TAG, "context.ClientCompartmentInfo failed with error %" PRIu32 "", error);
1276 
1277 	return error;
1278 }
1279 
1280 /**
1281  * Function description
1282  *
1283  * @return 0 on success, otherwise a Win32 error code
1284  */
rail_recv_client_cloak_order(RailServerContext * context,RAIL_CLOAK * cloak,wStream * s)1285 static UINT rail_recv_client_cloak_order(RailServerContext* context, RAIL_CLOAK* cloak, wStream* s)
1286 {
1287 	UINT error;
1288 
1289 	if (!context || !cloak || !s)
1290 		return ERROR_INVALID_PARAMETER;
1291 
1292 	if ((error = rail_read_cloak_order(s, cloak)))
1293 	{
1294 		WLog_ERR(TAG, "rail_read_cloak_order failed with error %" PRIu32 "!", error);
1295 		return error;
1296 	}
1297 
1298 	IFCALLRET(context->ClientCloak, error, context, cloak);
1299 
1300 	if (error)
1301 		WLog_ERR(TAG, "context.Cloak failed with error %" PRIu32 "", error);
1302 
1303 	return error;
1304 }
1305 
rail_server_thread(LPVOID arg)1306 static DWORD WINAPI rail_server_thread(LPVOID arg)
1307 {
1308 	RailServerContext* context = (RailServerContext*)arg;
1309 	RailServerPrivate* priv = context->priv;
1310 	DWORD status;
1311 	DWORD nCount = 0;
1312 	HANDLE events[8];
1313 	UINT error = CHANNEL_RC_OK;
1314 	events[nCount++] = priv->channelEvent;
1315 	events[nCount++] = priv->stopEvent;
1316 
1317 	while (TRUE)
1318 	{
1319 		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
1320 
1321 		if (status == WAIT_FAILED)
1322 		{
1323 			error = GetLastError();
1324 			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %" PRIu32 "!", error);
1325 			break;
1326 		}
1327 
1328 		status = WaitForSingleObject(context->priv->stopEvent, 0);
1329 
1330 		if (status == WAIT_FAILED)
1331 		{
1332 			error = GetLastError();
1333 			WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "!", error);
1334 			break;
1335 		}
1336 
1337 		if (status == WAIT_OBJECT_0)
1338 			break;
1339 
1340 		status = WaitForSingleObject(context->priv->channelEvent, 0);
1341 
1342 		if (status == WAIT_FAILED)
1343 		{
1344 			error = GetLastError();
1345 			WLog_ERR(
1346 			    TAG,
1347 			    "WaitForSingleObject(context->priv->channelEvent, 0) failed with error %" PRIu32
1348 			    "!",
1349 			    error);
1350 			break;
1351 		}
1352 
1353 		if (status == WAIT_OBJECT_0)
1354 		{
1355 			if ((error = rail_server_handle_messages(context)))
1356 			{
1357 				WLog_ERR(TAG, "rail_server_handle_messages failed with error %" PRIu32 "", error);
1358 				break;
1359 			}
1360 		}
1361 	}
1362 
1363 	if (error && context->rdpcontext)
1364 		setChannelError(context->rdpcontext, error, "rail_server_thread reported an error");
1365 
1366 	ExitThread(error);
1367 	return error;
1368 }
1369 
1370 /**
1371  * Function description
1372  *
1373  * @return 0 on success, otherwise a Win32 error code
1374  */
rail_server_start(RailServerContext * context)1375 static UINT rail_server_start(RailServerContext* context)
1376 {
1377 	void* buffer = NULL;
1378 	DWORD bytesReturned;
1379 	RailServerPrivate* priv = context->priv;
1380 	UINT error = ERROR_INTERNAL_ERROR;
1381 	priv->rail_channel =
1382 	    WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, RAIL_SVC_CHANNEL_NAME);
1383 
1384 	if (!priv->rail_channel)
1385 	{
1386 		WLog_ERR(TAG, "WTSVirtualChannelOpen failed!");
1387 		return error;
1388 	}
1389 
1390 	if (!WTSVirtualChannelQuery(priv->rail_channel, WTSVirtualEventHandle, &buffer,
1391 	                            &bytesReturned) ||
1392 	    (bytesReturned != sizeof(HANDLE)))
1393 	{
1394 		WLog_ERR(TAG,
1395 		         "error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned "
1396 		         "size(%" PRIu32 ")",
1397 		         bytesReturned);
1398 
1399 		if (buffer)
1400 			WTSFreeMemory(buffer);
1401 
1402 		goto out_close;
1403 	}
1404 
1405 	CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE));
1406 	WTSFreeMemory(buffer);
1407 	context->priv->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1408 
1409 	if (!context->priv->stopEvent)
1410 	{
1411 		WLog_ERR(TAG, "CreateEvent failed!");
1412 		goto out_close;
1413 	}
1414 
1415 	context->priv->thread = CreateThread(NULL, 0, rail_server_thread, (void*)context, 0, NULL);
1416 
1417 	if (!context->priv->thread)
1418 	{
1419 		WLog_ERR(TAG, "CreateThread failed!");
1420 		goto out_stop_event;
1421 	}
1422 
1423 	return CHANNEL_RC_OK;
1424 out_stop_event:
1425 	CloseHandle(context->priv->stopEvent);
1426 	context->priv->stopEvent = NULL;
1427 out_close:
1428 	WTSVirtualChannelClose(context->priv->rail_channel);
1429 	context->priv->rail_channel = NULL;
1430 	return error;
1431 }
1432 
rail_server_stop(RailServerContext * context)1433 static BOOL rail_server_stop(RailServerContext* context)
1434 {
1435 	RailServerPrivate* priv = (RailServerPrivate*)context->priv;
1436 
1437 	if (priv->thread)
1438 	{
1439 		SetEvent(priv->stopEvent);
1440 
1441 		if (WaitForSingleObject(priv->thread, INFINITE) == WAIT_FAILED)
1442 		{
1443 			WLog_ERR(TAG, "WaitForSingleObject failed with error %" PRIu32 "", GetLastError());
1444 			return FALSE;
1445 		}
1446 
1447 		CloseHandle(priv->thread);
1448 		CloseHandle(priv->stopEvent);
1449 		priv->thread = NULL;
1450 		priv->stopEvent = NULL;
1451 	}
1452 
1453 	if (priv->rail_channel)
1454 	{
1455 		WTSVirtualChannelClose(priv->rail_channel);
1456 		priv->rail_channel = NULL;
1457 	}
1458 
1459 	priv->channelEvent = NULL;
1460 	return TRUE;
1461 }
1462 
rail_server_context_new(HANDLE vcm)1463 RailServerContext* rail_server_context_new(HANDLE vcm)
1464 {
1465 	RailServerContext* context;
1466 	RailServerPrivate* priv;
1467 	context = (RailServerContext*)calloc(1, sizeof(RailServerContext));
1468 
1469 	if (!context)
1470 	{
1471 		WLog_ERR(TAG, "calloc failed!");
1472 		return NULL;
1473 	}
1474 
1475 	context->vcm = vcm;
1476 	context->Start = rail_server_start;
1477 	context->Stop = rail_server_stop;
1478 	context->ServerHandshake = rail_send_server_handshake;
1479 	context->ServerHandshakeEx = rail_send_server_handshake_ex;
1480 	context->ServerSysparam = rail_send_server_sysparam;
1481 	context->ServerLocalMoveSize = rail_send_server_local_move_size;
1482 	context->ServerMinMaxInfo = rail_send_server_min_max_info;
1483 	context->ServerTaskbarInfo = rail_send_server_taskbar_info;
1484 	context->ServerLangbarInfo = rail_send_server_langbar_info;
1485 	context->ServerExecResult = rail_send_server_exec_result;
1486 	context->ServerGetAppidResp = rail_send_server_get_app_id_resp;
1487 	context->ServerZOrderSync = rail_send_server_z_order_sync;
1488 	context->ServerCloak = rail_send_server_cloak;
1489 	context->ServerPowerDisplayRequest = rail_send_server_power_display_request;
1490 	context->ServerGetAppidRespEx = rail_send_server_get_appid_resp_ex;
1491 	context->priv = priv = (RailServerPrivate*)calloc(1, sizeof(RailServerPrivate));
1492 
1493 	if (!priv)
1494 	{
1495 		WLog_ERR(TAG, "calloc failed!");
1496 		goto out_free;
1497 	}
1498 
1499 	/* Create shared input stream */
1500 	priv->input_stream = Stream_New(NULL, 4096);
1501 
1502 	if (!priv->input_stream)
1503 	{
1504 		WLog_ERR(TAG, "Stream_New failed!");
1505 		goto out_free_priv;
1506 	}
1507 
1508 	return context;
1509 out_free_priv:
1510 	free(context->priv);
1511 out_free:
1512 	free(context);
1513 	return NULL;
1514 }
1515 
rail_server_context_free(RailServerContext * context)1516 void rail_server_context_free(RailServerContext* context)
1517 {
1518 	if (context->priv)
1519 		Stream_Free(context->priv->input_stream, TRUE);
1520 
1521 	free(context->priv);
1522 	free(context);
1523 }
1524 
rail_server_set_handshake_ex_flags(RailServerContext * context,DWORD flags)1525 void rail_server_set_handshake_ex_flags(RailServerContext* context, DWORD flags)
1526 {
1527 	RailServerPrivate* priv;
1528 
1529 	if (!context || !context->priv)
1530 		return;
1531 
1532 	priv = context->priv;
1533 	priv->channelFlags = flags;
1534 }
1535 
rail_server_handle_messages(RailServerContext * context)1536 UINT rail_server_handle_messages(RailServerContext* context)
1537 {
1538 	UINT status = CHANNEL_RC_OK;
1539 	DWORD bytesReturned;
1540 	UINT16 orderType;
1541 	UINT16 orderLength;
1542 	RailServerPrivate* priv = context->priv;
1543 	wStream* s = priv->input_stream;
1544 
1545 	/* Read header */
1546 	if (!Stream_EnsureRemainingCapacity(s, RAIL_PDU_HEADER_LENGTH))
1547 	{
1548 		WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed, RAIL_PDU_HEADER_LENGTH");
1549 		return CHANNEL_RC_NO_MEMORY;
1550 	}
1551 
1552 	if (!WTSVirtualChannelRead(priv->rail_channel, 0, (PCHAR)Stream_Pointer(s),
1553 	                           RAIL_PDU_HEADER_LENGTH, &bytesReturned))
1554 	{
1555 		if (GetLastError() == ERROR_NO_DATA)
1556 			return ERROR_NO_DATA;
1557 
1558 		WLog_ERR(TAG, "channel connection closed");
1559 		return ERROR_INTERNAL_ERROR;
1560 	}
1561 
1562 	/* Parse header */
1563 	if ((status = rail_read_pdu_header(s, &orderType, &orderLength)) != CHANNEL_RC_OK)
1564 	{
1565 		WLog_ERR(TAG, "rail_read_pdu_header failed with error %" PRIu32 "!", status);
1566 		return status;
1567 	}
1568 
1569 	if (!Stream_EnsureRemainingCapacity(s, orderLength - RAIL_PDU_HEADER_LENGTH))
1570 	{
1571 		WLog_ERR(TAG,
1572 		         "Stream_EnsureRemainingCapacity failed, orderLength - RAIL_PDU_HEADER_LENGTH");
1573 		return CHANNEL_RC_NO_MEMORY;
1574 	}
1575 
1576 	/* Read body */
1577 	if (!WTSVirtualChannelRead(priv->rail_channel, 0, (PCHAR)Stream_Pointer(s),
1578 	                           orderLength - RAIL_PDU_HEADER_LENGTH, &bytesReturned))
1579 	{
1580 		if (GetLastError() == ERROR_NO_DATA)
1581 			return ERROR_NO_DATA;
1582 
1583 		WLog_ERR(TAG, "channel connection closed");
1584 		return ERROR_INTERNAL_ERROR;
1585 	}
1586 
1587 	WLog_DBG(TAG, "Received %s PDU, length:%" PRIu16 "", rail_get_order_type_string(orderType),
1588 	         orderLength);
1589 
1590 	switch (orderType)
1591 	{
1592 		case TS_RAIL_ORDER_HANDSHAKE:
1593 		{
1594 			RAIL_HANDSHAKE_ORDER handshake;
1595 			return rail_recv_client_handshake_order(context, &handshake, s);
1596 		}
1597 
1598 		case TS_RAIL_ORDER_CLIENTSTATUS:
1599 		{
1600 			RAIL_CLIENT_STATUS_ORDER clientStatus;
1601 			return rail_recv_client_client_status_order(context, &clientStatus, s);
1602 		}
1603 
1604 		case TS_RAIL_ORDER_EXEC:
1605 			return rail_recv_client_exec_order(context, s);
1606 
1607 		case TS_RAIL_ORDER_SYSPARAM:
1608 		{
1609 			RAIL_SYSPARAM_ORDER sysparam = { 0 };
1610 			return rail_recv_client_sysparam_order(context, &sysparam, s);
1611 		}
1612 
1613 		case TS_RAIL_ORDER_ACTIVATE:
1614 		{
1615 			RAIL_ACTIVATE_ORDER activate;
1616 			return rail_recv_client_activate_order(context, &activate, s);
1617 		}
1618 
1619 		case TS_RAIL_ORDER_SYSMENU:
1620 		{
1621 			RAIL_SYSMENU_ORDER sysmenu;
1622 			return rail_recv_client_sysmenu_order(context, &sysmenu, s);
1623 		}
1624 
1625 		case TS_RAIL_ORDER_SYSCOMMAND:
1626 		{
1627 			RAIL_SYSCOMMAND_ORDER syscommand;
1628 			return rail_recv_client_syscommand_order(context, &syscommand, s);
1629 		}
1630 
1631 		case TS_RAIL_ORDER_NOTIFY_EVENT:
1632 		{
1633 			RAIL_NOTIFY_EVENT_ORDER notifyEvent;
1634 			return rail_recv_client_notify_event_order(context, &notifyEvent, s);
1635 		}
1636 
1637 		case TS_RAIL_ORDER_WINDOWMOVE:
1638 		{
1639 			RAIL_WINDOW_MOVE_ORDER windowMove;
1640 			return rail_recv_client_window_move_order(context, &windowMove, s);
1641 		}
1642 
1643 		case TS_RAIL_ORDER_SNAP_ARRANGE:
1644 		{
1645 			RAIL_SNAP_ARRANGE snapArrange;
1646 			return rail_recv_client_snap_arrange_order(context, &snapArrange, s);
1647 		}
1648 
1649 		case TS_RAIL_ORDER_GET_APPID_REQ:
1650 		{
1651 			RAIL_GET_APPID_REQ_ORDER getAppidReq;
1652 			return rail_recv_client_get_appid_req_order(context, &getAppidReq, s);
1653 		}
1654 
1655 		case TS_RAIL_ORDER_LANGBARINFO:
1656 		{
1657 			RAIL_LANGBAR_INFO_ORDER langbarInfo;
1658 			return rail_recv_client_langbar_info_order(context, &langbarInfo, s);
1659 		}
1660 
1661 		case TS_RAIL_ORDER_LANGUAGEIMEINFO:
1662 		{
1663 			RAIL_LANGUAGEIME_INFO_ORDER languageImeInfo;
1664 			return rail_recv_client_language_ime_info_order(context, &languageImeInfo, s);
1665 		}
1666 
1667 		case TS_RAIL_ORDER_COMPARTMENTINFO:
1668 		{
1669 			RAIL_COMPARTMENT_INFO_ORDER compartmentInfo;
1670 			return rail_recv_client_compartment_info(context, &compartmentInfo, s);
1671 		}
1672 
1673 		case TS_RAIL_ORDER_CLOAK:
1674 		{
1675 			RAIL_CLOAK cloak;
1676 			return rail_recv_client_cloak_order(context, &cloak, s);
1677 		}
1678 
1679 		default:
1680 			WLog_ERR(TAG, "Unknown RAIL PDU order received.");
1681 			return ERROR_INVALID_DATA;
1682 	}
1683 
1684 	Stream_SetPosition(s, 0);
1685 	return status;
1686 }
1687