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