diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index ea772dd25..01f5ee281 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -76,13 +76,15 @@ static UINT rail_send(railPlugin* rail, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length) +UINT rail_send_channel_data(railPlugin* rail, wStream* src) { - wStream* s = NULL; + wStream* s; + size_t length; - if (!rail || !data) + if (!rail || !src) return ERROR_INVALID_PARAMETER; + length = Stream_GetPosition(src); s = Stream_New(NULL, length); if (!s) @@ -91,7 +93,7 @@ UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length) return CHANNEL_RC_NO_MEMORY; } - Stream_Write(s, data, length); + Stream_Write(s, Stream_Buffer(src), length); return rail_send(rail, s); } @@ -388,23 +390,6 @@ static UINT rail_server_handshake(RailClientContext* context, return CHANNEL_RC_OK; /* stub - should be registered by client */ } -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT rail_client_handshake_ex(RailClientContext* context, - const RAIL_HANDSHAKE_EX_ORDER* handshakeEx) -{ - railPlugin* rail; - - if (!context || !handshakeEx) - return ERROR_INVALID_PARAMETER; - - rail = (railPlugin*) context->handle; - return rail_send_handshake_ex_order(rail, handshakeEx); -} - /** * Function description * @@ -577,6 +562,30 @@ static UINT rail_client_get_appid_request(RailClientContext* context, return rail_send_client_get_appid_req_order(rail, getAppIdReq); } +static UINT rail_client_cloak(RailClientContext* context, + const RAIL_CLOAK* cloak) +{ + railPlugin* rail; + + if (!context || !cloak || !context->handle) + return ERROR_INVALID_PARAMETER; + + rail = (railPlugin*) context->handle; + return rail_send_client_order_cloak_order(rail, cloak); +} + +static UINT rail_client_snap_arrange(RailClientContext* context, + const RAIL_SNAP_ARRANGE* snap) +{ + railPlugin* rail; + + if (!context || !snap || !context->handle) + return ERROR_INVALID_PARAMETER; + + rail = (railPlugin*) context->handle; + return rail_send_client_order_snap_arrange_order(rail, snap); +} + /** * Function description * @@ -917,7 +926,6 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p context->ClientSystemCommand = rail_client_system_command; context->ClientHandshake = rail_client_handshake; context->ServerHandshake = rail_server_handshake; - context->ClientHandshakeEx = rail_client_handshake_ex; context->ServerHandshakeEx = rail_server_handshake_ex; context->ClientNotifyEvent = rail_client_notify_event; context->ClientWindowMove = rail_client_window_move; @@ -930,6 +938,8 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p 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; rail->rdpcontext = pEntryPointsEx->context; rail->context = context; isFreerdp = TRUE; diff --git a/channels/rail/client/rail_main.h b/channels/rail/client/rail_main.h index 86e752fa4..01c3a5bca 100644 --- a/channels/rail/client/rail_main.h +++ b/channels/rail/client/rail_main.h @@ -54,6 +54,6 @@ struct rail_plugin typedef struct rail_plugin railPlugin; RailClientContext* rail_get_client_interface(railPlugin* rail); -UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length); +UINT rail_send_channel_data(railPlugin* rail, wStream* s); #endif /* FREERDP_CHANNEL_RAIL_CLIENT_MAIN_H */ diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index b474de690..fef07aafe 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -99,7 +99,7 @@ UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType) Stream_SetPosition(s, orderLength); WLog_Print(rail->log, WLOG_DEBUG, "Sending %s PDU, length: %"PRIu16"", RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength); - return rail_send_channel_data(rail, Stream_Buffer(s), orderLength); + return rail_send_channel_data(rail, s); } /** @@ -494,6 +494,7 @@ static UINT rail_write_langbar_info_order(wStream* s, const RAIL_LANGBAR_INFO_OR static UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_HANDSHAKE_ORDER clientHandshake = { 0 }; UINT error; if (!context || !handshake || !s) @@ -505,6 +506,14 @@ static UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* ha return error; } + 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; + if (context->custom) { IFCALLRET(context->ServerHandshake, error, context, handshake); @@ -525,6 +534,7 @@ static UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORD wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_HANDSHAKE_ORDER clientHandshake = { 0 }; UINT error; if (!context || !handshakeEx || !s) @@ -536,6 +546,14 @@ static UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORD return error; } + 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; + if (context->custom) { IFCALLRET(context->ServerHandshakeEx, error, context, handshakeEx); @@ -736,6 +754,155 @@ static UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORD return error; } +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) + { + WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, zorder->windowIdMarker); + return CHANNEL_RC_OK; +} + +static UINT rail_recv_zorder_sync_order(railPlugin* rail, RAIL_ZORDER_SYNC* zorder, + wStream* s) +{ + RailClientContext* context = rail_get_client_interface(rail); + UINT error; + + if (!context || !zorder) + return ERROR_INVALID_PARAMETER; + + if ((error = rail_read_zorder_sync_order(s, zorder))) + { + WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %"PRIu32"!", error); + return error; + } + + if (context->custom) + { + IFCALLRET(context->ServerZOrderSync, error, context, zorder); + + if (error) + WLog_ERR(TAG, "context.ServerZOrderSync failed with error %"PRIu32"", error); + } + + return error; +} + +static UINT rail_read_power_display_request_order(wStream* s, RAIL_POWER_DISPLAY_REQUEST* power) +{ + if (!s || !power) + return ERROR_INVALID_PARAMETER; + + if (Stream_GetRemainingLength(s) < 4) + { + WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, power->active); + return CHANNEL_RC_OK; +} + +static UINT rail_recv_power_display_request_order(railPlugin* rail, + RAIL_POWER_DISPLAY_REQUEST* power, + wStream* s) +{ + RailClientContext* context = rail_get_client_interface(rail); + UINT error; + + if (!context || !power) + return ERROR_INVALID_PARAMETER; + + if ((error = rail_read_power_display_request_order(s, power))) + { + WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %"PRIu32"!", error); + return error; + } + + if (context->custom) + { + IFCALLRET(context->ServerPowerDisplayRequest, error, context, power); + + if (error) + WLog_ERR(TAG, "context.ServerPowerDisplayRequest failed with error %"PRIu32"", error); + } + + return error; +} + + +static UINT rail_read_get_application_id_extended_response_order(wStream* s, + RAIL_GET_APPID_RESP_EX* id) +{ + if (!s || !id) + return ERROR_INVALID_PARAMETER; + + if (Stream_GetRemainingLength(s) < 4) + { + WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, id->windowID); + + if (!Stream_Read_UTF16_String(s, id->applicationID, ARRAYSIZE(id->applicationID))) + return ERROR_INVALID_DATA; + + if (_wcsnlen(id->applicationID, ARRAYSIZE(id->applicationID)) >= ARRAYSIZE(id->applicationID)) + return ERROR_INVALID_DATA; + + if (Stream_GetRemainingLength(s) < 4) + { + WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, id->processId); + + if (!Stream_Read_UTF16_String(s, id->processImageName, ARRAYSIZE(id->processImageName))) + return ERROR_INVALID_DATA; + + if (_wcsnlen(id->applicationID, ARRAYSIZE(id->processImageName)) >= ARRAYSIZE(id->processImageName)) + return ERROR_INVALID_DATA; + + return CHANNEL_RC_OK; +} + +static UINT rail_recv_get_application_id_extended_response_order(railPlugin* rail, + RAIL_GET_APPID_RESP_EX* id, + wStream* s) +{ + RailClientContext* context = rail_get_client_interface(rail); + UINT error; + + if (!context || !id) + return ERROR_INVALID_PARAMETER; + + if ((error = rail_read_get_application_id_extended_response_order(s, id))) + { + WLog_ERR(TAG, "rail_read_get_application_id_extended_response_order failed with error %"PRIu32"!", + error); + return error; + } + + if (context->custom) + { + IFCALLRET(context->ServerGetAppidResponseExtended, error, context, id); + + if (error) + WLog_ERR(TAG, "context.ServerGetAppidResponseExtended failed with error %"PRIu32"", error); + } + + return error; +} + /** * Function description * @@ -811,6 +978,24 @@ UINT rail_order_recv(railPlugin* rail, wStream* s) return rail_recv_langbar_info_order(rail, &langBarInfo, s); } + case RDP_RAIL_ORDER_ZORDER_SYNC: + { + RAIL_ZORDER_SYNC val; + return rail_recv_zorder_sync_order(rail, &val, s); + } + + case RDP_RAIL_ORDER_POWER_DISPLAY_REQUEST: + { + RAIL_POWER_DISPLAY_REQUEST val; + return rail_recv_power_display_request_order(rail, &val, s); + } + + case RDP_RAIL_ORDER_GET_APPID_RESP_EX: + { + RAIL_GET_APPID_RESP_EX val; + return rail_recv_get_application_id_extended_response_order(rail, &val, s); + } + default: WLog_ERR(TAG, "Unknown RAIL PDU order reveived."); return ERROR_INVALID_DATA; @@ -1315,3 +1500,52 @@ UINT rail_send_client_langbar_info_order(railPlugin* rail, Stream_Free(s, TRUE); return error; } + +UINT rail_send_client_order_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloak) +{ + wStream* s; + UINT error; + + if (!rail || !cloak) + return ERROR_INVALID_PARAMETER; + + s = rail_pdu_init(5); + + if (!s) + { + WLog_ERR(TAG, "rail_pdu_init failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT32(s, cloak->windowId); + Stream_Write_UINT8(s, cloak->cloak ? 1 : 0); + error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_CLOAK); + Stream_Free(s, TRUE); + return error; +} + +UINT rail_send_client_order_snap_arrange_order(railPlugin* rail, const RAIL_SNAP_ARRANGE* snap) +{ + wStream* s; + UINT error; + + if (!rail) + return ERROR_INVALID_PARAMETER; + + s = rail_pdu_init(12); + + if (!s) + { + WLog_ERR(TAG, "rail_pdu_init failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + Stream_Write_UINT32(s, snap->windowId); + Stream_Write_UINT16(s, snap->left); + Stream_Write_UINT16(s, snap->top); + Stream_Write_UINT16(s, snap->right); + Stream_Write_UINT16(s, snap->bottom); + error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SNAP_ARRANGE); + Stream_Free(s, TRUE); + return error; +} diff --git a/channels/rail/client/rail_orders.h b/channels/rail/client/rail_orders.h index 0b4fd93fb..182f07c57 100644 --- a/channels/rail/client/rail_orders.h +++ b/channels/rail/client/rail_orders.h @@ -52,4 +52,7 @@ UINT rail_send_client_get_appid_req_order(railPlugin* rail, UINT rail_send_client_langbar_info_order(railPlugin* rail, const RAIL_LANGBAR_INFO_ORDER* langBarInfo); +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); + #endif /* FREERDP_CHANNEL_RAIL_CLIENT_ORDERS_H */ diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 05c30052c..99fa39fa3 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -242,6 +242,7 @@ static BOOL wl_post_connect(freerdp* instance) w = (UINT32)gdi->width; h = (UINT32)gdi->height; + if (settings->SmartSizing && !context->fullscreen) { if (settings->SmartSizingWidth > 0) @@ -390,6 +391,22 @@ static BOOL handle_uwac_events(freerdp* instance, UwacDisplay* display) return TRUE; } +static BOOL handle_window_events(freerdp* instance) +{ + rdpSettings* settings; + + if (!instance || !instance->settings) + return FALSE; + + settings = instance->settings; + + if (!settings->AsyncInput) + { + } + + return TRUE; +} + static int wlfreerdp_run(freerdp* instance) { wlfContext* context; @@ -438,6 +455,18 @@ static int wlfreerdp_run(freerdp* instance) if (freerdp_check_event_handles(instance->context) != TRUE) { + if (client_auto_reconnect_ex(instance, handle_window_events)) + continue; + else + { + /* + * Indicate an unsuccessful connection attempt if reconnect + * did not succeed and no other error was specified. + */ + if (freerdp_error_info(instance) == 0) + status = 42; + } + if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_SUCCESS) WLog_Print(context->log, WLOG_ERROR, "Failed to check FreeRDP file descriptor"); diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index e90ee24d1..117d795b8 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -984,31 +984,23 @@ static UINT xf_rail_server_execute_result(RailClientContext* context, static UINT xf_rail_server_system_param(RailClientContext* context, const RAIL_SYSPARAM_ORDER* sysparam) { + // TODO: Actually apply param return CHANNEL_RC_OK; } -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ -static UINT xf_rail_server_handshake(RailClientContext* context, - const RAIL_HANDSHAKE_ORDER* handshake) +static UINT xf_rail_server_start_cmd(RailClientContext* context) { UINT status; RAIL_EXEC_ORDER exec = { 0 }; RAIL_SYSPARAM_ORDER sysparam = { 0 }; - RAIL_HANDSHAKE_ORDER clientHandshake; RAIL_CLIENT_STATUS_ORDER clientStatus = { 0 }; xfContext* xfc = (xfContext*) context->custom; rdpSettings* settings = xfc->context.settings; - clientHandshake.buildNumber = 0x00001DB0; - status = context->ClientHandshake(context, &clientHandshake); - - if (status != CHANNEL_RC_OK) - return status; - clientStatus.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE; + + if (settings->AutoReconnectionEnabled) + clientStatus.flags |= RAIL_CLIENTSTATUS_AUTORECONNECT; + status = context->ClientInformation(context, &clientStatus); if (status != CHANNEL_RC_OK) @@ -1018,7 +1010,10 @@ static UINT xf_rail_server_handshake(RailClientContext* context, { RAIL_LANGBAR_INFO_ORDER langBarInfo; langBarInfo.languageBarStatus = 0x00000008; /* TF_SFT_HIDDEN */ - context->ClientLanguageBarInfo(context, &langBarInfo); + status = context->ClientLanguageBarInfo(context, &langBarInfo); + + if (status != CHANNEL_RC_OK) + return status; } sysparam.params = 0; @@ -1050,6 +1045,16 @@ static UINT xf_rail_server_handshake(RailClientContext* context, exec.RemoteApplicationArguments = settings->RemoteApplicationCmdLine; return context->ClientExecute(context, &exec); } +/** + * Function description + * + * @return 0 on success, otherwise a Win32 error code + */ +static UINT xf_rail_server_handshake(RailClientContext* context, + const RAIL_HANDSHAKE_ORDER* handshake) +{ + return xf_rail_server_start_cmd(context); +} /** * Function description @@ -1059,7 +1064,7 @@ static UINT xf_rail_server_handshake(RailClientContext* context, static UINT xf_rail_server_handshake_ex(RailClientContext* context, const RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { - return CHANNEL_RC_OK; + return xf_rail_server_start_cmd(context); } /** diff --git a/include/freerdp/client/rail.h b/include/freerdp/client/rail.h index 69c8ba99b..81be8eabb 100644 --- a/include/freerdp/client/rail.h +++ b/include/freerdp/client/rail.h @@ -48,8 +48,6 @@ typedef UINT(*pcRailClientHandshake)(RailClientContext* context, const RAIL_HANDSHAKE_ORDER* handshake); typedef UINT(*pcRailServerHandshake)(RailClientContext* context, const RAIL_HANDSHAKE_ORDER* handshake); -typedef UINT(*pcRailClientHandshakeEx)(RailClientContext* context, - const RAIL_HANDSHAKE_EX_ORDER* handshakeEx); typedef UINT(*pcRailServerHandshakeEx)(RailClientContext* context, const RAIL_HANDSHAKE_EX_ORDER* handshakeEx); typedef UINT(*pcRailClientNotifyEvent)(RailClientContext* context, @@ -74,6 +72,16 @@ typedef UINT(*pcRailClientGetAppIdRequest)(RailClientContext* context, const RAIL_GET_APPID_REQ_ORDER* getAppIdReq); typedef UINT(*pcRailServerGetAppIdResponse)(RailClientContext* context, const RAIL_GET_APPID_RESP_ORDER* getAppIdResp); +typedef UINT(*pcRailServerZOrderSync)(RailClientContext* context, + const RAIL_ZORDER_SYNC* zorder); +typedef UINT(*pcRailClientCloak)(RailClientContext* context, + const RAIL_CLOAK* cloak); +typedef UINT(*pcRailServerPowerDisplayRequest)(RailClientContext* context, + const RAIL_POWER_DISPLAY_REQUEST* power); +typedef UINT(*pcRailClientSnapArrange)(RailClientContext* context, + const RAIL_SNAP_ARRANGE* snap); +typedef UINT(*pcRailServerGetAppidResponseExtended)(RailClientContext* context, + const RAIL_GET_APPID_RESP_EX* id); struct _rail_client_context { @@ -87,7 +95,6 @@ struct _rail_client_context pcRailClientSystemCommand ClientSystemCommand; pcRailClientHandshake ClientHandshake; pcRailServerHandshake ServerHandshake; - pcRailClientHandshakeEx ClientHandshakeEx; pcRailServerHandshakeEx ServerHandshakeEx; pcRailClientNotifyEvent ClientNotifyEvent; pcRailClientWindowMove ClientWindowMove; @@ -100,6 +107,11 @@ struct _rail_client_context pcRailServerExecuteResult ServerExecuteResult; pcRailClientGetAppIdRequest ClientGetAppIdRequest; pcRailServerGetAppIdResponse ServerGetAppIdResponse; + pcRailServerZOrderSync ServerZOrderSync; + pcRailClientCloak ClientCloak; + pcRailServerPowerDisplayRequest ServerPowerDisplayRequest; + pcRailClientSnapArrange ClientSnapArrange; + pcRailServerGetAppidResponseExtended ServerGetAppidResponseExtended; }; #endif /* FREERDP_CHANNEL_RAIL_CLIENT_RAIL_H */ diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h index 993a1a237..81c91027f 100644 --- a/include/freerdp/rail.h +++ b/include/freerdp/rail.h @@ -145,7 +145,9 @@ enum SPI_MASK #define TF_SFT_DESKBAND 0x00000800 /* Extended Handshake Flags */ -#define RAIL_ORDER_HANDSHAKEEX_FLAGS_HIDEF 0x00000001 +#define RAIL_ORDER_HANDSHAKEEX_FLAGS_HIDEF 0x00000001 +#define RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED 0x00000002 +#define RAIL_ORDER_HANDSHAKE_EX_FLAGS_SNAP_ARRANGE_SUPPORTED 0x00000004 /* Language Profile Information Flags */ #define TF_PROFILETYPE_INPUTPROCESSOR 0x00000001 @@ -352,26 +354,69 @@ struct _RAIL_COMPARTMENT_INFO_ORDER }; typedef struct _RAIL_COMPARTMENT_INFO_ORDER RAIL_COMPARTMENT_INFO_ORDER; +struct _RAIL_ZORDER_SYNC +{ + UINT32 windowIdMarker; +}; +typedef struct _RAIL_ZORDER_SYNC RAIL_ZORDER_SYNC; + +struct _RAIL_CLOAK +{ + UINT32 windowId; + BOOL cloak; +}; +typedef struct _RAIL_CLOAK RAIL_CLOAK; + +struct _RAIL_POWER_DISPLAY_REQUEST +{ + UINT32 active; +}; +typedef struct _RAIL_POWER_DISPLAY_REQUEST RAIL_POWER_DISPLAY_REQUEST; + +struct _RAIL_SNAP_ARRANGE +{ + UINT32 windowId; + UINT16 left; + UINT16 top; + UINT16 right; + UINT16 bottom; +}; +typedef struct _RAIL_SNAP_ARRANGE RAIL_SNAP_ARRANGE; + +struct _RAIL_GET_APPID_RESP_EX +{ + UINT32 windowID; + WCHAR applicationID[512 / sizeof(WCHAR)]; + UINT32 processId; + WCHAR processImageName[512 / sizeof(WCHAR)]; +}; +typedef struct _RAIL_GET_APPID_RESP_EX RAIL_GET_APPID_RESP_EX; + /* RAIL Constants */ -#define RDP_RAIL_ORDER_EXEC 0x0001 -#define RDP_RAIL_ORDER_ACTIVATE 0x0002 -#define RDP_RAIL_ORDER_SYSPARAM 0x0003 -#define RDP_RAIL_ORDER_SYSCOMMAND 0x0004 -#define RDP_RAIL_ORDER_HANDSHAKE 0x0005 -#define RDP_RAIL_ORDER_NOTIFY_EVENT 0x0006 -#define RDP_RAIL_ORDER_WINDOWMOVE 0x0008 -#define RDP_RAIL_ORDER_LOCALMOVESIZE 0x0009 -#define RDP_RAIL_ORDER_MINMAXINFO 0x000A -#define RDP_RAIL_ORDER_CLIENTSTATUS 0x000B -#define RDP_RAIL_ORDER_SYSMENU 0x000C -#define RDP_RAIL_ORDER_LANGBARINFO 0x000D -#define RDP_RAIL_ORDER_EXEC_RESULT 0x0080 -#define RDP_RAIL_ORDER_GET_APPID_REQ 0x000E -#define RDP_RAIL_ORDER_GET_APPID_RESP 0x000F -#define RDP_RAIL_ORDER_LANGUAGEIMEINFO 0x0011 -#define RDP_RAIL_ORDER_COMPARTMENTINFO 0x0012 -#define RDP_RAIL_ORDER_HANDSHAKE_EX 0x0013 +#define RDP_RAIL_ORDER_EXEC 0x0001 +#define RDP_RAIL_ORDER_ACTIVATE 0x0002 +#define RDP_RAIL_ORDER_SYSPARAM 0x0003 +#define RDP_RAIL_ORDER_SYSCOMMAND 0x0004 +#define RDP_RAIL_ORDER_HANDSHAKE 0x0005 +#define RDP_RAIL_ORDER_NOTIFY_EVENT 0x0006 +#define RDP_RAIL_ORDER_WINDOWMOVE 0x0008 +#define RDP_RAIL_ORDER_LOCALMOVESIZE 0x0009 +#define RDP_RAIL_ORDER_MINMAXINFO 0x000A +#define RDP_RAIL_ORDER_CLIENTSTATUS 0x000B +#define RDP_RAIL_ORDER_SYSMENU 0x000C +#define RDP_RAIL_ORDER_LANGBARINFO 0x000D +#define RDP_RAIL_ORDER_EXEC_RESULT 0x0080 +#define RDP_RAIL_ORDER_GET_APPID_REQ 0x000E +#define RDP_RAIL_ORDER_GET_APPID_RESP 0x000F +#define RDP_RAIL_ORDER_LANGUAGEIMEINFO 0x0011 +#define RDP_RAIL_ORDER_COMPARTMENTINFO 0x0012 +#define RDP_RAIL_ORDER_HANDSHAKE_EX 0x0013 +#define RDP_RAIL_ORDER_ZORDER_SYNC 0x0014 +#define RDP_RAIL_ORDER_CLOAK 0x0015 +#define RDP_RAIL_ORDER_POWER_DISPLAY_REQUEST 0x0016 +#define RDP_RAIL_ORDER_SNAP_ARRANGE 0x0017 +#define RDP_RAIL_ORDER_GET_APPID_RESP_EX 0x0018 #ifdef __cplusplus diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index bf6d4351b..5a4e4c699 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -756,6 +756,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_RemoteAppNumIconCacheEntries (2123) #define FreeRDP_RemoteAppLanguageBarSupported (2124) #define FreeRDP_RemoteWndSupportLevel (2125) +#define FreeRDP_RemoteApplicationSupportLevel (2126) #define FreeRDP_ReceivedCapabilities (2240) #define FreeRDP_ReceivedCapabilitiesSize (2241) #define FreeRDP_OsMajorType (2304) @@ -1253,7 +1254,8 @@ struct rdp_settings ALIGN64 UINT32 RemoteAppNumIconCacheEntries; /* 2123 */ ALIGN64 BOOL RemoteAppLanguageBarSupported; /* 2124 */ ALIGN64 UINT32 RemoteWndSupportLevel; /* 2125 */ - UINT64 padding2176[2176 - 2126]; /* 2126 */ + ALIGN64 UINT32 RemoteApplicationSupportLevel; /* 2126 */ + UINT64 padding2176[2176 - 2127]; /* 2127 */ UINT64 padding2240[2240 - 2176]; /* 2176 */ /** diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 1807b0ec9..e31831cfa 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -2183,6 +2183,7 @@ static BOOL rdp_read_remote_programs_capability_set(wStream* s, UINT16 length, return FALSE; Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ + settings->RemoteApplicationSupportLevel = railSupportLevel; if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0) { @@ -2215,8 +2216,14 @@ static BOOL rdp_write_remote_programs_capability_set(wStream* s, header = rdp_capability_set_start(s); railSupportLevel = RAIL_LEVEL_SUPPORTED; - if (settings->RemoteAppLanguageBarSupported) - railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED; + if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED) + { + if (settings->RemoteAppLanguageBarSupported) + railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED; + } + + if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED) + railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED; Stream_Write_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL); diff --git a/libfreerdp/core/capabilities.h b/libfreerdp/core/capabilities.h index b38d89771..00e300ead 100644 --- a/libfreerdp/core/capabilities.h +++ b/libfreerdp/core/capabilities.h @@ -136,12 +136,14 @@ #define DRAW_GDIPLUS_CACHE_LEVEL_ONE 0x00000001 /* RAIL Support Level */ -#define RAIL_LEVEL_SUPPORTED 0x00000001 -#define RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED 0x00000002 -#define RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED 0x00000004 -#define RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED 0x00000008 +#define RAIL_LEVEL_SUPPORTED 0x00000001 +#define RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED 0x00000002 +#define RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED 0x00000004 +#define RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED 0x00000008 #define RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED 0x00000010 -#define RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED 0x00000020 +#define RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED 0x00000020 +#define RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED 0x00000040 +#define RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED 0x00000080 /* Window Support Level */ #define WINDOW_LEVEL_NOT_SUPPORTED 0x00000000