FreeRDP
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 
41 static 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 
64 static 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 
86 static 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_UINT16(s, localMoveSize->posX); /* PosX (2 bytes) */
96  Stream_Write_UINT16(s, localMoveSize->posY); /* PosY (2 bytes) */
97  return ERROR_SUCCESS;
98 }
99 
105 static 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 
127 static 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 
143 static 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 
157 static 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 
180 static 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 
194 static 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 
209 static UINT
210 rail_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 
225 static 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 
243 static 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 
265 static 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 
293 static 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 
323 static 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 
359 static 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 
387 static 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 
415 static 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 
443 static 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 
471 static 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 
499 static 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 
527 static 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 
554 static UINT
555 rail_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 
583 static 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 
611 static 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 
639 static 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 
653 static 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;
695 fail:
696  free(args[0]);
697  free(args[1]);
698  free(args[2]);
699  *exec = order;
700  return ERROR_INTERNAL_ERROR;
701 }
702 
708 static 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 
726 static 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 
742 static 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 
757 static 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 
773 static 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 
787 static 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 
805 static 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 
823 static 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 
837 static 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 
859 static 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 
877 static 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 
895 static 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 
922 static 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 
949 static 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 
981 static 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 
1010 static 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 
1037 static 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 
1064 static 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 
1091 static 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 
1118 static 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 
1145 static 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 
1172 static 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 
1199 static 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 
1226 static 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 
1254 static 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 
1282 static 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 
1303 static 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 
1323 static 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 
1343 static 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 
1412 static 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  CopyMemory(&priv->channelEvent, buffer, sizeof(HANDLE));
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;
1461 out_stop_event:
1462  (void)CloseHandle(context->priv->stopEvent);
1463  context->priv->stopEvent = NULL;
1464 out_close:
1465  (void)WTSVirtualChannelClose(context->priv->rail_channel);
1466  context->priv->rail_channel = NULL;
1467  return error;
1468 }
1469 
1470 static 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 
1500 RailServerContext* 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;
1546 out_free_priv:
1547  free(context->priv);
1548 out_free:
1549  free(context);
1550  return NULL;
1551 }
1552 
1553 void 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 
1562 void 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 
1573 UINT 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 }