Blame channels/rail/client/rail_orders.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 * Remote Applications Integrated Locally (RAIL) Orders
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 * Copyright 2011 Roman Barabanov <romanbarabanov@gmail.com>
Packit 1fb8d4
 * Copyright 2015 Thincast Technologies GmbH
Packit 1fb8d4
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
Packit 1fb8d4
 * Copyright 2017 Armin Novak <armin.novak@thincast.com>
Packit 1fb8d4
 * Copyright 2017 Thincast Technologies GmbH
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/channels/log.h>
Packit 1fb8d4
Packit 1fb8d4
#include "rail_orders.h"
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT16 orderLength;
Packit 1fb8d4
Packit 1fb8d4
	if (!rail || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	orderLength = (UINT16)Stream_GetPosition(s);
Packit 1fb8d4
	Stream_SetPosition(s, 0);
Packit 1fb8d4
	rail_write_pdu_header(s, orderType, orderLength);
Packit 1fb8d4
	Stream_SetPosition(s, orderLength);
Packit Service 5a9772
	WLog_Print(rail->log, WLOG_DEBUG, "Sending %s PDU, length: %" PRIu16 "",
Packit Service 5a9772
	           rail_get_order_type_string(orderType), orderLength);
Packit Service 5a9772
	return rail_send_channel_data(rail, s);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT rail_read_server_exec_result_order(wStream* s, RAIL_EXEC_RESULT_ORDER* execResult)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !execResult)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_EXEC_RESULT_ORDER_LENGTH)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit 1fb8d4
		return ERROR_INVALID_DATA;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	Stream_Read_UINT16(s, execResult->flags);      /* flags (2 bytes) */
Packit 1fb8d4
	Stream_Read_UINT16(s, execResult->execResult); /* execResult (2 bytes) */
Packit Service 5a9772
	Stream_Read_UINT32(s, execResult->rawResult);  /* rawResult (4 bytes) */
Packit Service 5a9772
	Stream_Seek_UINT16(s);                         /* padding (2 bytes) */
Packit Service 5a9772
	return rail_read_unicode_string(s, &execResult->exeOrFile)
Packit Service 5a9772
	           ? CHANNEL_RC_OK
Packit Service 5a9772
	           : ERROR_INTERNAL_ERROR; /* exeOrFile */
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT rail_read_server_minmaxinfo_order(wStream* s, RAIL_MINMAXINFO_ORDER* minmaxinfo)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !minmaxinfo)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_MINMAXINFO_ORDER_LENGTH)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit 1fb8d4
		return ERROR_INVALID_DATA;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	Stream_Read_UINT32(s, minmaxinfo->windowId);      /* windowId (4 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, minmaxinfo->maxWidth);       /* maxWidth (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, minmaxinfo->maxHeight);      /* maxHeight (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, minmaxinfo->maxPosX);        /* maxPosX (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, minmaxinfo->maxPosY);        /* maxPosY (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, minmaxinfo->minTrackWidth);  /* minTrackWidth (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, minmaxinfo->minTrackHeight); /* minTrackHeight (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, minmaxinfo->maxTrackWidth);  /* maxTrackWidth (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, minmaxinfo->maxTrackHeight); /* maxTrackHeight (2 bytes) */
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT rail_read_server_localmovesize_order(wStream* s,
Packit Service 5a9772
                                                 RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT16 isMoveSizeStart;
Packit 1fb8d4
Packit 1fb8d4
	if (!s || !localMoveSize)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_LOCALMOVESIZE_ORDER_LENGTH)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit 1fb8d4
		return ERROR_INVALID_DATA;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Stream_Read_UINT32(s, localMoveSize->windowId); /* windowId (4 bytes) */
Packit Service 5a9772
	Stream_Read_UINT16(s, isMoveSizeStart);         /* isMoveSizeStart (2 bytes) */
Packit 1fb8d4
	localMoveSize->isMoveSizeStart = (isMoveSizeStart != 0) ? TRUE : FALSE;
Packit 1fb8d4
	Stream_Read_UINT16(s, localMoveSize->moveSizeType); /* moveSizeType (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, localMoveSize->posX);          /* posX (2 bytes) */
Packit Service 5a9772
	Stream_Read_INT16(s, localMoveSize->posY);          /* posY (2 bytes) */
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT rail_read_server_get_appid_resp_order(wStream* s,
Packit Service 5a9772
                                                  RAIL_GET_APPID_RESP_ORDER* getAppidResp)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !getAppidResp)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_GET_APPID_RESP_ORDER_LENGTH)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit 1fb8d4
		return ERROR_INVALID_DATA;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Stream_Read_UINT32(s, getAppidResp->windowId); /* windowId (4 bytes) */
