21 #include <freerdp/types.h>
22 #include <freerdp/constants.h>
24 #include <freerdp/freerdp.h>
25 #include <freerdp/channels/log.h>
27 #include <winpr/crt.h>
28 #include <winpr/synch.h>
29 #include <winpr/thread.h>
30 #include <winpr/stream.h>
32 #include "rail_main.h"
34 #define TAG CHANNELS_TAG("rail.server")
41 static UINT rail_send(RailServerContext* context,
wStream* s, ULONG length)
43 UINT status = CHANNEL_RC_OK;
47 return CHANNEL_RC_BAD_INIT_HANDLE;
49 if (!WTSVirtualChannelWrite(context->priv->rail_channel, Stream_BufferAs(s,
char), length,
52 WLog_ERR(TAG,
"WTSVirtualChannelWrite failed!");
53 status = ERROR_INTERNAL_ERROR;
64 static UINT rail_server_send_pdu(RailServerContext* context,
wStream* s, UINT16 orderType)
66 char buffer[128] = { 0 };
67 UINT16 orderLength = 0;
70 return ERROR_INVALID_PARAMETER;
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);
86 static UINT rail_write_local_move_size_order(
wStream* s,
89 if (!s || !localMoveSize)
90 return ERROR_INVALID_PARAMETER;
92 Stream_Write_UINT32(s, localMoveSize->windowId);
93 Stream_Write_UINT16(s, localMoveSize->isMoveSizeStart ? 1 : 0);
94 Stream_Write_UINT16(s, localMoveSize->moveSizeType);
95 Stream_Write_UINT16(s, localMoveSize->posX);
96 Stream_Write_UINT16(s, localMoveSize->posY);
107 if (!s || !minMaxInfo)
108 return ERROR_INVALID_PARAMETER;
110 Stream_Write_UINT32(s, minMaxInfo->windowId);
111 Stream_Write_INT16(s, minMaxInfo->maxWidth);
112 Stream_Write_INT16(s, minMaxInfo->maxHeight);
113 Stream_Write_INT16(s, minMaxInfo->maxPosX);
114 Stream_Write_INT16(s, minMaxInfo->maxPosY);
115 Stream_Write_INT16(s, minMaxInfo->minTrackWidth);
116 Stream_Write_INT16(s, minMaxInfo->minTrackHeight);
117 Stream_Write_INT16(s, minMaxInfo->maxTrackWidth);
118 Stream_Write_INT16(s, minMaxInfo->maxTrackHeight);
119 return ERROR_SUCCESS;
129 if (!s || !taskbarInfo)
130 return ERROR_INVALID_PARAMETER;
132 Stream_Write_UINT32(s, taskbarInfo->TaskbarMessage);
133 Stream_Write_UINT32(s, taskbarInfo->WindowIdTab);
134 Stream_Write_UINT32(s, taskbarInfo->Body);
135 return ERROR_SUCCESS;
145 if (!s || !langbarInfo)
146 return ERROR_INVALID_PARAMETER;
148 Stream_Write_UINT32(s, langbarInfo->languageBarStatus);
149 return ERROR_SUCCESS;
159 if (!s || !execResult)
160 return ERROR_INVALID_PARAMETER;
162 if (execResult->exeOrFile.length > 520 || execResult->exeOrFile.length < 1)
163 return ERROR_INVALID_DATA;
165 Stream_Write_UINT16(s, execResult->flags);
166 Stream_Write_UINT16(s, execResult->execResult);
167 Stream_Write_UINT32(s, execResult->rawResult);
168 Stream_Write_UINT16(s, 0);
169 Stream_Write_UINT16(s, execResult->exeOrFile.length);
170 Stream_Write(s, execResult->exeOrFile.string,
171 execResult->exeOrFile.length);
172 return ERROR_SUCCESS;
182 if (!s || !zOrderSync)
183 return ERROR_INVALID_PARAMETER;
185 Stream_Write_UINT32(s, zOrderSync->windowIdMarker);
186 return ERROR_SUCCESS;
197 return ERROR_INVALID_PARAMETER;
199 Stream_Write_UINT32(s, cloak->windowId);
200 Stream_Write_UINT8(s, cloak->cloak ? 1 : 0);
201 return ERROR_SUCCESS;
210 rail_write_power_display_request_order(
wStream* s,
213 if (!s || !powerDisplayRequest)
214 return ERROR_INVALID_PARAMETER;
216 Stream_Write_UINT32(s, powerDisplayRequest->active ? 1 : 0);
217 return ERROR_SUCCESS;
225 static UINT rail_write_get_app_id_resp_order(
wStream* s,
228 if (!s || !getAppidResp)
229 return ERROR_INVALID_PARAMETER;
231 Stream_Write_UINT32(s, getAppidResp->windowId);
232 Stream_Write_UTF16_String(
233 s, getAppidResp->applicationId,
234 ARRAYSIZE(getAppidResp->applicationId));
235 return ERROR_SUCCESS;
243 static UINT rail_write_get_appid_resp_ex_order(
wStream* s,
246 if (!s || !getAppidRespEx)
247 return ERROR_INVALID_PARAMETER;
249 Stream_Write_UINT32(s, getAppidRespEx->windowID);
250 Stream_Write_UTF16_String(
251 s, getAppidRespEx->applicationID,
252 ARRAYSIZE(getAppidRespEx->applicationID));
253 Stream_Write_UINT32(s, getAppidRespEx->processId);
254 Stream_Write_UTF16_String(
255 s, getAppidRespEx->processImageName,
256 ARRAYSIZE(getAppidRespEx->processImageName));
257 return ERROR_SUCCESS;
265 static UINT rail_send_server_handshake(RailServerContext* context,
271 if (!context || !handshake)
272 return ERROR_INVALID_PARAMETER;
274 s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH);
278 WLog_ERR(TAG,
"rail_pdu_init failed!");
279 return CHANNEL_RC_NO_MEMORY;
282 rail_write_handshake_order(s, handshake);
283 error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_HANDSHAKE);
284 Stream_Free(s, TRUE);
293 static UINT rail_send_server_handshake_ex(RailServerContext* context,
299 if (!context || !handshakeEx || !context->priv)
300 return ERROR_INVALID_PARAMETER;
302 s = rail_pdu_init(RAIL_HANDSHAKE_EX_ORDER_LENGTH);
306 WLog_ERR(TAG,
"rail_pdu_init failed!");
307 return CHANNEL_RC_NO_MEMORY;
310 rail_server_set_handshake_ex_flags(context, handshakeEx->railHandshakeFlags);
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);
323 static UINT rail_send_server_sysparam(RailServerContext* context,
328 RailServerPrivate* priv = NULL;
329 BOOL extendedSpiSupported = 0;
331 if (!context || !sysparam)
332 return ERROR_INVALID_PARAMETER;
334 priv = context->priv;
337 return ERROR_INVALID_PARAMETER;
339 extendedSpiSupported = rail_is_extended_spi_supported(context->priv->channelFlags);
340 s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH);
344 WLog_ERR(TAG,
"rail_pdu_init failed!");
345 return CHANNEL_RC_NO_MEMORY;
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);
359 static UINT rail_send_server_local_move_size(RailServerContext* context,
365 if (!context || !localMoveSize)
366 return ERROR_INVALID_PARAMETER;
368 s = rail_pdu_init(RAIL_LOCALMOVESIZE_ORDER_LENGTH);
372 WLog_ERR(TAG,
"rail_pdu_init failed!");
373 return CHANNEL_RC_NO_MEMORY;
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);
387 static UINT rail_send_server_min_max_info(RailServerContext* context,
393 if (!context || !minMaxInfo)
394 return ERROR_INVALID_PARAMETER;
396 s = rail_pdu_init(RAIL_MINMAXINFO_ORDER_LENGTH);
400 WLog_ERR(TAG,
"rail_pdu_init failed!");
401 return CHANNEL_RC_NO_MEMORY;
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);
415 static UINT rail_send_server_taskbar_info(RailServerContext* context,
421 if (!context || !taskbarInfo)
422 return ERROR_INVALID_PARAMETER;
424 s = rail_pdu_init(RAIL_TASKBAR_INFO_ORDER_LENGTH);
428 WLog_ERR(TAG,
"rail_pdu_init failed!");
429 return CHANNEL_RC_NO_MEMORY;
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);
443 static UINT rail_send_server_langbar_info(RailServerContext* context,
449 if (!context || !langbarInfo)
450 return ERROR_INVALID_PARAMETER;
452 s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH);
456 WLog_ERR(TAG,
"rail_pdu_init failed!");
457 return CHANNEL_RC_NO_MEMORY;
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);
471 static UINT rail_send_server_exec_result(RailServerContext* context,
477 if (!context || !execResult)
478 return ERROR_INVALID_PARAMETER;
480 s = rail_pdu_init(RAIL_EXEC_RESULT_ORDER_LENGTH + execResult->exeOrFile.length);
484 WLog_ERR(TAG,
"rail_pdu_init failed!");
485 return CHANNEL_RC_NO_MEMORY;
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);
499 static UINT rail_send_server_z_order_sync(RailServerContext* context,
505 if (!context || !zOrderSync)
506 return ERROR_INVALID_PARAMETER;
508 s = rail_pdu_init(RAIL_Z_ORDER_SYNC_ORDER_LENGTH);
512 WLog_ERR(TAG,
"rail_pdu_init failed!");
513 return CHANNEL_RC_NO_MEMORY;
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);
527 static UINT rail_send_server_cloak(RailServerContext* context,
const RAIL_CLOAK* cloak)
532 if (!context || !cloak)
533 return ERROR_INVALID_PARAMETER;
535 s = rail_pdu_init(RAIL_CLOAK_ORDER_LENGTH);
539 WLog_ERR(TAG,
"rail_pdu_init failed!");
540 return CHANNEL_RC_NO_MEMORY;
543 rail_write_cloak_order(s, cloak);
544 error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_CLOAK);
545 Stream_Free(s, TRUE);
555 rail_send_server_power_display_request(RailServerContext* context,
561 if (!context || !powerDisplayRequest)
562 return ERROR_INVALID_PARAMETER;
564 s = rail_pdu_init(RAIL_POWER_DISPLAY_REQUEST_ORDER_LENGTH);
568 WLog_ERR(TAG,
"rail_pdu_init failed!");
569 return CHANNEL_RC_NO_MEMORY;
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);
583 static UINT rail_send_server_get_app_id_resp(RailServerContext* context,
589 if (!context || !getAppidResp)
590 return ERROR_INVALID_PARAMETER;
592 s = rail_pdu_init(RAIL_GET_APPID_RESP_ORDER_LENGTH);
596 WLog_ERR(TAG,
"rail_pdu_init failed!");
597 return CHANNEL_RC_NO_MEMORY;
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);
611 static UINT rail_send_server_get_appid_resp_ex(RailServerContext* context,
617 if (!context || !getAppidRespEx)
618 return ERROR_INVALID_PARAMETER;
620 s = rail_pdu_init(RAIL_GET_APPID_RESP_EX_ORDER_LENGTH);
624 WLog_ERR(TAG,
"rail_pdu_init failed!");
625 return CHANNEL_RC_NO_MEMORY;
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);
641 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_CLIENT_STATUS_ORDER_LENGTH))
642 return ERROR_INVALID_DATA;
644 Stream_Read_UINT32(s, clientStatus->flags);
645 return CHANNEL_RC_OK;
660 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_EXEC_ORDER_LENGTH))
661 return ERROR_INVALID_DATA;
663 Stream_Read_UINT16(s, exec->flags);
664 Stream_Read_UINT16(s, exeLen);
665 Stream_Read_UINT16(s, workLen);
666 Stream_Read_UINT16(s, argLen);
668 if (!Stream_CheckAndLogRequiredLength(TAG, s, (
size_t)exeLen + workLen + argLen))
669 return ERROR_INVALID_DATA;
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)
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)
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)
694 return CHANNEL_RC_OK;
700 return ERROR_INTERNAL_ERROR;
712 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_ACTIVATE_ORDER_LENGTH))
713 return ERROR_INVALID_DATA;
715 Stream_Read_UINT32(s, activate->windowId);
716 Stream_Read_UINT8(s, enabled);
717 activate->enabled = (enabled != 0) ? TRUE : FALSE;
718 return CHANNEL_RC_OK;
728 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_SYSMENU_ORDER_LENGTH))
729 return ERROR_INVALID_DATA;
731 Stream_Read_UINT32(s, sysmenu->windowId);
732 Stream_Read_INT16(s, sysmenu->left);
733 Stream_Read_INT16(s, sysmenu->top);
734 return CHANNEL_RC_OK;
744 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_SYSCOMMAND_ORDER_LENGTH))
745 return ERROR_INVALID_DATA;
747 Stream_Read_UINT32(s, syscommand->windowId);
748 Stream_Read_UINT16(s, syscommand->command);
749 return CHANNEL_RC_OK;
759 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_NOTIFY_EVENT_ORDER_LENGTH))
760 return ERROR_INVALID_DATA;
762 Stream_Read_UINT32(s, notifyEvent->windowId);
763 Stream_Read_UINT32(s, notifyEvent->notifyIconId);
764 Stream_Read_UINT32(s, notifyEvent->message);
765 return CHANNEL_RC_OK;
775 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_GET_APPID_REQ_ORDER_LENGTH))
776 return ERROR_INVALID_DATA;
778 Stream_Read_UINT32(s, getAppidReq->windowId);
779 return CHANNEL_RC_OK;
789 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_WINDOW_MOVE_ORDER_LENGTH))
790 return ERROR_INVALID_DATA;
792 Stream_Read_UINT32(s, windowMove->windowId);
793 Stream_Read_INT16(s, windowMove->left);
794 Stream_Read_INT16(s, windowMove->top);
795 Stream_Read_INT16(s, windowMove->right);
796 Stream_Read_INT16(s, windowMove->bottom);
797 return CHANNEL_RC_OK;
807 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_SNAP_ARRANGE_ORDER_LENGTH))
808 return ERROR_INVALID_DATA;
810 Stream_Read_UINT32(s, snapArrange->windowId);
811 Stream_Read_INT16(s, snapArrange->left);
812 Stream_Read_INT16(s, snapArrange->top);
813 Stream_Read_INT16(s, snapArrange->right);
814 Stream_Read_INT16(s, snapArrange->bottom);
815 return CHANNEL_RC_OK;
825 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_LANGBAR_INFO_ORDER_LENGTH))
826 return ERROR_INVALID_DATA;
828 Stream_Read_UINT32(s, langbarInfo->languageBarStatus);
829 return CHANNEL_RC_OK;
837 static UINT rail_read_language_ime_info_order(
wStream* s,
840 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_LANGUAGEIME_INFO_ORDER_LENGTH))
841 return ERROR_INVALID_DATA;
843 Stream_Read_UINT32(s, languageImeInfo->ProfileType);
844 Stream_Read_UINT16(s, languageImeInfo->LanguageID);
846 s, &languageImeInfo->LanguageProfileCLSID,
847 sizeof(languageImeInfo->LanguageProfileCLSID));
848 Stream_Read(s, &languageImeInfo->ProfileGUID,
849 sizeof(languageImeInfo->ProfileGUID));
850 Stream_Read_UINT32(s, languageImeInfo->KeyboardLayout);
851 return CHANNEL_RC_OK;
859 static UINT rail_read_compartment_info_order(
wStream* s,
862 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_COMPARTMENT_INFO_ORDER_LENGTH))
863 return ERROR_INVALID_DATA;
865 Stream_Read_UINT32(s, compartmentInfo->ImeState);
866 Stream_Read_UINT32(s, compartmentInfo->ImeConvMode);
867 Stream_Read_UINT32(s, compartmentInfo->ImeSentenceMode);
868 Stream_Read_UINT32(s, compartmentInfo->KanaMode);
869 return CHANNEL_RC_OK;
881 if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_CLOAK_ORDER_LENGTH))
882 return ERROR_INVALID_DATA;
884 Stream_Read_UINT32(s, cloak->windowId);
885 Stream_Read_UINT8(s, cloaked);
886 cloak->cloak = (cloaked != 0) ? TRUE : FALSE;
887 return CHANNEL_RC_OK;
895 static UINT rail_recv_client_handshake_order(RailServerContext* context,
900 if (!context || !handshake || !s)
901 return ERROR_INVALID_PARAMETER;
903 if ((error = rail_read_handshake_order(s, handshake)))
905 WLog_ERR(TAG,
"rail_read_handshake_order failed with error %" PRIu32
"!", error);
909 IFCALLRET(context->ClientHandshake, error, context, handshake);
912 WLog_ERR(TAG,
"context.ClientHandshake failed with error %" PRIu32
"", error);
922 static UINT rail_recv_client_client_status_order(RailServerContext* context,
927 if (!context || !clientStatus || !s)
928 return ERROR_INVALID_PARAMETER;
930 if ((error = rail_read_client_status_order(s, clientStatus)))
932 WLog_ERR(TAG,
"rail_read_client_status_order failed with error %" PRIu32
"!", error);
936 IFCALLRET(context->ClientClientStatus, error, context, clientStatus);
939 WLog_ERR(TAG,
"context.ClientClientStatus failed with error %" PRIu32
"", error);
949 static UINT rail_recv_client_exec_order(RailServerContext* context,
wStream* s)
952 char* args[3] = { 0 };
956 return ERROR_INVALID_PARAMETER;
958 error = rail_read_exec_order(s, &exec, args);
961 WLog_ERR(TAG,
"rail_read_client_status_order failed with error %" PRIu32
"!", error);
965 IFCALLRET(context->ClientExec, error, context, &exec);
968 WLog_ERR(TAG,
"context.Exec failed with error %" PRIu32
"", error);
981 static UINT rail_recv_client_sysparam_order(RailServerContext* context,
985 BOOL extendedSpiSupported = 0;
987 if (!context || !sysparam || !s)
988 return ERROR_INVALID_PARAMETER;
990 extendedSpiSupported = rail_is_extended_spi_supported(context->priv->channelFlags);
991 if ((error = rail_read_sysparam_order(s, sysparam, extendedSpiSupported)))
993 WLog_ERR(TAG,
"rail_read_sysparam_order failed with error %" PRIu32
"!", error);
997 IFCALLRET(context->ClientSysparam, error, context, sysparam);
1000 WLog_ERR(TAG,
"context.ClientSysparam failed with error %" PRIu32
"", error);
1010 static UINT rail_recv_client_activate_order(RailServerContext* context,
1015 if (!context || !activate || !s)
1016 return ERROR_INVALID_PARAMETER;
1018 if ((error = rail_read_activate_order(s, activate)))
1020 WLog_ERR(TAG,
"rail_read_activate_order failed with error %" PRIu32
"!", error);
1024 IFCALLRET(context->ClientActivate, error, context, activate);
1027 WLog_ERR(TAG,
"context.ClientActivate failed with error %" PRIu32
"", error);
1037 static UINT rail_recv_client_sysmenu_order(RailServerContext* context,
RAIL_SYSMENU_ORDER* sysmenu,
1042 if (!context || !sysmenu || !s)
1043 return ERROR_INVALID_PARAMETER;
1045 if ((error = rail_read_sysmenu_order(s, sysmenu)))
1047 WLog_ERR(TAG,
"rail_read_sysmenu_order failed with error %" PRIu32
"!", error);
1051 IFCALLRET(context->ClientSysmenu, error, context, sysmenu);
1054 WLog_ERR(TAG,
"context.ClientSysmenu failed with error %" PRIu32
"", error);
1064 static UINT rail_recv_client_syscommand_order(RailServerContext* context,
1069 if (!context || !syscommand || !s)
1070 return ERROR_INVALID_PARAMETER;
1072 if ((error = rail_read_syscommand_order(s, syscommand)))
1074 WLog_ERR(TAG,
"rail_read_syscommand_order failed with error %" PRIu32
"!", error);
1078 IFCALLRET(context->ClientSyscommand, error, context, syscommand);
1081 WLog_ERR(TAG,
"context.ClientSyscommand failed with error %" PRIu32
"", error);
1091 static UINT rail_recv_client_notify_event_order(RailServerContext* context,
1096 if (!context || !notifyEvent || !s)
1097 return ERROR_INVALID_PARAMETER;
1099 if ((error = rail_read_notify_event_order(s, notifyEvent)))
1101 WLog_ERR(TAG,
"rail_read_notify_event_order failed with error %" PRIu32
"!", error);
1105 IFCALLRET(context->ClientNotifyEvent, error, context, notifyEvent);
1108 WLog_ERR(TAG,
"context.ClientNotifyEvent failed with error %" PRIu32
"", error);
1118 static UINT rail_recv_client_window_move_order(RailServerContext* context,
1123 if (!context || !windowMove || !s)
1124 return ERROR_INVALID_PARAMETER;
1126 if ((error = rail_read_window_move_order(s, windowMove)))
1128 WLog_ERR(TAG,
"rail_read_window_move_order failed with error %" PRIu32
"!", error);
1132 IFCALLRET(context->ClientWindowMove, error, context, windowMove);
1135 WLog_ERR(TAG,
"context.ClientWindowMove failed with error %" PRIu32
"", error);
1145 static UINT rail_recv_client_snap_arrange_order(RailServerContext* context,
1150 if (!context || !snapArrange || !s)
1151 return ERROR_INVALID_PARAMETER;
1153 if ((error = rail_read_snap_arange_order(s, snapArrange)))
1155 WLog_ERR(TAG,
"rail_read_snap_arange_order failed with error %" PRIu32
"!", error);
1159 IFCALLRET(context->ClientSnapArrange, error, context, snapArrange);
1162 WLog_ERR(TAG,
"context.ClientSnapArrange failed with error %" PRIu32
"", error);
1172 static UINT rail_recv_client_get_appid_req_order(RailServerContext* context,
1177 if (!context || !getAppidReq || !s)
1178 return ERROR_INVALID_PARAMETER;
1180 if ((error = rail_read_get_appid_req_order(s, getAppidReq)))
1182 WLog_ERR(TAG,
"rail_read_get_appid_req_order failed with error %" PRIu32
"!", error);
1186 IFCALLRET(context->ClientGetAppidReq, error, context, getAppidReq);
1189 WLog_ERR(TAG,
"context.ClientGetAppidReq failed with error %" PRIu32
"", error);
1199 static UINT rail_recv_client_langbar_info_order(RailServerContext* context,
1204 if (!context || !langbarInfo || !s)
1205 return ERROR_INVALID_PARAMETER;
1207 if ((error = rail_read_langbar_info_order(s, langbarInfo)))
1209 WLog_ERR(TAG,
"rail_read_langbar_info_order failed with error %" PRIu32
"!", error);
1213 IFCALLRET(context->ClientLangbarInfo, error, context, langbarInfo);
1216 WLog_ERR(TAG,
"context.ClientLangbarInfo failed with error %" PRIu32
"", error);
1226 static UINT rail_recv_client_language_ime_info_order(RailServerContext* context,
1232 if (!context || !languageImeInfo || !s)
1233 return ERROR_INVALID_PARAMETER;
1235 if ((error = rail_read_language_ime_info_order(s, languageImeInfo)))
1237 WLog_ERR(TAG,
"rail_read_language_ime_info_order failed with error %" PRIu32
"!", error);
1241 IFCALLRET(context->ClientLanguageImeInfo, error, context, languageImeInfo);
1244 WLog_ERR(TAG,
"context.ClientLanguageImeInfo failed with error %" PRIu32
"", error);
1254 static UINT rail_recv_client_compartment_info(RailServerContext* context,
1260 if (!context || !compartmentInfo || !s)
1261 return ERROR_INVALID_PARAMETER;
1263 if ((error = rail_read_compartment_info_order(s, compartmentInfo)))
1265 WLog_ERR(TAG,
"rail_read_compartment_info_order failed with error %" PRIu32
"!", error);
1269 IFCALLRET(context->ClientCompartmentInfo, error, context, compartmentInfo);
1272 WLog_ERR(TAG,
"context.ClientCompartmentInfo failed with error %" PRIu32
"", error);
1282 static UINT rail_recv_client_cloak_order(RailServerContext* context,
RAIL_CLOAK* cloak,
wStream* s)
1286 if (!context || !cloak || !s)
1287 return ERROR_INVALID_PARAMETER;
1289 if ((error = rail_read_cloak_order(s, cloak)))
1291 WLog_ERR(TAG,
"rail_read_cloak_order failed with error %" PRIu32
"!", error);
1295 IFCALLRET(context->ClientCloak, error, context, cloak);
1298 WLog_ERR(TAG,
"context.Cloak failed with error %" PRIu32
"", error);
1303 static UINT rail_recv_client_text_scale_order(RailServerContext* context,
wStream* s)
1305 UINT error = CHANNEL_RC_OK;
1306 UINT32 TextScaleFactor = 0;
1309 return ERROR_INVALID_PARAMETER;
1311 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1312 return ERROR_INVALID_DATA;
1314 Stream_Read_UINT32(s, TextScaleFactor);
1315 IFCALLRET(context->ClientTextScale, error, context, TextScaleFactor);
1318 WLog_ERR(TAG,
"context.TextScale failed with error %" PRIu32
"", error);
1323 static UINT rail_recv_client_caret_blink(RailServerContext* context,
wStream* s)
1325 UINT error = CHANNEL_RC_OK;
1326 UINT32 CaretBlinkRate = 0;
1329 return ERROR_INVALID_PARAMETER;
1331 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1332 return ERROR_INVALID_DATA;
1334 Stream_Read_UINT32(s, CaretBlinkRate);
1335 IFCALLRET(context->ClientCaretBlinkRate, error, context, CaretBlinkRate);
1338 WLog_ERR(TAG,
"context.CaretBlinkRate failed with error %" PRIu32
"", error);
1343 static DWORD WINAPI rail_server_thread(LPVOID arg)
1345 RailServerContext* context = (RailServerContext*)arg;
1346 RailServerPrivate* priv = context->priv;
1350 UINT error = CHANNEL_RC_OK;
1351 events[nCount++] = priv->channelEvent;
1352 events[nCount++] = priv->stopEvent;
1356 status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
1358 if (status == WAIT_FAILED)
1360 error = GetLastError();
1361 WLog_ERR(TAG,
"WaitForMultipleObjects failed with error %" PRIu32
"!", error);
1365 status = WaitForSingleObject(context->priv->stopEvent, 0);
1367 if (status == WAIT_FAILED)
1369 error = GetLastError();
1370 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"!", error);
1374 if (status == WAIT_OBJECT_0)
1377 status = WaitForSingleObject(context->priv->channelEvent, 0);
1379 if (status == WAIT_FAILED)
1381 error = GetLastError();
1384 "WaitForSingleObject(context->priv->channelEvent, 0) failed with error %" PRIu32
1390 if (status == WAIT_OBJECT_0)
1392 if ((error = rail_server_handle_messages(context)))
1394 WLog_ERR(TAG,
"rail_server_handle_messages failed with error %" PRIu32
"", error);
1400 if (error && context->rdpcontext)
1401 setChannelError(context->rdpcontext, error,
"rail_server_thread reported an error");
1412 static UINT rail_server_start(RailServerContext* context)
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);
1421 if (!priv->rail_channel)
1423 WLog_ERR(TAG,
"WTSVirtualChannelOpen failed!");
1427 if (!WTSVirtualChannelQuery(priv->rail_channel, WTSVirtualEventHandle, &buffer,
1429 (bytesReturned !=
sizeof(HANDLE)))
1432 "error during WTSVirtualChannelQuery(WTSVirtualEventHandle) or invalid returned "
1433 "size(%" PRIu32
")",
1437 WTSFreeMemory(buffer);
1442 CopyMemory(&priv->channelEvent, buffer,
sizeof(HANDLE));
1443 WTSFreeMemory(buffer);
1444 context->priv->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1446 if (!context->priv->stopEvent)
1448 WLog_ERR(TAG,
"CreateEvent failed!");
1452 context->priv->thread = CreateThread(NULL, 0, rail_server_thread, (
void*)context, 0, NULL);
1454 if (!context->priv->thread)
1456 WLog_ERR(TAG,
"CreateThread failed!");
1457 goto out_stop_event;
1460 return CHANNEL_RC_OK;
1462 (void)CloseHandle(context->priv->stopEvent);
1463 context->priv->stopEvent = NULL;
1465 (void)WTSVirtualChannelClose(context->priv->rail_channel);
1466 context->priv->rail_channel = NULL;
1470 static BOOL rail_server_stop(RailServerContext* context)
1472 RailServerPrivate* priv = context->priv;
1476 (void)SetEvent(priv->stopEvent);
1478 if (WaitForSingleObject(priv->thread, INFINITE) == WAIT_FAILED)
1480 WLog_ERR(TAG,
"WaitForSingleObject failed with error %" PRIu32
"", GetLastError());
1484 (void)CloseHandle(priv->thread);
1485 (void)CloseHandle(priv->stopEvent);
1486 priv->thread = NULL;
1487 priv->stopEvent = NULL;
1490 if (priv->rail_channel)
1492 (void)WTSVirtualChannelClose(priv->rail_channel);
1493 priv->rail_channel = NULL;
1496 priv->channelEvent = NULL;
1500 RailServerContext* rail_server_context_new(HANDLE vcm)
1502 RailServerContext* context = NULL;
1503 RailServerPrivate* priv = NULL;
1504 context = (RailServerContext*)calloc(1,
sizeof(RailServerContext));
1508 WLog_ERR(TAG,
"calloc failed!");
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));
1532 WLog_ERR(TAG,
"calloc failed!");
1537 priv->input_stream = Stream_New(NULL, 4096);
1539 if (!priv->input_stream)
1541 WLog_ERR(TAG,
"Stream_New failed!");
1547 free(context->priv);
1553 void rail_server_context_free(RailServerContext* context)
1556 Stream_Free(context->priv->input_stream, TRUE);
1558 free(context->priv);
1562 void rail_server_set_handshake_ex_flags(RailServerContext* context, DWORD flags)
1564 RailServerPrivate* priv = NULL;
1566 if (!context || !context->priv)
1569 priv = context->priv;
1570 priv->channelFlags = flags;
1573 UINT rail_server_handle_messages(RailServerContext* context)
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;
1584 if (!Stream_EnsureRemainingCapacity(s, RAIL_PDU_HEADER_LENGTH))
1586 WLog_ERR(TAG,
"Stream_EnsureRemainingCapacity failed, RAIL_PDU_HEADER_LENGTH");
1587 return CHANNEL_RC_NO_MEMORY;
1590 if (!WTSVirtualChannelRead(priv->rail_channel, 0, Stream_Pointer(s), RAIL_PDU_HEADER_LENGTH,
1593 if (GetLastError() == ERROR_NO_DATA)
1594 return ERROR_NO_DATA;
1596 WLog_ERR(TAG,
"channel connection closed");
1597 return ERROR_INTERNAL_ERROR;
1601 if ((status = rail_read_pdu_header(s, &orderType, &orderLength)) != CHANNEL_RC_OK)
1603 WLog_ERR(TAG,
"rail_read_pdu_header failed with error %" PRIu32
"!", status);
1607 if (!Stream_EnsureRemainingCapacity(s, orderLength - RAIL_PDU_HEADER_LENGTH))
1610 "Stream_EnsureRemainingCapacity failed, orderLength - RAIL_PDU_HEADER_LENGTH");
1611 return CHANNEL_RC_NO_MEMORY;
1615 if (!WTSVirtualChannelRead(priv->rail_channel, 0, Stream_Pointer(s),
1616 orderLength - RAIL_PDU_HEADER_LENGTH, &bytesReturned))
1618 if (GetLastError() == ERROR_NO_DATA)
1619 return ERROR_NO_DATA;
1621 WLog_ERR(TAG,
"channel connection closed");
1622 return ERROR_INTERNAL_ERROR;
1625 WLog_DBG(TAG,
"Received %s PDU, length:%" PRIu16
"",
1626 rail_get_order_type_string_full(orderType, buffer,
sizeof(buffer)), orderLength);
1630 case TS_RAIL_ORDER_HANDSHAKE:
1633 return rail_recv_client_handshake_order(context, &handshake, s);
1636 case TS_RAIL_ORDER_CLIENTSTATUS:
1639 return rail_recv_client_client_status_order(context, &clientStatus, s);
1642 case TS_RAIL_ORDER_EXEC:
1643 return rail_recv_client_exec_order(context, s);
1645 case TS_RAIL_ORDER_SYSPARAM:
1648 return rail_recv_client_sysparam_order(context, &sysparam, s);
1651 case TS_RAIL_ORDER_ACTIVATE:
1654 return rail_recv_client_activate_order(context, &activate, s);
1657 case TS_RAIL_ORDER_SYSMENU:
1660 return rail_recv_client_sysmenu_order(context, &sysmenu, s);
1663 case TS_RAIL_ORDER_SYSCOMMAND:
1666 return rail_recv_client_syscommand_order(context, &syscommand, s);
1669 case TS_RAIL_ORDER_NOTIFY_EVENT:
1672 return rail_recv_client_notify_event_order(context, ¬ifyEvent, s);
1675 case TS_RAIL_ORDER_WINDOWMOVE:
1678 return rail_recv_client_window_move_order(context, &windowMove, s);
1681 case TS_RAIL_ORDER_SNAP_ARRANGE:
1684 return rail_recv_client_snap_arrange_order(context, &snapArrange, s);
1687 case TS_RAIL_ORDER_GET_APPID_REQ:
1690 return rail_recv_client_get_appid_req_order(context, &getAppidReq, s);
1693 case TS_RAIL_ORDER_LANGBARINFO:
1696 return rail_recv_client_langbar_info_order(context, &langbarInfo, s);
1699 case TS_RAIL_ORDER_LANGUAGEIMEINFO:
1702 return rail_recv_client_language_ime_info_order(context, &languageImeInfo, s);
1705 case TS_RAIL_ORDER_COMPARTMENTINFO:
1708 return rail_recv_client_compartment_info(context, &compartmentInfo, s);
1711 case TS_RAIL_ORDER_CLOAK:
1714 return rail_recv_client_cloak_order(context, &cloak, s);
1717 case TS_RAIL_ORDER_TEXTSCALEINFO:
1719 return rail_recv_client_text_scale_order(context, s);
1722 case TS_RAIL_ORDER_CARETBLINKINFO:
1724 return rail_recv_client_caret_blink(context, s);
1728 WLog_ERR(TAG,
"Unknown RAIL PDU order received.");
1729 return ERROR_INVALID_DATA;