21#include <freerdp/types.h> 
   22#include <freerdp/constants.h> 
   24#include <freerdp/freerdp.h> 
   25#include <freerdp/channels/log.h> 
   28#include <winpr/synch.h> 
   29#include <winpr/thread.h> 
   30#include <winpr/stream.h> 
   34#define TAG CHANNELS_TAG("rail.server") 
   41static 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;
 
   64static 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);
 
   86static 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_INT16(s, localMoveSize->posX);                     
 
   96  Stream_Write_INT16(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;
 
  210rail_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;
 
  225static 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;
 
  243static 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;
 
  265static 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);
 
  293static 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);
 
  323static 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);
 
  359static 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);
 
  387static 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);
 
  415static 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);
 
  443static 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);
 
  471static 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);
 
  499static 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);
 
  527static 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);
 
  555rail_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);
 
  583static 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);
 
  611static 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;
 
  837static 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;
 
  859static 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;
 
  895static 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);
 
  922static 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);
 
  949static 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);
 
  981static 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);
 
 1010static 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);
 
 1037static 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);
 
 1064static 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);
 
 1091static 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);
 
 1118static 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);
 
 1145static 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);
 
 1172static 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);
 
 1199static 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);
 
 1226static 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);
 
 1254static 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);
 
 1282static 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);
 
 1303static 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);
 
 1323static 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);
 
 1343static 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");
 
 1412static 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  priv->channelEvent = *(HANDLE*)buffer;
 
 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;
 
 1470static 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;
 
 1500RailServerContext* 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);
 
 1553void rail_server_context_free(RailServerContext* context)
 
 1556    Stream_Free(context->priv->input_stream, TRUE);
 
 1558  free(context->priv);
 
 1562void 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;
 
 1573UINT 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;