Packit Service 5a9772
	Stream_Read_UTF16_String(
Packit Service 5a9772
	    s, getAppidResp->applicationId,
Packit Service 5a9772
	    ARRAYSIZE(getAppidResp->applicationId)); /* applicationId (260 UNICODE chars) */
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbarInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !langbarInfo)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_LANGBAR_INFO_ORDER_LENGTH)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit 1fb8d4
		return ERROR_INVALID_DATA;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Stream_Read_UINT32(s, langbarInfo->languageBarStatus); /* languageBarStatus (4 bytes) */
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT rail_write_client_status_order(wStream* s, const RAIL_CLIENT_STATUS_ORDER* clientStatus)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !clientStatus)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Write_UINT32(s, clientStatus->flags); /* flags (4 bytes) */
Packit 1fb8d4
	return ERROR_SUCCESS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT rail_write_client_exec_order(wStream* s, UINT16 flags,
Packit Service 5a9772
                                         const RAIL_UNICODE_STRING* exeOrFile,
Packit Service 5a9772
                                         const RAIL_UNICODE_STRING* workingDir,
Packit Service 5a9772
                                         const RAIL_UNICODE_STRING* arguments)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit 1fb8d4
	if (!s || !exeOrFile || !workingDir || !arguments)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	/* [MS-RDPERP] 2.2.2.3.1 Client Execute PDU (TS_RAIL_ORDER_EXEC)
Packit 1fb8d4
	 * Check argument limits */
Packit Service 5a9772
	if ((exeOrFile->length > 520) || (workingDir->length > 520) || (arguments->length > 16000))
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG,
Packit Service 5a9772
		         "TS_RAIL_ORDER_EXEC argument limits exceeded: ExeOrFile=%" PRIu16
Packit Service 5a9772
		         " [max=520], WorkingDir=%" PRIu16 " [max=520], Arguments=%" PRIu16 " [max=16000]",
Packit 1fb8d4
		         exeOrFile->length, workingDir->length, arguments->length);
Packit 1fb8d4
		return ERROR_BAD_ARGUMENTS;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	Stream_Write_UINT16(s, flags);              /* flags (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, exeOrFile->length);  /* exeOrFileLength (2 bytes) */
Packit 1fb8d4
	Stream_Write_UINT16(s, workingDir->length); /* workingDirLength (2 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, arguments->length);  /* argumentsLength (2 bytes) */
