25#include <freerdp/config.h> 
   28#include <winpr/cast.h> 
   30#include <freerdp/channels/log.h> 
   31#include <freerdp/freerdp.h> 
   33#include "rail_orders.h" 
   35static BOOL rail_is_feature_supported(
const rdpContext* context, UINT32 featureMask);
 
   44  char buffer[128] = { 0 };
 
   45  UINT16 orderLength = 0;
 
   50    return ERROR_INVALID_PARAMETER;
 
   53  orderLength = (UINT16)Stream_GetPosition(s);
 
   54  Stream_SetPosition(s, 0);
 
   55  rail_write_pdu_header(s, orderType, orderLength);
 
   56  Stream_SetPosition(s, orderLength);
 
   57  WLog_Print(rail->log, WLOG_DEBUG, 
"Sending %s PDU, length: %" PRIu16 
"",
 
   58             rail_get_order_type_string_full(orderType, buffer, 
sizeof(buffer)), orderLength);
 
   59  return rail_send_channel_data(rail, s);
 
   69  if (!s || !execResult)
 
   70    return ERROR_INVALID_PARAMETER;
 
   72  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_EXEC_RESULT_ORDER_LENGTH))
 
   73    return ERROR_INVALID_DATA;
 
   75  Stream_Read_UINT16(s, execResult->flags);      
 
   76  Stream_Read_UINT16(s, execResult->execResult); 
 
   77  Stream_Read_UINT32(s, execResult->rawResult);  
 
   78  Stream_Seek_UINT16(s);                         
 
   79  return rail_read_unicode_string(s, &execResult->exeOrFile)
 
   81             : ERROR_INTERNAL_ERROR; 
 
   91  if (!s || !minmaxinfo)
 
   92    return ERROR_INVALID_PARAMETER;
 
   94  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_MINMAXINFO_ORDER_LENGTH))
 
   95    return ERROR_INVALID_DATA;
 
   97  Stream_Read_UINT32(s, minmaxinfo->windowId);      
 
   98  Stream_Read_INT16(s, minmaxinfo->maxWidth);       
 
   99  Stream_Read_INT16(s, minmaxinfo->maxHeight);      
 
  100  Stream_Read_INT16(s, minmaxinfo->maxPosX);        
 
  101  Stream_Read_INT16(s, minmaxinfo->maxPosY);        
 
  102  Stream_Read_INT16(s, minmaxinfo->minTrackWidth);  
 
  103  Stream_Read_INT16(s, minmaxinfo->minTrackHeight); 
 
  104  Stream_Read_INT16(s, minmaxinfo->maxTrackWidth);  
 
  105  Stream_Read_INT16(s, minmaxinfo->maxTrackHeight); 
 
  106  return CHANNEL_RC_OK;
 
  114static UINT rail_read_server_localmovesize_order(
wStream* s,
 
  117  UINT16 isMoveSizeStart = 0;
 
  119  if (!s || !localMoveSize)
 
  120    return ERROR_INVALID_PARAMETER;
 
  122  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_LOCALMOVESIZE_ORDER_LENGTH))
 
  123    return ERROR_INVALID_DATA;
 
  125  Stream_Read_UINT32(s, localMoveSize->windowId); 
 
  126  Stream_Read_UINT16(s, isMoveSizeStart);         
 
  127  localMoveSize->isMoveSizeStart = (isMoveSizeStart != 0) ? TRUE : FALSE;
 
  128  Stream_Read_UINT16(s, localMoveSize->moveSizeType); 
 
  129  Stream_Read_INT16(s, localMoveSize->posX);          
 
  130  Stream_Read_INT16(s, localMoveSize->posY);          
 
  131  return CHANNEL_RC_OK;
 
  139static UINT rail_read_server_get_appid_resp_order(
wStream* s,
 
  142  if (!s || !getAppidResp)
 
  143    return ERROR_INVALID_PARAMETER;
 
  145  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_GET_APPID_RESP_ORDER_LENGTH))
 
  146    return ERROR_INVALID_DATA;
 
  148  Stream_Read_UINT32(s, getAppidResp->windowId); 
 
  149  Stream_Read_UTF16_String(
 
  150      s, getAppidResp->applicationId,
 
  151      ARRAYSIZE(getAppidResp->applicationId)); 
 
  152  return CHANNEL_RC_OK;
 
  162  if (!s || !langbarInfo)
 
  163    return ERROR_INVALID_PARAMETER;
 
  165  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_LANGBAR_INFO_ORDER_LENGTH))
 
  166    return ERROR_INVALID_DATA;
 
  168  Stream_Read_UINT32(s, langbarInfo->languageBarStatus); 
 
  169  return CHANNEL_RC_OK;
 
  174  if (!s || !clientStatus)
 
  175    return ERROR_INVALID_PARAMETER;
 
  177  Stream_Write_UINT32(s, clientStatus->flags); 
 
  178  return ERROR_SUCCESS;
 
  186static UINT rail_write_client_exec_order(
wStream* s, UINT16 flags,
 
  193  if (!s || !exeOrFile || !workingDir || !arguments)
 
  194    return ERROR_INVALID_PARAMETER;
 
  198  if ((exeOrFile->length > 520) || (workingDir->length > 520) || (arguments->length > 16000))
 
  201             "TS_RAIL_ORDER_EXEC argument limits exceeded: ExeOrFile=%" PRIu16
 
  202             " [max=520], WorkingDir=%" PRIu16 
" [max=520], Arguments=%" PRIu16 
" [max=16000]",
 
  203             exeOrFile->length, workingDir->length, arguments->length);
 
  204    return ERROR_BAD_ARGUMENTS;
 
  207  Stream_Write_UINT16(s, flags);              
 
  208  Stream_Write_UINT16(s, exeOrFile->length);  
 
  209  Stream_Write_UINT16(s, workingDir->length); 
 
  210  Stream_Write_UINT16(s, arguments->length);  
 
  212  if ((error = rail_write_unicode_string_value(s, exeOrFile)))
 
  214    WLog_ERR(TAG, 
"rail_write_unicode_string_value failed with error %" PRIu32 
"", error);
 
  218  if ((error = rail_write_unicode_string_value(s, workingDir)))
 
  220    WLog_ERR(TAG, 
"rail_write_unicode_string_value failed with error %" PRIu32 
"", error);
 
  224  if ((error = rail_write_unicode_string_value(s, arguments)))
 
  226    WLog_ERR(TAG, 
"rail_write_unicode_string_value failed with error %" PRIu32 
"", error);
 
  238    return ERROR_INVALID_PARAMETER;
 
  240  Stream_Write_UINT32(s, activate->windowId); 
 
  241  enabled = activate->enabled ? 1 : 0;
 
  242  Stream_Write_UINT8(s, enabled); 
 
  243  return ERROR_SUCCESS;
 
  249    return ERROR_INVALID_PARAMETER;
 
  251  Stream_Write_UINT32(s, sysmenu->windowId); 
 
  252  Stream_Write_INT16(s, sysmenu->left);      
 
  253  Stream_Write_INT16(s, sysmenu->top);       
 
  254  return ERROR_SUCCESS;
 
  259  if (!s || !syscommand)
 
  260    return ERROR_INVALID_PARAMETER;
 
  262  Stream_Write_UINT32(s, syscommand->windowId); 
 
  263  Stream_Write_UINT16(s, syscommand->command);  
 
  264  return ERROR_SUCCESS;
 
  267static UINT rail_write_client_notify_event_order(
wStream* s,
 
  270  if (!s || !notifyEvent)
 
  271    return ERROR_INVALID_PARAMETER;
 
  273  Stream_Write_UINT32(s, notifyEvent->windowId);     
 
  274  Stream_Write_UINT32(s, notifyEvent->notifyIconId); 
 
  275  Stream_Write_UINT32(s, notifyEvent->message);      
 
  276  return ERROR_SUCCESS;
 
  279static UINT rail_write_client_window_move_order(
wStream* s,
 
  282  if (!s || !windowMove)
 
  283    return ERROR_INVALID_PARAMETER;
 
  285  Stream_Write_UINT32(s, windowMove->windowId); 
 
  286  Stream_Write_INT16(s, windowMove->left);      
 
  287  Stream_Write_INT16(s, windowMove->top);       
 
  288  Stream_Write_INT16(s, windowMove->right);     
 
  289  Stream_Write_INT16(s, windowMove->bottom);    
 
  290  return ERROR_SUCCESS;
 
  293static UINT rail_write_client_get_appid_req_order(
wStream* s,
 
  296  if (!s || !getAppidReq)
 
  297    return ERROR_INVALID_PARAMETER;
 
  299  Stream_Write_UINT32(s, getAppidReq->windowId); 
 
  300  return ERROR_SUCCESS;
 
  305  if (!s || !langbarInfo)
 
  306    return ERROR_INVALID_PARAMETER;
 
  308  Stream_Write_UINT32(s, langbarInfo->languageBarStatus); 
 
  309  return ERROR_SUCCESS;
 
  312static UINT rail_write_languageime_info_order(
wStream* s,
 
  315  if (!s || !langImeInfo)
 
  316    return ERROR_INVALID_PARAMETER;
 
  318  Stream_Write_UINT32(s, langImeInfo->ProfileType);
 
  319  Stream_Write_UINT16(s, WINPR_ASSERTING_INT_CAST(UINT16, langImeInfo->LanguageID));
 
  320  Stream_Write(s, &langImeInfo->LanguageProfileCLSID, 
sizeof(langImeInfo->LanguageProfileCLSID));
 
  321  Stream_Write(s, &langImeInfo->ProfileGUID, 
sizeof(langImeInfo->ProfileGUID));
 
  322  Stream_Write_UINT32(s, langImeInfo->KeyboardLayout);
 
  323  return ERROR_SUCCESS;
 
  326static UINT rail_write_compartment_info_order(
wStream* s,
 
  329  if (!s || !compartmentInfo)
 
  330    return ERROR_INVALID_PARAMETER;
 
  332  Stream_Write_UINT32(s, compartmentInfo->ImeState);
 
  333  Stream_Write_UINT32(s, compartmentInfo->ImeConvMode);
 
  334  Stream_Write_UINT32(s, compartmentInfo->ImeSentenceMode);
 
  335  Stream_Write_UINT32(s, compartmentInfo->KanaMode);
 
  336  return ERROR_SUCCESS;
 
  346  RailClientContext* context = rail_get_client_interface(rail);
 
  351    return ERROR_INVALID_PARAMETER;
 
  353  if ((error = rail_read_handshake_order(s, &serverHandshake)))
 
  355    WLog_ERR(TAG, 
"rail_read_handshake_order failed with error %" PRIu32 
"!", error);
 
  359  rail->channelBuildNumber = serverHandshake.buildNumber;
 
  361  if (rail->sendHandshake)
 
  364    clientHandshake.buildNumber = 0x00001DB0;
 
  365    error = context->ClientHandshake(context, &clientHandshake);
 
  368  if (error != CHANNEL_RC_OK)
 
  373    IFCALLRET(context->ServerHandshake, error, context, &serverHandshake);
 
  376      WLog_ERR(TAG, 
"context.ServerHandshake failed with error %" PRIu32 
"", error);
 
  382static UINT rail_read_compartment_info_order(
wStream* s,
 
  385  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_COMPARTMENT_INFO_ORDER_LENGTH))
 
  386    return ERROR_INVALID_DATA;
 
  388  Stream_Read_UINT32(s, compartmentInfo->ImeState);        
 
  389  Stream_Read_UINT32(s, compartmentInfo->ImeConvMode);     
 
  390  Stream_Read_UINT32(s, compartmentInfo->ImeSentenceMode); 
 
  391  Stream_Read_UINT32(s, compartmentInfo->KanaMode);        
 
  392  return CHANNEL_RC_OK;
 
  397  RailClientContext* context = rail_get_client_interface(rail);
 
  402    return ERROR_INVALID_PARAMETER;
 
  404  if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED))
 
  405    return ERROR_BAD_CONFIGURATION;
 
  407  if ((error = rail_read_compartment_info_order(s, &pdu)))
 
  412    IFCALLRET(context->ClientCompartmentInfo, error, context, &pdu);
 
  415      WLog_ERR(TAG, 
"context.ClientCompartmentInfo failed with error %" PRIu32 
"", error);
 
  421BOOL rail_is_feature_supported(
const rdpContext* context, UINT32 featureMask)
 
  423  UINT32 supported = 0;
 
  426  if (!context || !context->settings)
 
  433  supported = level & mask;
 
  434  masked = (supported & featureMask);
 
  436  if (masked != featureMask)
 
  438    char maskstr[256] = { 0 };
 
  439    char actualstr[256] = { 0 };
 
  441    WLog_WARN(TAG, 
"have %s, require %s",
 
  457  RailClientContext* context = rail_get_client_interface(rail);
 
  461  if (!rail || !context || !s)
 
  462    return ERROR_INVALID_PARAMETER;
 
  464  if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED))
 
  465    return ERROR_BAD_CONFIGURATION;
 
  467  if ((error = rail_read_handshake_ex_order(s, &serverHandshake)))
 
  469    WLog_ERR(TAG, 
"rail_read_handshake_ex_order failed with error %" PRIu32 
"!", error);
 
  473  rail->channelBuildNumber = serverHandshake.buildNumber;
 
  474  rail->channelFlags = serverHandshake.railHandshakeFlags;
 
  477    char buffer[192] = { 0 };
 
  478    WLog_DBG(TAG, 
"HandshakeFlags=%s [buildNumber=0x%08" PRIx32 
"]",
 
  479             rail_handshake_ex_flags_to_string(rail->channelFlags, buffer, 
sizeof(buffer)),
 
  480             rail->channelBuildNumber);
 
  483  if (rail->sendHandshake)
 
  486    clientHandshake.buildNumber = 0x00001DB0;
 
  489    error = context->ClientHandshake(context, &clientHandshake);
 
  492  if (error != CHANNEL_RC_OK)
 
  497    IFCALLRET(context->ServerHandshakeEx, error, context, &serverHandshake);
 
  500      WLog_ERR(TAG, 
"context.ServerHandshakeEx failed with error %" PRIu32 
"", error);
 
  513  RailClientContext* context = rail_get_client_interface(rail);
 
  518    return ERROR_INVALID_PARAMETER;
 
  520  if ((error = rail_read_server_exec_result_order(s, &execResult)))
 
  522    WLog_ERR(TAG, 
"rail_read_server_exec_result_order failed with error %" PRIu32 
"!", error);
 
  528    IFCALLRET(context->ServerExecuteResult, error, context, &execResult);
 
  531      WLog_ERR(TAG, 
"context.ServerExecuteResult failed with error %" PRIu32 
"", error);
 
  535  free(execResult.exeOrFile.string);
 
  546  RailClientContext* context = rail_get_client_interface(rail);
 
  549  BOOL extendedSpiSupported = 0;
 
  552    return ERROR_INVALID_PARAMETER;
 
  554  extendedSpiSupported = rail_is_extended_spi_supported(rail->channelFlags);
 
  555  if ((error = rail_read_sysparam_order(s, &sysparam, extendedSpiSupported)))
 
  557    WLog_ERR(TAG, 
"rail_read_sysparam_order failed with error %" PRIu32 
"!", error);
 
  563    IFCALLRET(context->ServerSystemParam, error, context, &sysparam);
 
  566      WLog_ERR(TAG, 
"context.ServerSystemParam failed with error %" PRIu32 
"", error);
 
  579  RailClientContext* context = rail_get_client_interface(rail);
 
  584    return ERROR_INVALID_PARAMETER;
 
  586  if ((error = rail_read_server_minmaxinfo_order(s, &minMaxInfo)))
 
  588    WLog_ERR(TAG, 
"rail_read_server_minmaxinfo_order failed with error %" PRIu32 
"!", error);
 
  594    IFCALLRET(context->ServerMinMaxInfo, error, context, &minMaxInfo);
 
  597      WLog_ERR(TAG, 
"context.ServerMinMaxInfo failed with error %" PRIu32 
"", error);
 
  610  RailClientContext* context = rail_get_client_interface(rail);
 
  615    return ERROR_INVALID_PARAMETER;
 
  617  if ((error = rail_read_server_localmovesize_order(s, &localMoveSize)))
 
  619    WLog_ERR(TAG, 
"rail_read_server_localmovesize_order failed with error %" PRIu32 
"!", error);
 
  625    IFCALLRET(context->ServerLocalMoveSize, error, context, &localMoveSize);
 
  628      WLog_ERR(TAG, 
"context.ServerLocalMoveSize failed with error %" PRIu32 
"", error);
 
  641  RailClientContext* context = rail_get_client_interface(rail);
 
  646    return ERROR_INVALID_PARAMETER;
 
  648  if ((error = rail_read_server_get_appid_resp_order(s, &getAppIdResp)))
 
  650    WLog_ERR(TAG, 
"rail_read_server_get_appid_resp_order failed with error %" PRIu32 
"!",
 
  657    IFCALLRET(context->ServerGetAppIdResponse, error, context, &getAppIdResp);
 
  660      WLog_ERR(TAG, 
"context.ServerGetAppIdResponse failed with error %" PRIu32 
"", error);
 
  673  RailClientContext* context = rail_get_client_interface(rail);
 
  678    return ERROR_INVALID_PARAMETER;
 
  680  if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED))
 
  681    return ERROR_BAD_CONFIGURATION;
 
  683  if ((error = rail_read_langbar_info_order(s, &langBarInfo)))
 
  685    WLog_ERR(TAG, 
"rail_read_langbar_info_order failed with error %" PRIu32 
"!", error);
 
  691    IFCALLRET(context->ServerLanguageBarInfo, error, context, &langBarInfo);
 
  694      WLog_ERR(TAG, 
"context.ServerLanguageBarInfo failed with error %" PRIu32 
"", error);
 
  702  if (!s || !taskbarInfo)
 
  703    return ERROR_INVALID_PARAMETER;
 
  705  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_TASKBAR_INFO_ORDER_LENGTH))
 
  706    return ERROR_INVALID_DATA;
 
  708  Stream_Read_UINT32(s, taskbarInfo->TaskbarMessage);
 
  709  Stream_Read_UINT32(s, taskbarInfo->WindowIdTab);
 
  710  Stream_Read_UINT32(s, taskbarInfo->Body);
 
  711  return CHANNEL_RC_OK;
 
  716  RailClientContext* context = rail_get_client_interface(rail);
 
  721    return ERROR_INVALID_PARAMETER;
 
  725  if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED))
 
  726    return ERROR_BAD_CONFIGURATION;
 
  728  if ((error = rail_read_taskbar_info_order(s, &taskBarInfo)))
 
  730    WLog_ERR(TAG, 
"rail_read_langbar_info_order failed with error %" PRIu32 
"!", error);
 
  736    IFCALLRET(context->ServerTaskBarInfo, error, context, &taskBarInfo);
 
  739      WLog_ERR(TAG, 
"context.ServerTaskBarInfo failed with error %" PRIu32 
"", error);
 
  748    return ERROR_INVALID_PARAMETER;
 
  750  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_Z_ORDER_SYNC_ORDER_LENGTH))
 
  751    return ERROR_INVALID_DATA;
 
  753  Stream_Read_UINT32(s, zorder->windowIdMarker);
 
  754  return CHANNEL_RC_OK;
 
  759  RailClientContext* context = rail_get_client_interface(rail);
 
  764    return ERROR_INVALID_PARAMETER;
 
  766  if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_ZORDER_SYNC) == 0)
 
  767    return ERROR_INVALID_DATA;
 
  769  if ((error = rail_read_zorder_sync_order(s, &zorder)))
 
  771    WLog_ERR(TAG, 
"rail_read_zorder_sync_order failed with error %" PRIu32 
"!", error);
 
  777    IFCALLRET(context->ServerZOrderSync, error, context, &zorder);
 
  780      WLog_ERR(TAG, 
"context.ServerZOrderSync failed with error %" PRIu32 
"", error);
 
  790  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_CLOAK_ORDER_LENGTH))
 
  791    return ERROR_INVALID_DATA;
 
  793  Stream_Read_UINT32(s, cloak->windowId); 
 
  794  Stream_Read_UINT8(s, cloaked);          
 
  795  cloak->cloak = (cloaked != 0) ? TRUE : FALSE;
 
  796  return CHANNEL_RC_OK;
 
  801  RailClientContext* context = rail_get_client_interface(rail);
 
  806    return ERROR_INVALID_PARAMETER;
 
  810  if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_BIDIRECTIONAL_CLOAK_SUPPORTED) == 0)
 
  811    return ERROR_INVALID_DATA;
 
  813  if ((error = rail_read_cloak_order(s, &cloak)))
 
  815    WLog_ERR(TAG, 
"rail_read_zorder_sync_order failed with error %" PRIu32 
"!", error);
 
  821    IFCALLRET(context->ServerCloak, error, context, &cloak);
 
  824      WLog_ERR(TAG, 
"context.ServerZOrderSync failed with error %" PRIu32 
"", error);
 
  835    return ERROR_INVALID_PARAMETER;
 
  837  if (!Stream_CheckAndLogRequiredLength(TAG, s, RAIL_POWER_DISPLAY_REQUEST_ORDER_LENGTH))
 
  838    return ERROR_INVALID_DATA;
 
  840  Stream_Read_UINT32(s, active);
 
  841  power->active = active != 0;
 
  842  return CHANNEL_RC_OK;
 
  847  RailClientContext* context = rail_get_client_interface(rail);
 
  852    return ERROR_INVALID_PARAMETER;
 
  856  if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED) == 0)
 
  857    return ERROR_INVALID_DATA;
 
  859  if ((error = rail_read_power_display_request_order(s, &power)))
 
  861    WLog_ERR(TAG, 
"rail_read_zorder_sync_order failed with error %" PRIu32 
"!", error);
 
  867    IFCALLRET(context->ServerPowerDisplayRequest, error, context, &power);
 
  870      WLog_ERR(TAG, 
"context.ServerPowerDisplayRequest failed with error %" PRIu32 
"", error);
 
  876static UINT rail_read_get_application_id_extended_response_order(
wStream* s,
 
  880    return ERROR_INVALID_PARAMETER;
 
  882  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  883    return ERROR_INVALID_DATA;
 
  885  Stream_Read_UINT32(s, id->windowID);
 
  887  if (!Stream_Read_UTF16_String(s, id->applicationID, ARRAYSIZE(id->applicationID)))
 
  888    return ERROR_INVALID_DATA;
 
  890  if (_wcsnlen(id->applicationID, ARRAYSIZE(id->applicationID)) >= ARRAYSIZE(id->applicationID))
 
  891    return ERROR_INVALID_DATA;
 
  893  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  894    return ERROR_INVALID_DATA;
 
  896  Stream_Read_UINT32(s, id->processId);
 
  898  if (!Stream_Read_UTF16_String(s, id->processImageName, ARRAYSIZE(id->processImageName)))
 
  899    return ERROR_INVALID_DATA;
 
  901  if (_wcsnlen(id->applicationID, ARRAYSIZE(id->processImageName)) >=
 
  902      ARRAYSIZE(id->processImageName))
 
  903    return ERROR_INVALID_DATA;
 
  905  return CHANNEL_RC_OK;
 
  908static UINT rail_recv_get_application_id_extended_response_order(
railPlugin* rail, 
wStream* s)
 
  910  RailClientContext* context = rail_get_client_interface(rail);
 
  915    return ERROR_INVALID_PARAMETER;
 
  917  if ((error = rail_read_get_application_id_extended_response_order(s, &
id)))
 
  920             "rail_read_get_application_id_extended_response_order failed with error %" PRIu32
 
  928    IFCALLRET(context->ServerGetAppidResponseExtended, error, context, &
id);
 
  931      WLog_ERR(TAG, 
"context.ServerGetAppidResponseExtended failed with error %" PRIu32 
"",
 
  938static UINT rail_read_textscaleinfo_order(
wStream* s, UINT32* pTextScaleFactor)
 
  940  WINPR_ASSERT(pTextScaleFactor);
 
  942  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  943    return ERROR_INVALID_DATA;
 
  945  Stream_Read_UINT32(s, *pTextScaleFactor);
 
  946  return CHANNEL_RC_OK;
 
  951  RailClientContext* context = rail_get_client_interface(rail);
 
  952  UINT32 TextScaleFactor = 0;
 
  956    return ERROR_INVALID_PARAMETER;
 
  958  if ((error = rail_read_textscaleinfo_order(s, &TextScaleFactor)))
 
  963    IFCALLRET(context->ClientTextScale, error, context, TextScaleFactor);
 
  966      WLog_ERR(TAG, 
"context.ClientTextScale failed with error %" PRIu32 
"", error);
 
  972static UINT rail_read_caretblinkinfo_order(
wStream* s, UINT32* pCaretBlinkRate)
 
  974  WINPR_ASSERT(pCaretBlinkRate);
 
  976  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  977    return ERROR_INVALID_DATA;
 
  979  Stream_Read_UINT32(s, *pCaretBlinkRate);
 
  980  return CHANNEL_RC_OK;
 
  985  RailClientContext* context = rail_get_client_interface(rail);
 
  986  UINT32 CaretBlinkRate = 0;
 
  990    return ERROR_INVALID_PARAMETER;
 
  991  if ((error = rail_read_caretblinkinfo_order(s, &CaretBlinkRate)))
 
  996    IFCALLRET(context->ClientCaretBlinkRate, error, context, CaretBlinkRate);
 
  999      WLog_ERR(TAG, 
"context.ClientCaretBlinkRate failed with error %" PRIu32 
"", error);
 
 1010UINT rail_order_recv(LPVOID userdata, 
wStream* s)
 
 1012  char buffer[128] = { 0 };
 
 1014  UINT16 orderType = 0;
 
 1015  UINT16 orderLength = 0;
 
 1016  UINT error = CHANNEL_RC_OK;
 
 1019    return ERROR_INVALID_PARAMETER;
 
 1021  if ((error = rail_read_pdu_header(s, &orderType, &orderLength)))
 
 1023    WLog_ERR(TAG, 
"rail_read_pdu_header failed with error %" PRIu32 
"!", error);
 
 1027  WLog_Print(rail->log, WLOG_DEBUG, 
"Received %s PDU, length:%" PRIu16 
"",
 
 1028             rail_get_order_type_string_full(orderType, buffer, 
sizeof(buffer)), orderLength);
 
 1032    case TS_RAIL_ORDER_HANDSHAKE:
 
 1033      error = rail_recv_handshake_order(rail, s);
 
 1036    case TS_RAIL_ORDER_COMPARTMENTINFO:
 
 1037      error = rail_recv_compartmentinfo_order(rail, s);
 
 1040    case TS_RAIL_ORDER_HANDSHAKE_EX:
 
 1041      error = rail_recv_handshake_ex_order(rail, s);
 
 1044    case TS_RAIL_ORDER_EXEC_RESULT:
 
 1045      error = rail_recv_exec_result_order(rail, s);
 
 1048    case TS_RAIL_ORDER_SYSPARAM:
 
 1049      error = rail_recv_server_sysparam_order(rail, s);
 
 1052    case TS_RAIL_ORDER_MINMAXINFO:
 
 1053      error = rail_recv_server_minmaxinfo_order(rail, s);
 
 1056    case TS_RAIL_ORDER_LOCALMOVESIZE:
 
 1057      error = rail_recv_server_localmovesize_order(rail, s);
 
 1060    case TS_RAIL_ORDER_GET_APPID_RESP:
 
 1061      error = rail_recv_server_get_appid_resp_order(rail, s);
 
 1064    case TS_RAIL_ORDER_LANGBARINFO:
 
 1065      error = rail_recv_langbar_info_order(rail, s);
 
 1068    case TS_RAIL_ORDER_TASKBARINFO:
 
 1069      error = rail_recv_taskbar_info_order(rail, s);
 
 1072    case TS_RAIL_ORDER_ZORDER_SYNC:
 
 1073      error = rail_recv_zorder_sync_order(rail, s);
 
 1076    case TS_RAIL_ORDER_CLOAK:
 
 1077      error = rail_recv_cloak_order(rail, s);
 
 1080    case TS_RAIL_ORDER_POWER_DISPLAY_REQUEST:
 
 1081      error = rail_recv_power_display_request_order(rail, s);
 
 1084    case TS_RAIL_ORDER_GET_APPID_RESP_EX:
 
 1085      error = rail_recv_get_application_id_extended_response_order(rail, s);
 
 1088    case TS_RAIL_ORDER_TEXTSCALEINFO:
 
 1089      error = rail_recv_textscaleinfo_order(rail, s);
 
 1092    case TS_RAIL_ORDER_CARETBLINKINFO:
 
 1093      error = rail_recv_caretblinkinfo_order(rail, s);
 
 1097      WLog_ERR(TAG, 
"Unknown RAIL PDU %s received.",
 
 1098               rail_get_order_type_string_full(orderType, buffer, 
sizeof(buffer)));
 
 1099      return ERROR_INVALID_DATA;
 
 1102  if (error != CHANNEL_RC_OK)
 
 1104    char ebuffer[128] = { 0 };
 
 1105    WLog_Print(rail->log, WLOG_ERROR, 
"Failed to process rail %s PDU, length:%" PRIu16 
"",
 
 1106               rail_get_order_type_string_full(orderType, ebuffer, 
sizeof(ebuffer)),
 
 1110  Stream_Free(s, TRUE);
 
 1121  if (!rail || !handshake)
 
 1122    return ERROR_INVALID_PARAMETER;
 
 1124  wStream* s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH);
 
 1128    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1129    return CHANNEL_RC_NO_MEMORY;
 
 1132  rail_write_handshake_order(s, handshake);
 
 1133  return rail_send_pdu(rail, s, TS_RAIL_ORDER_HANDSHAKE);
 
 1143  if (!rail || !handshakeEx)
 
 1144    return ERROR_INVALID_PARAMETER;
 
 1146  wStream* s = rail_pdu_init(RAIL_HANDSHAKE_EX_ORDER_LENGTH);
 
 1150    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1151    return CHANNEL_RC_NO_MEMORY;
 
 1154  rail_write_handshake_ex_order(s, handshakeEx);
 
 1155  return rail_send_pdu(rail, s, TS_RAIL_ORDER_HANDSHAKE_EX);
 
 1168  if (!rail || !clientStatus)
 
 1169    return ERROR_INVALID_PARAMETER;
 
 1171  rail->clientStatus = *clientStatus;
 
 1172  s = rail_pdu_init(RAIL_CLIENT_STATUS_ORDER_LENGTH);
 
 1176    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1177    return CHANNEL_RC_NO_MEMORY;
 
 1180  error = rail_write_client_status_order(s, clientStatus);
 
 1182  if (ERROR_SUCCESS != error)
 
 1185    Stream_Free(s, TRUE);
 
 1189  return rail_send_pdu(rail, s, TS_RAIL_ORDER_CLIENTSTATUS);
 
 1197UINT rail_send_client_exec_order(
railPlugin* rail, UINT16 flags,
 
 1206  if (!rail || !exeOrFile || !workingDir || !arguments)
 
 1207    return ERROR_INVALID_PARAMETER;
 
 1209  length = RAIL_EXEC_ORDER_LENGTH + exeOrFile->length + workingDir->length + arguments->length;
 
 1210  s = rail_pdu_init(length);
 
 1214    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1215    return CHANNEL_RC_NO_MEMORY;
 
 1218  if ((error = rail_write_client_exec_order(s, flags, exeOrFile, workingDir, arguments)))
 
 1220    WLog_ERR(TAG, 
"rail_write_client_exec_order failed with error %" PRIu32 
"!", error);
 
 1224  return rail_send_pdu(rail, s, TS_RAIL_ORDER_EXEC);
 
 1227  Stream_Free(s, TRUE);
 
 1241  if (!rail || !activate)
 
 1242    return ERROR_INVALID_PARAMETER;
 
 1244  s = rail_pdu_init(RAIL_ACTIVATE_ORDER_LENGTH);
 
 1248    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1249    return CHANNEL_RC_NO_MEMORY;
 
 1252  error = rail_write_client_activate_order(s, activate);
 
 1254  if (ERROR_SUCCESS != error)
 
 1257    Stream_Free(s, TRUE);
 
 1261  return rail_send_pdu(rail, s, TS_RAIL_ORDER_ACTIVATE);
 
 1274  if (!rail || !sysmenu)
 
 1275    return ERROR_INVALID_PARAMETER;
 
 1277  s = rail_pdu_init(RAIL_SYSMENU_ORDER_LENGTH);
 
 1281    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1282    return CHANNEL_RC_NO_MEMORY;
 
 1285  error = rail_write_client_sysmenu_order(s, sysmenu);
 
 1287  if (ERROR_SUCCESS != error)
 
 1290    Stream_Free(s, TRUE);
 
 1294  return rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSMENU);
 
 1307  if (!rail || !syscommand)
 
 1308    return ERROR_INVALID_PARAMETER;
 
 1310  s = rail_pdu_init(RAIL_SYSCOMMAND_ORDER_LENGTH);
 
 1314    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1315    return CHANNEL_RC_NO_MEMORY;
 
 1318  error = rail_write_client_syscommand_order(s, syscommand);
 
 1320  if (ERROR_SUCCESS != error)
 
 1323    Stream_Free(s, TRUE);
 
 1327  return rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSCOMMAND);
 
 1335UINT rail_send_client_notify_event_order(
railPlugin* rail,
 
 1341  if (!rail || !notifyEvent)
 
 1342    return ERROR_INVALID_PARAMETER;
 
 1344  s = rail_pdu_init(RAIL_NOTIFY_EVENT_ORDER_LENGTH);
 
 1348    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1349    return CHANNEL_RC_NO_MEMORY;
 
 1352  error = rail_write_client_notify_event_order(s, notifyEvent);
 
 1354  if (ERROR_SUCCESS != error)
 
 1357    Stream_Free(s, TRUE);
 
 1361  return rail_send_pdu(rail, s, TS_RAIL_ORDER_NOTIFY_EVENT);
 
 1374  if (!rail || !windowMove)
 
 1375    return ERROR_INVALID_PARAMETER;
 
 1377  s = rail_pdu_init(RAIL_WINDOW_MOVE_ORDER_LENGTH);
 
 1381    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1382    return CHANNEL_RC_NO_MEMORY;
 
 1385  error = rail_write_client_window_move_order(s, windowMove);
 
 1387  if (ERROR_SUCCESS != error)
 
 1390    Stream_Free(s, TRUE);
 
 1394  return rail_send_pdu(rail, s, TS_RAIL_ORDER_WINDOWMOVE);
 
 1402UINT rail_send_client_get_appid_req_order(
railPlugin* rail,
 
 1408  if (!rail || !getAppIdReq)
 
 1409    return ERROR_INVALID_PARAMETER;
 
 1411  s = rail_pdu_init(RAIL_GET_APPID_REQ_ORDER_LENGTH);
 
 1415    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1416    return CHANNEL_RC_NO_MEMORY;
 
 1419  error = rail_write_client_get_appid_req_order(s, getAppIdReq);
 
 1421  if (ERROR_SUCCESS != error)
 
 1424    Stream_Free(s, TRUE);
 
 1427  return rail_send_pdu(rail, s, TS_RAIL_ORDER_GET_APPID_REQ);
 
 1435UINT rail_send_client_langbar_info_order(
railPlugin* rail,
 
 1441  if (!rail || !langBarInfo)
 
 1442    return ERROR_INVALID_PARAMETER;
 
 1444  if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED))
 
 1445    return ERROR_BAD_CONFIGURATION;
 
 1447  s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH);
 
 1451    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1452    return CHANNEL_RC_NO_MEMORY;
 
 1455  error = rail_write_langbar_info_order(s, langBarInfo);
 
 1457  if (ERROR_SUCCESS != error)
 
 1460    Stream_Free(s, TRUE);
 
 1463  return rail_send_pdu(rail, s, TS_RAIL_ORDER_LANGBARINFO);
 
 1466UINT rail_send_client_languageime_info_order(
railPlugin* rail,
 
 1472  if (!rail || !langImeInfo)
 
 1473    return ERROR_INVALID_PARAMETER;
 
 1475  if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED))
 
 1476    return ERROR_BAD_CONFIGURATION;
 
 1478  s = rail_pdu_init(RAIL_LANGUAGEIME_INFO_ORDER_LENGTH);
 
 1482    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1483    return CHANNEL_RC_NO_MEMORY;
 
 1486  error = rail_write_languageime_info_order(s, langImeInfo);
 
 1488  if (ERROR_SUCCESS != error)
 
 1491    Stream_Free(s, TRUE);
 
 1494  return rail_send_pdu(rail, s, TS_RAIL_ORDER_LANGUAGEIMEINFO);
 
 1497UINT rail_send_client_compartment_info_order(
railPlugin* rail,
 
 1503  if (!rail || !compartmentInfo)
 
 1504    return ERROR_INVALID_PARAMETER;
 
 1506  if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED))
 
 1507    return ERROR_BAD_CONFIGURATION;
 
 1509  s = rail_pdu_init(RAIL_COMPARTMENT_INFO_ORDER_LENGTH);
 
 1513    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1514    return CHANNEL_RC_NO_MEMORY;
 
 1517  error = rail_write_compartment_info_order(s, compartmentInfo);
 
 1519  if (ERROR_SUCCESS != error)
 
 1521    Stream_Free(s, TRUE);
 
 1524  return rail_send_pdu(rail, s, TS_RAIL_ORDER_COMPARTMENTINFO);
 
 1529  if (!rail || !cloak)
 
 1530    return ERROR_INVALID_PARAMETER;
 
 1532  wStream* s = rail_pdu_init(5);
 
 1536    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1537    return CHANNEL_RC_NO_MEMORY;
 
 1540  Stream_Write_UINT32(s, cloak->windowId);
 
 1541  Stream_Write_UINT8(s, cloak->cloak ? 1 : 0);
 
 1542  return rail_send_pdu(rail, s, TS_RAIL_ORDER_CLOAK);
 
 1548    return ERROR_INVALID_PARAMETER;
 
 1551  if ((rail->channelFlags & TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_SNAP_ARRANGE_SUPPORTED) == 0)
 
 1554    move.top = snap->top;
 
 1555    move.left = snap->left;
 
 1556    move.right = snap->right;
 
 1557    move.bottom = snap->bottom;
 
 1558    move.windowId = snap->windowId;
 
 1559    return rail_send_client_window_move_order(rail, &move);
 
 1562  wStream* s = rail_pdu_init(12);
 
 1566    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1567    return CHANNEL_RC_NO_MEMORY;
 
 1570  Stream_Write_UINT32(s, snap->windowId);
 
 1571  Stream_Write_INT16(s, snap->left);
 
 1572  Stream_Write_INT16(s, snap->top);
 
 1573  Stream_Write_INT16(s, snap->right);
 
 1574  Stream_Write_INT16(s, snap->bottom);
 
 1575  return rail_send_pdu(rail, s, TS_RAIL_ORDER_SNAP_ARRANGE);
 
 1578UINT rail_send_client_text_scale_order(
railPlugin* rail, UINT32 textScale)
 
 1581    return ERROR_INVALID_PARAMETER;
 
 1583  wStream* s = rail_pdu_init(4);
 
 1587    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1588    return CHANNEL_RC_NO_MEMORY;
 
 1591  Stream_Write_UINT32(s, textScale);
 
 1592  return rail_send_pdu(rail, s, TS_RAIL_ORDER_TEXTSCALEINFO);
 
 1595UINT rail_send_client_caret_blink_rate_order(
railPlugin* rail, UINT32 rate)
 
 1598    return ERROR_INVALID_PARAMETER;
 
 1600  wStream* s = rail_pdu_init(4);
 
 1604    WLog_ERR(TAG, 
"rail_pdu_init failed!");
 
 1605    return CHANNEL_RC_NO_MEMORY;
 
 1608  Stream_Write_UINT32(s, rate);
 
 1609  return rail_send_pdu(rail, s, TS_RAIL_ORDER_CARETBLINKINFO);
 
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
 
FREERDP_API const char * freerdp_rail_support_flags_to_string(UINT32 flags, char *buffer, size_t length)
Returns a stringified representation of RAIL support flags.