From 2cc714a57d54e8b5179f81911a3dd7944972438f Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 8 May 2019 15:36:20 +0200 Subject: [PATCH] Updated RAILS implementation * Implement new messages and callbacks * Announce most recent channel features * Added settings to configure flags to announce --- channels/rail/client/rail_main.c | 24 +- channels/rail/client/rail_main.h | 3 + channels/rail/client/rail_orders.c | 471 +++++++++++++++++++++-------- channels/rail/client/rail_orders.h | 6 +- channels/rail/rail_common.h | 1 + client/X11/xf_event.c | 16 +- client/X11/xf_rail.c | 136 ++++++--- client/X11/xf_rail.h | 10 + client/X11/xf_window.c | 40 ++- client/X11/xf_window.h | 4 +- include/freerdp/client/rail.h | 9 + include/freerdp/rail.h | 239 +++++++++++---- include/freerdp/settings.h | 14 +- include/freerdp/window.h | 123 +++++--- libfreerdp/core/capabilities.c | 168 +++++----- libfreerdp/core/capabilities.h | 11 - libfreerdp/core/info.c | 13 +- libfreerdp/core/message.c | 39 +-- libfreerdp/core/settings.c | 11 +- libfreerdp/core/update.c | 10 +- libfreerdp/core/window.c | 228 +++++++++----- libfreerdp/core/window.h | 1 + winpr/include/winpr/windows.h | 69 +++++ 23 files changed, 1135 insertions(+), 511 deletions(-) diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index 01f5ee281..16eaa9efe 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -130,7 +130,7 @@ static UINT rail_client_execute(RailClientContext* context, if (strnlen(exeOrFile, MAX_PATH) >= 2) { if (strncmp(exeOrFile, "||", 2) != 0) - flags |= RAIL_EXEC_FLAG_FILE; + flags |= TS_RAIL_EXEC_FLAG_FILE; } if (!rail_string_to_unicode_string(exec->RemoteApplicationProgram, @@ -216,14 +216,14 @@ static UINT rail_send_client_sysparam(RailClientContext* context, return CHANNEL_RC_NO_MEMORY; } - if ((error = rail_write_client_sysparam_order(s, sysparam))) + if ((error = rail_write_client_sysparam_order(rail, s, sysparam))) { WLog_ERR(TAG, "rail_write_client_sysparam_order failed with error %"PRIu32"!", error); Stream_Free(s, TRUE); return error; } - if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSPARAM))) + if ((error = rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSPARAM))) { WLog_ERR(TAG, "rail_send_pdu failed with error %"PRIu32"!", error); } @@ -398,10 +398,13 @@ static UINT rail_server_handshake(RailClientContext* context, static UINT rail_server_handshake_ex(RailClientContext* context, const RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { + railPlugin* rail; + if (!context || !handshakeEx) return ERROR_INVALID_PARAMETER; - return CHANNEL_RC_OK; /* stub - should be registered by client */ + rail = (railPlugin*) context->handle; + return CHANNEL_RC_OK; } /** @@ -531,6 +534,18 @@ static UINT rail_server_language_bar_info(RailClientContext* context, 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) +{ + railPlugin* rail; + + if (!context || !langImeInfo) + return ERROR_INVALID_PARAMETER; + + rail = (railPlugin*) context->handle; + return rail_send_client_languageime_info_order(rail, langImeInfo); +} + /** * Function description * @@ -935,6 +950,7 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p 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; diff --git a/channels/rail/client/rail_main.h b/channels/rail/client/rail_main.h index 01c3a5bca..577a21b39 100644 --- a/channels/rail/client/rail_main.h +++ b/channels/rail/client/rail_main.h @@ -50,6 +50,9 @@ struct rail_plugin DWORD OpenHandle; wMessageQueue* queue; rdpContext* rdpcontext; + DWORD channelBuildNumber; + DWORD channelFlags; + RAIL_CLIENT_STATUS_ORDER clientStatus; }; typedef struct rail_plugin railPlugin; diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index fef07aafe..c688af3eb 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -120,6 +120,19 @@ static UINT rail_write_high_contrast(wStream* s, const RAIL_HIGH_CONTRAST* highC 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 * @@ -167,11 +180,11 @@ static UINT rail_read_server_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sys switch (sysparam->param) { - case SPI_SET_SCREEN_SAVE_ACTIVE: + case SPI_SETSCREENSAVEACTIVE: sysparam->setScreenSaveActive = (body != 0) ? TRUE : FALSE; break; - case SPI_SET_SCREEN_SAVE_SECURE: + case SPI_SETSCREENSAVESECURE: sysparam->setScreenSaveSecure = (body != 0) ? TRUE : FALSE; break; @@ -346,7 +359,8 @@ static UINT rail_write_client_exec_order(wStream* s, UINT16 flags, * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_write_client_sysparam_order(wStream* s, const RAIL_SYSPARAM_ORDER* sysparam) +UINT rail_write_client_sysparam_order(railPlugin* rail, wStream* s, + const RAIL_SYSPARAM_ORDER* sysparam) { BYTE body; UINT error = CHANNEL_RC_OK; @@ -402,6 +416,37 @@ UINT rail_write_client_sysparam_order(wStream* s, const RAIL_SYSPARAM_ORDER* sys 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; + + error = rail_write_high_contrast(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; @@ -486,26 +531,42 @@ static UINT rail_write_langbar_info_order(wStream* s, const RAIL_LANGBAR_INFO_OR return ERROR_SUCCESS; } +static UINT rail_write_languageime_info_order(wStream* s, + const RAIL_LANGUAGEIME_INFO_ORDER* langImeInfo) +{ + if (!s || !langImeInfo) + return ERROR_INVALID_PARAMETER; + + Stream_Write_UINT32(s, langImeInfo->ProfileType); + Stream_Write_UINT32(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; +} + /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake, wStream* s) +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 || !handshake || !s) + if (!context || !s) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_handshake_order(s, handshake))) + if ((error = rail_read_handshake_order(s, &serverHandshake))) { WLog_ERR(TAG, "rail_read_handshake_order failed with error %"PRIu32"!", error); return error; } + 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 */ @@ -516,7 +577,7 @@ static UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* ha if (context->custom) { - IFCALLRET(context->ServerHandshake, error, context, handshake); + IFCALLRET(context->ServerHandshake, error, context, &serverHandshake); if (error) WLog_ERR(TAG, "context.ServerHandshake failed with error %"PRIu32"", error); @@ -525,27 +586,49 @@ static UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* ha return error; } +static BOOL rail_is_feature_supported(const rdpContext* context, UINT32 featureMask) +{ + UINT32 supported, masked; + + if (!context || !context->settings) + return FALSE; + + supported = context->settings->RemoteApplicationSupportLevel & + context->settings->RemoteApplicationSupportMask; + masked = (supported & featureMask); + + if (masked != featureMask) + return FALSE; + + return TRUE; +} + /** * Function description * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* handshakeEx, - wStream* s) +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 (!context || !handshakeEx || !s) + if (!rail || !context || !s) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_handshake_ex_order(s, handshakeEx))) + if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED)) + return ERROR_BAD_CONFIGURATION; + + if ((error = rail_read_handshake_ex_order(s, &serverHandshake))) { WLog_ERR(TAG, "rail_read_handshake_ex_order failed with error %"PRIu32"!", error); return error; } + 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 */ @@ -556,7 +639,7 @@ static UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORD if (context->custom) { - IFCALLRET(context->ServerHandshakeEx, error, context, handshakeEx); + IFCALLRET(context->ServerHandshakeEx, error, context, &serverHandshake); if (error) WLog_ERR(TAG, "context.ServerHandshakeEx failed with error %"PRIu32"", error); @@ -570,31 +653,31 @@ static UINT rail_recv_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORD * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER* execResult, - wStream* s) +static UINT rail_recv_exec_result_order(railPlugin* rail, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_EXEC_RESULT_ORDER execResult = { 0 }; UINT error; - if (!context || !execResult || !s) + if (!context || !s) return ERROR_INVALID_PARAMETER; - ZeroMemory(execResult, sizeof(RAIL_EXEC_RESULT_ORDER)); - - if ((error = rail_read_server_exec_result_order(s, execResult))) + if ((error = rail_read_server_exec_result_order(s, &execResult))) { WLog_ERR(TAG, "rail_read_server_exec_result_order failed with error %"PRIu32"!", error); - return error; + goto fail; } if (context->custom) { - IFCALLRET(context->ServerExecuteResult, error, context, execResult); + IFCALLRET(context->ServerExecuteResult, error, context, &execResult); if (error) WLog_ERR(TAG, "context.ServerExecuteResult failed with error %"PRIu32"", error); } +fail: + free(execResult.exeOrFile.string); return error; } @@ -603,16 +686,16 @@ static UINT rail_recv_exec_result_order(railPlugin* rail, RAIL_EXEC_RESULT_ORDER * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysparam, - wStream* s) +static UINT rail_recv_server_sysparam_order(railPlugin* rail, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_SYSPARAM_ORDER sysparam; UINT error; - if (!context || !sysparam || !s) + if (!context || !s) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_server_sysparam_order(s, sysparam))) + if ((error = rail_read_server_sysparam_order(s, &sysparam))) { WLog_ERR(TAG, "rail_read_server_sysparam_order failed with error %"PRIu32"!", error); return error; @@ -620,7 +703,7 @@ static UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDE if (context->custom) { - IFCALLRET(context->ServerSystemParam, error, context, sysparam); + IFCALLRET(context->ServerSystemParam, error, context, &sysparam); if (error) WLog_ERR(TAG, "context.ServerSystemParam failed with error %"PRIu32"", error); @@ -634,16 +717,16 @@ static UINT rail_recv_server_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDE * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ORDER* minMaxInfo, - wStream* s) +static UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_MINMAXINFO_ORDER minMaxInfo = { 0 }; UINT error; - if (!context || !minMaxInfo || !s) + if (!context || !s) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_server_minmaxinfo_order(s, minMaxInfo))) + if ((error = rail_read_server_minmaxinfo_order(s, &minMaxInfo))) { WLog_ERR(TAG, "rail_read_server_minmaxinfo_order failed with error %"PRIu32"!", error); return error; @@ -651,7 +734,7 @@ static UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ if (context->custom) { - IFCALLRET(context->ServerMinMaxInfo, error, context, minMaxInfo); + IFCALLRET(context->ServerMinMaxInfo, error, context, &minMaxInfo); if (error) WLog_ERR(TAG, "context.ServerMinMaxInfo failed with error %"PRIu32"", error); @@ -665,17 +748,16 @@ static UINT rail_recv_server_minmaxinfo_order(railPlugin* rail, RAIL_MINMAXINFO_ * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_recv_server_localmovesize_order(railPlugin* rail, - RAIL_LOCALMOVESIZE_ORDER* localMoveSize, - wStream* s) +static UINT rail_recv_server_localmovesize_order(railPlugin* rail, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_LOCALMOVESIZE_ORDER localMoveSize = { 0 }; UINT error; - if (!context || !localMoveSize || !s) + if (!context || !s) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_server_localmovesize_order(s, localMoveSize))) + if ((error = rail_read_server_localmovesize_order(s, &localMoveSize))) { WLog_ERR(TAG, "rail_read_server_localmovesize_order failed with error %"PRIu32"!", error); return error; @@ -683,7 +765,7 @@ static UINT rail_recv_server_localmovesize_order(railPlugin* rail, if (context->custom) { - IFCALLRET(context->ServerLocalMoveSize, error, context, localMoveSize); + IFCALLRET(context->ServerLocalMoveSize, error, context, &localMoveSize); if (error) WLog_ERR(TAG, "context.ServerLocalMoveSize failed with error %"PRIu32"", error); @@ -697,16 +779,16 @@ static UINT rail_recv_server_localmovesize_order(railPlugin* rail, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, - RAIL_GET_APPID_RESP_ORDER* getAppIdResp, wStream* s) +static UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_GET_APPID_RESP_ORDER getAppIdResp = { 0 }; UINT error; - if (!context || !getAppIdResp || !s) + if (!context || !s) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_server_get_appid_resp_order(s, getAppIdResp))) + if ((error = rail_read_server_get_appid_resp_order(s, &getAppIdResp))) { WLog_ERR(TAG, "rail_read_server_get_appid_resp_order failed with error %"PRIu32"!", error); return error; @@ -714,7 +796,7 @@ static UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, if (context->custom) { - IFCALLRET(context->ServerGetAppIdResponse, error, context, getAppIdResp); + IFCALLRET(context->ServerGetAppIdResponse, error, context, &getAppIdResp); if (error) WLog_ERR(TAG, "context.ServerGetAppIdResponse failed with error %"PRIu32"", error); @@ -728,16 +810,19 @@ static UINT rail_recv_server_get_appid_resp_order(railPlugin* rail, * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* langBarInfo, - wStream* s) +static UINT rail_recv_langbar_info_order(railPlugin* rail, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_LANGBAR_INFO_ORDER langBarInfo = { 0 }; UINT error; - if (!context || !langBarInfo) + if (!context) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_langbar_info_order(s, langBarInfo))) + if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)) + return ERROR_BAD_CONFIGURATION; + + if ((error = rail_read_langbar_info_order(s, &langBarInfo))) { WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %"PRIu32"!", error); return error; @@ -745,7 +830,57 @@ static UINT rail_recv_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORD if (context->custom) { - IFCALLRET(context->ServerLanguageBarInfo, error, context, langBarInfo); + IFCALLRET(context->ServerLanguageBarInfo, error, context, &langBarInfo); + + if (error) + WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %"PRIu32"", error); + } + + return error; +} + + +static UINT rail_read_taskbar_info_order(wStream* s, RAIL_TASKBAR_INFO_ORDER* taskbarInfo) +{ + if (!s || !taskbarInfo) + return ERROR_INVALID_PARAMETER; + + if (Stream_GetRemainingLength(s) < 12) + { + WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, taskbarInfo->TaskbarMessage); + Stream_Read_UINT32(s, taskbarInfo->WindowIdTab); + Stream_Read_UINT32(s, taskbarInfo->Body); + return CHANNEL_RC_OK; +} + + +static UINT rail_recv_taskbar_info_order(railPlugin* rail, wStream* s) +{ + RailClientContext* context = rail_get_client_interface(rail); + RAIL_TASKBAR_INFO_ORDER taskBarInfo = { 0 }; + UINT error; + + if (!context) + return ERROR_INVALID_PARAMETER; + + /* 2.2.2.14.1 Taskbar Tab Info PDU (TS_RAIL_ORDER_TASKBARINFO) + * server -> client message only supported if announced. */ + if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED)) + return ERROR_BAD_CONFIGURATION; + + if ((error = rail_read_taskbar_info_order(s, &taskBarInfo))) + { + WLog_ERR(TAG, "rail_read_langbar_info_order failed with error %"PRIu32"!", error); + return error; + } + + if (context->custom) + { + IFCALLRET(context->ServerTaskBarInfo, error, context, &taskBarInfo); if (error) WLog_ERR(TAG, "context.ServerLanguageBarInfo failed with error %"PRIu32"", error); @@ -769,16 +904,19 @@ static UINT rail_read_zorder_sync_order(wStream* s, RAIL_ZORDER_SYNC* zorder) return CHANNEL_RC_OK; } -static UINT rail_recv_zorder_sync_order(railPlugin* rail, RAIL_ZORDER_SYNC* zorder, - wStream* s) +static UINT rail_recv_zorder_sync_order(railPlugin* rail, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_ZORDER_SYNC zorder = { 0 }; UINT error; - if (!context || !zorder) + if (!context) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_zorder_sync_order(s, zorder))) + if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_ZORDER_SYNC) == 0) + return ERROR_INVALID_DATA; + + if ((error = rail_read_zorder_sync_order(s, &zorder))) { WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %"PRIu32"!", error); return error; @@ -786,7 +924,54 @@ static UINT rail_recv_zorder_sync_order(railPlugin* rail, RAIL_ZORDER_SYNC* zord if (context->custom) { - IFCALLRET(context->ServerZOrderSync, error, context, zorder); + IFCALLRET(context->ServerZOrderSync, error, context, &zorder); + + if (error) + WLog_ERR(TAG, "context.ServerZOrderSync failed with error %"PRIu32"", error); + } + + return error; +} + +static UINT rail_read_order_cloak(wStream* s, RAIL_CLOAK* cloak) +{ + if (!s || !cloak) + return ERROR_INVALID_PARAMETER; + + if (Stream_GetRemainingLength(s) < 5) + { + WLog_ERR(TAG, "Stream_GetRemainingLength failed!"); + return ERROR_INVALID_DATA; + } + + Stream_Read_UINT32(s, cloak->windowId); + Stream_Read_UINT8(s, cloak->cloak); + return CHANNEL_RC_OK; +} + +static UINT rail_recv_order_cloak(railPlugin* rail, wStream* s) +{ + RailClientContext* context = rail_get_client_interface(rail); + RAIL_CLOAK cloak = { 0 }; + UINT error; + + if (!context) + return ERROR_INVALID_PARAMETER; + + /* 2.2.2.12.1 Window Cloak State Change PDU (TS_RAIL_ORDER_CLOAK) + * server -> client message only supported if announced. */ + if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_BIDIRECTIONAL_CLOAK_SUPPORTED) == 0) + return ERROR_INVALID_DATA; + + if ((error = rail_read_order_cloak(s, &cloak))) + { + WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %"PRIu32"!", error); + return error; + } + + if (context->custom) + { + IFCALLRET(context->ServerCloak, error, context, &cloak); if (error) WLog_ERR(TAG, "context.ServerZOrderSync failed with error %"PRIu32"", error); @@ -810,17 +995,21 @@ static UINT rail_read_power_display_request_order(wStream* s, RAIL_POWER_DISPLAY return CHANNEL_RC_OK; } -static UINT rail_recv_power_display_request_order(railPlugin* rail, - RAIL_POWER_DISPLAY_REQUEST* power, - wStream* s) +static UINT rail_recv_power_display_request_order(railPlugin* rail, wStream* s) { RailClientContext* context = rail_get_client_interface(rail); + RAIL_POWER_DISPLAY_REQUEST power = { 0 }; UINT error; - if (!context || !power) + if (!context) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_power_display_request_order(s, power))) + /* 2.2.2.13.1 Power Display Request PDU(TS_RAIL_ORDER_POWER_DISPLAY_REQUEST) + */ + if ((rail->clientStatus.flags & TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED) == 0) + return ERROR_INVALID_DATA; + + 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; @@ -828,7 +1017,7 @@ static UINT rail_recv_power_display_request_order(railPlugin* rail, if (context->custom) { - IFCALLRET(context->ServerPowerDisplayRequest, error, context, power); + IFCALLRET(context->ServerPowerDisplayRequest, error, context, &power); if (error) WLog_ERR(TAG, "context.ServerPowerDisplayRequest failed with error %"PRIu32"", error); @@ -876,16 +1065,16 @@ static UINT rail_read_get_application_id_extended_response_order(wStream* s, } 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); + RAIL_GET_APPID_RESP_EX id = { 0 }; UINT error; - if (!context || !id) + if (!context) return ERROR_INVALID_PARAMETER; - if ((error = rail_read_get_application_id_extended_response_order(s, id))) + 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); @@ -894,7 +1083,7 @@ static UINT rail_recv_get_application_id_extended_response_order(railPlugin* rai if (context->custom) { - IFCALLRET(context->ServerGetAppidResponseExtended, error, context, id); + IFCALLRET(context->ServerGetAppidResponseExtended, error, context, &id); if (error) WLog_ERR(TAG, "context.ServerGetAppidResponseExtended failed with error %"PRIu32"", error); @@ -928,73 +1117,44 @@ UINT rail_order_recv(railPlugin* rail, wStream* s) switch (orderType) { - case RDP_RAIL_ORDER_HANDSHAKE: - { - RAIL_HANDSHAKE_ORDER handshake; - return rail_recv_handshake_order(rail, &handshake, s); - } + case TS_RAIL_ORDER_HANDSHAKE: + return rail_recv_handshake_order(rail, s); - case RDP_RAIL_ORDER_HANDSHAKE_EX: - { - RAIL_HANDSHAKE_EX_ORDER handshakeEx; - return rail_recv_handshake_ex_order(rail, &handshakeEx, s); - } + case TS_RAIL_ORDER_HANDSHAKE_EX: + return rail_recv_handshake_ex_order(rail, s); - case RDP_RAIL_ORDER_EXEC_RESULT: - { - RAIL_EXEC_RESULT_ORDER execResult = { 0 }; - error = rail_recv_exec_result_order(rail, &execResult, s); - free(execResult.exeOrFile.string); - return error; - } + case TS_RAIL_ORDER_EXEC_RESULT: + return rail_recv_exec_result_order(rail, s); - case RDP_RAIL_ORDER_SYSPARAM: - { - RAIL_SYSPARAM_ORDER sysparam; - return rail_recv_server_sysparam_order(rail, &sysparam, s); - } + case TS_RAIL_ORDER_SYSPARAM: + return rail_recv_server_sysparam_order(rail, s); - case RDP_RAIL_ORDER_MINMAXINFO: - { - RAIL_MINMAXINFO_ORDER minMaxInfo; - return rail_recv_server_minmaxinfo_order(rail, &minMaxInfo, s); - } + case TS_RAIL_ORDER_MINMAXINFO: + return rail_recv_server_minmaxinfo_order(rail, s); - case RDP_RAIL_ORDER_LOCALMOVESIZE: - { - RAIL_LOCALMOVESIZE_ORDER localMoveSize; - return rail_recv_server_localmovesize_order(rail, &localMoveSize, s); - } + case TS_RAIL_ORDER_LOCALMOVESIZE: + return rail_recv_server_localmovesize_order(rail, s); - case RDP_RAIL_ORDER_GET_APPID_RESP: - { - RAIL_GET_APPID_RESP_ORDER getAppIdResp; - return rail_recv_server_get_appid_resp_order(rail, &getAppIdResp, s); - } + case TS_RAIL_ORDER_GET_APPID_RESP: + return rail_recv_server_get_appid_resp_order(rail, s); - case RDP_RAIL_ORDER_LANGBARINFO: - { - RAIL_LANGBAR_INFO_ORDER langBarInfo; - return rail_recv_langbar_info_order(rail, &langBarInfo, s); - } + case TS_RAIL_ORDER_LANGBARINFO: + return rail_recv_langbar_info_order(rail, s); - case RDP_RAIL_ORDER_ZORDER_SYNC: - { - RAIL_ZORDER_SYNC val; - return rail_recv_zorder_sync_order(rail, &val, s); - } + case TS_RAIL_ORDER_TASKBARINFO: + return rail_recv_taskbar_info_order(rail, s); - case RDP_RAIL_ORDER_POWER_DISPLAY_REQUEST: - { - RAIL_POWER_DISPLAY_REQUEST val; - return rail_recv_power_display_request_order(rail, &val, s); - } + case TS_RAIL_ORDER_ZORDER_SYNC: + return rail_recv_zorder_sync_order(rail, 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); - } + case TS_RAIL_ORDER_CLOAK: + return rail_recv_order_cloak(rail, s); + + case TS_RAIL_ORDER_POWER_DISPLAY_REQUEST: + return rail_recv_power_display_request_order(rail, s); + + case TS_RAIL_ORDER_GET_APPID_RESP_EX: + return rail_recv_get_application_id_extended_response_order(rail, s); default: WLog_ERR(TAG, "Unknown RAIL PDU order reveived."); @@ -1026,7 +1186,7 @@ UINT rail_send_handshake_order(railPlugin* rail, const RAIL_HANDSHAKE_ORDER* han } rail_write_handshake_order(s, handshake); - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_HANDSHAKE); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_HANDSHAKE); Stream_Free(s, TRUE); return error; } @@ -1053,7 +1213,7 @@ UINT rail_send_handshake_ex_order(railPlugin* rail, const RAIL_HANDSHAKE_EX_ORDE } rail_write_handshake_ex_order(s, handshakeEx); - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_HANDSHAKE_EX); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_HANDSHAKE_EX); Stream_Free(s, TRUE); return error; } @@ -1071,6 +1231,7 @@ UINT rail_send_client_status_order(railPlugin* rail, const RAIL_CLIENT_STATUS_OR if (!rail || !clientStatus) return ERROR_INVALID_PARAMETER; + rail->clientStatus = *clientStatus; s = rail_pdu_init(RAIL_CLIENT_STATUS_ORDER_LENGTH); if (!s) @@ -1082,7 +1243,7 @@ UINT rail_send_client_status_order(railPlugin* rail, const RAIL_CLIENT_STATUS_OR error = rail_write_client_status_order(s, clientStatus); if (error == ERROR_SUCCESS) - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_CLIENTSTATUS); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_CLIENTSTATUS); Stream_Free(s, TRUE); return error; @@ -1122,7 +1283,7 @@ UINT rail_send_client_exec_order(railPlugin* rail, UINT16 flags, goto out; } - if ((error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_EXEC))) + if ((error = rail_send_pdu(rail, s, TS_RAIL_ORDER_EXEC))) { WLog_ERR(TAG, "rail_send_pdu failed with error %"PRIu32"!", error); goto out; @@ -1179,13 +1340,13 @@ static UINT rail_send_client_sysparam_order(railPlugin* rail, const RAIL_SYSPARA return CHANNEL_RC_NO_MEMORY; } - if ((error = rail_write_client_sysparam_order(s, sysparam))) + 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, RDP_RAIL_ORDER_SYSPARAM))) + if ((error = rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSPARAM))) { WLog_ERR(TAG, "rail_send_pdu failed with error %"PRIu32"!", error); goto out; @@ -1312,7 +1473,7 @@ UINT rail_send_client_activate_order(railPlugin* rail, const RAIL_ACTIVATE_ORDER error = rail_write_client_activate_order(s, activate); if (error == ERROR_SUCCESS) - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_ACTIVATE); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_ACTIVATE); Stream_Free(s, TRUE); return error; @@ -1342,7 +1503,7 @@ UINT rail_send_client_sysmenu_order(railPlugin* rail, const RAIL_SYSMENU_ORDER* error = rail_write_client_sysmenu_order(s, sysmenu); if (error == ERROR_SUCCESS) - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSMENU); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSMENU); Stream_Free(s, TRUE); return error; @@ -1372,7 +1533,7 @@ UINT rail_send_client_syscommand_order(railPlugin* rail, const RAIL_SYSCOMMAND_O error = rail_write_client_syscommand_order(s, syscommand); if (error == ERROR_SUCCESS) - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SYSCOMMAND); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_SYSCOMMAND); Stream_Free(s, TRUE); return error; @@ -1403,7 +1564,7 @@ UINT rail_send_client_notify_event_order(railPlugin* rail, error = rail_write_client_notify_event_order(s, notifyEvent); if (ERROR_SUCCESS == error) - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_NOTIFY_EVENT); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_NOTIFY_EVENT); Stream_Free(s, TRUE); return error; @@ -1433,7 +1594,7 @@ UINT rail_send_client_window_move_order(railPlugin* rail, const RAIL_WINDOW_MOVE error = rail_write_client_window_move_order(s, windowMove); if (error == ERROR_SUCCESS) - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_WINDOWMOVE); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_WINDOWMOVE); Stream_Free(s, TRUE); return error; @@ -1464,7 +1625,7 @@ UINT rail_send_client_get_appid_req_order(railPlugin* rail, error = rail_write_client_get_appid_req_order(s, getAppIdReq); if (error == ERROR_SUCCESS) - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_GET_APPID_REQ); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_GET_APPID_REQ); Stream_Free(s, TRUE); return error; @@ -1484,6 +1645,9 @@ UINT rail_send_client_langbar_info_order(railPlugin* rail, if (!rail || !langBarInfo) return ERROR_INVALID_PARAMETER; + if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)) + return ERROR_BAD_CONFIGURATION; + s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH); if (!s) @@ -1495,7 +1659,36 @@ UINT rail_send_client_langbar_info_order(railPlugin* rail, error = rail_write_langbar_info_order(s, langBarInfo); if (ERROR_SUCCESS == error) - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_LANGBARINFO); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_LANGBARINFO); + + Stream_Free(s, TRUE); + return error; +} + +UINT rail_send_client_languageime_info_order(railPlugin* rail, + const RAIL_LANGUAGEIME_INFO_ORDER* langImeInfo) +{ + wStream* s; + UINT error; + + if (!rail || !langImeInfo) + return ERROR_INVALID_PARAMETER; + + if (!rail_is_feature_supported(rail->rdpcontext, RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED)) + return ERROR_BAD_CONFIGURATION; + + s = rail_pdu_init(RAIL_LANGUAGEIME_INFO_ORDER_LENGTH); + + if (!s) + { + WLog_ERR(TAG, "rail_pdu_init failed!"); + return CHANNEL_RC_NO_MEMORY; + } + + error = rail_write_languageime_info_order(s, langImeInfo); + + if (ERROR_SUCCESS == error) + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_LANGUAGEIMEINFO); Stream_Free(s, TRUE); return error; @@ -1519,7 +1712,7 @@ UINT rail_send_client_order_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloa Stream_Write_UINT32(s, cloak->windowId); Stream_Write_UINT8(s, cloak->cloak ? 1 : 0); - error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_CLOAK); + error = rail_send_pdu(rail, s, TS_RAIL_ORDER_CLOAK); Stream_Free(s, TRUE); return error; } @@ -1532,6 +1725,18 @@ UINT rail_send_client_order_snap_arrange_order(railPlugin* rail, const RAIL_SNAP if (!rail) return ERROR_INVALID_PARAMETER; + /* 2.2.2.7.5 Client Window Snap PDU (TS_RAIL_ORDER_SNAP_ARRANGE) */ + if ((rail->channelFlags & TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_SNAP_ARRANGE_SUPPORTED) == 0) + { + RAIL_WINDOW_MOVE_ORDER move = { 0 }; + move.top = snap->top; + move.left = snap->left; + move.right = snap->right; + move.bottom = snap->bottom; + move.windowId = snap->windowId; + return rail_send_client_window_move_order(rail, &move); + } + s = rail_pdu_init(12); if (!s) @@ -1545,7 +1750,7 @@ UINT rail_send_client_order_snap_arrange_order(railPlugin* rail, const RAIL_SNAP 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); + error = rail_send_pdu(rail, s, TS_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 182f07c57..41ef3ebb9 100644 --- a/channels/rail/client/rail_orders.h +++ b/channels/rail/client/rail_orders.h @@ -29,7 +29,8 @@ #define TAG CHANNELS_TAG("rail.client") -UINT rail_write_client_sysparam_order(wStream* s, const RAIL_SYSPARAM_ORDER* sysparam); +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); @@ -51,7 +52,8 @@ UINT rail_send_client_get_appid_req_order(railPlugin* rail, const RAIL_GET_APPID_REQ_ORDER* getAppIdReq); 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); diff --git a/channels/rail/rail_common.h b/channels/rail/rail_common.h index fe1bc0290..c481cc4ce 100644 --- a/channels/rail/rail_common.h +++ b/channels/rail/rail_common.h @@ -43,6 +43,7 @@ extern const char* const RAIL_ORDER_TYPE_STRINGS[]; #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 */ 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); diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 562903319..3c227eb2d 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -298,14 +298,13 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app) h = event->xexpose.height; } - if (xfc->context.gdi->gfx) - { - xf_OutputExpose(xfc, x, y, w, h); - return TRUE; - } - if (!app) { + if (xfc->context.gdi->gfx) + { + xf_OutputExpose(xfc, x, y, w, h); + return TRUE; + } xf_draw_screen(xfc, x, y, w, h); } else @@ -531,6 +530,7 @@ static BOOL xf_event_FocusOut(xfContext* xfc, XEvent* event, BOOL app) static BOOL xf_event_MappingNotify(xfContext* xfc, XEvent* event, BOOL app) { WINPR_UNUSED(app); + if (event->xmapping.request == MappingModifier) { if (xfc->modifierMap) @@ -602,6 +602,7 @@ static BOOL xf_event_EnterNotify(xfContext* xfc, XEvent* event, BOOL app) static BOOL xf_event_LeaveNotify(xfContext* xfc, XEvent* event, BOOL app) { WINPR_UNUSED(event); + if (!app) { xfc->mouse_active = FALSE; @@ -718,7 +719,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app) * Doing this here would inhibit the ability to restore a maximized window * that is minimized back to the maximized state */ - //xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE); + xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE); appWindow->is_mapped = TRUE; } } @@ -930,6 +931,7 @@ static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, return FALSE; } + BOOL xf_event_process(freerdp* instance, XEvent* event) { BOOL status = TRUE; diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 117d795b8..2808dde77 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -210,7 +210,7 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow) static void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) { int index; - int count; + int count = 0; RECTANGLE_16 updateRect; RECTANGLE_16 windowRect; ULONG_PTR* pKeys = NULL; @@ -218,11 +218,12 @@ static void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) const RECTANGLE_16* extents; REGION16 windowInvalidRegion; region16_init(&windowInvalidRegion); - count = HashTable_GetKeys(xfc->railWindows, &pKeys); + if (xfc->railWindows) + count = HashTable_GetKeys(xfc->railWindows, &pKeys); for (index = 0; index < count; index++) { - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*)pKeys[index]); + appWindow = xf_rail_get_window(xfc, *(UINT64*)pKeys[index]); if (appWindow) { @@ -269,28 +270,26 @@ void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, /* RemoteApp Core Protocol Extension */ static BOOL xf_rail_window_common(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState) + const WINDOW_ORDER_INFO* orderInfo, const WINDOW_STATE_ORDER* windowState) { xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context; UINT32 fieldFlags = orderInfo->fieldFlags; BOOL position_or_size_updated = FALSE; + appWindow = xf_rail_get_window(xfc, orderInfo->windowId); if (fieldFlags & WINDOW_ORDER_STATE_NEW) { - appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow)); + if (!appWindow) + appWindow = xf_rail_add_window(xfc, orderInfo->windowId, windowState->windowOffsetX, + windowState->windowOffsetY, windowState->windowWidth, + windowState->windowHeight, 0xFFFFFFFF); if (!appWindow) return FALSE; - appWindow->xfc = xfc; - appWindow->windowId = orderInfo->windowId; appWindow->dwStyle = windowState->style; appWindow->dwExStyle = windowState->extendedStyle; - appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX; - appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY; - appWindow->width = appWindow->windowWidth = windowState->windowWidth; - appWindow->height = appWindow->windowHeight = windowState->windowHeight; /* Ensure window always gets a window title */ if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) @@ -326,13 +325,8 @@ static BOOL xf_rail_window_common(rdpContext* context, return FALSE; } - HashTable_Add(xfc->railWindows, &appWindow->windowId, (void*) appWindow); xf_AppWindowInit(xfc, appWindow); } - else - { - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, &orderInfo->windowId); - } if (!appWindow) return FALSE; @@ -534,15 +528,10 @@ static BOOL xf_rail_window_common(rdpContext* context, } static BOOL xf_rail_window_delete(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo) + const WINDOW_ORDER_INFO* orderInfo) { xfContext* xfc = (xfContext*) context; - - if (!xfc) - return FALSE; - - HashTable_Remove(xfc->railWindows, &orderInfo->windowId); - return TRUE; + return xf_rail_del_window(xfc, orderInfo->windowId); } static xfRailIconCache* RailIconCache_New(rdpSettings* settings) @@ -804,19 +793,14 @@ static void xf_rail_set_window_icon(xfContext* xfc, XFlush(xfc->display); } -static xfAppWindow* xf_rail_get_window_by_id(xfContext* xfc, UINT32 windowId) -{ - return (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, &windowId); -} - static BOOL xf_rail_window_icon(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon) + const WINDOW_ORDER_INFO* orderInfo, const WINDOW_ICON_ORDER* windowIcon) { xfContext* xfc = (xfContext*) context; xfAppWindow* railWindow; xfRailIcon* icon; BOOL replaceIcon; - railWindow = xf_rail_get_window_by_id(xfc, orderInfo->windowId); + railWindow = xf_rail_get_window(xfc, orderInfo->windowId); if (!railWindow) return TRUE; @@ -845,13 +829,13 @@ static BOOL xf_rail_window_icon(rdpContext* context, } static BOOL xf_rail_window_cached_icon(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* windowCachedIcon) + const WINDOW_ORDER_INFO* orderInfo, const WINDOW_CACHED_ICON_ORDER* windowCachedIcon) { xfContext* xfc = (xfContext*) context; xfAppWindow* railWindow; xfRailIcon* icon; BOOL replaceIcon; - railWindow = xf_rail_get_window_by_id(xfc, orderInfo->windowId); + railWindow = xf_rail_get_window(xfc, orderInfo->windowId); if (!railWindow) return TRUE; @@ -874,7 +858,7 @@ static BOOL xf_rail_window_cached_icon(rdpContext* context, } static BOOL xf_rail_notify_icon_common(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) + const WINDOW_ORDER_INFO* orderInfo, const NOTIFY_ICON_STATE_ORDER* notifyIconState) { if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) { @@ -904,31 +888,31 @@ static BOOL xf_rail_notify_icon_common(rdpContext* context, } static BOOL xf_rail_notify_icon_create(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) + const WINDOW_ORDER_INFO* orderInfo, const NOTIFY_ICON_STATE_ORDER* notifyIconState) { return xf_rail_notify_icon_common(context, orderInfo, notifyIconState); } static BOOL xf_rail_notify_icon_update(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState) + const WINDOW_ORDER_INFO* orderInfo, const NOTIFY_ICON_STATE_ORDER* notifyIconState) { return xf_rail_notify_icon_common(context, orderInfo, notifyIconState); } static BOOL xf_rail_notify_icon_delete(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo) + const WINDOW_ORDER_INFO* orderInfo) { return TRUE; } static BOOL xf_rail_monitored_desktop(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop) + const WINDOW_ORDER_INFO* orderInfo, const MONITORED_DESKTOP_ORDER* monitoredDesktop) { return TRUE; } static BOOL xf_rail_non_monitored_desktop(rdpContext* context, - WINDOW_ORDER_INFO* orderInfo) + const WINDOW_ORDER_INFO* orderInfo) { xfContext* xfc = (xfContext*) context; xf_rail_disable_remoteapp_mode(xfc); @@ -996,11 +980,16 @@ static UINT xf_rail_server_start_cmd(RailClientContext* context) RAIL_CLIENT_STATUS_ORDER clientStatus = { 0 }; xfContext* xfc = (xfContext*) context->custom; rdpSettings* settings = xfc->context.settings; - clientStatus.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE; + clientStatus.flags = TS_RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE; if (settings->AutoReconnectionEnabled) - clientStatus.flags |= RAIL_CLIENTSTATUS_AUTORECONNECT; + clientStatus.flags |= TS_RAIL_CLIENTSTATUS_AUTORECONNECT; + clientStatus.flags |= TS_RAIL_CLIENTSTATUS_ZORDER_SYNC; + clientStatus.flags |= TS_RAIL_CLIENTSTATUS_WINDOW_RESIZE_MARGIN_SUPPORTED; + clientStatus.flags |= TS_RAIL_CLIENTSTATUS_APPBAR_REMOTING_SUPPORTED; + clientStatus.flags |= TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED; + clientStatus.flags |= TS_RAIL_CLIENTSTATUS_BIDIRECTIONAL_CLOAK_SUPPORTED; status = context->ClientInformation(context, &clientStatus); if (status != CHANNEL_RC_OK) @@ -1078,10 +1067,8 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context, int x = 0, y = 0; int direction = 0; Window child_window; - xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context->custom; - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, - (void*)&localMoveSize->windowId); + xfAppWindow* appWindow = xf_rail_get_window(xfc, localMoveSize->windowId); if (!appWindow) return ERROR_INTERNAL_ERROR; @@ -1174,9 +1161,8 @@ static UINT xf_rail_server_local_move_size(RailClientContext* context, static UINT xf_rail_server_min_max_info(RailClientContext* context, const RAIL_MINMAXINFO_ORDER* minMaxInfo) { - xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context->custom; - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*)&minMaxInfo->windowId); + xfAppWindow* appWindow = xf_rail_get_window(xfc, minMaxInfo->windowId); if (appWindow) { @@ -1214,12 +1200,19 @@ static UINT xf_rail_server_get_appid_response(RailClientContext* context, static BOOL rail_window_key_equals(void* key1, void* key2) { - return *(UINT32*)key1 == *(UINT32*)key2; + const UINT64* k1 = (const UINT64*)key1; + const UINT64* k2 = (const UINT64*)key2; + + if (!k1 || !k2) + return FALSE; + + return *k1 == *k2; } static UINT32 rail_window_key_hash(void* key) { - return *(UINT32*)key; + const UINT64* k1 = (const UINT64*)key; + return (UINT32) * k1; } static void rail_window_free(void* value) @@ -1272,6 +1265,7 @@ int xf_rail_init(xfContext* xfc, RailClientContext* rail) int xf_rail_uninit(xfContext* xfc, RailClientContext* rail) { WINPR_UNUSED(rail); + if (xfc->rail) { xfc->rail->custom = NULL; @@ -1292,3 +1286,51 @@ int xf_rail_uninit(xfContext* xfc, RailClientContext* rail) return 1; } + +xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, UINT32 x, UINT32 y, UINT32 width, + UINT32 height, UINT32 surfaceId) +{ + xfAppWindow* appWindow; + + if (!xfc) + return NULL; + + appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow)); + + if (!appWindow) + return NULL; + + appWindow->xfc = xfc; + appWindow->windowId = id; + appWindow->surfaceId = surfaceId; + appWindow->x = x; + appWindow->y = y; + appWindow->width = width; + appWindow->height = height; + xf_AppWindowCreate(xfc, appWindow); + HashTable_Add(xfc->railWindows, &appWindow->windowId, (void*) appWindow); + return appWindow; +} + +BOOL xf_rail_del_window(xfContext* xfc, UINT64 id) +{ + if (!xfc) + return FALSE; + + if (!xfc->railWindows) + return FALSE; + + return HashTable_Remove(xfc->railWindows, &id); +} + +xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id) +{ + if (!xfc) + return NULL; + + if (!xfc->railWindows) + return FALSE; + + return HashTable_GetItemValue(xfc->railWindows, &id); +} + diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h index 2e1ea539c..0953ae6be 100644 --- a/client/X11/xf_rail.h +++ b/client/X11/xf_rail.h @@ -33,6 +33,16 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow); void xf_rail_enable_remoteapp_mode(xfContext* xfc); void xf_rail_disable_remoteapp_mode(xfContext* xfc); +xfAppWindow* xf_rail_add_window(xfContext* xfc, UINT64 id, UINT32 x, UINT32 y, + UINT32 width, UINT32 height, UINT32 surfaceId); +xfAppWindow* xf_rail_get_window(xfContext* xfc, UINT64 id); + +BOOL xf_rail_del_window(xfContext* xfc, UINT64 id); + +BOOL xf_rail_draw_window(xfContext* xfc, xfAppWindow* window, const char* data, + UINT32 scanline, UINT32 width, UINT32 height, + const RECTANGLE_16* src, const RECTANGLE_16* dst); + int xf_rail_init(xfContext* xfc, RailClientContext* rail); int xf_rail_uninit(xfContext* xfc, RailClientContext* rail); diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 45dc28940..ece2966a8 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -757,6 +757,24 @@ static void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, } int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow) +{ + if (!xfc || !appWindow) + return -1; + + xf_SetWindowDecorations(xfc, appWindow->handle, appWindow->decorations); + xf_SetWindowStyle(xfc, appWindow, appWindow->dwStyle, appWindow->dwExStyle); + xf_SetWindowPID(xfc, appWindow->handle, 0); + xf_ShowWindow(xfc, appWindow, WINDOW_SHOW); + XClearWindow(xfc->display, appWindow->handle); + XMapWindow(xfc->display, appWindow->handle); + /* Move doesn't seem to work until window is mapped. */ + xf_MoveWindow(xfc, appWindow, appWindow->x, appWindow->y, appWindow->width, + appWindow->height); + xf_SetWindowText(xfc, appWindow, appWindow->title); + return 1; +} + +int xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow) { XGCValues gcv; int input_mask; @@ -794,7 +812,7 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow) else { class = malloc(sizeof("RAIL:00000000")); - sprintf_s(class, sizeof("RAIL:00000000"), "RAIL:%08"PRIX32"", appWindow->windowId); + sprintf_s(class, sizeof("RAIL:00000000"), "RAIL:%08"PRIX64"", appWindow->windowId); class_hints->res_class = class; } @@ -820,16 +838,7 @@ int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow) SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask | ColormapChangeMask | OwnerGrabButtonMask; XSelectInput(xfc->display, appWindow->handle, input_mask); - xf_SetWindowDecorations(xfc, appWindow->handle, appWindow->decorations); - xf_SetWindowStyle(xfc, appWindow, appWindow->dwStyle, appWindow->dwExStyle); - xf_SetWindowPID(xfc, appWindow->handle, 0); - xf_ShowWindow(xfc, appWindow, WINDOW_SHOW); - XClearWindow(xfc->display, appWindow->handle); - XMapWindow(xfc->display, appWindow->handle); - /* Move doesn't seem to work until window is mapped. */ - xf_MoveWindow(xfc, appWindow, appWindow->x, appWindow->y, appWindow->width, - appWindow->height); - xf_SetWindowText(xfc, appWindow, appWindow->title); + return 1; } @@ -986,7 +995,6 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state) xf_SetWindowUnlisted(xfc, appWindow->handle); XMapWindow(xfc->display, appWindow->handle); - break; } @@ -1055,6 +1063,9 @@ void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, if (appWindow == NULL) return; + if (appWindow->surfaceId < UINT16_MAX) + return; + ax = x + appWindow->windowOffsetX; ay = y + appWindow->windowOffsetY; @@ -1117,7 +1128,10 @@ xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd) for (index = 0; index < count; index++) { - appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]); + appWindow = xf_rail_get_window(xfc, *(UINT64*)pKeys[index]); + + if (!appWindow) + return NULL; if (appWindow->handle == wnd) { diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index b0ecb0270..6e4b90966 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -97,7 +97,8 @@ struct xf_app_window int height; char* title; - UINT32 windowId; + UINT32 surfaceId; + UINT64 windowId; UINT32 ownerWindowId; UINT32 dwStyle; @@ -160,6 +161,7 @@ BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int leng unsigned long* nitems, unsigned long* bytes, BYTE** prop); void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int numArgs, ...); +int xf_AppWindowCreate(xfContext* xfc, xfAppWindow* appWindow); int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow); void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, const char* name); void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height); diff --git a/include/freerdp/client/rail.h b/include/freerdp/client/rail.h index 81be8eabb..43a8f490b 100644 --- a/include/freerdp/client/rail.h +++ b/include/freerdp/client/rail.h @@ -62,10 +62,14 @@ typedef UINT(*pcRailClientInformation)(RailClientContext* context, const RAIL_CLIENT_STATUS_ORDER* clientStatus); typedef UINT(*pcRailClientSystemMenu)(RailClientContext* context, const RAIL_SYSMENU_ORDER* sysmenu); +typedef UINT(*pcRailServerTaskBarInfo)(RailClientContext* context, + const RAIL_TASKBAR_INFO_ORDER* taskBarInfo); typedef UINT(*pcRailClientLanguageBarInfo)(RailClientContext* context, const RAIL_LANGBAR_INFO_ORDER* langBarInfo); typedef UINT(*pcRailServerLanguageBarInfo)(RailClientContext* context, const RAIL_LANGBAR_INFO_ORDER* langBarInfo); +typedef UINT(*pcRailClientLanguageIMEInfo)(RailClientContext* context, + const RAIL_LANGUAGEIME_INFO_ORDER* langBarInfo); typedef UINT(*pcRailServerExecuteResult)(RailClientContext* context, const RAIL_EXEC_RESULT_ORDER* execResult); typedef UINT(*pcRailClientGetAppIdRequest)(RailClientContext* context, @@ -74,6 +78,8 @@ typedef UINT(*pcRailServerGetAppIdResponse)(RailClientContext* context, const RAIL_GET_APPID_RESP_ORDER* getAppIdResp); typedef UINT(*pcRailServerZOrderSync)(RailClientContext* context, const RAIL_ZORDER_SYNC* zorder); +typedef UINT(*pcRailServerCloak)(RailClientContext* context, + const RAIL_CLOAK* cloak); typedef UINT(*pcRailClientCloak)(RailClientContext* context, const RAIL_CLOAK* cloak); typedef UINT(*pcRailServerPowerDisplayRequest)(RailClientContext* context, @@ -102,13 +108,16 @@ struct _rail_client_context pcRailServerMinMaxInfo ServerMinMaxInfo; pcRailClientInformation ClientInformation; pcRailClientSystemMenu ClientSystemMenu; + pcRailServerTaskBarInfo ServerTaskBarInfo; pcRailClientLanguageBarInfo ClientLanguageBarInfo; pcRailServerLanguageBarInfo ServerLanguageBarInfo; + pcRailClientLanguageIMEInfo ClientLanguageIMEInfo; pcRailServerExecuteResult ServerExecuteResult; pcRailClientGetAppIdRequest ClientGetAppIdRequest; pcRailServerGetAppIdResponse ServerGetAppIdResponse; pcRailServerZOrderSync ServerZOrderSync; pcRailClientCloak ClientCloak; + pcRailServerCloak ServerCloak; pcRailServerPowerDisplayRequest ServerPowerDisplayRequest; pcRailClientSnapArrange ClientSnapArrange; pcRailServerGetAppidResponseExtended ServerGetAppidResponseExtended; diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h index 81c91027f..9c45e07e9 100644 --- a/include/freerdp/rail.h +++ b/include/freerdp/rail.h @@ -22,15 +22,23 @@ #define FREERDP_RAIL_GLOBAL_H #include +#include #include -/* RAIL PDU flags */ +/* 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 #define RAIL_EXEC_FLAG_FILE 0x0004 #define RAIL_EXEC_FLAG_EXPAND_ARGUMENTS 0x0008 +/* RAIL PDU flags */ +#define TS_RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY 0x0001 +#define TS_RAIL_EXEC_FLAG_TRANSLATE_FILES 0x0002 +#define TS_RAIL_EXEC_FLAG_FILE 0x0004 +#define TS_RAIL_EXEC_FLAG_EXPAND_ARGUMENTS 0x0008 +#define TS_RAIL_EXEC_FLAG_APP_USER_MODEL_ID 0x0010 + /* Notification Icon Balloon Tooltip */ #define NIIF_NONE 0x00000000 #define NIIF_INFO 0x00000001 @@ -55,17 +63,9 @@ #define RAIL_EXEC_E_FAIL 0x0006 #define RAIL_EXEC_E_SESSION_LOCKED 0x0007 -/* Client System Parameters Update PDU */ -#define SPI_SET_DRAG_FULL_WINDOWS 0x00000025 -#define SPI_SET_KEYBOARD_CUES 0x0000100B -#define SPI_SET_KEYBOARD_PREF 0x00000045 -#define SPI_SET_MOUSE_BUTTON_SWAP 0x00000021 -#define SPI_SET_WORK_AREA 0x0000002F -#define SPI_DISPLAY_CHANGE 0x0000F001 -#define SPI_TASKBAR_POS 0x0000F000 -#define SPI_SET_HIGH_CONTRAST 0x00000043 - -/* Server System Parameters Update PDU */ +/* DEPRECATED: Server System Parameters Update PDU + * use the spec conformant naming scheme from winpr/windows.h + */ #define SPI_SET_SCREEN_SAVE_ACTIVE 0x00000011 #define SPI_SET_SCREEN_SAVE_SECURE 0x00000077 @@ -84,6 +84,18 @@ enum SPI_MASK SPI_MASK_SET_SET_SCREEN_SAVE_SECURE = 0x00000200 }; +/* Client System Parameters Update PDU + * some are defined in winuser.h (winpr/windows.h wrapper) + */ +#define SPI_SET_DRAG_FULL_WINDOWS 0x00000025 +#define SPI_SET_KEYBOARD_CUES 0x0000100B +#define SPI_SET_KEYBOARD_PREF 0x00000045 +#define SPI_SET_MOUSE_BUTTON_SWAP 0x00000021 +#define SPI_SET_WORK_AREA 0x0000002F +#define SPI_DISPLAY_CHANGE 0x0000F001 +#define SPI_TASKBAR_POS 0x0000F000 +#define SPI_SET_HIGH_CONTRAST 0x00000043 + /* Client System Command PDU */ #define SC_SIZE 0xF000 #define SC_MOVE 0xF010 @@ -96,66 +108,98 @@ enum SPI_MASK /* Client Notify Event PDU */ #ifndef _WIN32 -#define NIN_SELECT 0x00000400 -#define NIN_KEYSELECT 0x00000401 -#define NIN_BALLOONSHOW 0x00000402 -#define NIN_BALLOONHIDE 0x00000403 -#define NIN_BALLOONTIMEOUT 0x00000404 -#define NIN_BALLOONUSERCLICK 0x00000405 +#define NIN_SELECT 0x00000400 +#define NIN_KEYSELECT 0x00000401 +#define NIN_BALLOONSHOW 0x00000402 +#define NIN_BALLOONHIDE 0x00000403 +#define NIN_BALLOONTIMEOUT 0x00000404 +#define NIN_BALLOONUSERCLICK 0x00000405 +#else +#include #endif -/* Client Information PDU */ +/* DEPRECATED: Client Information PDU + * use the spec conformant naming scheme TS_ below + */ #define RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE 0x00000001 #define RAIL_CLIENTSTATUS_AUTORECONNECT 0x00000002 -/* HIGHCONTRAST flags values */ -#define HCF_AVAILABLE 0x00000002 -#define HCF_CONFIRMHOTKEY 0x00000008 -#define HCF_HIGHCONTRASTON 0x00000001 -#define HCF_HOTKEYACTIVE 0x00000004 -#define HCF_HOTKEYAVAILABLE 0x00000040 -#define HCF_HOTKEYSOUND 0x00000010 -#define HCF_INDICATOR 0x00000020 +/* Client Information PDU */ +#define TS_RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE 0x00000001 +#define TS_RAIL_CLIENTSTATUS_AUTORECONNECT 0x00000002 +#define TS_RAIL_CLIENTSTATUS_ZORDER_SYNC 0x00000004 +#define TS_RAIL_CLIENTSTATUS_WINDOW_RESIZE_MARGIN_SUPPORTED 0x00000010 +#define TS_RAIL_CLIENTSTATUS_APPBAR_REMOTING_SUPPORTED 0x00000040 +#define TS_RAIL_CLIENTSTATUS_POWER_DISPLAY_REQUEST_SUPPORTED 0x00000080 +#define TS_RAIL_CLIENTSTATUS_BIDIRECTIONAL_CLOAK_SUPPORTED 0x00000200 /* Server Move/Size Start PDU */ -#define RAIL_WMSZ_LEFT 0x0001 -#define RAIL_WMSZ_RIGHT 0x0002 -#define RAIL_WMSZ_TOP 0x0003 -#define RAIL_WMSZ_TOPLEFT 0x0004 -#define RAIL_WMSZ_TOPRIGHT 0x0005 -#define RAIL_WMSZ_BOTTOM 0x0006 -#define RAIL_WMSZ_BOTTOMLEFT 0x0007 -#define RAIL_WMSZ_BOTTOMRIGHT 0x0008 -#define RAIL_WMSZ_MOVE 0x0009 -#define RAIL_WMSZ_KEYMOVE 0x000A -#define RAIL_WMSZ_KEYSIZE 0x000B +#define RAIL_WMSZ_LEFT 0x0001 +#define RAIL_WMSZ_RIGHT 0x0002 +#define RAIL_WMSZ_TOP 0x0003 +#define RAIL_WMSZ_TOPLEFT 0x0004 +#define RAIL_WMSZ_TOPRIGHT 0x0005 +#define RAIL_WMSZ_BOTTOM 0x0006 +#define RAIL_WMSZ_BOTTOMLEFT 0x0007 +#define RAIL_WMSZ_BOTTOMRIGHT 0x0008 +#define RAIL_WMSZ_MOVE 0x0009 +#define RAIL_WMSZ_KEYMOVE 0x000A +#define RAIL_WMSZ_KEYSIZE 0x000B /* Language Bar Information PDU */ -#define TF_SFT_SHOWNORMAL 0x00000001 -#define TF_SFT_DOCK 0x00000002 -#define TF_SFT_MINIMIZED 0x00000004 -#define TF_SFT_HIDDEN 0x00000008 -#define TF_SFT_NOTRANSPARENCY 0x00000010 -#define TF_SFT_LOWTRANSPARENCY 0x00000020 -#define TF_SFT_HIGHTRANSPARENCY 0x00000040 -#define TF_SFT_LABELS 0x00000080 -#define TF_SFT_NOLABELS 0x00000100 -#define TF_SFT_EXTRAICONSONMINIMIZED 0x00000200 -#define TF_SFT_NOEXTRAICONSONMINIMIZED 0x00000400 -#define TF_SFT_DESKBAND 0x00000800 +#define TF_SFT_SHOWNORMAL 0x00000001 +#define TF_SFT_DOCK 0x00000002 +#define TF_SFT_MINIMIZED 0x00000004 +#define TF_SFT_HIDDEN 0x00000008 +#define TF_SFT_NOTRANSPARENCY 0x00000010 +#define TF_SFT_LOWTRANSPARENCY 0x00000020 +#define TF_SFT_HIGHTRANSPARENCY 0x00000040 +#define TF_SFT_LABELS 0x00000080 +#define TF_SFT_NOLABELS 0x00000100 +#define TF_SFT_EXTRAICONSONMINIMIZED 0x00000200 +#define TF_SFT_NOEXTRAICONSONMINIMIZED 0x00000400 +#define TF_SFT_DESKBAND 0x00000800 -/* Extended Handshake Flags */ +/* DEPRECATED: Extended Handshake Flags + * use the spec conformant naming scheme TS_ below + */ #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 -#define TF_PROFILETYPE_KEYBOARDLAYOUT 0x00000002 +/* Extended Handshake Flags */ +#define TS_RAIL_ORDER_HANDSHAKEEX_FLAGS_HIDEF 0x00000001 +#define TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED 0x00000002 +#define TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_SNAP_ARRANGE_SUPPORTED 0x00000004 +/* Language Profile Information Flags */ +#define TF_PROFILETYPE_INPUTPROCESSOR 0x00000001 +#define TF_PROFILETYPE_KEYBOARDLAYOUT 0x00000002 + +/* LanguageProfileCLSID and ProfileGUID */ +#ifndef _WIN32 +#define GUID_NULL {0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +#else +#include +#endif +#define GUID_MSIME_JPN {0x03B5835F, 0xF03C, 0x411B, 0x9C, 0xE2, 0xAA, 0x23, 0xE1, 0x17, 0x1E, 0x36} +#define GUID_MSIME_KOR {0xA028AE76, 0x01B1, 0x46C2, 0x99, 0xC4, 0xAC, 0xD9, 0x85, 0x8A, 0xE0, 0x02} +#define GUID_CHSIME {0x81D4E9C9, 0x1D3B, 0x41BC, 0x9E, 0x6C, 0x4B, 0x40, 0xBF, 0x79, 0xE3, 0x5E} +#define GUID_CHTIME {0x531FDEBF, 0x9B4C, 0x4A43, 0xA2, 0xAA, 0x96, 0x0E, 0x8F, 0xCD, 0xC7, 0x32} +#define GUID_PROFILE_NEWPHONETIC {0xB2F9C502, 0x1742, 0x11D4, 0x97, 0x90, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E} +#define GUID_PROFILE_CHANGJIE {0x4BDF9F03, 0xC7D3, 0x11D4, 0xB2, 0xAB, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E} +#define GUID_PROFILE_QUICK {0x6024B45F, 0x5C54, 0x11D4, 0xB9, 0x21, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E} +#define GUID_PROFILE_CANTONESE {0x0AEC109C, 0x7E96, 0x11D4, 0xB2, 0xEF, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E} +#define GUID_PROFILE_PINYIN {0xF3BA9077, 0x6C7E, 0x11D4, 0x97, 0xFA, 0x00, 0x80, 0xC8, 0x82, 0x68, 0x7E} +#define GUID_PROFILE_SIMPLEFAST {0xFA550B04, 0x5AD7, 0x411F, 0xA5, 0xAC, 0xCA, 0x03, 0x8E, 0xC5, 0x15, 0xD7} +#define GUID_GUID_PROFILE_MSIME_JPN {0xA76C93D9, 0x5523, 0x4E90, 0xAA, 0xFA, 0x4D, 0xB1, 0x12, 0xF9, 0xAC, 0x76} +#define GUID_PROFILE_MSIME_KOR {0xB5FE1F02, 0xD5F2, 0x4445, 0x9C, 0x03, 0xC5, 0x68, 0xF2, 0x3C, 0x99, 0xA1} + +/* ImeState */ #define IME_STATE_CLOSED 0x00000000 #define IME_STATE_OPEN 0x00000001 +/* ImeConvMode */ #ifndef _IME_CMODES_ #define IME_CMODE_NATIVE 0x00000001 #define IME_CMODE_KATAKANA 0x00000002 @@ -170,6 +214,7 @@ enum SPI_MASK #define IME_CMODE_FIXED 0x00000800 #endif +/* ImeSentenceMode */ #ifndef _IMM_ #define IME_SMODE_NONE 0x00000000 #define IME_SMODE_PLURALCASE 0x00000001 @@ -179,9 +224,24 @@ enum SPI_MASK #define IME_SMODE_CONVERSATION 0x00000010 #endif +/* KANAMode */ #define KANA_MODE_OFF 0x00000000 #define KANA_MODE_ON 0x00000001 +/* Taskbar */ +#define RAIL_TASKBAR_MSG_TAB_REGISTER 0x00000001 +#define RAIL_TASKBAR_MSG_TAB_UNREGISTER 0x00000002 +#define RAIL_TASKBAR_MSG_TAB_ORDER 0x00000003 +#define RAIL_TASKBAR_MSG_TAB_ACTIVE 0x00000004 +#define RAIL_TASKBAR_MSG_TAB_PROPERTIES 0x00000005 + +/* Taskbar body */ +#define RAIL_TASKBAR_MSG_TAB_REGISTER 0x00000001 +#define RAIL_TASKBAR_MSG_TAB_UNREGISTER 0x00000002 +#define RAIL_TASKBAR_MSG_TAB_ORDER 0x00000003 +#define RAIL_TASKBAR_MSG_TAB_ACTIVE 0x00000004 +#define RAIL_TASKBAR_MSG_TAB_PROPERTIES 0x00000005 + struct _RAIL_UNICODE_STRING { UINT16 length; @@ -236,6 +296,16 @@ struct _RAIL_EXEC_RESULT_ORDER }; typedef struct _RAIL_EXEC_RESULT_ORDER RAIL_EXEC_RESULT_ORDER; +struct _TS_FILTERKEYS +{ + UINT32 Flags; + UINT32 WaitTime; + UINT32 DelayTime; + UINT32 RepeatTime; + UINT32 BounceTime; +}; +typedef struct _TS_FILTERKEYS TS_FILTERKEYS; + struct _RAIL_SYSPARAM_ORDER { UINT32 param; @@ -248,6 +318,10 @@ struct _RAIL_SYSPARAM_ORDER RECTANGLE_16 displayChange; RECTANGLE_16 taskbarPos; RAIL_HIGH_CONTRAST highContrast; + RAIL_HIGH_CONTRAST caretWidth; + UINT32 stickyKeys; + UINT32 toggleKeys; + TS_FILTERKEYS filterKeys; BOOL setScreenSaveActive; BOOL setScreenSaveSecure; }; @@ -336,15 +410,6 @@ struct _RAIL_LANGBAR_INFO_ORDER }; typedef struct _RAIL_LANGBAR_INFO_ORDER RAIL_LANGBAR_INFO_ORDER; -struct _RAIL_LANGUAGE_IME_INFO_ORDER -{ - UINT32 ProfileType; - UINT32 LanguageId; - GUID LanguageProfileClsId; - GUID ProfileGuid; -}; -typedef struct _RAIL_LANGUAGE_IME_INFO_ORDER RAIL_LANGUAGE_IME_INFO_ORDER; - struct _RAIL_COMPARTMENT_INFO_ORDER { UINT32 ImeState; @@ -373,6 +438,24 @@ struct _RAIL_POWER_DISPLAY_REQUEST }; typedef struct _RAIL_POWER_DISPLAY_REQUEST RAIL_POWER_DISPLAY_REQUEST; +struct _RAIL_TASKBAR_INFO_ORDER +{ + UINT32 TaskbarMessage; + UINT32 WindowIdTab; + UINT32 Body; +}; +typedef struct _RAIL_TASKBAR_INFO_ORDER RAIL_TASKBAR_INFO_ORDER; + +struct _RAIL_LANGUAGEIME_INFO_ORDER +{ + UINT32 ProfileType; + UINT32 LanguageID; + GUID LanguageProfileCLSID; + GUID ProfileGUID; + UINT32 KeyboardLayout; +}; +typedef struct _RAIL_LANGUAGEIME_INFO_ORDER RAIL_LANGUAGEIME_INFO_ORDER; + struct _RAIL_SNAP_ARRANGE { UINT32 windowId; @@ -392,7 +475,9 @@ struct _RAIL_GET_APPID_RESP_EX }; typedef struct _RAIL_GET_APPID_RESP_EX RAIL_GET_APPID_RESP_EX; -/* RAIL Constants */ +/* DEPRECATED: RAIL Constants + * use the spec conformant naming scheme TS_ below + */ #define RDP_RAIL_ORDER_EXEC 0x0001 #define RDP_RAIL_ORDER_ACTIVATE 0x0002 @@ -418,6 +503,32 @@ typedef struct _RAIL_GET_APPID_RESP_EX RAIL_GET_APPID_RESP_EX; #define RDP_RAIL_ORDER_SNAP_ARRANGE 0x0017 #define RDP_RAIL_ORDER_GET_APPID_RESP_EX 0x0018 +/* RAIL Constants */ + +#define TS_RAIL_ORDER_EXEC 0x0001 +#define TS_RAIL_ORDER_ACTIVATE 0x0002 +#define TS_RAIL_ORDER_SYSPARAM 0x0003 +#define TS_RAIL_ORDER_SYSCOMMAND 0x0004 +#define TS_RAIL_ORDER_HANDSHAKE 0x0005 +#define TS_RAIL_ORDER_NOTIFY_EVENT 0x0006 +#define TS_RAIL_ORDER_WINDOWMOVE 0x0008 +#define TS_RAIL_ORDER_LOCALMOVESIZE 0x0009 +#define TS_RAIL_ORDER_MINMAXINFO 0x000A +#define TS_RAIL_ORDER_CLIENTSTATUS 0x000B +#define TS_RAIL_ORDER_SYSMENU 0x000C +#define TS_RAIL_ORDER_LANGBARINFO 0x000D +#define TS_RAIL_ORDER_GET_APPID_REQ 0x000E +#define TS_RAIL_ORDER_GET_APPID_RESP 0x000F +#define TS_RAIL_ORDER_TASKBARINFO 0x0010 +#define TS_RAIL_ORDER_LANGUAGEIMEINFO 0x0011 +#define TS_RAIL_ORDER_COMPARTMENTINFO 0x0012 +#define TS_RAIL_ORDER_HANDSHAKE_EX 0x0013 +#define TS_RAIL_ORDER_ZORDER_SYNC 0x0014 +#define TS_RAIL_ORDER_CLOAK 0x0015 +#define TS_RAIL_ORDER_POWER_DISPLAY_REQUEST 0x0016 +#define TS_RAIL_ORDER_SNAP_ARRANGE 0x0017 +#define TS_RAIL_ORDER_GET_APPID_RESP_EX 0x0018 +#define TS_RAIL_ORDER_EXEC_RESULT 0x0080 #ifdef __cplusplus extern "C" { diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index d6eef5c36..556d3611e 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -27,6 +27,16 @@ #include #include +/* 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_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED 0x00000010 +#define RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED 0x00000020 +#define RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED 0x00000040 +#define RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED 0x00000080 + /* Performance Flags */ #define PERF_FLAG_NONE 0x00000000 #define PERF_DISABLE_WALLPAPER 0x00000001 @@ -757,6 +767,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_RemoteAppLanguageBarSupported (2124) #define FreeRDP_RemoteWndSupportLevel (2125) #define FreeRDP_RemoteApplicationSupportLevel (2126) +#define FreeRDP_RemoteApplicationSupportMask (2127) #define FreeRDP_ReceivedCapabilities (2240) #define FreeRDP_ReceivedCapabilitiesSize (2241) #define FreeRDP_OsMajorType (2304) @@ -1256,7 +1267,8 @@ struct rdp_settings ALIGN64 BOOL RemoteAppLanguageBarSupported; /* 2124 */ ALIGN64 UINT32 RemoteWndSupportLevel; /* 2125 */ ALIGN64 UINT32 RemoteApplicationSupportLevel; /* 2126 */ - UINT64 padding2176[2176 - 2127]; /* 2127 */ + ALIGN64 UINT32 RemoteApplicationSupportMask; /* 2127 */ + UINT64 padding2176[2176 - 2128]; /* 2128 */ UINT64 padding2240[2240 - 2176]; /* 2176 */ /** diff --git a/include/freerdp/window.h b/include/freerdp/window.h index 4a5b2b84f..4bfd5a2c4 100644 --- a/include/freerdp/window.h +++ b/include/freerdp/window.h @@ -23,38 +23,54 @@ #include /* Window Order Header Flags */ -#define WINDOW_ORDER_TYPE_WINDOW 0x01000000 -#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000 -#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000 -#define WINDOW_ORDER_STATE_NEW 0x10000000 -#define WINDOW_ORDER_STATE_DELETED 0x20000000 -#define WINDOW_ORDER_FIELD_OWNER 0x00000002 -#define WINDOW_ORDER_FIELD_STYLE 0x00000008 -#define WINDOW_ORDER_FIELD_SHOW 0x00000010 -#define WINDOW_ORDER_FIELD_TITLE 0x00000004 -#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000 -#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000 -#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000 -#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000 -#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800 -#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000 -#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400 -#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100 -#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000 -#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200 -#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000 -#define WINDOW_ORDER_ICON 0x40000000 -#define WINDOW_ORDER_CACHED_ICON 0x80000000 -#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008 -#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001 -#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002 -#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004 -#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001 -#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002 -#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004 -#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008 -#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010 -#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020 +#define WINDOW_ORDER_TYPE_WINDOW 0x01000000 +#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000 +#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000 + +#define WINDOW_ORDER_STATE_NEW 0x10000000 +#define WINDOW_ORDER_STATE_DELETED 0x20000000 + +/* Window Order Update */ +#define WINDOW_ORDER_FIELD_OWNER 0x00000002 +#define WINDOW_ORDER_FIELD_STYLE 0x00000008 +#define WINDOW_ORDER_FIELD_SHOW 0x00000010 +#define WINDOW_ORDER_FIELD_TITLE 0x00000004 +#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000 +#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000 +#define WINDOW_ORDER_FIELD_RESIZE_MARGIN_X 0x00000080 +#define WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y 0x08000000 +#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000 +#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000 +#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800 +#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000 +#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400 +#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100 +#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000 +#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200 +#define WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION 0x00400000 +#define WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL 0x00200000 +#define WINDOW_ORDER_FIELD_TASKBAR_BUTTON 0x00800000 +#define WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER 0x00080000 +#define WINDOW_ORDER_FIELD_APPBAR_STATE 0x00000040 +#define WINDOW_ORDER_FIELD_APPBAR_EDGE 0x00000001 + +/* Window (chached) Icon */ +#define WINDOW_ORDER_ICON 0x40000000 +#define WINDOW_ORDER_CACHED_ICON 0x80000000 +#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000 +#define WINDOW_ORDER_FIELD_ICON_OVERLAY 0x00100000 + + +#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008 +#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001 +#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002 +#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004 +#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001 +#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002 +#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004 +#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008 +#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010 +#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020 /* Window Show States */ #define WINDOW_HIDE 0x00 @@ -190,8 +206,17 @@ struct _WINDOW_STATE_ORDER RECTANGLE_16* windowRects; INT32 visibleOffsetX; INT32 visibleOffsetY; + UINT32 resizeMarginLeft; + UINT32 resizeMarginTop; + UINT32 resizeMarginRight; + UINT32 resizeMarginBottom; UINT32 numVisibilityRects; RECTANGLE_16* visibilityRects; + RAIL_UNICODE_STRING OverlayDescription; + BYTE TaskbarButton; + UINT8 EnforceServerZOrder; + UINT8 AppBarState; + UINT8 AppBarEdge; }; typedef struct _WINDOW_STATE_ORDER WINDOW_STATE_ORDER; @@ -226,16 +251,23 @@ struct _MONITORED_DESKTOP_ORDER }; typedef struct _MONITORED_DESKTOP_ORDER MONITORED_DESKTOP_ORDER; -typedef BOOL (*pWindowCreate)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); -typedef BOOL (*pWindowUpdate)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); -typedef BOOL (*pWindowIcon)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon); -typedef BOOL (*pWindowCachedIcon)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon); -typedef BOOL (*pWindowDelete)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo); -typedef BOOL (*pNotifyIconCreate)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state); -typedef BOOL (*pNotifyIconUpdate)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state); -typedef BOOL (*pNotifyIconDelete)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo); -typedef BOOL (*pMonitoredDesktop)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop); -typedef BOOL (*pNonMonitoredDesktop)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo); +typedef BOOL (*pWindowCreate)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const WINDOW_STATE_ORDER* window_state); +typedef BOOL (*pWindowUpdate)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const WINDOW_STATE_ORDER* window_state); +typedef BOOL (*pWindowIcon)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const WINDOW_ICON_ORDER* window_icon); +typedef BOOL (*pWindowCachedIcon)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const WINDOW_CACHED_ICON_ORDER* window_cached_icon); +typedef BOOL (*pWindowDelete)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo); +typedef BOOL (*pNotifyIconCreate)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const NOTIFY_ICON_STATE_ORDER* notify_icon_state); +typedef BOOL (*pNotifyIconUpdate)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const NOTIFY_ICON_STATE_ORDER* notify_icon_state); +typedef BOOL (*pNotifyIconDelete)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo); +typedef BOOL (*pMonitoredDesktop)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const MONITORED_DESKTOP_ORDER* monitored_desktop); +typedef BOOL (*pNonMonitoredDesktop)(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo); struct rdp_window_update { @@ -255,13 +287,6 @@ struct rdp_window_update UINT32 paddingB[32 - 26]; /* 26 */ /* internal */ - - WINDOW_ORDER_INFO orderInfo; - WINDOW_STATE_ORDER window_state; - WINDOW_ICON_ORDER window_icon; - WINDOW_CACHED_ICON_ORDER window_cached_icon; - NOTIFY_ICON_STATE_ORDER notify_icon_state; - MONITORED_DESKTOP_ORDER monitored_desktop; }; typedef struct rdp_window_update rdpWindowUpdate; diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index e31831cfa..389724232 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -139,18 +139,17 @@ static void rdp_write_capability_set_header(wStream* s, UINT16 length, Stream_Write_UINT16(s, length); /* lengthCapability */ } -static int rdp_capability_set_start(wStream* s) +static size_t rdp_capability_set_start(wStream* s) { - size_t header; - header = Stream_GetPosition(s); + size_t header = Stream_GetPosition(s); Stream_Zero(s, CAPSET_HEADER_LENGTH); return header; } -static void rdp_capability_set_finish(wStream* s, int header, UINT16 type) +static void rdp_capability_set_finish(wStream* s, size_t header, UINT16 type) { size_t footer; - UINT16 length; + size_t length; footer = Stream_GetPosition(s); length = footer - header; Stream_SetPosition(s, header); @@ -229,9 +228,9 @@ static BOOL rdp_read_general_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_general_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_general_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; UINT16 extraFlags; if (!Stream_EnsureRemainingCapacity(s, 64)) @@ -386,9 +385,9 @@ static BOOL rdp_read_bitmap_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_bitmap_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_bitmap_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; BYTE drawingFlags = 0; UINT16 preferredBitsPerPixel; @@ -560,9 +559,9 @@ static BOOL rdp_read_order_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_order_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_order_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; UINT16 orderFlags; UINT16 orderSupportExFlags; UINT16 textANSICodePage = 0; @@ -745,10 +744,10 @@ static BOOL rdp_read_bitmap_cache_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_bitmap_cache_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int bpp; - int header; + UINT16 bpp; + size_t header; UINT16 size; if (!Stream_EnsureRemainingCapacity(s, 64)) @@ -847,9 +846,9 @@ static BOOL rdp_read_control_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_control_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_control_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -916,9 +915,9 @@ static BOOL rdp_read_window_activation_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_window_activation_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -1003,9 +1002,9 @@ static BOOL rdp_read_pointer_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_pointer_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_pointer_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; UINT16 colorPointerFlag; if (!Stream_EnsureRemainingCapacity(s, 32)) @@ -1072,9 +1071,9 @@ static BOOL rdp_read_share_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_share_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_share_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; UINT16 nodeId; if (!Stream_EnsureRemainingCapacity(s, 32)) @@ -1133,9 +1132,9 @@ static BOOL rdp_read_color_cache_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_color_cache_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -1194,9 +1193,9 @@ static BOOL rdp_read_sound_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_sound_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_sound_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; UINT16 soundFlags; if (!Stream_EnsureRemainingCapacity(s, 32)) @@ -1300,9 +1299,9 @@ static BOOL rdp_read_input_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_input_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_input_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; UINT16 inputFlags; if (!Stream_EnsureRemainingCapacity(s, 128)) @@ -1395,9 +1394,9 @@ static BOOL rdp_read_font_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_font_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_font_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -1453,9 +1452,9 @@ static BOOL rdp_read_brush_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_brush_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_brush_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -1544,9 +1543,9 @@ static BOOL rdp_read_glyph_cache_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_glyph_cache_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 64)) return FALSE; @@ -1658,10 +1657,10 @@ static BOOL rdp_read_offscreen_bitmap_cache_capability_set(wStream* s, */ static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; - UINT32 offscreenSupportLevel = FALSE; + size_t header; + UINT32 offscreenSupportLevel = 0x00; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -1669,11 +1668,15 @@ static BOOL rdp_write_offscreen_bitmap_cache_capability_set(wStream* s, header = rdp_capability_set_start(s); if (settings->OffscreenSupportLevel) - offscreenSupportLevel = TRUE; + { + offscreenSupportLevel = 0x01; + Stream_Write_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + Stream_Write_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ + Stream_Write_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ + } + else + Stream_Zero(s, 8); - Stream_Write_UINT32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ - Stream_Write_UINT16(s, settings->OffscreenCacheSize); /* offscreenCacheSize (2 bytes) */ - Stream_Write_UINT16(s, settings->OffscreenCacheEntries); /* offscreenCacheEntries (2 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE); return TRUE; } @@ -1734,9 +1737,9 @@ static BOOL rdp_read_bitmap_cache_host_support_capability_set(wStream* s, */ static BOOL rdp_write_bitmap_cache_host_support_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -1829,9 +1832,9 @@ static BOOL rdp_read_bitmap_cache_v2_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_bitmap_cache_v2_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; UINT16 cacheFlags; if (!Stream_EnsureRemainingCapacity(s, 64)) @@ -1938,9 +1941,9 @@ static BOOL rdp_read_virtual_channel_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_virtual_channel_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; UINT32 flags; if (!Stream_EnsureRemainingCapacity(s, 32)) @@ -2013,9 +2016,9 @@ static BOOL rdp_read_draw_nine_grid_cache_capability_set(wStream* s, */ static BOOL rdp_write_draw_nine_grid_cache_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; UINT32 drawNineGridSupportLevel; if (!Stream_EnsureRemainingCapacity(s, 32)) @@ -2119,9 +2122,9 @@ static BOOL rdp_read_draw_gdiplus_cache_capability_set(wStream* s, * @param settings settings */ -static BOOL rdp_write_draw_gdiplus_cache_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_draw_gdiplus_cache_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; UINT32 drawGDIPlusSupportLevel; UINT32 drawGdiplusCacheLevel; @@ -2183,7 +2186,6 @@ 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) { @@ -2194,6 +2196,13 @@ static BOOL rdp_read_remote_programs_capability_set(wStream* s, UINT16 length, } } + /* 2.2.2.2.3 HandshakeEx PDU (TS_RAIL_ORDER_HANDSHAKE_EX) + * the handshake ex pdu is supported when both, client and server announce + * it OR if we are ready to begin enhanced remoteAPP mode. */ + if (settings->RemoteApplicationMode) + railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED; + + settings->RemoteApplicationSupportLevel = railSupportLevel & settings->RemoteApplicationSupportMask; return TRUE; } @@ -2205,9 +2214,9 @@ static BOOL rdp_read_remote_programs_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_remote_programs_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; UINT32 railSupportLevel; if (!Stream_EnsureRemainingCapacity(s, 64)) @@ -2222,9 +2231,14 @@ static BOOL rdp_write_remote_programs_capability_set(wStream* s, railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED; } - if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED) - railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED; - + railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED; + railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED; + railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED; + railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED; + railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED; + railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED; + /* Mask out everything the server does not support. */ + railSupportLevel &= settings->RemoteApplicationSupportLevel; Stream_Write_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL); return TRUE; @@ -2272,9 +2286,9 @@ static BOOL rdp_read_window_list_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_window_list_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_window_list_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -2334,9 +2348,9 @@ static BOOL rdp_read_desktop_composition_capability_set(wStream* s, */ static BOOL rdp_write_desktop_composition_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; UINT16 compDeskSupportLevel; if (!Stream_EnsureRemainingCapacity(s, 32)) @@ -2447,7 +2461,7 @@ static BOOL rdp_read_multifragment_update_capability_set(wStream* s, static BOOL rdp_write_multifragment_update_capability_set(wStream* s, rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -2523,9 +2537,9 @@ static BOOL rdp_read_large_pointer_capability_set(wStream* s, UINT16 length, * @param settings settings */ -static BOOL rdp_write_large_pointer_capability_set(wStream* s, rdpSettings* settings) +static BOOL rdp_write_large_pointer_capability_set(wStream* s, const rdpSettings* settings) { - int header; + size_t header; UINT16 largePointerSupportFlags; if (!Stream_EnsureRemainingCapacity(s, 32)) @@ -2585,9 +2599,9 @@ static BOOL rdp_read_surface_commands_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_surface_commands_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; UINT32 cmdFlags; if (!Stream_EnsureRemainingCapacity(s, 32)) @@ -2907,7 +2921,7 @@ static BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, * @param settings settings */ static BOOL rdp_write_rfx_client_capability_container(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { UINT32 captureFlags; BYTE codecMode; @@ -2956,7 +2970,7 @@ static BOOL rdp_write_rfx_client_capability_container(wStream* s, * @param settings settings */ static BOOL rdp_write_nsc_client_capability_container(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { BYTE colorLossLevel; BYTE fAllowSubsampling; @@ -3002,7 +3016,7 @@ static BOOL rdp_write_jpeg_client_capability_container(wStream* s, * @param settings settings */ static BOOL rdp_write_rfx_server_capability_container(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { if (!Stream_EnsureRemainingCapacity(s, 8)) return FALSE; @@ -3029,7 +3043,7 @@ static BOOL rdp_write_jpeg_server_capability_container(wStream* s, * @param settings settings */ static BOOL rdp_write_nsc_server_capability_container(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { if (!Stream_EnsureRemainingCapacity(s, 8)) return FALSE; @@ -3047,9 +3061,9 @@ static BOOL rdp_write_nsc_server_capability_container(wStream* s, */ static BOOL rdp_write_bitmap_codecs_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; BYTE bitmapCodecCount; if (!Stream_EnsureRemainingCapacity(s, 64)) @@ -3241,9 +3255,9 @@ static BOOL rdp_read_frame_acknowledge_capability_set(wStream* s, UINT16 length, */ static BOOL rdp_write_frame_acknowledge_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -3283,9 +3297,9 @@ static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(wStream* s, } static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(wStream* s, - rdpSettings* settings) + const rdpSettings* settings) { - int header; + size_t header; if (!Stream_EnsureRemainingCapacity(s, 32)) return FALSE; @@ -3906,7 +3920,7 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) return TRUE; } -BOOL rdp_write_demand_active(wStream* s, rdpSettings* settings) +static BOOL rdp_write_demand_active(wStream* s, rdpSettings* settings) { size_t bm, em, lm; UINT16 numberCapabilities; diff --git a/libfreerdp/core/capabilities.h b/libfreerdp/core/capabilities.h index 00e300ead..1898c8efb 100644 --- a/libfreerdp/core/capabilities.h +++ b/libfreerdp/core/capabilities.h @@ -135,16 +135,6 @@ #define DRAW_GDIPLUS_CACHE_LEVEL_DEFAULT 0x00000000 #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_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED 0x00000010 -#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 #define WINDOW_LEVEL_SUPPORTED 0x00000001 @@ -177,7 +167,6 @@ FREERDP_LOCAL BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId); FREERDP_LOCAL BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s); -FREERDP_LOCAL BOOL rdp_write_demand_active(wStream* s, rdpSettings* settings); FREERDP_LOCAL BOOL rdp_send_demand_active(rdpRdp* rdp); FREERDP_LOCAL BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s); FREERDP_LOCAL BOOL rdp_write_confirm_active(wStream* s, rdpSettings* settings); diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 16530bef4..67a66e77d 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -732,14 +732,16 @@ static void rdp_write_info_packet(rdpRdp* rdp, wStream* s) flags |= INFO_AUTOLOGON; if (settings->RemoteApplicationMode) + { + if (settings->HiDefRemoteApp) + flags |= INFO_HIDEF_RAIL_SUPPORTED; + flags |= INFO_RAIL; + } if (settings->RemoteConsoleAudio) flags |= INFO_REMOTECONSOLEAUDIO; - if (settings->HiDefRemoteApp) - flags |= INFO_HIDEF_RAIL_SUPPORTED; - if (settings->CompressionEnabled) { flags |= INFO_COMPRESSION; @@ -847,7 +849,6 @@ static void rdp_write_info_packet(rdpRdp* rdp, wStream* s) /* excludes (!) the length of the mandatory null terminator */ cbWorkingDir = cbWorkingDir >= 2 ? cbWorkingDir - 2 : cbWorkingDir; - Stream_Write_UINT32(s, 0); /* CodePage (4 bytes) */ Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ Stream_Write_UINT16(s, cbDomain); /* cbDomain (2 bytes) */ @@ -885,7 +886,6 @@ static void rdp_write_info_packet(rdpRdp* rdp, wStream* s) /* the mandatory null terminator */ Stream_Write_UINT16(s, 0); - free(domainW); free(userNameW); free(alternateShellW); @@ -1493,6 +1493,5 @@ BOOL rdp_send_server_status_info(rdpContext* context, UINT32 status) return FALSE; Stream_Write_UINT32(s, status); - - return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_STATUS_INFO, rdp->mcs->userId); + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_STATUS_INFO, rdp->mcs->userId);; } diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index 0b1d30e26..7a1a0ab64 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -1104,8 +1104,8 @@ static BOOL update_message_DrawGdiPlusCacheEnd( /* Window Update */ -static BOOL update_message_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - WINDOW_STATE_ORDER* windowState) +static BOOL update_message_WindowCreate(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const WINDOW_STATE_ORDER* windowState) { WINDOW_ORDER_INFO* wParam; WINDOW_STATE_ORDER* lParam; @@ -1132,8 +1132,8 @@ static BOOL update_message_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* MakeMessageId(WindowUpdate, WindowCreate), (void*) wParam, (void*) lParam); } -static BOOL update_message_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - WINDOW_STATE_ORDER* windowState) +static BOOL update_message_WindowUpdate(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const WINDOW_STATE_ORDER* windowState) { WINDOW_ORDER_INFO* wParam; WINDOW_STATE_ORDER* lParam; @@ -1160,8 +1160,8 @@ static BOOL update_message_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* MakeMessageId(WindowUpdate, WindowUpdate), (void*) wParam, (void*) lParam); } -static BOOL update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - WINDOW_ICON_ORDER* windowIcon) +static BOOL update_message_WindowIcon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const WINDOW_ICON_ORDER* windowIcon) { WINDOW_ORDER_INFO* wParam; WINDOW_ICON_ORDER* lParam; @@ -1181,6 +1181,7 @@ static BOOL update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* or goto out_fail; lParam->iconInfo = calloc(1, sizeof(ICON_INFO)); + if (!lParam->iconInfo) goto out_fail; @@ -1223,6 +1224,7 @@ static BOOL update_message_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* or return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(WindowUpdate, WindowIcon), (void*) wParam, (void*) lParam); out_fail: + if (lParam && lParam->iconInfo) { free(lParam->iconInfo->bitsColor); @@ -1231,13 +1233,13 @@ out_fail: free(lParam->iconInfo); } - free(lParam); + free(lParam); free(wParam); return FALSE; } -static BOOL update_message_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - WINDOW_CACHED_ICON_ORDER* windowCachedIcon) +static BOOL update_message_WindowCachedIcon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const WINDOW_CACHED_ICON_ORDER* windowCachedIcon) { WINDOW_ORDER_INFO* wParam; WINDOW_CACHED_ICON_ORDER* lParam; @@ -1264,7 +1266,7 @@ static BOOL update_message_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_IN MakeMessageId(WindowUpdate, WindowCachedIcon), (void*) wParam, (void*) lParam); } -static BOOL update_message_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +static BOOL update_message_WindowDelete(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo) { WINDOW_ORDER_INFO* wParam; @@ -1281,8 +1283,8 @@ static BOOL update_message_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* MakeMessageId(WindowUpdate, WindowDelete), (void*) wParam, NULL); } -static BOOL update_message_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - NOTIFY_ICON_STATE_ORDER* notifyIconState) +static BOOL update_message_NotifyIconCreate(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const NOTIFY_ICON_STATE_ORDER* notifyIconState) { WINDOW_ORDER_INFO* wParam; NOTIFY_ICON_STATE_ORDER* lParam; @@ -1309,8 +1311,8 @@ static BOOL update_message_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_IN MakeMessageId(WindowUpdate, NotifyIconCreate), (void*) wParam, (void*) lParam); } -static BOOL update_message_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - NOTIFY_ICON_STATE_ORDER* notifyIconState) +static BOOL update_message_NotifyIconUpdate(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const NOTIFY_ICON_STATE_ORDER* notifyIconState) { WINDOW_ORDER_INFO* wParam; NOTIFY_ICON_STATE_ORDER* lParam; @@ -1337,7 +1339,7 @@ static BOOL update_message_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_IN MakeMessageId(WindowUpdate, NotifyIconUpdate), (void*) wParam, (void*) lParam); } -static BOOL update_message_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +static BOOL update_message_NotifyIconDelete(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo) { WINDOW_ORDER_INFO* wParam; @@ -1354,8 +1356,8 @@ static BOOL update_message_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_IN MakeMessageId(WindowUpdate, NotifyIconDelete), (void*) wParam, NULL); } -static BOOL update_message_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, - MONITORED_DESKTOP_ORDER* monitoredDesktop) +static BOOL update_message_MonitoredDesktop(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo, + const MONITORED_DESKTOP_ORDER* monitoredDesktop) { WINDOW_ORDER_INFO* wParam; MONITORED_DESKTOP_ORDER* lParam; @@ -1390,7 +1392,8 @@ static BOOL update_message_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_IN MakeMessageId(WindowUpdate, MonitoredDesktop), (void*) wParam, (void*) lParam); } -static BOOL update_message_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +static BOOL update_message_NonMonitoredDesktop(rdpContext* context, + const WINDOW_ORDER_INFO* orderInfo) { WINDOW_ORDER_INFO* wParam; diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 6a6a2de0f..063833bec 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -322,6 +322,15 @@ rdpSettings* freerdp_settings_new(DWORD flags) if (!settings) return NULL; + settings->HiDefRemoteApp = FALSE; + settings->RemoteApplicationSupportMask = RAIL_LEVEL_SUPPORTED | + RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED | + RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED | + RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED | + RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED | + RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED | + RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED | + RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED; settings->SupportHeartbeatPdu = TRUE; settings->ServerMode = (flags & FREERDP_SETTINGS_SERVER_MODE) ? TRUE : FALSE; settings->WaitForOutputBufferFlush = TRUE; @@ -495,7 +504,7 @@ rdpSettings* freerdp_settings_new(DWORD flags) if (!settings->ClientDir) goto out_fail; - settings->RemoteWndSupportLevel = WINDOW_LEVEL_SUPPORTED_EX; + settings->RemoteWndSupportLevel = WINDOW_LEVEL_SUPPORTED | WINDOW_LEVEL_SUPPORTED_EX; settings->RemoteAppNumIconCaches = 3; settings->RemoteAppNumIconCacheEntries = 12; settings->VirtualChannelChunkSize = CHANNEL_CHUNK_LENGTH; diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index f6f059c0a..65ff7d7cd 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -2135,17 +2135,16 @@ static void update_free_queued_message(void* obj) update_message_queue_free_message(msg); } -static void update_free_window_state(WINDOW_STATE_ORDER* window_state) +void update_free_window_state(WINDOW_STATE_ORDER* window_state) { if (!window_state) return; + free(window_state->OverlayDescription.string); free(window_state->titleInfo.string); - window_state->titleInfo.string = NULL; free(window_state->windowRects); - window_state->windowRects = NULL; free(window_state->visibilityRects); - window_state->visibilityRects = NULL; + memset(window_state, 0, sizeof(WINDOW_STATE_ORDER)); } rdpUpdate* update_new(rdpRdp* rdp) @@ -2230,9 +2229,6 @@ void update_free(rdpUpdate* update) if (update->window) { - free(update->window->monitored_desktop.windowIds); - update_free_window_state(&update->window->window_state); - update_free_window_icon_info(update->window->window_icon.iconInfo); free(update->window); } diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c index 9159fa59a..f9ba18be7 100644 --- a/libfreerdp/core/window.c +++ b/libfreerdp/core/window.c @@ -199,8 +199,8 @@ static BOOL update_read_notify_icon_infotip(wStream* s, NOTIFY_ICON_INFOTIP* not static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState) { - int i; - int size; + UINT32 i; + size_t size; RECTANGLE_16* newRect; if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) @@ -236,22 +236,40 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) { - if (Stream_GetRemainingLength(s) < 4) + if (Stream_GetRemainingLength(s) < 8) return FALSE; - Stream_Read_UINT32(s, windowState->clientOffsetX); /* clientOffsetX (4 bytes) */ - Stream_Read_UINT32(s, windowState->clientOffsetY); /* clientOffsetY (4 bytes) */ + Stream_Read_INT32(s, windowState->clientOffsetX); /* clientOffsetX (4 bytes) */ + Stream_Read_INT32(s, windowState->clientOffsetY); /* clientOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) { - if (Stream_GetRemainingLength(s) < 4) + if (Stream_GetRemainingLength(s) < 8) return FALSE; Stream_Read_UINT32(s, windowState->clientAreaWidth); /* clientAreaWidth (4 bytes) */ Stream_Read_UINT32(s, windowState->clientAreaHeight); /* clientAreaHeight (4 bytes) */ } + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X) + { + if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, windowState->resizeMarginLeft); + Stream_Read_UINT32(s, windowState->resizeMarginRight); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y) + { + if (Stream_GetRemainingLength(s) < 8) + return FALSE; + + Stream_Read_UINT32(s, windowState->resizeMarginTop); + Stream_Read_UINT32(s, windowState->resizeMarginBottom); + } + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) { if (Stream_GetRemainingLength(s) < 1) @@ -273,8 +291,8 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (Stream_GetRemainingLength(s) < 8) return FALSE; - Stream_Read_UINT32(s, windowState->windowOffsetX); /* windowOffsetX (4 bytes) */ - Stream_Read_UINT32(s, windowState->windowOffsetY); /* windowOffsetY (4 bytes) */ + Stream_Read_INT32(s, windowState->windowOffsetX); /* windowOffsetX (4 bytes) */ + Stream_Read_INT32(s, windowState->windowOffsetY); /* windowOffsetY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) @@ -282,8 +300,8 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (Stream_GetRemainingLength(s) < 8) return FALSE; - Stream_Read_UINT32(s, windowState->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */ - Stream_Read_UINT32(s, windowState->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */ + Stream_Read_INT32(s, windowState->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */ + Stream_Read_INT32(s, windowState->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */ } if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) @@ -323,7 +341,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI return FALSE; /* windowRects */ - for (i = 0; i < (int) windowState->numWindowRects; i++) + for (i = 0; i < windowState->numWindowRects; i++) { Stream_Read_UINT16(s, windowState->windowRects[i].left); /* left (2 bytes) */ Stream_Read_UINT16(s, windowState->windowRects[i].top); /* top (2 bytes) */ @@ -334,7 +352,7 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) { - if (Stream_GetRemainingLength(s) < 4) + if (Stream_GetRemainingLength(s) < 8) return FALSE; Stream_Read_UINT32(s, windowState->visibleOffsetX); /* visibleOffsetX (4 bytes) */ @@ -348,34 +366,78 @@ static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderI Stream_Read_UINT16(s, windowState->numVisibilityRects); /* numVisibilityRects (2 bytes) */ - if (windowState->numVisibilityRects == 0) + if (windowState->numVisibilityRects != 0) { - return TRUE; + size = sizeof(RECTANGLE_16) * windowState->numVisibilityRects; + newRect = (RECTANGLE_16*)realloc(windowState->visibilityRects, size); + + if (!newRect) + { + free(windowState->visibilityRects); + windowState->visibilityRects = NULL; + return FALSE; + } + + windowState->visibilityRects = newRect; + + if (Stream_GetRemainingLength(s) < windowState->numVisibilityRects * 8) + return FALSE; + + /* visibilityRects */ + for (i = 0; i < windowState->numVisibilityRects; i++) + { + Stream_Read_UINT16(s, windowState->visibilityRects[i].left); /* left (2 bytes) */ + Stream_Read_UINT16(s, windowState->visibilityRects[i].top); /* top (2 bytes) */ + Stream_Read_UINT16(s, windowState->visibilityRects[i].right); /* right (2 bytes) */ + Stream_Read_UINT16(s, windowState->visibilityRects[i].bottom); /* bottom (2 bytes) */ + } } + } - size = sizeof(RECTANGLE_16) * windowState->numVisibilityRects; - newRect = (RECTANGLE_16*)realloc(windowState->visibilityRects, size); - - if (!newRect) - { - free(windowState->visibilityRects); - windowState->visibilityRects = NULL; + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION) + { + if (!rail_read_unicode_string(s, &windowState->OverlayDescription)) return FALSE; - } + } - windowState->visibilityRects = newRect; - - if (Stream_GetRemainingLength(s) < windowState->numVisibilityRects * 8) + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL) + { + if (Stream_GetRemainingLength(s) < 1) return FALSE; - /* visibilityRects */ - for (i = 0; i < (int) windowState->numVisibilityRects; i++) - { - Stream_Read_UINT16(s, windowState->visibilityRects[i].left); /* left (2 bytes) */ - Stream_Read_UINT16(s, windowState->visibilityRects[i].top); /* top (2 bytes) */ - Stream_Read_UINT16(s, windowState->visibilityRects[i].right); /* right (2 bytes) */ - Stream_Read_UINT16(s, windowState->visibilityRects[i].bottom); /* bottom (2 bytes) */ - } + Stream_Read_UINT8(s, windowState->TaskbarButton); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON) + { + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, windowState->TaskbarButton); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER) + { + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, windowState->EnforceServerZOrder); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE) + { + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, windowState->AppBarState); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE) + { + if (Stream_GetRemainingLength(s) < 1) + return FALSE; + + Stream_Read_UINT8(s, windowState->AppBarEdge); } return TRUE; @@ -447,19 +509,27 @@ static BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s, if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) { - if (!update_read_window_icon_order(s, orderInfo, &window->window_icon)) - return FALSE; + WINDOW_ICON_ORDER window_icon = { 0 }; + result = update_read_window_icon_order(s, orderInfo, &window_icon); - WLog_Print(update->log, WLOG_DEBUG, "WindowIcon"); - IFCALLRET(window->WindowIcon, result, context, orderInfo, &window->window_icon); + if (result) + { + WLog_Print(update->log, WLOG_DEBUG, "WindowIcon"); + IFCALLRET(window->WindowIcon, result, context, orderInfo, &window_icon); + } + + update_free_window_icon_info(window_icon.iconInfo); } else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) { - if (!update_read_window_cached_icon_order(s, orderInfo, &window->window_cached_icon)) - return FALSE; + WINDOW_CACHED_ICON_ORDER window_cached_icon = { 0 }; + result = update_read_window_cached_icon_order(s, orderInfo, &window_cached_icon); - WLog_Print(update->log, WLOG_DEBUG, "WindowCachedIcon"); - IFCALLRET(window->WindowCachedIcon, result, context, orderInfo, &window->window_cached_icon); + if (result) + { + WLog_Print(update->log, WLOG_DEBUG, "WindowCachedIcon"); + IFCALLRET(window->WindowCachedIcon, result, context, orderInfo, &window_cached_icon); + } } else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED) { @@ -469,18 +539,23 @@ static BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s, } else { - if (!update_read_window_state_order(s, orderInfo, &window->window_state)) - return FALSE; + WINDOW_STATE_ORDER windowState = { 0 }; + result = update_read_window_state_order(s, orderInfo, &windowState); - if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) + if (result) { - WLog_Print(update->log, WLOG_DEBUG, "WindowCreate"); - IFCALLRET(window->WindowCreate, result, context, orderInfo, &window->window_state); - } - else - { - WLog_Print(update->log, WLOG_DEBUG, "WindowUpdate"); - IFCALLRET(window->WindowUpdate, result, context, orderInfo, &window->window_state); + if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) + { + WLog_Print(update->log, WLOG_DEBUG, "WindowCreate"); + IFCALLRET(window->WindowCreate, result, context, orderInfo, &windowState); + } + else + { + WLog_Print(update->log, WLOG_DEBUG, "WindowUpdate"); + IFCALLRET(window->WindowUpdate, result, context, orderInfo, &windowState); + } + + update_free_window_state(&windowState); } } @@ -561,18 +636,20 @@ static BOOL update_recv_notification_icon_info_order(rdpUpdate* update, wStream* } else { - if (!update_read_notification_icon_state_order(s, orderInfo, &window->notify_icon_state)) + NOTIFY_ICON_STATE_ORDER notify_icon_state = { 0 }; + + if (!update_read_notification_icon_state_order(s, orderInfo, ¬ify_icon_state)) return FALSE; if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) { WLog_Print(update->log, WLOG_DEBUG, "NotifyIconCreate"); - IFCALLRET(window->NotifyIconCreate, result, context, orderInfo, &window->notify_icon_state); + IFCALLRET(window->NotifyIconCreate, result, context, orderInfo, ¬ify_icon_state); } else { WLog_Print(update->log, WLOG_DEBUG, "NotifyIconUpdate"); - IFCALLRET(window->NotifyIconUpdate, result, context, orderInfo, &window->notify_icon_state); + IFCALLRET(window->NotifyIconUpdate, result, context, orderInfo, ¬ify_icon_state); } } @@ -650,11 +727,16 @@ static BOOL update_recv_desktop_info_order(rdpUpdate* update, wStream* s, } else { - if (!update_read_desktop_actively_monitored_order(s, orderInfo, &window->monitored_desktop)) - return FALSE; + MONITORED_DESKTOP_ORDER monitored_desktop = { 0 }; + result = update_read_desktop_actively_monitored_order(s, orderInfo, &monitored_desktop); - WLog_Print(update->log, WLOG_DEBUG, "ActivelyMonitoredDesktop"); - IFCALLRET(window->MonitoredDesktop, result, context, orderInfo, &window->monitored_desktop); + if (result) + { + WLog_Print(update->log, WLOG_DEBUG, "ActivelyMonitoredDesktop"); + IFCALLRET(window->MonitoredDesktop, result, context, orderInfo, &monitored_desktop); + } + + free(monitored_desktop.windowIds); } return result; @@ -677,31 +759,39 @@ void update_free_window_icon_info(ICON_INFO* iconInfo) BOOL update_recv_altsec_window_order(rdpUpdate* update, wStream* s) { BOOL rc = TRUE; + size_t remaining; UINT16 orderSize; - rdpWindowUpdate* window = update->window; + WINDOW_ORDER_INFO orderInfo = { 0 }; + remaining = Stream_GetRemainingLength(s); - if (Stream_GetRemainingLength(s) < 6) + if (remaining < 6) { WLog_Print(update->log, WLOG_ERROR, "Stream short"); return FALSE; } Stream_Read_UINT16(s, orderSize); /* orderSize (2 bytes) */ - Stream_Read_UINT32(s, window->orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */ + Stream_Read_UINT32(s, orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */ - if (!window_order_supported(update->context->settings, window->orderInfo.fieldFlags)) + if (remaining + 1 < orderSize) + { + WLog_Print(update->log, WLOG_ERROR, "Stream short orderSize"); + return FALSE; + } + + if (!window_order_supported(update->context->settings, orderInfo.fieldFlags)) return FALSE; - if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW) - rc = update_recv_window_info_order(update, s, &window->orderInfo); - else if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY) - rc = update_recv_notification_icon_info_order(update, s, &window->orderInfo); - else if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP) - rc = update_recv_desktop_info_order(update, s, &window->orderInfo); + if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW) + rc = update_recv_window_info_order(update, s, &orderInfo); + else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY) + rc = update_recv_notification_icon_info_order(update, s, &orderInfo); + else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP) + rc = update_recv_desktop_info_order(update, s, &orderInfo); if (!rc) WLog_Print(update->log, WLOG_ERROR, "windoworder flags %08"PRIx32" failed", - window->orderInfo.fieldFlags); + orderInfo.fieldFlags); return rc; } diff --git a/libfreerdp/core/window.h b/libfreerdp/core/window.h index 7bb8a2040..52b4edf22 100644 --- a/libfreerdp/core/window.h +++ b/libfreerdp/core/window.h @@ -30,6 +30,7 @@ FREERDP_LOCAL void update_free_window_icon_info(ICON_INFO* iconInfo); FREERDP_LOCAL BOOL update_recv_altsec_window_order(rdpUpdate* update, wStream* s); +FREERDP_LOCAL void update_free_window_state(WINDOW_STATE_ORDER* window_state); #define WND_TAG FREERDP_TAG("core.wnd") #ifdef WITH_DEBUG_WND diff --git a/winpr/include/winpr/windows.h b/winpr/include/winpr/windows.h index 8daed265b..75f1839bd 100644 --- a/winpr/include/winpr/windows.h +++ b/winpr/include/winpr/windows.h @@ -32,6 +32,75 @@ #include #include +#else + +/* Client System Parameters Update PDU + * defined in winuser.h + */ +#define SPI_SETCARETWIDTH 0x00002007 +#define SPI_SETSTICKYKEYS 0x0000003B +#define SPI_SETTOGGLEKEYS 0x00000035 +#define SPI_SETFILTERKEYS 0x00000033 + +/* Server System Parameters Update PDU */ +#define SPI_SETSCREENSAVEACTIVE 0x00000011 + +/* HIGHCONTRAST flags values */ +#define HCF_HIGHCONTRASTON 0x00000001 +#define HCF_AVAILABLE 0x00000002 +#define HCF_HOTKEYACTIVE 0x00000004 +#define HCF_CONFIRMHOTKEY 0x00000008 +#define HCF_HOTKEYSOUND 0x00000010 +#define HCF_INDICATOR 0x00000020 +#define HCF_HOTKEYAVAILABLE 0x00000040 + +/* TS_FILTERKEYS */ +#define FKF_FILTERKEYSON 0x00000001 +#define FKF_AVAILABLE 0x00000002 +#define FKF_HOTKEYACTIVE 0x00000004 +#define FKF_CONFIRMHOTKEY 0x00000008 +#define FKF_HOTKEYSOUND 0x00000010 +#define FKF_INDICATOR 0x00000020 +#define FKF_CLICKON 0x00000040 + +/* TS_TOGGLEKEYS */ +#define TKF_TOGGLEKEYSON 0x00000001 +#define TKF_AVAILABLE 0x00000002 +#define TKF_HOTKEYACTIVE 0x00000004 +#define TKF_CONFIRMHOTKEY 0x00000008 +#define TKF_HOTKEYSOUND 0x00000010 + +/* TS_STICKYKEYS */ +#define SKF_STICKYKEYSON 0x00000001 +#define SKF_AVAILABLE 0x00000002 +#define SKF_HOTKEYACTIVE 0x00000004 +#define SKF_CONFIRMHOTKEY 0x00000008 +#define SKF_HOTKEYSOUND 0x00000010 +#define SKF_INDICATOR 0x00000020 +#define SKF_AUDIBLEFEEDBACK 0x00000040 +#define SKF_TRISTATE 0x00000080 +#define SKF_TWOKEYSOFF 0x00000100 +#define SKF_LSHIFTLOCKED 0x00010000 +#define SKF_RSHIFTLOCKED 0x00020000 +#define SKF_LCTLLOCKED 0x00040000 +#define SKF_RCTLLOCKED 0x00080000 +#define SKF_LALTLOCKED 0x00100000 +#define SKF_RALTLOCKED 0x00200000 +#define SKF_LWINLOCKED 0x00400000 +#define SKF_RWINLOCKED 0x00800000 +#define SKF_LSHIFTLATCHED 0x01000000 +#define SKF_RSHIFTLATCHED 0x02000000 +#define SKF_LCTLLATCHED 0x04000000 +#define SKF_RCTLLATCHED 0x08000000 +#define SKF_LALTLATCHED 0x10000000 +#define SKF_RALTLATCHED 0x20000000 +#define SKF_LWINLATCHED 0x40000000 +#define SKF_RWINLATCHED 0x80000000 + +#endif + +#ifndef SPI_SETSCREENSAVESECURE +#define SPI_SETSCREENSAVESECURE 0x00000077 #endif #endif /* WINPR_WINDOWS_H */