mirror of https://github.com/FreeRDP/FreeRDP
rail server: implement channel code for rail server
* Split common functionality from client code * Clean up client code and use proper defines for constants * Implements the channel code to read/write server side messages.
This commit is contained in:
parent
8298728663
commit
4dacb57f6f
|
@ -20,3 +20,7 @@ define_channel("rail")
|
|||
if(WITH_CLIENT_CHANNELS)
|
||||
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
|
||||
endif()
|
||||
|
||||
if(WITH_SERVER_CHANNELS)
|
||||
add_channel_server(${MODULE_PREFIX} ${CHANNEL_NAME})
|
||||
endif()
|
||||
|
|
|
@ -129,12 +129,12 @@ static UINT rail_client_execute(RailClientContext* context, const RAIL_EXEC_ORDE
|
|||
if (!exeOrFile)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (!rail_string_to_unicode_string(exec->RemoteApplicationProgram,
|
||||
&ruExeOrFile) || /* RemoteApplicationProgram */
|
||||
!rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir,
|
||||
&ruWorkingDir) || /* ShellWorkingDirectory */
|
||||
!rail_string_to_unicode_string(exec->RemoteApplicationArguments,
|
||||
&ruArguments)) /* RemoteApplicationCmdLine */
|
||||
if (!utf8_string_to_rail_string(exec->RemoteApplicationProgram,
|
||||
&ruExeOrFile) || /* RemoteApplicationProgram */
|
||||
!utf8_string_to_rail_string(exec->RemoteApplicationWorkingDir,
|
||||
&ruWorkingDir) || /* ShellWorkingDirectory */
|
||||
!utf8_string_to_rail_string(exec->RemoteApplicationArguments,
|
||||
&ruArguments)) /* RemoteApplicationCmdLine */
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
else
|
||||
error = rail_send_client_exec_order(rail, flags, &ruExeOrFile, &ruWorkingDir, &ruArguments);
|
||||
|
@ -219,7 +219,9 @@ static UINT rail_send_client_sysparam(RailClientContext* context, RAIL_SYSPARAM_
|
|||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
if ((error = rail_write_client_sysparam_order(rail, s, sysparam)))
|
||||
if ((error = rail_write_sysparam_order(
|
||||
s, sysparam,
|
||||
(rail->channelFlags & TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED) != 0)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
Stream_Free(s, TRUE);
|
||||
|
@ -331,20 +333,6 @@ static UINT rail_client_system_param(RailClientContext* context,
|
|||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_server_system_param(RailClientContext* context,
|
||||
const RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
if (!context || !sysparam)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -378,36 +366,6 @@ static UINT rail_client_handshake(RailClientContext* context, const RAIL_HANDSHA
|
|||
return rail_send_handshake_order(rail, handshake);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_server_handshake(RailClientContext* context, const RAIL_HANDSHAKE_ORDER* handshake)
|
||||
{
|
||||
if (!context || !handshake)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_server_handshake_ex(RailClientContext* context,
|
||||
const RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
|
||||
{
|
||||
railPlugin* rail;
|
||||
|
||||
if (!context || !handshakeEx)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
rail = (railPlugin*)context->handle;
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -442,34 +400,6 @@ static UINT rail_client_window_move(RailClientContext* context,
|
|||
return rail_send_client_window_move_order(rail, windowMove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_server_local_move_size(RailClientContext* context,
|
||||
const RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
|
||||
{
|
||||
if (!context || !localMoveSize)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_server_min_max_info(RailClientContext* context,
|
||||
const RAIL_MINMAXINFO_ORDER* minMaxInfo)
|
||||
{
|
||||
if (!context || !minMaxInfo)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -520,20 +450,6 @@ static UINT rail_client_language_bar_info(RailClientContext* context,
|
|||
return rail_send_client_langbar_info_order(rail, langBarInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_server_language_bar_info(RailClientContext* context,
|
||||
const RAIL_LANGBAR_INFO_ORDER* langBarInfo)
|
||||
{
|
||||
if (!context || !langBarInfo)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
static UINT rail_client_language_ime_info(RailClientContext* context,
|
||||
const RAIL_LANGUAGEIME_INFO_ORDER* langImeInfo)
|
||||
{
|
||||
|
@ -546,20 +462,6 @@ static UINT rail_client_language_ime_info(RailClientContext* context,
|
|||
return rail_send_client_languageime_info_order(rail, langImeInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_server_execute_result(RailClientContext* context,
|
||||
const RAIL_EXEC_RESULT_ORDER* execResult)
|
||||
{
|
||||
if (!context || !execResult)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -577,6 +479,18 @@ static UINT rail_client_get_appid_request(RailClientContext* context,
|
|||
return rail_send_client_get_appid_req_order(rail, getAppIdReq);
|
||||
}
|
||||
|
||||
static UINT rail_client_compartment_info(RailClientContext* context,
|
||||
const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo)
|
||||
{
|
||||
railPlugin* rail;
|
||||
|
||||
if (!context || !compartmentInfo || !context->handle)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
rail = (railPlugin*)context->handle;
|
||||
return rail_send_client_compartment_info_order(rail, compartmentInfo);
|
||||
}
|
||||
|
||||
static UINT rail_client_cloak(RailClientContext* context, const RAIL_CLOAK* cloak)
|
||||
{
|
||||
railPlugin* rail;
|
||||
|
@ -585,7 +499,7 @@ static UINT rail_client_cloak(RailClientContext* context, const RAIL_CLOAK* cloa
|
|||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
rail = (railPlugin*)context->handle;
|
||||
return rail_send_client_order_cloak_order(rail, cloak);
|
||||
return rail_send_client_cloak_order(rail, cloak);
|
||||
}
|
||||
|
||||
static UINT rail_client_snap_arrange(RailClientContext* context, const RAIL_SNAP_ARRANGE* snap)
|
||||
|
@ -596,21 +510,7 @@ static UINT rail_client_snap_arrange(RailClientContext* context, const RAIL_SNAP
|
|||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
rail = (railPlugin*)context->handle;
|
||||
return rail_send_client_order_snap_arrange_order(rail, snap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_server_get_appid_response(RailClientContext* context,
|
||||
const RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
|
||||
{
|
||||
if (!context || !getAppIdResp)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return CHANNEL_RC_OK; /* stub - should be registered by client */
|
||||
return rail_send_client_snap_arrange_order(rail, snap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -645,7 +545,7 @@ static UINT rail_virtual_channel_event_data_received(railPlugin* rail, void* pDa
|
|||
|
||||
data_in = rail->data_in;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(data_in, (int)dataLength))
|
||||
if (!Stream_EnsureRemainingCapacity(data_in, dataLength))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
|
@ -774,6 +674,7 @@ static DWORD WINAPI rail_virtual_channel_client_thread(LPVOID arg)
|
|||
*/
|
||||
static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData, UINT32 dataLength)
|
||||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
UINT status;
|
||||
status = rail->channelEntryPoints.pVirtualChannelOpenEx(rail->InitHandle, &rail->OpenHandle,
|
||||
rail->channelDef.name,
|
||||
|
@ -786,6 +687,15 @@ static UINT rail_virtual_channel_event_connected(railPlugin* rail, LPVOID pData,
|
|||
return status;
|
||||
}
|
||||
|
||||
if (context)
|
||||
{
|
||||
IFCALLRET(context->OnOpen, status, context, &rail->sendHandshake);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
WLog_ERR(TAG, "context->OnOpen failed with %s [%08" PRIX32 "]",
|
||||
WTSErrorToString(status), status);
|
||||
}
|
||||
|
||||
rail->queue = MessageQueue_New(NULL);
|
||||
|
||||
if (!rail->queue)
|
||||
|
@ -919,9 +829,11 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Default to automatically replying to server handshakes */
|
||||
rail->sendHandshake = TRUE;
|
||||
rail->channelDef.options = CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
|
||||
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL;
|
||||
sprintf_s(rail->channelDef.name, ARRAYSIZE(rail->channelDef.name), "rail");
|
||||
sprintf_s(rail->channelDef.name, ARRAYSIZE(rail->channelDef.name), RAIL_SVC_CHANNEL_NAME);
|
||||
pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP_EX*)pEntryPoints;
|
||||
|
||||
if ((pEntryPointsEx->cbSize >= sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX)) &&
|
||||
|
@ -941,25 +853,18 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
|
|||
context->ClientExecute = rail_client_execute;
|
||||
context->ClientActivate = rail_client_activate;
|
||||
context->ClientSystemParam = rail_client_system_param;
|
||||
context->ServerSystemParam = rail_server_system_param;
|
||||
context->ClientSystemCommand = rail_client_system_command;
|
||||
context->ClientHandshake = rail_client_handshake;
|
||||
context->ServerHandshake = rail_server_handshake;
|
||||
context->ServerHandshakeEx = rail_server_handshake_ex;
|
||||
context->ClientNotifyEvent = rail_client_notify_event;
|
||||
context->ClientWindowMove = rail_client_window_move;
|
||||
context->ServerLocalMoveSize = rail_server_local_move_size;
|
||||
context->ServerMinMaxInfo = rail_server_min_max_info;
|
||||
context->ClientInformation = rail_client_information;
|
||||
context->ClientSystemMenu = rail_client_system_menu;
|
||||
context->ClientLanguageBarInfo = rail_client_language_bar_info;
|
||||
context->ServerLanguageBarInfo = rail_server_language_bar_info;
|
||||
context->ClientLanguageIMEInfo = rail_client_language_ime_info;
|
||||
context->ServerExecuteResult = rail_server_execute_result;
|
||||
context->ClientGetAppIdRequest = rail_client_get_appid_request;
|
||||
context->ServerGetAppIdResponse = rail_server_get_appid_response;
|
||||
context->ClientSnapArrange = rail_client_snap_arrange;
|
||||
context->ClientCloak = rail_client_cloak;
|
||||
context->ClientCompartmentInfo = rail_client_compartment_info;
|
||||
rail->rdpcontext = pEntryPointsEx->context;
|
||||
rail->context = context;
|
||||
isFreerdp = TRUE;
|
||||
|
|
|
@ -53,6 +53,7 @@ struct rail_plugin
|
|||
DWORD channelBuildNumber;
|
||||
DWORD channelFlags;
|
||||
RAIL_CLIENT_STATUS_ORDER clientStatus;
|
||||
BOOL sendHandshake;
|
||||
};
|
||||
typedef struct rail_plugin railPlugin;
|
||||
|
||||
|
|
|
@ -32,55 +32,6 @@
|
|||
|
||||
#include "rail_orders.h"
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_write_unicode_string(wStream* s, const RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
if (!s || !unicode_string)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, 2 + unicode_string->length))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, unicode_string->length); /* cbString (2 bytes) */
|
||||
Stream_Write(s, unicode_string->string, unicode_string->length); /* string */
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_write_unicode_string_value(wStream* s, const RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (!s || !unicode_string)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
length = unicode_string->length;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
if (!Stream_EnsureRemainingCapacity(s, length))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
Stream_Write(s, unicode_string->string, length); /* string */
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -103,37 +54,6 @@ UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType)
|
|||
return rail_send_channel_data(rail, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_write_high_contrast(wStream* s, const RAIL_HIGH_CONTRAST* highContrast)
|
||||
{
|
||||
UINT32 colorSchemeLength;
|
||||
|
||||
if (!s || !highContrast)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
colorSchemeLength = highContrast->colorScheme.length + 2;
|
||||
Stream_Write_UINT32(s, highContrast->flags); /* flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, colorSchemeLength); /* colorSchemeLength (4 bytes) */
|
||||
return rail_write_unicode_string(s, &highContrast->colorScheme); /* colorScheme */
|
||||
}
|
||||
|
||||
static UINT rail_write_filterkeys(wStream* s, const TS_FILTERKEYS* filterKeys)
|
||||
{
|
||||
if (!s || !filterKeys)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
Stream_Write_UINT32(s, filterKeys->Flags);
|
||||
Stream_Write_UINT32(s, filterKeys->WaitTime);
|
||||
Stream_Write_UINT32(s, filterKeys->DelayTime);
|
||||
Stream_Write_UINT32(s, filterKeys->RepeatTime);
|
||||
Stream_Write_UINT32(s, filterKeys->BounceTime);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -144,7 +64,7 @@ static UINT rail_read_server_exec_result_order(wStream* s, RAIL_EXEC_RESULT_ORDE
|
|||
if (!s || !execResult)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_EXEC_RESULT_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
|
@ -159,44 +79,6 @@ static UINT rail_read_server_exec_result_order(wStream* s, RAIL_EXEC_RESULT_ORDE
|
|||
: ERROR_INTERNAL_ERROR; /* exeOrFile */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_read_server_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
BYTE body;
|
||||
|
||||
if (!s || !sysparam)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 5)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, sysparam->param); /* systemParam (4 bytes) */
|
||||
Stream_Read_UINT8(s, body); /* body (1 byte) */
|
||||
|
||||
switch (sysparam->param)
|
||||
{
|
||||
case SPI_SETSCREENSAVEACTIVE:
|
||||
sysparam->setScreenSaveActive = (body != 0) ? TRUE : FALSE;
|
||||
break;
|
||||
|
||||
case SPI_SETSCREENSAVESECURE:
|
||||
sysparam->setScreenSaveSecure = (body != 0) ? TRUE : FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -207,7 +89,7 @@ static UINT rail_read_server_minmaxinfo_order(wStream* s, RAIL_MINMAXINFO_ORDER*
|
|||
if (!s || !minmaxinfo)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 20)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_MINMAXINFO_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
|
@ -238,7 +120,7 @@ static UINT rail_read_server_localmovesize_order(wStream* s,
|
|||
if (!s || !localMoveSize)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 12)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_LOCALMOVESIZE_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
|
@ -264,15 +146,16 @@ static UINT rail_read_server_get_appid_resp_order(wStream* s,
|
|||
if (!s || !getAppidResp)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 524)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_GET_APPID_RESP_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, getAppidResp->windowId); /* windowId (4 bytes) */
|
||||
Stream_Read(s, (BYTE*)&(getAppidResp->applicationId),
|
||||
520); /* applicationId (260 UNICODE chars) */
|
||||
Stream_Read_UTF16_String(
|
||||
s, getAppidResp->applicationId,
|
||||
ARRAYSIZE(getAppidResp->applicationId)); /* applicationId (260 UNICODE chars) */
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -286,7 +169,7 @@ static UINT rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* la
|
|||
if (!s || !langbarInfo)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_LANGBAR_INFO_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
|
@ -357,107 +240,6 @@ static UINT rail_write_client_exec_order(wStream* s, UINT16 flags,
|
|||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_write_client_sysparam_order(railPlugin* rail, wStream* s,
|
||||
const RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
BYTE body;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
if (!s || !sysparam)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->param); /* systemParam (4 bytes) */
|
||||
|
||||
switch (sysparam->param)
|
||||
{
|
||||
case SPI_SET_DRAG_FULL_WINDOWS:
|
||||
body = sysparam->dragFullWindows ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SET_KEYBOARD_CUES:
|
||||
body = sysparam->keyboardCues ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SET_KEYBOARD_PREF:
|
||||
body = sysparam->keyboardPref ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SET_MOUSE_BUTTON_SWAP:
|
||||
body = sysparam->mouseButtonSwap ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SET_WORK_AREA:
|
||||
Stream_Write_UINT16(s, sysparam->workArea.left); /* left (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->workArea.top); /* top (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->workArea.right); /* right (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->workArea.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_DISPLAY_CHANGE:
|
||||
Stream_Write_UINT16(s, sysparam->displayChange.left); /* left (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->displayChange.top); /* top (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->displayChange.right); /* right (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->displayChange.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_TASKBAR_POS:
|
||||
Stream_Write_UINT16(s, sysparam->taskbarPos.left); /* left (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->taskbarPos.top); /* top (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->taskbarPos.right); /* right (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->taskbarPos.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_SET_HIGH_CONTRAST:
|
||||
error = rail_write_high_contrast(s, &sysparam->highContrast);
|
||||
break;
|
||||
|
||||
case SPI_SETCARETWIDTH:
|
||||
if ((rail->channelFlags & TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED) == 0)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (sysparam->caretWidth < 0x0001)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->caretWidth);
|
||||
break;
|
||||
|
||||
case SPI_SETSTICKYKEYS:
|
||||
if ((rail->channelFlags & TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED) == 0)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->stickyKeys);
|
||||
break;
|
||||
|
||||
case SPI_SETTOGGLEKEYS:
|
||||
if ((rail->channelFlags & TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED) == 0)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->toggleKeys);
|
||||
break;
|
||||
|
||||
case SPI_SETFILTERKEYS:
|
||||
if ((rail->channelFlags & TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED) == 0)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
error = rail_write_filterkeys(s, &sysparam->filterKeys);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static UINT rail_write_client_activate_order(wStream* s, const RAIL_ACTIVATE_ORDER* activate)
|
||||
{
|
||||
BYTE enabled;
|
||||
|
@ -544,13 +326,26 @@ static UINT rail_write_languageime_info_order(wStream* s,
|
|||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
Stream_Write_UINT32(s, langImeInfo->ProfileType);
|
||||
Stream_Write_UINT32(s, langImeInfo->LanguageID);
|
||||
Stream_Write_UINT16(s, langImeInfo->LanguageID);
|
||||
Stream_Write(s, &langImeInfo->LanguageProfileCLSID, sizeof(langImeInfo->LanguageProfileCLSID));
|
||||
Stream_Write(s, &langImeInfo->ProfileGUID, sizeof(langImeInfo->ProfileGUID));
|
||||
Stream_Write_UINT32(s, langImeInfo->KeyboardLayout);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT rail_write_compartment_info_order(wStream* s,
|
||||
const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo)
|
||||
{
|
||||
if (!s || !compartmentInfo)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
Stream_Write_UINT32(s, compartmentInfo->ImeState);
|
||||
Stream_Write_UINT32(s, compartmentInfo->ImeConvMode);
|
||||
Stream_Write_UINT32(s, compartmentInfo->ImeSentenceMode);
|
||||
Stream_Write_UINT32(s, compartmentInfo->KanaMode);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -560,7 +355,6 @@ static UINT rail_recv_handshake_order(railPlugin* rail, wStream* s)
|
|||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
RAIL_HANDSHAKE_ORDER serverHandshake = { 0 };
|
||||
RAIL_HANDSHAKE_ORDER clientHandshake = { 0 };
|
||||
UINT error;
|
||||
|
||||
if (!context || !s)
|
||||
|
@ -573,10 +367,13 @@ static UINT rail_recv_handshake_order(railPlugin* rail, wStream* s)
|
|||
}
|
||||
|
||||
rail->channelBuildNumber = serverHandshake.buildNumber;
|
||||
clientHandshake.buildNumber = 0x00001DB0;
|
||||
/* 2.2.2.2.3 HandshakeEx PDU (TS_RAIL_ORDER_HANDSHAKE_EX)
|
||||
* Client response is really a Handshake PDU */
|
||||
error = context->ClientHandshake(context, &clientHandshake);
|
||||
|
||||
if (rail->sendHandshake)
|
||||
{
|
||||
RAIL_HANDSHAKE_ORDER clientHandshake = { 0 };
|
||||
clientHandshake.buildNumber = 0x00001DB0;
|
||||
error = context->ClientHandshake(context, &clientHandshake);
|
||||
}
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
return error;
|
||||
|
@ -618,7 +415,6 @@ static UINT rail_recv_handshake_ex_order(railPlugin* rail, wStream* s)
|
|||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
RAIL_HANDSHAKE_EX_ORDER serverHandshake = { 0 };
|
||||
RAIL_HANDSHAKE_ORDER clientHandshake = { 0 };
|
||||
UINT error;
|
||||
|
||||
if (!rail || !context || !s)
|
||||
|
@ -635,10 +431,15 @@ static UINT rail_recv_handshake_ex_order(railPlugin* rail, wStream* s)
|
|||
|
||||
rail->channelBuildNumber = serverHandshake.buildNumber;
|
||||
rail->channelFlags = serverHandshake.railHandshakeFlags;
|
||||
clientHandshake.buildNumber = 0x00001DB0;
|
||||
/* 2.2.2.2.3 HandshakeEx PDU (TS_RAIL_ORDER_HANDSHAKE_EX)
|
||||
* Client response is really a Handshake PDU */
|
||||
error = context->ClientHandshake(context, &clientHandshake);
|
||||
|
||||
if (rail->sendHandshake)
|
||||
{
|
||||
RAIL_HANDSHAKE_ORDER clientHandshake = { 0 };
|
||||
clientHandshake.buildNumber = 0x00001DB0;
|
||||
/* 2.2.2.2.3 HandshakeEx PDU (TS_RAIL_ORDER_HANDSHAKE_EX)
|
||||
* Client response is really a Handshake PDU */
|
||||
error = context->ClientHandshake(context, &clientHandshake);
|
||||
}
|
||||
|
||||
if (error != CHANNEL_RC_OK)
|
||||
return error;
|
||||
|
@ -701,9 +502,9 @@ static UINT rail_recv_server_sysparam_order(railPlugin* rail, wStream* s)
|
|||
if (!context || !s)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if ((error = rail_read_server_sysparam_order(s, &sysparam)))
|
||||
if ((error = rail_read_sysparam_order(s, &sysparam, FALSE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_read_server_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
WLog_ERR(TAG, "rail_read_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -851,7 +652,7 @@ static UINT rail_read_taskbar_info_order(wStream* s, RAIL_TASKBAR_INFO_ORDER* ta
|
|||
if (!s || !taskbarInfo)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 12)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_TASKBAR_INFO_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
|
@ -888,7 +689,7 @@ static UINT rail_recv_taskbar_info_order(railPlugin* rail, wStream* s)
|
|||
IFCALLRET(context->ServerTaskBarInfo, error, context, &taskBarInfo);
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %" PRIu32 "", error);
|
||||
WLog_ERR(TAG, "context.ServerTaskBarInfo failed with error %" PRIu32 "", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -899,7 +700,7 @@ static UINT rail_read_zorder_sync_order(wStream* s, RAIL_ZORDER_SYNC* zorder)
|
|||
if (!s || !zorder)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_Z_ORDER_SYNC_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
|
@ -938,23 +739,23 @@ static UINT rail_recv_zorder_sync_order(railPlugin* rail, wStream* s)
|
|||
return error;
|
||||
}
|
||||
|
||||
static UINT rail_read_order_cloak(wStream* s, RAIL_CLOAK* cloak)
|
||||
static UINT rail_read_cloak_order(wStream* s, RAIL_CLOAK* cloak)
|
||||
{
|
||||
if (!s || !cloak)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
BYTE cloaked;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 5)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_CLOAK_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, cloak->windowId);
|
||||
Stream_Read_UINT8(s, cloak->cloak);
|
||||
Stream_Read_UINT32(s, cloak->windowId); /* WindowId (4 bytes) */
|
||||
Stream_Read_UINT8(s, cloaked); /* Cloaked (1 byte) */
|
||||
cloak->cloak = (cloaked != 0) ? TRUE : FALSE;
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
static UINT rail_recv_order_cloak(railPlugin* rail, wStream* s)
|
||||
static UINT rail_recv_cloak_order(railPlugin* rail, wStream* s)
|
||||
{
|
||||
RailClientContext* context = rail_get_client_interface(rail);
|
||||
RAIL_CLOAK cloak = { 0 };
|
||||
|
@ -968,7 +769,7 @@ static UINT rail_recv_order_cloak(railPlugin* rail, wStream* s)
|
|||
if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_BIDIRECTIONAL_CLOAK_SUPPORTED) == 0)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if ((error = rail_read_order_cloak(s, &cloak)))
|
||||
if ((error = rail_read_cloak_order(s, &cloak)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
|
@ -987,16 +788,19 @@ static UINT rail_recv_order_cloak(railPlugin* rail, wStream* s)
|
|||
|
||||
static UINT rail_read_power_display_request_order(wStream* s, RAIL_POWER_DISPLAY_REQUEST* power)
|
||||
{
|
||||
UINT32 active;
|
||||
|
||||
if (!s || !power)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
if (Stream_GetRemainingLength(s) < RAIL_POWER_DISPLAY_REQUEST_ORDER_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, power->active);
|
||||
Stream_Read_UINT32(s, active);
|
||||
power->active = active != 0;
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
|
@ -1156,7 +960,7 @@ UINT rail_order_recv(railPlugin* rail, wStream* s)
|
|||
return rail_recv_zorder_sync_order(rail, s);
|
||||
|
||||
case TS_RAIL_ORDER_CLOAK:
|
||||
return rail_recv_order_cloak(rail, s);
|
||||
return rail_recv_cloak_order(rail, s);
|
||||
|
||||
case TS_RAIL_ORDER_POWER_DISPLAY_REQUEST:
|
||||
return rail_recv_power_display_request_order(rail, s);
|
||||
|
@ -1300,215 +1104,6 @@ out:
|
|||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_send_client_sysparam_order(railPlugin* rail, const RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
wStream* s;
|
||||
size_t length = RAIL_SYSPARAM_ORDER_LENGTH;
|
||||
UINT error;
|
||||
|
||||
if (!rail || !sysparam)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
switch (sysparam->param)
|
||||
{
|
||||
case SPI_SET_DRAG_FULL_WINDOWS:
|
||||
case SPI_SET_KEYBOARD_CUES:
|
||||
case SPI_SET_KEYBOARD_PREF:
|
||||
case SPI_SET_MOUSE_BUTTON_SWAP:
|
||||
length += 1;
|
||||
break;
|
||||
|
||||
case SPI_SETCARETWIDTH:
|
||||
case SPI_SETSTICKYKEYS:
|
||||
case SPI_SETTOGGLEKEYS:
|
||||
length += 4;
|
||||
break;
|
||||
|
||||
case SPI_SETFILTERKEYS:
|
||||
length += 20;
|
||||
break;
|
||||
|
||||
case SPI_SET_WORK_AREA:
|
||||
case SPI_DISPLAY_CHANGE:
|
||||
case SPI_TASKBAR_POS:
|
||||
length += 8;
|
||||
break;
|
||||
|
||||
case SPI_SET_HIGH_CONTRAST:
|
||||
length += sysparam->highContrast.colorSchemeLength + 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
length += 8;
|
||||
break;
|
||||
}
|
||||
|
||||
s = rail_pdu_init(length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
if ((error = rail_write_client_sysparam_order(rail, s, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((error = rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSPARAM)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_pdu failed with error %" PRIu32 "!", error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysparam)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
if (!rail || !sysparam)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST)
|
||||
{
|
||||
sysparam->param = SPI_SET_HIGH_CONTRAST;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_TASKBAR_POS)
|
||||
{
|
||||
sysparam->param = SPI_TASKBAR_POS;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP)
|
||||
{
|
||||
sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF)
|
||||
{
|
||||
sysparam->param = SPI_SET_KEYBOARD_PREF;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS)
|
||||
{
|
||||
sysparam->param = SPI_SET_DRAG_FULL_WINDOWS;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES)
|
||||
{
|
||||
sysparam->param = SPI_SET_KEYBOARD_CUES;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_WORK_AREA)
|
||||
{
|
||||
sysparam->param = SPI_SET_WORK_AREA;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_CARET_WIDTH)
|
||||
{
|
||||
sysparam->param = SPI_SETCARETWIDTH;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_STICKY_KEYS)
|
||||
{
|
||||
sysparam->param = SPI_SETSTICKYKEYS;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_TOGGLE_KEYS)
|
||||
{
|
||||
sysparam->param = SPI_SETTOGGLEKEYS;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (sysparam->params & SPI_MASK_SET_FILTER_KEYS)
|
||||
{
|
||||
sysparam->param = SPI_SETFILTERKEYS;
|
||||
|
||||
if ((error = rail_send_client_sysparam_order(rail, sysparam)))
|
||||
{
|
||||
WLog_ERR(TAG, "rail_send_client_sysparam_order failed with error %" PRIu32 "!", error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -1754,7 +1349,33 @@ UINT rail_send_client_languageime_info_order(railPlugin* rail,
|
|||
return error;
|
||||
}
|
||||
|
||||
UINT rail_send_client_order_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloak)
|
||||
UINT rail_send_client_compartment_info_order(railPlugin* rail,
|
||||
const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo)
|
||||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
||||
if (!rail || !compartmentInfo)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
s = rail_pdu_init(RAIL_COMPARTMENT_INFO_ORDER_LENGTH);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "rail_pdu_init failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
error = rail_write_compartment_info_order(s, compartmentInfo);
|
||||
|
||||
if (ERROR_SUCCESS == error)
|
||||
error = rail_send_pdu(rail, s, TS_RAIL_ORDER_COMPARTMENTINFO);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
UINT rail_send_client_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloak)
|
||||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
@ -1777,7 +1398,7 @@ UINT rail_send_client_order_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloa
|
|||
return error;
|
||||
}
|
||||
|
||||
UINT rail_send_client_order_snap_arrange_order(railPlugin* rail, const RAIL_SNAP_ARRANGE* snap)
|
||||
UINT rail_send_client_snap_arrange_order(railPlugin* rail, const RAIL_SNAP_ARRANGE* snap)
|
||||
{
|
||||
wStream* s;
|
||||
UINT error;
|
||||
|
|
|
@ -29,9 +29,6 @@
|
|||
|
||||
#define TAG CHANNELS_TAG("rail.client")
|
||||
|
||||
UINT rail_write_client_sysparam_order(railPlugin* rail, wStream* s,
|
||||
const RAIL_SYSPARAM_ORDER* sysparam);
|
||||
|
||||
UINT rail_order_recv(railPlugin* rail, wStream* s);
|
||||
UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType);
|
||||
|
||||
|
@ -55,7 +52,9 @@ UINT rail_send_client_langbar_info_order(railPlugin* rail,
|
|||
const RAIL_LANGBAR_INFO_ORDER* langBarInfo);
|
||||
UINT rail_send_client_languageime_info_order(railPlugin* rail,
|
||||
const RAIL_LANGUAGEIME_INFO_ORDER* langImeInfo);
|
||||
UINT rail_send_client_order_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloak);
|
||||
UINT rail_send_client_order_snap_arrange_order(railPlugin* rail, const RAIL_SNAP_ARRANGE* snap);
|
||||
UINT rail_send_client_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloak);
|
||||
UINT rail_send_client_snap_arrange_order(railPlugin* rail, const RAIL_SNAP_ARRANGE* snap);
|
||||
UINT rail_send_client_compartment_info_order(railPlugin* rail,
|
||||
const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RAIL_CLIENT_ORDERS_H */
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include "rail_common.h"
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <freerdp/channels/log.h>
|
||||
|
||||
#define TAG CHANNELS_TAG("rail.common")
|
||||
|
||||
const char* const RAIL_ORDER_TYPE_STRINGS[] = { "",
|
||||
"Execute",
|
||||
|
@ -48,30 +51,6 @@ const char* const RAIL_ORDER_TYPE_STRINGS[] = { "",
|
|||
"",
|
||||
"" };
|
||||
|
||||
BOOL rail_string_to_unicode_string(const char* string, RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
WCHAR* buffer = NULL;
|
||||
int length = 0;
|
||||
free(unicode_string->string);
|
||||
unicode_string->string = NULL;
|
||||
unicode_string->length = 0;
|
||||
|
||||
if (!string || strlen(string) < 1)
|
||||
return TRUE;
|
||||
|
||||
length = ConvertToUnicode(CP_UTF8, 0, string, -1, &buffer, 0);
|
||||
|
||||
if ((length < 0) || ((size_t)length * sizeof(WCHAR) > UINT16_MAX))
|
||||
{
|
||||
free(buffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
unicode_string->string = (BYTE*)buffer;
|
||||
unicode_string->length = (UINT16)length * sizeof(WCHAR);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
|
@ -147,3 +126,383 @@ void rail_write_handshake_ex_order(wStream* s, const RAIL_HANDSHAKE_EX_ORDER* ha
|
|||
Stream_Write_UINT32(s, handshakeEx->buildNumber); /* buildNumber (4 bytes) */
|
||||
Stream_Write_UINT32(s, handshakeEx->railHandshakeFlags); /* railHandshakeFlags (4 bytes) */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_write_unicode_string(wStream* s, const RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
if (!s || !unicode_string)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, 2 + unicode_string->length))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, unicode_string->length); /* cbString (2 bytes) */
|
||||
Stream_Write(s, unicode_string->string, unicode_string->length); /* string */
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_write_unicode_string_value(wStream* s, const RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
if (!s || !unicode_string)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
length = unicode_string->length;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
if (!Stream_EnsureRemainingCapacity(s, length))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
Stream_Write(s, unicode_string->string, length); /* string */
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_read_high_contrast(wStream* s, RAIL_HIGH_CONTRAST* highContrast)
|
||||
{
|
||||
if (!s || !highContrast)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
Stream_Read_UINT32(s, highContrast->flags); /* flags (4 bytes) */
|
||||
Stream_Read_UINT32(s, highContrast->colorSchemeLength); /* colorSchemeLength (4 bytes) */
|
||||
return rail_read_unicode_string(s, &highContrast->colorScheme); /* colorScheme */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_write_high_contrast(wStream* s, const RAIL_HIGH_CONTRAST* highContrast)
|
||||
{
|
||||
UINT32 colorSchemeLength;
|
||||
|
||||
if (!s || !highContrast)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
colorSchemeLength = highContrast->colorScheme.length + 2;
|
||||
Stream_Write_UINT32(s, highContrast->flags); /* flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, colorSchemeLength); /* colorSchemeLength (4 bytes) */
|
||||
return rail_write_unicode_string(s, &highContrast->colorScheme); /* colorScheme */
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rail_write_filterkeys(wStream* s, const TS_FILTERKEYS* filterKeys)
|
||||
{
|
||||
if (!s || !filterKeys)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
Stream_Write_UINT32(s, filterKeys->Flags);
|
||||
Stream_Write_UINT32(s, filterKeys->WaitTime);
|
||||
Stream_Write_UINT32(s, filterKeys->DelayTime);
|
||||
Stream_Write_UINT32(s, filterKeys->RepeatTime);
|
||||
Stream_Write_UINT32(s, filterKeys->BounceTime);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL extendedSpiSupported)
|
||||
{
|
||||
BYTE body;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
if (!s || !sysparam)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 5)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, sysparam->param); /* systemParam (4 bytes) */
|
||||
|
||||
switch (sysparam->param)
|
||||
{
|
||||
/* Client sysparams */
|
||||
case SPI_SET_DRAG_FULL_WINDOWS:
|
||||
Stream_Read_UINT8(s, body); /* body (1 byte) */
|
||||
sysparam->dragFullWindows = body != 0;
|
||||
break;
|
||||
|
||||
case SPI_SET_KEYBOARD_CUES:
|
||||
Stream_Read_UINT8(s, body); /* body (1 byte) */
|
||||
sysparam->keyboardCues = body != 0;
|
||||
break;
|
||||
|
||||
case SPI_SET_KEYBOARD_PREF:
|
||||
Stream_Read_UINT8(s, body); /* body (1 byte) */
|
||||
sysparam->keyboardPref = body != 0;
|
||||
break;
|
||||
|
||||
case SPI_SET_MOUSE_BUTTON_SWAP:
|
||||
Stream_Read_UINT8(s, body); /* body (1 byte) */
|
||||
sysparam->mouseButtonSwap = body != 0;
|
||||
break;
|
||||
|
||||
case SPI_SET_WORK_AREA:
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT16(s, sysparam->workArea.left); /* left (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->workArea.top); /* top (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->workArea.right); /* right (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->workArea.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_DISPLAY_CHANGE:
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT16(s, sysparam->displayChange.left); /* left (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->displayChange.top); /* top (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->displayChange.right); /* right (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->displayChange.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_TASKBAR_POS:
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT16(s, sysparam->taskbarPos.left); /* left (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->taskbarPos.top); /* top (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->taskbarPos.right); /* right (2 bytes) */
|
||||
Stream_Read_UINT16(s, sysparam->taskbarPos.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_SET_HIGH_CONTRAST:
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
error = rail_read_high_contrast(s, &sysparam->highContrast);
|
||||
break;
|
||||
|
||||
case SPI_SETCARETWIDTH:
|
||||
if (extendedSpiSupported)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, sysparam->caretWidth);
|
||||
|
||||
if (sysparam->caretWidth < 0x0001)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
break;
|
||||
|
||||
case SPI_SETSTICKYKEYS:
|
||||
if (extendedSpiSupported)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->stickyKeys);
|
||||
break;
|
||||
|
||||
case SPI_SETTOGGLEKEYS:
|
||||
if (extendedSpiSupported)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->toggleKeys);
|
||||
break;
|
||||
|
||||
case SPI_SETFILTERKEYS:
|
||||
if (extendedSpiSupported)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 20)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
error = rail_write_filterkeys(s, &sysparam->filterKeys);
|
||||
break;
|
||||
|
||||
/* Server sysparams */
|
||||
case SPI_SETSCREENSAVEACTIVE:
|
||||
Stream_Read_UINT8(s, body); /* body (1 byte) */
|
||||
sysparam->setScreenSaveActive = body != 0;
|
||||
break;
|
||||
|
||||
case SPI_SETSCREENSAVESECURE:
|
||||
Stream_Read_UINT8(s, body); /* body (1 byte) */
|
||||
sysparam->setScreenSaveSecure = body != 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 err2or code
|
||||
*/
|
||||
UINT rail_write_sysparam_order(wStream* s, const RAIL_SYSPARAM_ORDER* sysparam,
|
||||
BOOL extendedSpiSupported)
|
||||
{
|
||||
BYTE body;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
if (!s || !sysparam)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->param); /* systemParam (4 bytes) */
|
||||
|
||||
switch (sysparam->param)
|
||||
{
|
||||
/* Client sysparams */
|
||||
case SPI_SET_DRAG_FULL_WINDOWS:
|
||||
body = sysparam->dragFullWindows ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SET_KEYBOARD_CUES:
|
||||
body = sysparam->keyboardCues ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SET_KEYBOARD_PREF:
|
||||
body = sysparam->keyboardPref ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SET_MOUSE_BUTTON_SWAP:
|
||||
body = sysparam->mouseButtonSwap ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SET_WORK_AREA:
|
||||
Stream_Write_UINT16(s, sysparam->workArea.left); /* left (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->workArea.top); /* top (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->workArea.right); /* right (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->workArea.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_DISPLAY_CHANGE:
|
||||
Stream_Write_UINT16(s, sysparam->displayChange.left); /* left (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->displayChange.top); /* top (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->displayChange.right); /* right (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->displayChange.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_TASKBAR_POS:
|
||||
Stream_Write_UINT16(s, sysparam->taskbarPos.left); /* left (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->taskbarPos.top); /* top (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->taskbarPos.right); /* right (2 bytes) */
|
||||
Stream_Write_UINT16(s, sysparam->taskbarPos.bottom); /* bottom (2 bytes) */
|
||||
break;
|
||||
|
||||
case SPI_SET_HIGH_CONTRAST:
|
||||
error = rail_write_high_contrast(s, &sysparam->highContrast);
|
||||
break;
|
||||
|
||||
case SPI_SETCARETWIDTH:
|
||||
if (!extendedSpiSupported)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if (sysparam->caretWidth < 0x0001)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->caretWidth);
|
||||
break;
|
||||
|
||||
case SPI_SETSTICKYKEYS:
|
||||
if (!extendedSpiSupported)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->stickyKeys);
|
||||
break;
|
||||
|
||||
case SPI_SETTOGGLEKEYS:
|
||||
if (!extendedSpiSupported)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Write_UINT32(s, sysparam->toggleKeys);
|
||||
break;
|
||||
|
||||
case SPI_SETFILTERKEYS:
|
||||
if (!extendedSpiSupported)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
error = rail_write_filterkeys(s, &sysparam->filterKeys);
|
||||
break;
|
||||
|
||||
/* Server sysparams */
|
||||
case SPI_SETSCREENSAVEACTIVE:
|
||||
body = sysparam->setScreenSaveActive ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
case SPI_SETSCREENSAVESECURE:
|
||||
body = sysparam->setScreenSaveSecure ? 1 : 0;
|
||||
Stream_Write_UINT8(s, body);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -31,21 +31,31 @@ extern const char* const RAIL_ORDER_TYPE_STRINGS[];
|
|||
#define RAIL_PDU_HEADER_LENGTH 4
|
||||
|
||||
/* Fixed length of PDUs, excluding variable lengths */
|
||||
#define RAIL_HANDSHAKE_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_HANDSHAKE_EX_ORDER_LENGTH 8 /* fixed */
|
||||
#define RAIL_CLIENT_STATUS_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_EXEC_ORDER_LENGTH 8 /* variable */
|
||||
#define RAIL_SYSPARAM_ORDER_LENGTH 4 /* variable */
|
||||
#define RAIL_ACTIVATE_ORDER_LENGTH 5 /* fixed */
|
||||
#define RAIL_SYSMENU_ORDER_LENGTH 8 /* fixed */
|
||||
#define RAIL_SYSCOMMAND_ORDER_LENGTH 6 /* fixed */
|
||||
#define RAIL_NOTIFY_EVENT_ORDER_LENGTH 12 /* fixed */
|
||||
#define RAIL_WINDOW_MOVE_ORDER_LENGTH 12 /* fixed */
|
||||
#define RAIL_GET_APPID_REQ_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_LANGBAR_INFO_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_LANGUAGEIME_INFO_ORDER_LENGTH 44 /* fixed */
|
||||
#define RAIL_HANDSHAKE_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_HANDSHAKE_EX_ORDER_LENGTH 8 /* fixed */
|
||||
#define RAIL_CLIENT_STATUS_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_EXEC_ORDER_LENGTH 8 /* variable */
|
||||
#define RAIL_EXEC_RESULT_ORDER_LENGTH 12 /* variable */
|
||||
#define RAIL_SYSPARAM_ORDER_LENGTH 4 /* variable */
|
||||
#define RAIL_MINMAXINFO_ORDER_LENGTH 20 /* fixed */
|
||||
#define RAIL_LOCALMOVESIZE_ORDER_LENGTH 12 /* fixed */
|
||||
#define RAIL_ACTIVATE_ORDER_LENGTH 5 /* fixed */
|
||||
#define RAIL_SYSMENU_ORDER_LENGTH 8 /* fixed */
|
||||
#define RAIL_SYSCOMMAND_ORDER_LENGTH 6 /* fixed */
|
||||
#define RAIL_NOTIFY_EVENT_ORDER_LENGTH 12 /* fixed */
|
||||
#define RAIL_WINDOW_MOVE_ORDER_LENGTH 12 /* fixed */
|
||||
#define RAIL_SNAP_ARRANGE_ORDER_LENGTH 12 /* fixed */
|
||||
#define RAIL_GET_APPID_REQ_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_LANGBAR_INFO_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_LANGUAGEIME_INFO_ORDER_LENGTH 42 /* fixed */
|
||||
#define RAIL_COMPARTMENT_INFO_ORDER_LENGTH 16 /* fixed */
|
||||
#define RAIL_CLOAK_ORDER_LENGTH 5 /* fixed */
|
||||
#define RAIL_TASKBAR_INFO_ORDER_LENGTH 12 /* fixed */
|
||||
#define RAIL_Z_ORDER_SYNC_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_POWER_DISPLAY_REQUEST_ORDER_LENGTH 4 /* fixed */
|
||||
#define RAIL_GET_APPID_RESP_ORDER_LENGTH 524 /* fixed */
|
||||
#define RAIL_GET_APPID_RESP_EX_ORDER_LENGTH 1048 /* fixed */
|
||||
|
||||
BOOL rail_string_to_unicode_string(const char* string, RAIL_UNICODE_STRING* unicode_string);
|
||||
UINT rail_read_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake);
|
||||
void rail_write_handshake_order(wStream* s, const RAIL_HANDSHAKE_ORDER* handshake);
|
||||
UINT rail_read_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx);
|
||||
|
@ -55,4 +65,11 @@ wStream* rail_pdu_init(size_t length);
|
|||
UINT rail_read_pdu_header(wStream* s, UINT16* orderType, UINT16* orderLength);
|
||||
void rail_write_pdu_header(wStream* s, UINT16 orderType, UINT16 orderLength);
|
||||
|
||||
UINT rail_write_unicode_string(wStream* s, const RAIL_UNICODE_STRING* unicode_string);
|
||||
UINT rail_write_unicode_string_value(wStream* s, const RAIL_UNICODE_STRING* unicode_string);
|
||||
|
||||
UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL extendedSpiSupported);
|
||||
UINT rail_write_sysparam_order(wStream* s, const RAIL_SYSPARAM_ORDER* sysparam,
|
||||
BOOL extendedSpiSupported);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RAIL_COMMON_H */
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# Copyright 2019 Mati Shabtay <matishabtay@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
define_channel_server("rail")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
../rail_common.c
|
||||
../rail_common.h
|
||||
rail_main.c
|
||||
rail_main.h)
|
||||
|
||||
include_directories(..)
|
||||
|
||||
add_channel_server_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")
|
||||
|
||||
target_link_libraries(${MODULE_NAME} freerdp)
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Server")
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RAIL Virtual Channel Plugin
|
||||
*
|
||||
* Copyright 2019 Mati Shabtay <matishabtay@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CHANNEL_RAIL_SERVER_MAIN_H
|
||||
#define FREERDP_CHANNEL_RAIL_SERVER_MAIN_H
|
||||
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/server/rail.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/wlog.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include "../rail_common.h"
|
||||
|
||||
struct _rail_server_private
|
||||
{
|
||||
HANDLE thread;
|
||||
HANDLE stopEvent;
|
||||
HANDLE channelEvent;
|
||||
void* rail_channel;
|
||||
|
||||
wStream* input_stream;
|
||||
|
||||
DWORD channelFlags;
|
||||
};
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RAIL_SERVER_MAIN_H */
|
|
@ -49,6 +49,7 @@
|
|||
#include <freerdp/server/drdynvc.h>
|
||||
#include <freerdp/server/remdesk.h>
|
||||
#include <freerdp/server/encomsp.h>
|
||||
#include <freerdp/server/rail.h>
|
||||
#include <freerdp/server/rdpgfx.h>
|
||||
#include <freerdp/server/disp.h>
|
||||
|
||||
|
@ -63,6 +64,7 @@ void freerdp_channels_dummy(void)
|
|||
RdpeiServerContext* rdpei;
|
||||
RemdeskServerContext* remdesk;
|
||||
EncomspServerContext* encomsp;
|
||||
RailServerContext* rail;
|
||||
RdpgfxServerContext* rdpgfx;
|
||||
DispServerContext* disp;
|
||||
audin = audin_server_context_new(NULL);
|
||||
|
@ -83,6 +85,8 @@ void freerdp_channels_dummy(void)
|
|||
remdesk_server_context_free(remdesk);
|
||||
encomsp = encomsp_server_context_new(NULL);
|
||||
encomsp_server_context_free(encomsp);
|
||||
rail = rail_server_context_new(NULL);
|
||||
rail_server_context_free(rail);
|
||||
rdpgfx = rdpgfx_server_context_new(NULL);
|
||||
rdpgfx_server_context_free(rdpgfx);
|
||||
disp = disp_server_context_new(NULL);
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
* Client Interface
|
||||
*/
|
||||
|
||||
#define RAIL_SVC_CHANNEL_NAME "rail"
|
||||
|
||||
typedef struct _rail_client_context RailClientContext;
|
||||
|
||||
typedef UINT (*pcRailOnOpen)(RailClientContext* context, BOOL* sendHandshake);
|
||||
|
||||
typedef UINT (*pcRailClientExecute)(RailClientContext* context, const RAIL_EXEC_ORDER* exec);
|
||||
typedef UINT (*pcRailClientActivate)(RailClientContext* context,
|
||||
const RAIL_ACTIVATE_ORDER* activate);
|
||||
|
@ -69,7 +69,7 @@ typedef UINT (*pcRailClientLanguageBarInfo)(RailClientContext* context,
|
|||
typedef UINT (*pcRailServerLanguageBarInfo)(RailClientContext* context,
|
||||
const RAIL_LANGBAR_INFO_ORDER* langBarInfo);
|
||||
typedef UINT (*pcRailClientLanguageIMEInfo)(RailClientContext* context,
|
||||
const RAIL_LANGUAGEIME_INFO_ORDER* langBarInfo);
|
||||
const RAIL_LANGUAGEIME_INFO_ORDER* langImeInfo);
|
||||
typedef UINT (*pcRailServerExecuteResult)(RailClientContext* context,
|
||||
const RAIL_EXEC_RESULT_ORDER* execResult);
|
||||
typedef UINT (*pcRailClientGetAppIdRequest)(RailClientContext* context,
|
||||
|
@ -84,6 +84,8 @@ typedef UINT (*pcRailServerPowerDisplayRequest)(RailClientContext* context,
|
|||
typedef UINT (*pcRailClientSnapArrange)(RailClientContext* context, const RAIL_SNAP_ARRANGE* snap);
|
||||
typedef UINT (*pcRailServerGetAppidResponseExtended)(RailClientContext* context,
|
||||
const RAIL_GET_APPID_RESP_EX* id);
|
||||
typedef UINT (*pcRailClientCompartmentInfo)(RailClientContext* context,
|
||||
const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo);
|
||||
|
||||
struct _rail_client_context
|
||||
{
|
||||
|
@ -117,6 +119,8 @@ struct _rail_client_context
|
|||
pcRailServerPowerDisplayRequest ServerPowerDisplayRequest;
|
||||
pcRailClientSnapArrange ClientSnapArrange;
|
||||
pcRailServerGetAppidResponseExtended ServerGetAppidResponseExtended;
|
||||
pcRailClientCompartmentInfo ClientCompartmentInfo;
|
||||
pcRailOnOpen OnOpen;
|
||||
};
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RAIL_CLIENT_RAIL_H */
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <freerdp/types.h>
|
||||
|
||||
#define RAIL_SVC_CHANNEL_NAME "rail"
|
||||
|
||||
/* DEPRECATED: RAIL PDU flags use the spec conformant naming with TS_ prefix */
|
||||
#define RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY 0x0001
|
||||
#define RAIL_EXEC_FLAG_TRANSLATE_FILES 0x0002
|
||||
|
@ -580,6 +582,8 @@ extern "C"
|
|||
#endif
|
||||
|
||||
FREERDP_API BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string);
|
||||
FREERDP_API BOOL utf8_string_to_rail_string(const char* string,
|
||||
RAIL_UNICODE_STRING* unicode_string);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RAIL Virtual Channel Plugin
|
||||
*
|
||||
* Copyright 2019 Mati Shabtay <matishabtay@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CHANNEL_RAIL_SERVER_RAIL_H
|
||||
#define FREERDP_CHANNEL_RAIL_SERVER_RAIL_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
|
||||
#include <freerdp/rail.h>
|
||||
#include <freerdp/channels/rail.h>
|
||||
|
||||
typedef struct _rail_server_context RailServerContext;
|
||||
typedef struct _rail_server_private RailServerPrivate;
|
||||
|
||||
typedef UINT (*psRailStart)(RailServerContext* context);
|
||||
typedef BOOL (*psRailStop)(RailServerContext* context);
|
||||
|
||||
/* Client side callback types */
|
||||
typedef UINT (*psRailClientHandshake)(RailServerContext* context,
|
||||
const RAIL_HANDSHAKE_ORDER* handshake);
|
||||
typedef UINT (*psRailClientClientStatus)(RailServerContext* context,
|
||||
const RAIL_CLIENT_STATUS_ORDER* clientStatus);
|
||||
typedef UINT (*psRailClientExec)(RailServerContext* context, const RAIL_EXEC_ORDER* exec);
|
||||
typedef UINT (*psRailClientSysparam)(RailServerContext* context,
|
||||
const RAIL_SYSPARAM_ORDER* sysparam);
|
||||
typedef UINT (*psRailClientActivate)(RailServerContext* context,
|
||||
const RAIL_ACTIVATE_ORDER* activate);
|
||||
typedef UINT (*psRailClientSysmenu)(RailServerContext* context, const RAIL_SYSMENU_ORDER* sysmenu);
|
||||
typedef UINT (*psRailClientSyscommand)(RailServerContext* context,
|
||||
const RAIL_SYSCOMMAND_ORDER* syscommand);
|
||||
typedef UINT (*psRailClientNotifyEvent)(RailServerContext* context,
|
||||
const RAIL_NOTIFY_EVENT_ORDER* notifyEvent);
|
||||
typedef UINT (*psRailClientGetAppidReq)(RailServerContext* context,
|
||||
const RAIL_GET_APPID_REQ_ORDER* getAppidReq);
|
||||
typedef UINT (*psRailClientWindowMove)(RailServerContext* context,
|
||||
const RAIL_WINDOW_MOVE_ORDER* windowMove);
|
||||
typedef UINT (*psRailClientSnapArrange)(RailServerContext* context,
|
||||
const RAIL_SNAP_ARRANGE* snapArrange);
|
||||
typedef UINT (*psRailClientLangbarInfo)(RailServerContext* context,
|
||||
const RAIL_LANGBAR_INFO_ORDER* langbarInfo);
|
||||
typedef UINT (*psRailClientLanguageImeInfo)(RailServerContext* context,
|
||||
const RAIL_LANGUAGEIME_INFO_ORDER* languageImeInfo);
|
||||
typedef UINT (*psRailClientCompartmentInfo)(RailServerContext* context,
|
||||
const RAIL_COMPARTMENT_INFO_ORDER* compartmentInfo);
|
||||
typedef UINT (*psRailClientCloak)(RailServerContext* context, const RAIL_CLOAK* cloak);
|
||||
|
||||
/* Server side messages sending methods */
|
||||
typedef UINT (*psRailServerHandshake)(RailServerContext* context,
|
||||
const RAIL_HANDSHAKE_ORDER* handshake);
|
||||
typedef UINT (*psRailServerHandshakeEx)(RailServerContext* context,
|
||||
const RAIL_HANDSHAKE_EX_ORDER* handshakeEx);
|
||||
typedef UINT (*psRailServerSysparam)(RailServerContext* context,
|
||||
const RAIL_SYSPARAM_ORDER* sysparam);
|
||||
typedef UINT (*psRailServerLocalMoveSize)(RailServerContext* context,
|
||||
const RAIL_LOCALMOVESIZE_ORDER* localMoveSize);
|
||||
typedef UINT (*psRailServerMinMaxInfo)(RailServerContext* context,
|
||||
const RAIL_MINMAXINFO_ORDER* minMaxInfo);
|
||||
typedef UINT (*psRailServerTaskbarInfo)(RailServerContext* context,
|
||||
const RAIL_TASKBAR_INFO_ORDER* taskbarInfo);
|
||||
typedef UINT (*psRailServerLangbarInfo)(RailServerContext* context,
|
||||
const RAIL_LANGBAR_INFO_ORDER* langbarInfo);
|
||||
typedef UINT (*psRailServerExecResult)(RailServerContext* context,
|
||||
const RAIL_EXEC_RESULT_ORDER* execResult);
|
||||
typedef UINT (*psRailServerGetAppidResp)(RailServerContext* context,
|
||||
const RAIL_GET_APPID_RESP_ORDER* getAppIdResp);
|
||||
typedef UINT (*psRailServerZOrderSync)(RailServerContext* context,
|
||||
const RAIL_ZORDER_SYNC* zOrderSync);
|
||||
typedef UINT (*psRailServerCloak)(RailServerContext* context, const RAIL_CLOAK* cloak);
|
||||
typedef UINT (*psRailServerPowerDisplayRequest)(
|
||||
RailServerContext* context, const RAIL_POWER_DISPLAY_REQUEST* PowerDisplayRequest);
|
||||
typedef UINT (*psRailServerGetAppidRespEx)(RailServerContext* context,
|
||||
const RAIL_GET_APPID_RESP_EX* GetAppidRespEx);
|
||||
|
||||
struct _rail_server_context
|
||||
{
|
||||
HANDLE vcm;
|
||||
void* custom;
|
||||
|
||||
psRailStart Start;
|
||||
psRailStop Stop;
|
||||
|
||||
/* Callbacks from client */
|
||||
psRailClientHandshake ClientHandshake;
|
||||
psRailClientClientStatus ClientClientStatus;
|
||||
psRailClientExec ClientExec;
|
||||
psRailClientSysparam ClientSysparam;
|
||||
psRailClientActivate ClientActivate;
|
||||
psRailClientSysmenu ClientSysmenu;
|
||||
psRailClientSyscommand ClientSyscommand;
|
||||
psRailClientNotifyEvent ClientNotifyEvent;
|
||||
psRailClientGetAppidReq ClientGetAppidReq;
|
||||
psRailClientWindowMove ClientWindowMove;
|
||||
psRailClientSnapArrange ClientSnapArrange;
|
||||
psRailClientLangbarInfo ClientLangbarInfo;
|
||||
psRailClientLanguageImeInfo ClientLanguageImeInfo;
|
||||
psRailClientCompartmentInfo ClientCompartmentInfo;
|
||||
psRailClientCloak ClientCloak;
|
||||
|
||||
/* Methods for sending server side messages */
|
||||
psRailServerHandshake ServerHandshake;
|
||||
psRailServerHandshakeEx ServerHandshakeEx;
|
||||
psRailServerSysparam ServerSysparam;
|
||||
psRailServerLocalMoveSize ServerLocalMoveSize;
|
||||
psRailServerMinMaxInfo ServerMinMaxInfo;
|
||||
psRailServerTaskbarInfo ServerTaskbarInfo;
|
||||
psRailServerLangbarInfo ServerLangbarInfo;
|
||||
psRailServerExecResult ServerExecResult;
|
||||
psRailServerZOrderSync ServerZOrderSync;
|
||||
psRailServerCloak ServerCloak;
|
||||
psRailServerPowerDisplayRequest ServerPowerDisplayRequest;
|
||||
psRailServerGetAppidResp ServerGetAppidResp;
|
||||
psRailServerGetAppidRespEx ServerGetAppidRespEx;
|
||||
|
||||
RailServerPrivate* priv;
|
||||
rdpContext* rdpContext;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
FREERDP_API RailServerContext* rail_server_context_new(HANDLE vcm);
|
||||
FREERDP_API void rail_server_context_free(RailServerContext* context);
|
||||
FREERDP_API UINT rail_server_handle_messages(RailServerContext* context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RAIL_SERVER_RAIL_H */
|
|
@ -86,7 +86,6 @@ static BOOL update_recv_orders(rdpUpdate* update, wStream* s)
|
|||
static BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* bitmapData)
|
||||
{
|
||||
WINPR_UNUSED(update);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 18)
|
||||
return FALSE;
|
||||
|
||||
|
@ -2251,7 +2250,6 @@ BOOL update_send_window_icon(rdpContext* context, const WINDOW_ORDER_INFO* order
|
|||
Stream_Write_UINT16(s, orderSize);
|
||||
Stream_SetPosition(s, orderEndPos);
|
||||
update->numberOrders++;
|
||||
/* Write body */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,30 @@ BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL utf8_string_to_rail_string(const char* string, RAIL_UNICODE_STRING* unicode_string)
|
||||
{
|
||||
WCHAR* buffer = NULL;
|
||||
int length = 0;
|
||||
free(unicode_string->string);
|
||||
unicode_string->string = NULL;
|
||||
unicode_string->length = 0;
|
||||
|
||||
if (!string || strlen(string) < 1)
|
||||
return TRUE;
|
||||
|
||||
length = ConvertToUnicode(CP_UTF8, 0, string, -1, &buffer, 0);
|
||||
|
||||
if ((length < 0) || ((size_t)length * sizeof(WCHAR) > UINT16_MAX))
|
||||
{
|
||||
free(buffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
unicode_string->string = (BYTE*)buffer;
|
||||
unicode_string->length = (UINT16)length * sizeof(WCHAR);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* See [MS-RDPERP] 2.2.1.2.3 Icon Info (TS_ICON_INFO) */
|
||||
static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo)
|
||||
{
|
||||
|
@ -993,7 +1017,10 @@ BOOL update_recv_altsec_window_order(rdpUpdate* update, wStream* s)
|
|||
}
|
||||
|
||||
if (!window_order_supported(update->context->settings, orderInfo.fieldFlags))
|
||||
{
|
||||
WLog_INFO(TAG, "Window order %08" PRIx32 " not supported!", orderInfo.fieldFlags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW)
|
||||
rc = update_recv_window_info_order(update, s, &orderInfo);
|
||||
|
|
Loading…
Reference in New Issue