Packit 1fb8d4
Packit 1fb8d4
	if ((error = rail_write_unicode_string_value(s, exeOrFile)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %" PRIu32 "", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if ((error = rail_write_unicode_string_value(s, workingDir)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %" PRIu32 "", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if ((error = rail_write_unicode_string_value(s, arguments)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %" PRIu32 "", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT rail_write_client_activate_order(wStream* s, const RAIL_ACTIVATE_ORDER* activate)
Packit 1fb8d4
{
Packit 1fb8d4
	BYTE enabled;
Packit 1fb8d4
Packit 1fb8d4
	if (!s || !activate)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Write_UINT32(s, activate->windowId); /* windowId (4 bytes) */
Packit 1fb8d4
	enabled = activate->enabled ? 1 : 0;
Packit 1fb8d4
	Stream_Write_UINT8(s, enabled); /* enabled (1 byte) */
Packit 1fb8d4
	return ERROR_SUCCESS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT rail_write_client_sysmenu_order(wStream* s, const RAIL_SYSMENU_ORDER* sysmenu)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !sysmenu)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Write_UINT32(s, sysmenu->windowId); /* windowId (4 bytes) */
Packit Service 5a9772
	Stream_Write_INT16(s, sysmenu->left);      /* left (2 bytes) */
Packit Service 5a9772
	Stream_Write_INT16(s, sysmenu->top);       /* top (2 bytes) */
Packit 1fb8d4
	return ERROR_SUCCESS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT rail_write_client_syscommand_order(wStream* s, const RAIL_SYSCOMMAND_ORDER* syscommand)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !syscommand)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Write_UINT32(s, syscommand->windowId); /* windowId (4 bytes) */
Packit Service 5a9772
	Stream_Write_UINT16(s, syscommand->command);  /* command (2 bytes) */
Packit 1fb8d4
	return ERROR_SUCCESS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT rail_write_client_notify_event_order(wStream* s,
Packit Service 5a9772
                                                 const RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !notifyEvent)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	Stream_Write_UINT32(s, notifyEvent->windowId);     /* windowId (4 bytes) */
Packit 1fb8d4
	Stream_Write_UINT32(s, notifyEvent->notifyIconId); /* notifyIconId (4 bytes) */
Packit Service 5a9772
	Stream_Write_UINT32(s, notifyEvent->message);      /* notifyIconId (4 bytes) */
Packit 1fb8d4
	return ERROR_SUCCESS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT rail_write_client_window_move_order(wStream* s,
Packit Service 5a9772
                                                const RAIL_WINDOW_MOVE_ORDER* windowMove)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !windowMove)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Write_UINT32(s, windowMove->windowId); /* windowId (4 bytes) */
Packit Service 5a9772
	Stream_Write_INT16(s, windowMove->left);      /* left (2 bytes) */
Packit Service 5a9772
	Stream_Write_INT16(s, windowMove->top);       /* top (2 bytes) */
Packit Service 5a9772
	Stream_Write_INT16(s, windowMove->right);     /* right (2 bytes) */
Packit Service 5a9772
	Stream_Write_INT16(s, windowMove->bottom);    /* bottom (2 bytes) */
Packit 1fb8d4
	return ERROR_SUCCESS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT rail_write_client_get_appid_req_order(wStream* s,
Packit Service 5a9772
                                                  const RAIL_GET_APPID_REQ_ORDER* getAppidReq)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !getAppidReq)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Write_UINT32(s, getAppidReq->windowId); /* windowId (4 bytes) */
Packit 1fb8d4
	return ERROR_SUCCESS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT rail_write_langbar_info_order(wStream* s, const RAIL_LANGBAR_INFO_ORDER* langbarInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!s || !langbarInfo)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	Stream_Write_UINT32(s, langbarInfo->languageBarStatus); /* languageBarStatus (4 bytes) */
Packit 1fb8d4
	return ERROR_SUCCESS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static UINT rail_write_languageime_info_order(wStream* s,
Packit Service 5a9772
                                              const RAIL_LANGUAGEIME_INFO_ORDER* langImeInfo)
Packit Service 5a9772
{
Packit Service 5a9772
	if (!s || !langImeInfo)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	Stream_Write_UINT32(s, langImeInfo->ProfileType);
Packit Service 5a9772
	Stream_Write_UINT16(s, langImeInfo->LanguageID);
Packit Service 5a9772
	Stream_Write(s, &langImeInfo->LanguageProfileCLSID, sizeof(langImeInfo->LanguageProfileCLSID));
Packit Service 5a9772
	Stream_Write(s, &langImeInfo->ProfileGUID, sizeof(langImeInfo->ProfileGUID));
Packit Service 5a9772
	Stream_Write_UINT32(s, langImeInfo->KeyboardLayout);
Packit Service 5a9772
	return ERROR_SUCCESS;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_write_compartment_info_order(wStream* s,
Packit Service 5a9772
                                              const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo)
Packit Service 5a9772
{
Packit Service 5a9772
	if (!s || !compartmentInfo)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	Stream_Write_UINT32(s, compartmentInfo->ImeState);
Packit Service 5a9772
	Stream_Write_UINT32(s, compartmentInfo->ImeConvMode);
Packit Service 5a9772
	Stream_Write_UINT32(s, compartmentInfo->ImeSentenceMode);
Packit Service 5a9772
	Stream_Write_UINT32(s, compartmentInfo->KanaMode);
Packit Service 5a9772
	return ERROR_SUCCESS;
Packit Service 5a9772
}
Packit Service 5a9772
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
static UINT rail_recv_handshake_order(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_HANDSHAKE_ORDER serverHandshake = { 0 };
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!context || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if ((error = rail_read_handshake_order(s, &serverHandshake)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_handshake_order failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	rail->channelBuildNumber = serverHandshake.buildNumber;
Packit Service 5a9772
Packit Service 5a9772
	if (rail->sendHandshake)
Packit Service 5a9772
	{
Packit Service 5a9772
		RAIL_HANDSHAKE_ORDER clientHandshake = { 0 };
Packit Service 5a9772
		clientHandshake.buildNumber = 0x00001DB0;
Packit Service 5a9772
		error = context->ClientHandshake(context, &clientHandshake);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (error != CHANNEL_RC_OK)
Packit Service 5a9772
		return error;
Packit Service 5a9772
Packit 1fb8d4
	if (context->custom)
Packit 1fb8d4
	{
Packit Service 5a9772
		IFCALLRET(context->ServerHandshake, error, context, &serverHandshake);
Packit 1fb8d4
Packit 1fb8d4
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerHandshake failed with error %" PRIu32 "", error);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
static BOOL rail_is_feature_supported(const rdpContext* context, UINT32 featureMask)
Packit Service 5a9772
{
Packit Service 5a9772
	UINT32 supported, masked;
Packit Service 5a9772
Packit Service 5a9772
	if (!context || !context->settings)
Packit Service 5a9772
		return FALSE;
Packit Service 5a9772
Packit Service 5a9772
	supported = context->settings->RemoteApplicationSupportLevel &
Packit Service 5a9772
	            context->settings->RemoteApplicationSupportMask;
Packit Service 5a9772
	masked = (supported & featureMask);
Packit Service 5a9772
Packit Service 5a9772
	if (masked != featureMask)
Packit Service 5a9772
		return FALSE;
Packit Service 5a9772
Packit Service 5a9772
	return TRUE;
Packit Service 5a9772
}
Packit Service 5a9772
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
static UINT rail_recv_handshake_ex_order(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_HANDSHAKE_EX_ORDER serverHandshake = { 0 };
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !context || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED))
Packit Service 5a9772
		return ERROR_BAD_CONFIGURATION;
Packit Service 5a9772
Packit Service 5a9772
	if ((error = rail_read_handshake_ex_order(s, &serverHandshake)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_handshake_ex_order failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	rail->channelBuildNumber = serverHandshake.buildNumber;
Packit Service 5a9772
	rail->channelFlags = serverHandshake.railHandshakeFlags;
Packit Service 5a9772
Packit Service 5a9772
	if (rail->sendHandshake)
Packit Service 5a9772
	{
Packit Service 5a9772
		RAIL_HANDSHAKE_ORDER clientHandshake = { 0 };
Packit Service 5a9772
		clientHandshake.buildNumber = 0x00001DB0;
Packit Service 5a9772
		/* 2.2.2.2.3 HandshakeEx PDU (TS_RAIL_ORDER_HANDSHAKE_EX)
Packit Service 5a9772
		 * Client response is really a Handshake PDU */
Packit Service 5a9772
		error = context->ClientHandshake(context, &clientHandshake);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (error != CHANNEL_RC_OK)
Packit Service 5a9772
		return error;
Packit Service 5a9772
Packit 1fb8d4
	if (context->custom)
Packit 1fb8d4
	{
Packit Service 5a9772
		IFCALLRET(context->ServerHandshakeEx, error, context, &serverHandshake);
Packit 1fb8d4
Packit 1fb8d4
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerHandshakeEx failed with error %" PRIu32 "", error);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
static UINT rail_recv_exec_result_order(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_EXEC_RESULT_ORDER execResult = { 0 };
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!context || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if ((error = rail_read_server_exec_result_order(s, &execResult)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_server_exec_result_order failed with error %" PRIu32 "!", error);
Packit Service 5a9772
		goto fail;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (context->custom)
Packit 1fb8d4
	{
Packit Service 5a9772
		IFCALLRET(context->ServerExecuteResult, error, context, &execResult);
Packit 1fb8d4
Packit 1fb8d4
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerExecuteResult failed with error %" PRIu32 "", error);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
fail:
Packit Service 5a9772
	free(execResult.exeOrFile.string);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
static UINT rail_recv_server_sysparam_order(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_SYSPARAM_ORDER sysparam;
Packit 1fb8d4
	UINT error;
Packit Service 5a9772
	BOOL extendedSpiSupported;
Packit 1fb8d4
Packit Service 5a9772
	if (!context || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	extendedSpiSupported = rail_is_extended_spi_supported(rail->channelFlags);
Packit Service 5a9772
	if ((error = rail_read_sysparam_order(s, &sysparam, extendedSpiSupported)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_sysparam_order failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (context->custom)
Packit 1fb8d4
	{
Packit Service 5a9772
		IFCALLRET(context->ServerSystemParam, error, context, &sysparam);
Packit 1fb8d4
Packit 1fb8d4
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerSystemParam failed with error %" PRIu32 "", error);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
static UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_MINMAXINFO_ORDER minMaxInfo = { 0 };
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!context || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if ((error = rail_read_server_minmaxinfo_order(s, &minMaxInfo)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_server_minmaxinfo_order failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (context->custom)
Packit 1fb8d4
	{
Packit Service 5a9772
		IFCALLRET(context->ServerMinMaxInfo, error, context, &minMaxInfo);
Packit 1fb8d4
Packit 1fb8d4
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerMinMaxInfo failed with error %" PRIu32 "", error);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
static UINT rail_recv_server_localmovesize_order(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_LOCALMOVESIZE_ORDER localMoveSize = { 0 };
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!context || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if ((error = rail_read_server_localmovesize_order(s, &localMoveSize)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_server_localmovesize_order failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (context->custom)
Packit 1fb8d4
	{
Packit Service 5a9772
		IFCALLRET(context->ServerLocalMoveSize, error, context, &localMoveSize);
Packit 1fb8d4
Packit 1fb8d4
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerLocalMoveSize failed with error %" PRIu32 "", error);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
static UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_GET_APPID_RESP_ORDER getAppIdResp = { 0 };
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!context || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if ((error = rail_read_server_get_appid_resp_order(s, &getAppIdResp)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_server_get_appid_resp_order failed with error %" PRIu32 "!",
Packit Service 5a9772
		         error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (context->custom)
Packit 1fb8d4
	{
Packit Service 5a9772
		IFCALLRET(context->ServerGetAppIdResponse, error, context, &getAppIdResp);
Packit 1fb8d4
Packit 1fb8d4
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerGetAppIdResponse failed with error %" PRIu32 "", error);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
static UINT rail_recv_langbar_info_order(railPlugin* rail, wStream* s)
Packit Service 5a9772
{
Packit Service 5a9772
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_LANGBAR_INFO_ORDER langBarInfo = { 0 };
Packit Service 5a9772
	UINT error;
Packit Service 5a9772
Packit Service 5a9772
	if (!context)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED))
Packit Service 5a9772
		return ERROR_BAD_CONFIGURATION;
Packit Service 5a9772
Packit Service 5a9772
	if ((error = rail_read_langbar_info_order(s, &langBarInfo)))
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %" PRIu32 "!", error);
Packit Service 5a9772
		return error;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (context->custom)
Packit Service 5a9772
	{
Packit Service 5a9772
		IFCALLRET(context->ServerLanguageBarInfo, error, context, &langBarInfo);
Packit Service 5a9772
Packit Service 5a9772
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %" PRIu32 "", error);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return error;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_read_taskbar_info_order(wStream* s, RAIL_TASKBAR_INFO_ORDER* taskbarInfo)
Packit Service 5a9772
{
Packit Service 5a9772
	if (!s || !taskbarInfo)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_TASKBAR_INFO_ORDER_LENGTH)
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	Stream_Read_UINT32(s, taskbarInfo->TaskbarMessage);
Packit Service 5a9772
	Stream_Read_UINT32(s, taskbarInfo->WindowIdTab);
Packit Service 5a9772
	Stream_Read_UINT32(s, taskbarInfo->Body);
Packit Service 5a9772
	return CHANNEL_RC_OK;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_recv_taskbar_info_order(railPlugin* rail, wStream* s)
Packit Service 5a9772
{
Packit Service 5a9772
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_TASKBAR_INFO_ORDER taskBarInfo = { 0 };
Packit Service 5a9772
	UINT error;
Packit Service 5a9772
Packit Service 5a9772
	if (!context)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	/* 2.2.2.14.1 Taskbar Tab Info PDU (TS_RAIL_ORDER_TASKBARINFO)
Packit Service 5a9772
	 * server -> client message only supported if announced. */
Packit Service 5a9772
	if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED))
Packit Service 5a9772
		return ERROR_BAD_CONFIGURATION;
Packit Service 5a9772
Packit Service 5a9772
	if ((error = rail_read_taskbar_info_order(s, &taskBarInfo)))
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %" PRIu32 "!", error);
Packit Service 5a9772
		return error;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (context->custom)
Packit Service 5a9772
	{
Packit Service 5a9772
		IFCALLRET(context->ServerTaskBarInfo, error, context, &taskBarInfo);
Packit Service 5a9772
Packit Service 5a9772
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerTaskBarInfo failed with error %" PRIu32 "", error);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return error;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_read_zorder_sync_order(wStream* s, RAIL_ZORDER_SYNC* zorder)
Packit Service 5a9772
{
Packit Service 5a9772
	if (!s || !zorder)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_Z_ORDER_SYNC_ORDER_LENGTH)
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	Stream_Read_UINT32(s, zorder->windowIdMarker);
Packit Service 5a9772
	return CHANNEL_RC_OK;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_recv_zorder_sync_order(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_ZORDER_SYNC zorder = { 0 };
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!context)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_ZORDER_SYNC) == 0)
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
Packit Service 5a9772
	if ((error = rail_read_zorder_sync_order(s, &zorder)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (context->custom)
Packit 1fb8d4
	{
Packit Service 5a9772
		IFCALLRET(context->ServerZOrderSync, error, context, &zorder);
Packit 1fb8d4
Packit 1fb8d4
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerZOrderSync failed with error %" PRIu32 "", error);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return error;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_read_cloak_order(wStream* s, RAIL_CLOAK* cloak)
Packit Service 5a9772
{
Packit Service 5a9772
	BYTE cloaked;
Packit Service 5a9772
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_CLOAK_ORDER_LENGTH)
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	Stream_Read_UINT32(s, cloak->windowId); /* WindowId (4 bytes) */
Packit Service 5a9772
	Stream_Read_UINT8(s, cloaked);          /* Cloaked (1 byte) */
Packit Service 5a9772
	cloak->cloak = (cloaked != 0) ? TRUE : FALSE;
Packit Service 5a9772
	return CHANNEL_RC_OK;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_recv_cloak_order(railPlugin* rail, wStream* s)
Packit Service 5a9772
{
Packit Service 5a9772
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_CLOAK cloak = { 0 };
Packit Service 5a9772
	UINT error;
Packit Service 5a9772
Packit Service 5a9772
	if (!context)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	/* 2.2.2.12.1 Window Cloak State Change PDU (TS_RAIL_ORDER_CLOAK)
Packit Service 5a9772
	 * server -> client message only supported if announced. */
Packit Service 5a9772
	if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_BIDIRECTIONAL_CLOAK_SUPPORTED) == 0)
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
Packit Service 5a9772
	if ((error = rail_read_cloak_order(s, &cloak)))
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %" PRIu32 "!", error);
Packit Service 5a9772
		return error;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (context->custom)
Packit Service 5a9772
	{
Packit Service 5a9772
		IFCALLRET(context->ServerCloak, error, context, &cloak);
Packit Service 5a9772
Packit Service 5a9772
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerZOrderSync failed with error %" PRIu32 "", error);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return error;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_read_power_display_request_order(wStream* s, RAIL_POWER_DISPLAY_REQUEST* power)
Packit Service 5a9772
{
Packit Service 5a9772
	UINT32 active;
Packit Service 5a9772
Packit Service 5a9772
	if (!s || !power)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < RAIL_POWER_DISPLAY_REQUEST_ORDER_LENGTH)
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	Stream_Read_UINT32(s, active);
Packit Service 5a9772
	power->active = active != 0;
Packit Service 5a9772
	return CHANNEL_RC_OK;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_recv_power_display_request_order(railPlugin* rail, wStream* s)
Packit Service 5a9772
{
Packit Service 5a9772
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_POWER_DISPLAY_REQUEST power = { 0 };
Packit Service 5a9772
	UINT error;
Packit Service 5a9772
Packit Service 5a9772
	if (!context)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	/* 2.2.2.13.1 Power Display Request PDU(TS_RAIL_ORDER_POWER_DISPLAY_REQUEST)
Packit Service 5a9772
	 */
Packit Service 5a9772
	if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED) == 0)
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
Packit Service 5a9772
	if ((error = rail_read_power_display_request_order(s, &power)))
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %" PRIu32 "!", error);
Packit Service 5a9772
		return error;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (context->custom)
Packit Service 5a9772
	{
Packit Service 5a9772
		IFCALLRET(context->ServerPowerDisplayRequest, error, context, &power);
Packit Service 5a9772
Packit Service 5a9772
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerPowerDisplayRequest failed with error %" PRIu32 "", error);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	return error;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_read_get_application_id_extended_response_order(wStream* s,
Packit Service 5a9772
                                                                 RAIL_GET_APPID_RESP_EX* id)
Packit Service 5a9772
{
Packit Service 5a9772
	if (!s || !id)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < 4)
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	Stream_Read_UINT32(s, id->windowID);
Packit Service 5a9772
Packit Service 5a9772
	if (!Stream_Read_UTF16_String(s, id->applicationID, ARRAYSIZE(id->applicationID)))
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
Packit Service 5a9772
	if (_wcsnlen(id->applicationID, ARRAYSIZE(id->applicationID)) >= ARRAYSIZE(id->applicationID))
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
Packit Service 5a9772
	if (Stream_GetRemainingLength(s) < 4)
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	Stream_Read_UINT32(s, id->processId);
Packit Service 5a9772
Packit Service 5a9772
	if (!Stream_Read_UTF16_String(s, id->processImageName, ARRAYSIZE(id->processImageName)))
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
Packit Service 5a9772
	if (_wcsnlen(id->applicationID, ARRAYSIZE(id->processImageName)) >=
Packit Service 5a9772
	    ARRAYSIZE(id->processImageName))
Packit Service 5a9772
		return ERROR_INVALID_DATA;
Packit Service 5a9772
Packit Service 5a9772
	return CHANNEL_RC_OK;
Packit Service 5a9772
}
Packit Service 5a9772
Packit Service 5a9772
static UINT rail_recv_get_application_id_extended_response_order(railPlugin* rail, wStream* s)
Packit Service 5a9772
{
Packit Service 5a9772
	RailClientContext* context = rail_get_client_interface(rail);
Packit Service 5a9772
	RAIL_GET_APPID_RESP_EX id = { 0 };
Packit Service 5a9772
	UINT error;
Packit Service 5a9772
Packit Service 5a9772
	if (!context)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	if ((error = rail_read_get_application_id_extended_response_order(s, &id)))
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG,
Packit Service 5a9772
		         "rail_read_get_application_id_extended_response_order failed with error %" PRIu32
Packit Service 5a9772
		         "!",
Packit Service 5a9772
		         error);
Packit Service 5a9772
		return error;
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	if (context->custom)
Packit Service 5a9772
	{
Packit Service 5a9772
		IFCALLRET(context->ServerGetAppidResponseExtended, error, context, &id;;
Packit Service 5a9772
Packit Service 5a9772
		if (error)
Packit Service 5a9772
			WLog_ERR(TAG, "context.ServerGetAppidResponseExtended failed with error %" PRIu32 "",
Packit Service 5a9772
			         error);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
UINT rail_order_recv(railPlugin* rail, wStream* s)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT16 orderType;
Packit 1fb8d4
	UINT16 orderLength;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit 1fb8d4
	if (!rail || !s)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	if ((error = rail_read_pdu_header(s, &orderType, &orderLength)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_read_pdu_header failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		return error;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	WLog_Print(rail->log, WLOG_DEBUG, "Received %s PDU, length:%" PRIu16 "",
Packit Service 5a9772
	           rail_get_order_type_string(orderType), orderLength);
Packit 1fb8d4
Packit 1fb8d4
	switch (orderType)
Packit 1fb8d4
	{
Packit Service 5a9772
		case TS_RAIL_ORDER_HANDSHAKE:
Packit Service 5a9772
			return rail_recv_handshake_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_HANDSHAKE_EX:
Packit Service 5a9772
			return rail_recv_handshake_ex_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_EXEC_RESULT:
Packit Service 5a9772
			return rail_recv_exec_result_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_SYSPARAM:
Packit Service 5a9772
			return rail_recv_server_sysparam_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_MINMAXINFO:
Packit Service 5a9772
			return rail_recv_server_minmaxinfo_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_LOCALMOVESIZE:
Packit Service 5a9772
			return rail_recv_server_localmovesize_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_GET_APPID_RESP:
Packit Service 5a9772
			return rail_recv_server_get_appid_resp_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_LANGBARINFO:
Packit Service 5a9772
			return rail_recv_langbar_info_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_TASKBARINFO:
Packit Service 5a9772
			return rail_recv_taskbar_info_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_ZORDER_SYNC:
Packit Service 5a9772
			return rail_recv_zorder_sync_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_CLOAK:
Packit Service 5a9772
			return rail_recv_cloak_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_POWER_DISPLAY_REQUEST:
Packit Service 5a9772
			return rail_recv_power_display_request_order(rail, s);
Packit Service 5a9772
Packit Service 5a9772
		case TS_RAIL_ORDER_GET_APPID_RESP_EX:
Packit Service 5a9772
			return rail_recv_get_application_id_extended_response_order(rail, s);
Packit 1fb8d4
Packit 1fb8d4
		default:
Packit Service 5a9772
			WLog_ERR(TAG, "Unknown RAIL PDU order reveived.");
Packit 1fb8d4
			return ERROR_INVALID_DATA;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
UINT rail_send_handshake_order(railPlugin* rail, const RAIL_HANDSHAKE_ORDER* handshake)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit 1fb8d4
	if (!rail || !handshake)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	rail_write_handshake_order(s, handshake);
Packit Service 5a9772
	error = rail_send_pdu(rail, s, TS_RAIL_ORDER_HANDSHAKE);
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
UINT rail_send_handshake_ex_order(railPlugin* rail, const RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit 1fb8d4
	if (!rail || !handshakeEx)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit 1fb8d4
	s = rail_pdu_init(RAIL_HANDSHAKE_EX_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	rail_write_handshake_ex_order(s, handshakeEx);
Packit Service 5a9772
	error = rail_send_pdu(rail, s, TS_RAIL_ORDER_HANDSHAKE_EX);
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
UINT rail_send_client_status_order(railPlugin* rail, const RAIL_CLIENT_STATUS_ORDER* clientStatus)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit 1fb8d4
	if (!rail || !clientStatus)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	rail->clientStatus = *clientStatus;
Packit 1fb8d4
	s = rail_pdu_init(RAIL_CLIENT_STATUS_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	error = rail_write_client_status_order(s, clientStatus);
Packit 1fb8d4
Packit 1fb8d4
	if (error == ERROR_SUCCESS)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_CLIENTSTATUS);
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
UINT rail_send_client_exec_order(railPlugin* rail, UINT16 flags,
Packit Service 5a9772
                                 const RAIL_UNICODE_STRING* exeOrFile,
Packit Service 5a9772
                                 const RAIL_UNICODE_STRING* workingDir,
Packit 1fb8d4
                                 const RAIL_UNICODE_STRING* arguments)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
	size_t length;
Packit 1fb8d4
Packit 1fb8d4
	if (!rail || !exeOrFile || !workingDir || !arguments)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	length = RAIL_EXEC_ORDER_LENGTH + exeOrFile->length + workingDir->length + arguments->length;
Packit 1fb8d4
	s = rail_pdu_init(length);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if ((error = rail_write_client_exec_order(s, flags, exeOrFile, workingDir, arguments)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_write_client_exec_order failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	if ((error = rail_send_pdu(rail, s, TS_RAIL_ORDER_EXEC)))
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_send_pdu failed with error %" PRIu32 "!", error);
Packit 1fb8d4
		goto out;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
out:
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
UINT rail_send_client_activate_order(railPlugin* rail, const RAIL_ACTIVATE_ORDER* activate)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !activate)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	s = rail_pdu_init(RAIL_ACTIVATE_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_client_activate_order(s, activate);
Packit 1fb8d4
Packit Service 5a9772
	if (error == ERROR_SUCCESS)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_ACTIVATE);
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
UINT rail_send_client_sysmenu_order(railPlugin* rail, const RAIL_SYSMENU_ORDER* sysmenu)
Packit 1fb8d4
{
Packit Service 5a9772
	wStream* s;
Packit Service 5a9772
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !sysmenu)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	s = rail_pdu_init(RAIL_SYSMENU_ORDER_LENGTH);
Packit 1fb8d4
Packit Service 5a9772
	if (!s)
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit Service 5a9772
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_client_sysmenu_order(s, sysmenu);
Packit 1fb8d4
Packit Service 5a9772
	if (error == ERROR_SUCCESS)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSMENU);
Packit 1fb8d4
Packit Service 5a9772
	Stream_Free(s, TRUE);
Packit Service 5a9772
	return error;
Packit Service 5a9772
}
Packit 1fb8d4
Packit Service 5a9772
/**
Packit Service 5a9772
 * Function description
Packit Service 5a9772
 *
Packit Service 5a9772
 * @return 0 on success, otherwise a Win32 error code
Packit Service 5a9772
 */
Packit Service 5a9772
UINT rail_send_client_syscommand_order(railPlugin* rail, const RAIL_SYSCOMMAND_ORDER* syscommand)
Packit Service 5a9772
{
Packit Service 5a9772
	wStream* s;
Packit Service 5a9772
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !syscommand)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	s = rail_pdu_init(RAIL_SYSCOMMAND_ORDER_LENGTH);
Packit 1fb8d4
Packit Service 5a9772
	if (!s)
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit Service 5a9772
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_client_syscommand_order(s, syscommand);
Packit 1fb8d4
Packit Service 5a9772
	if (error == ERROR_SUCCESS)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSCOMMAND);
Packit 1fb8d4
Packit Service 5a9772
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
UINT rail_send_client_notify_event_order(railPlugin* rail,
Packit Service 5a9772
                                         const RAIL_NOTIFY_EVENT_ORDER* notifyEvent)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !notifyEvent)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	s = rail_pdu_init(RAIL_NOTIFY_EVENT_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_client_notify_event_order(s, notifyEvent);
Packit 1fb8d4
Packit Service 5a9772
	if (ERROR_SUCCESS == error)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_NOTIFY_EVENT);
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
UINT rail_send_client_window_move_order(railPlugin* rail, const RAIL_WINDOW_MOVE_ORDER* windowMove)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !windowMove)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	s = rail_pdu_init(RAIL_WINDOW_MOVE_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_client_window_move_order(s, windowMove);
Packit 1fb8d4
Packit 1fb8d4
	if (error == ERROR_SUCCESS)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_WINDOWMOVE);
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
UINT rail_send_client_get_appid_req_order(railPlugin* rail,
Packit Service 5a9772
                                          const RAIL_GET_APPID_REQ_ORDER* getAppIdReq)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !getAppIdReq)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	s = rail_pdu_init(RAIL_GET_APPID_REQ_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_client_get_appid_req_order(s, getAppIdReq);
Packit 1fb8d4
Packit 1fb8d4
	if (error == ERROR_SUCCESS)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_GET_APPID_REQ);
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit Service 5a9772
UINT rail_send_client_langbar_info_order(railPlugin* rail,
Packit Service 5a9772
                                         const RAIL_LANGBAR_INFO_ORDER* langBarInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !langBarInfo)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED))
Packit Service 5a9772
		return ERROR_BAD_CONFIGURATION;
Packit Service 5a9772
Packit Service 5a9772
	s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_langbar_info_order(s, langBarInfo);
Packit 1fb8d4
Packit 1fb8d4
	if (ERROR_SUCCESS == error)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_LANGBARINFO);
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
UINT rail_send_client_languageime_info_order(railPlugin* rail,
Packit Service 5a9772
                                             const RAIL_LANGUAGEIME_INFO_ORDER* langImeInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !langImeInfo)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED))
Packit Service 5a9772
		return ERROR_BAD_CONFIGURATION;
Packit Service 5a9772
Packit Service 5a9772
	s = rail_pdu_init(RAIL_LANGUAGEIME_INFO_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_languageime_info_order(s, langImeInfo);
Packit 1fb8d4
Packit Service 5a9772
	if (ERROR_SUCCESS == error)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_LANGUAGEIMEINFO);
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
UINT rail_send_client_compartment_info_order(railPlugin* rail,
Packit Service 5a9772
                                             const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !compartmentInfo)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	s = rail_pdu_init(RAIL_COMPARTMENT_INFO_ORDER_LENGTH);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	error = rail_write_compartment_info_order(s, compartmentInfo);
Packit 1fb8d4
Packit Service 5a9772
	if (ERROR_SUCCESS == error)
Packit Service 5a9772
		error = rail_send_pdu(rail, s, TS_RAIL_ORDER_COMPARTMENTINFO);
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
UINT rail_send_client_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloak)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	UINT error;
Packit 1fb8d4
Packit Service 5a9772
	if (!rail || !cloak)
Packit 1fb8d4
		return ERROR_INVALID_PARAMETER;
Packit 1fb8d4
Packit Service 5a9772
	s = rail_pdu_init(5);
Packit 1fb8d4
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit 1fb8d4
		return CHANNEL_RC_NO_MEMORY;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	Stream_Write_UINT32(s, cloak->windowId);
Packit Service 5a9772
	Stream_Write_UINT8(s, cloak->cloak ? 1 : 0);
Packit Service 5a9772
	error = rail_send_pdu(rail, s, TS_RAIL_ORDER_CLOAK);
Packit Service 5a9772
	Stream_Free(s, TRUE);
Packit Service 5a9772
	return error;
Packit Service 5a9772
}
Packit 1fb8d4
Packit Service 5a9772
UINT rail_send_client_snap_arrange_order(railPlugin* rail, const RAIL_SNAP_ARRANGE* snap)
Packit Service 5a9772
{
Packit Service 5a9772
	wStream* s;
Packit Service 5a9772
	UINT error;
Packit Service 5a9772
Packit Service 5a9772
	if (!rail)
Packit Service 5a9772
		return ERROR_INVALID_PARAMETER;
Packit Service 5a9772
Packit Service 5a9772
	/* 2.2.2.7.5 Client Window Snap PDU (TS_RAIL_ORDER_SNAP_ARRANGE) */
Packit Service 5a9772
	if ((rail->channelFlags & TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_SNAP_ARRANGE_SUPPORTED) == 0)
Packit Service 5a9772
	{
Packit Service 5a9772
		RAIL_WINDOW_MOVE_ORDER move = { 0 };
Packit Service 5a9772
		move.top = snap->top;
Packit Service 5a9772
		move.left = snap->left;
Packit Service 5a9772
		move.right = snap->right;
Packit Service 5a9772
		move.bottom = snap->bottom;
Packit Service 5a9772
		move.windowId = snap->windowId;
Packit Service 5a9772
		return rail_send_client_window_move_order(rail, &move);
Packit Service 5a9772
	}
Packit Service 5a9772
Packit Service 5a9772
	s = rail_pdu_init(12);
Packit Service 5a9772
Packit Service 5a9772
	if (!s)
Packit Service 5a9772
	{
Packit Service 5a9772
		WLog_ERR(TAG, "rail_pdu_init failed!");
Packit Service 5a9772
		return CHANNEL_RC_NO_MEMORY;
Packit Service 5a9772
	}
Packit 1fb8d4
Packit Service 5a9772
	Stream_Write_UINT32(s, snap->windowId);
Packit Service 5a9772
	Stream_Write_INT16(s, snap->left);
Packit Service 5a9772
	Stream_Write_INT16(s, snap->top);
Packit Service 5a9772
	Stream_Write_INT16(s, snap->right);
Packit Service 5a9772
	Stream_Write_INT16(s, snap->bottom);
Packit Service 5a9772
	error = rail_send_pdu(rail, s, TS_RAIL_ORDER_SNAP_ARRANGE);
Packit 1fb8d4
	Stream_Free(s, TRUE);
Packit 1fb8d4
	return error;
Packit 1fb8d4
}