*
* @return 0 on success, otherwise a Win32 error code
*/
-UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length)
+UINT rail_send_channel_data(railPlugin* rail, wStream* src)
{
- wStream* s = NULL;
+ wStream* s;
+ size_t length;
- if (!rail || !data)
+ if (!rail || !src)
return ERROR_INVALID_PARAMETER;
+ length = Stream_GetPosition(src);
s = Stream_New(NULL, length);
if (!s)
return CHANNEL_RC_NO_MEMORY;
}
- Stream_Write(s, data, length);
+ Stream_Write(s, Stream_Buffer(src), length);
return rail_send(rail, s);
}
*
* @return 0 on success, otherwise a Win32 error code
*/
-static UINT rail_client_handshake_ex(RailClientContext* context,
- const RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
-{
- railPlugin* rail;
-
- if (!context || !handshakeEx)
- return ERROR_INVALID_PARAMETER;
-
- rail = (railPlugin*) context->handle;
- return rail_send_handshake_ex_order(rail, handshakeEx);
-}
-
-/**
- * Function description
- *
- * @return 0 on success, otherwise a Win32 error code
- */
static UINT rail_server_handshake_ex(RailClientContext* context,
const RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
{
return rail_send_client_get_appid_req_order(rail, getAppIdReq);
}
+static UINT rail_client_cloak(RailClientContext* context,
+ const RAIL_CLOAK* cloak)
+{
+ railPlugin* rail;
+
+ if (!context || !cloak || !context->handle)
+ return ERROR_INVALID_PARAMETER;
+
+ rail = (railPlugin*) context->handle;
+ return rail_send_client_order_cloak_order(rail, cloak);
+}
+
+static UINT rail_client_snap_arrange(RailClientContext* context,
+ const RAIL_SNAP_ARRANGE* snap)
+{
+ railPlugin* rail;
+
+ if (!context || !snap || !context->handle)
+ return ERROR_INVALID_PARAMETER;
+
+ rail = (railPlugin*) context->handle;
+ return rail_send_client_order_snap_arrange_order(rail, snap);
+}
+
/**
* Function description
*
context->ClientSystemCommand = rail_client_system_command;
context->ClientHandshake = rail_client_handshake;
context->ServerHandshake = rail_server_handshake;
- context->ClientHandshakeEx = rail_client_handshake_ex;
context->ServerHandshakeEx = rail_server_handshake_ex;
context->ClientNotifyEvent = rail_client_notify_event;
context->ClientWindowMove = rail_client_window_move;
context->ServerExecuteResult = rail_server_execute_result;
context->ClientGetAppIdRequest = rail_client_get_appid_request;
context->ServerGetAppIdResponse = rail_server_get_appid_response;
+ context->ClientSnapArrange = rail_client_snap_arrange;
+ context->ClientCloak = rail_client_cloak;
rail->rdpcontext = pEntryPointsEx->context;
rail->context = context;
isFreerdp = TRUE;
typedef struct rail_plugin railPlugin;
RailClientContext* rail_get_client_interface(railPlugin* rail);
-UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length);
+UINT rail_send_channel_data(railPlugin* rail, wStream* s);
#endif /* FREERDP_CHANNEL_RAIL_CLIENT_MAIN_H */
Stream_SetPosition(s, orderLength);
WLog_Print(rail->log, WLOG_DEBUG, "Sending %s PDU, length: %"PRIu16"",
RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength);
- return rail_send_channel_data(rail, Stream_Buffer(s), orderLength);
+ return rail_send_channel_data(rail, s);
}
/**
static UINT rail_recv_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake, wStream* s)
{
RailClientContext* context = rail_get_client_interface(rail);
+ RAIL_HANDSHAKE_ORDER clientHandshake = { 0 };
UINT error;
if (!context || !handshake || !s)
return error;
}
+ clientHandshake.buildNumber = 0x00001DB0;
+ /* 2.2.2.2.3 HandshakeEx PDU (TS_RAIL_ORDER_HANDSHAKE_EX)
+ * Client response is really a Handshake PDU */
+ error = context->ClientHandshake(context, &clientHandshake);
+
+ if (error != CHANNEL_RC_OK)
+ return error;
+
if (context->custom)
{
IFCALLRET(context->ServerHandshake, error, context, handshake);
wStream* s)
{
RailClientContext* context = rail_get_client_interface(rail);
+ RAIL_HANDSHAKE_ORDER clientHandshake = { 0 };
UINT error;
if (!context || !handshakeEx || !s)
return error;
}
+ clientHandshake.buildNumber = 0x00001DB0;
+ /* 2.2.2.2.3 HandshakeEx PDU (TS_RAIL_ORDER_HANDSHAKE_EX)
+ * Client response is really a Handshake PDU */
+ error = context->ClientHandshake(context, &clientHandshake);
+
+ if (error != CHANNEL_RC_OK)
+ return error;
+
if (context->custom)
{
- IFCALLRET(context->ClientHandshakeEx, error, context, handshakeEx);
+ IFCALLRET(context->ServerHandshakeEx, error, context, handshakeEx);
if (error)
WLog_ERR(TAG, "context.ClientHandshakeEx failed with error %"PRIu32"", error);
return error;
}
+static UINT rail_read_zorder_sync_order(wStream* s, RAIL_ZORDER_ZYNC* zorder)
+{
+ if (!s || !zorder)
+ return ERROR_INVALID_PARAMETER;
+
+ if (Stream_GetRemainingLength(s) < 4)
+ {
+ WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
+ return ERROR_INVALID_DATA;
+ }
+
+ Stream_Read_UINT32(s, zorder->windowIdMarker);
+ return CHANNEL_RC_OK;
+}
+
+static UINT rail_recv_zorder_sync_order(railPlugin* rail, RAIL_ZORDER_ZYNC* zorder,
+ wStream* s)
+{
+ RailClientContext* context = rail_get_client_interface(rail);
+ UINT error;
+
+ if (!context || !zorder)
+ return ERROR_INVALID_PARAMETER;
+
+ if ((error = rail_read_zorder_sync_order(s, zorder)))
+ {
+ WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %"PRIu32"!", error);
+ return error;
+ }
+
+ if (context->custom)
+ {
+ IFCALLRET(context->ServerZOrderSync, error, context, zorder);
+
+ if (error)
+ WLog_ERR(TAG, "context.ServerZOrderSync failed with error %"PRIu32"", error);
+ }
+
+ return error;
+}
+
+static UINT rail_read_power_display_request_order(wStream* s, RAIL_POWER_DISPLAY_REQUEST* power)
+{
+ if (!s || !power)
+ return ERROR_INVALID_PARAMETER;
+
+ if (Stream_GetRemainingLength(s) < 4)
+ {
+ WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
+ return ERROR_INVALID_DATA;
+ }
+
+ Stream_Read_UINT32(s, power->active);
+ return CHANNEL_RC_OK;
+}
+
+static UINT rail_recv_power_display_request_order(railPlugin* rail,
+ RAIL_POWER_DISPLAY_REQUEST* power,
+ wStream* s)
+{
+ RailClientContext* context = rail_get_client_interface(rail);
+ UINT error;
+
+ if (!context || !power)
+ return ERROR_INVALID_PARAMETER;
+
+ if ((error = rail_read_power_display_request_order(s, power)))
+ {
+ WLog_ERR(TAG, "rail_read_zorder_sync_order failed with error %"PRIu32"!", error);
+ return error;
+ }
+
+ if (context->custom)
+ {
+ IFCALLRET(context->ServerPowerDisplayRequest, error, context, power);
+
+ if (error)
+ WLog_ERR(TAG, "context.ServerPowerDisplayRequest failed with error %"PRIu32"", error);
+ }
+
+ return error;
+}
+
+
+static UINT rail_read_get_application_id_extended_response_order(wStream* s,
+ RAIL_GET_APPID_RESP_EX* id)
+{
+ if (!s || !id)
+ return ERROR_INVALID_PARAMETER;
+
+ if (Stream_GetRemainingLength(s) < 4)
+ {
+ WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
+ return ERROR_INVALID_DATA;
+ }
+
+ Stream_Read_UINT32(s, id->windowID);
+
+ if (!Stream_Read_UTF16_String(s, id->applicationID, ARRAYSIZE(id->applicationID)))
+ return ERROR_INVALID_DATA;
+
+ if (_wcsnlen(id->applicationID, ARRAYSIZE(id->applicationID)) >= ARRAYSIZE(id->applicationID))
+ return ERROR_INVALID_DATA;
+
+ if (Stream_GetRemainingLength(s) < 4)
+ {
+ WLog_ERR(TAG, "Stream_GetRemainingLength failed!");
+ return ERROR_INVALID_DATA;
+ }
+
+ Stream_Read_UINT32(s, id->processId);
+
+ if (!Stream_Read_UTF16_String(s, id->processImageName, ARRAYSIZE(id->processImageName)))
+ return ERROR_INVALID_DATA;
+
+ if (_wcsnlen(id->applicationID, ARRAYSIZE(id->processImageName)) >= ARRAYSIZE(id->processImageName))
+ return ERROR_INVALID_DATA;
+
+ return CHANNEL_RC_OK;
+}
+
+static UINT rail_recv_get_application_id_extended_response_order(railPlugin* rail,
+ RAIL_GET_APPID_RESP_EX* id,
+ wStream* s)
+{
+ RailClientContext* context = rail_get_client_interface(rail);
+ UINT error;
+
+ if (!context || !id)
+ return ERROR_INVALID_PARAMETER;
+
+ if ((error = rail_read_get_application_id_extended_response_order(s, id)))
+ {
+ WLog_ERR(TAG, "rail_read_get_application_id_extended_response_order failed with error %"PRIu32"!",
+ error);
+ return error;
+ }
+
+ if (context->custom)
+ {
+ IFCALLRET(context->ServerGetAppidResponseExtended, error, context, id);
+
+ if (error)
+ WLog_ERR(TAG, "context.ServerGetAppidResponseExtended failed with error %"PRIu32"", error);
+ }
+
+ return error;
+}
+
/**
* Function description
*
return rail_recv_langbar_info_order(rail, &langBarInfo, s);
}
+ case RDP_RAIL_ORDER_ZORDER_SYNC:
+ {
+ RAIL_ZORDER_ZYNC val;
+ return rail_recv_zorder_sync_order(rail, &val, s);
+ }
+
+ case RDP_RAIL_ORDER_POWER_DISPLAY_REQUEST:
+ {
+ RAIL_POWER_DISPLAY_REQUEST val;
+ return rail_recv_power_display_request_order(rail, &val, s);
+ }
+
+ case RDP_RAIL_ORDER_GET_APPID_RESP_EX:
+ {
+ RAIL_GET_APPID_RESP_EX val;
+ return rail_recv_get_application_id_extended_response_order(rail, &val, s);
+ }
+
default:
WLog_ERR(TAG, "Unknown RAIL PDU order reveived.");
return ERROR_INVALID_DATA;
Stream_Free(s, TRUE);
return error;
}
+
+UINT rail_send_client_order_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloak)
+{
+ wStream* s;
+ UINT error;
+
+ if (!rail || !cloak)
+ return ERROR_INVALID_PARAMETER;
+
+ s = rail_pdu_init(5);
+
+ if (!s)
+ {
+ WLog_ERR(TAG, "rail_pdu_init failed!");
+ return CHANNEL_RC_NO_MEMORY;
+ }
+
+ Stream_Write_UINT32(s, cloak->windowId);
+ Stream_Write_UINT8(s, cloak->cloak ? 1 : 0);
+ error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_CLOAK);
+ Stream_Free(s, TRUE);
+ return error;
+}
+
+UINT rail_send_client_order_snap_arrange_order(railPlugin* rail, const RAIL_SNAP_ARRANGE* snap)
+{
+ wStream* s;
+ UINT error;
+
+ if (!rail)
+ return ERROR_INVALID_PARAMETER;
+
+ s = rail_pdu_init(12);
+
+ if (!s)
+ {
+ WLog_ERR(TAG, "rail_pdu_init failed!");
+ return CHANNEL_RC_NO_MEMORY;
+ }
+
+ Stream_Write_UINT32(s, snap->windowId);
+ Stream_Write_UINT16(s, snap->left);
+ Stream_Write_UINT16(s, snap->top);
+ Stream_Write_UINT16(s, snap->right);
+ Stream_Write_UINT16(s, snap->bottom);
+ error = rail_send_pdu(rail, s, RDP_RAIL_ORDER_SNAP_ARRANGE);
+ Stream_Free(s, TRUE);
+ return error;
+}
UINT rail_send_client_langbar_info_order(railPlugin* rail,
const RAIL_LANGBAR_INFO_ORDER* langBarInfo);
+UINT rail_send_client_order_cloak_order(railPlugin* rail, const RAIL_CLOAK* cloak);
+UINT rail_send_client_order_snap_arrange_order(railPlugin* rail, const RAIL_SNAP_ARRANGE* snap);
+
#endif /* FREERDP_CHANNEL_RAIL_CLIENT_ORDERS_H */
static UINT xf_rail_server_system_param(RailClientContext* context,
const RAIL_SYSPARAM_ORDER* sysparam)
{
+ // TODO: Actually apply param
return CHANNEL_RC_OK;
}
-/**
- * Function description
- *
- * @return 0 on success, otherwise a Win32 error code
- */
-static UINT xf_rail_server_handshake(RailClientContext* context,
- const RAIL_HANDSHAKE_ORDER* handshake)
+static UINT xf_rail_server_start_cmd(RailClientContext* context)
{
UINT status;
RAIL_EXEC_ORDER exec = { 0 };
RAIL_SYSPARAM_ORDER sysparam = { 0 };
- RAIL_HANDSHAKE_ORDER clientHandshake;
RAIL_CLIENT_STATUS_ORDER clientStatus = { 0 };
xfContext* xfc = (xfContext*) context->custom;
rdpSettings* settings = xfc->context.settings;
- clientHandshake.buildNumber = 0x00001DB0;
- status = context->ClientHandshake(context, &clientHandshake);
+ clientStatus.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
- if (status != CHANNEL_RC_OK)
- return status;
+ if (settings->AutoReconnectionEnabled)
+ clientStatus.flags |= RAIL_CLIENTSTATUS_AUTORECONNECT;
- clientStatus.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
status = context->ClientInformation(context, &clientStatus);
if (status != CHANNEL_RC_OK)
{
RAIL_LANGBAR_INFO_ORDER langBarInfo;
langBarInfo.languageBarStatus = 0x00000008; /* TF_SFT_HIDDEN */
- context->ClientLanguageBarInfo(context, &langBarInfo);
+ status = context->ClientLanguageBarInfo(context, &langBarInfo);
+
+ if (status != CHANNEL_RC_OK)
+ return status;
}
sysparam.params = 0;
exec.RemoteApplicationArguments = settings->RemoteApplicationCmdLine;
return context->ClientExecute(context, &exec);
}
+/**
+ * Function description
+ *
+ * @return 0 on success, otherwise a Win32 error code
+ */
+static UINT xf_rail_server_handshake(RailClientContext* context,
+ const RAIL_HANDSHAKE_ORDER* handshake)
+{
+ return xf_rail_server_start_cmd(context);
+}
/**
* Function description
static UINT xf_rail_server_handshake_ex(RailClientContext* context,
const RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
{
- return CHANNEL_RC_OK;
+ return xf_rail_server_start_cmd(context);
}
/**
const RAIL_HANDSHAKE_ORDER* handshake);
typedef UINT(*pcRailServerHandshake)(RailClientContext* context,
const RAIL_HANDSHAKE_ORDER* handshake);
-typedef UINT(*pcRailClientHandshakeEx)(RailClientContext* context,
- const RAIL_HANDSHAKE_EX_ORDER* handshakeEx);
typedef UINT(*pcRailServerHandshakeEx)(RailClientContext* context,
const RAIL_HANDSHAKE_EX_ORDER* handshakeEx);
typedef UINT(*pcRailClientNotifyEvent)(RailClientContext* context,
const RAIL_GET_APPID_REQ_ORDER* getAppIdReq);
typedef UINT(*pcRailServerGetAppIdResponse)(RailClientContext* context,
const RAIL_GET_APPID_RESP_ORDER* getAppIdResp);
+typedef UINT(*pcRailServerZOrderSync)(RailClientContext* context,
+ const RAIL_ZORDER_ZYNC* zorder);
+typedef UINT(*pcRailClientCloak)(RailClientContext* context,
+ const RAIL_CLOAK* cloak);
+typedef UINT(*pcRailServerPowerDisplayRequest)(RailClientContext* context,
+ const RAIL_POWER_DISPLAY_REQUEST* power);
+typedef UINT(*pcRailClientSnapArrange)(RailClientContext* context,
+ const RAIL_SNAP_ARRANGE* snap);
+typedef UINT(*pcRailServerGetAppidResponseExtended)(RailClientContext* context,
+ const RAIL_GET_APPID_RESP_EX* id);
struct _rail_client_context
{
pcRailClientSystemCommand ClientSystemCommand;
pcRailClientHandshake ClientHandshake;
pcRailServerHandshake ServerHandshake;
- pcRailClientHandshakeEx ClientHandshakeEx;
pcRailServerHandshakeEx ServerHandshakeEx;
pcRailClientNotifyEvent ClientNotifyEvent;
pcRailClientWindowMove ClientWindowMove;
pcRailServerExecuteResult ServerExecuteResult;
pcRailClientGetAppIdRequest ClientGetAppIdRequest;
pcRailServerGetAppIdResponse ServerGetAppIdResponse;
+ pcRailServerZOrderSync ServerZOrderSync;
+ pcRailClientCloak ClientCloak;
+ pcRailServerPowerDisplayRequest ServerPowerDisplayRequest;
+ pcRailClientSnapArrange ClientSnapArrange;
+ pcRailServerGetAppidResponseExtended ServerGetAppidResponseExtended;
};
#endif /* FREERDP_CHANNEL_RAIL_CLIENT_RAIL_H */
#define TF_SFT_DESKBAND 0x00000800
/* Extended Handshake Flags */
-#define RAIL_ORDER_HANDSHAKEEX_FLAGS_HIDEF 0x00000001
+#define RAIL_ORDER_HANDSHAKEEX_FLAGS_HIDEF 0x00000001
+#define RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED 0x00000002
+#define RAIL_ORDER_HANDSHAKE_EX_FLAGS_SNAP_ARRANGE_SUPPORTED 0x00000004
/* Language Profile Information Flags */
#define TF_PROFILETYPE_INPUTPROCESSOR 0x00000001
};
typedef struct _RAIL_COMPARTMENT_INFO_ORDER RAIL_COMPARTMENT_INFO_ORDER;
+struct _RAIL_ZORDER_ZYNC
+{
+ UINT32 windowIdMarker;
+};
+typedef struct _RAIL_ZORDER_ZYNC RAIL_ZORDER_ZYNC;
+
+struct _RAIL_CLOAK
+{
+ UINT32 windowId;
+ BOOL cloak;
+};
+typedef struct _RAIL_CLOAK RAIL_CLOAK;
+
+struct _RAIL_POWER_DISPLAY_REQUEST
+{
+ UINT32 active;
+};
+typedef struct _RAIL_POWER_DISPLAY_REQUEST RAIL_POWER_DISPLAY_REQUEST;
+
+struct _RAIL_SNAP_ARRANGE
+{
+ UINT32 windowId;
+ UINT16 left;
+ UINT16 top;
+ UINT16 right;
+ UINT16 bottom;
+};
+typedef struct _RAIL_SNAP_ARRANGE RAIL_SNAP_ARRANGE;
+
+struct _RAIL_GET_APPID_RESP_EX
+{
+ UINT32 windowID;
+ WCHAR applicationID[512 / sizeof(WCHAR)];
+ UINT32 processId;
+ WCHAR processImageName[512 / sizeof(WCHAR)];
+};
+typedef struct _RAIL_GET_APPID_RESP_EX RAIL_GET_APPID_RESP_EX;
+
/* RAIL Constants */
-#define RDP_RAIL_ORDER_EXEC 0x0001
-#define RDP_RAIL_ORDER_ACTIVATE 0x0002
-#define RDP_RAIL_ORDER_SYSPARAM 0x0003
-#define RDP_RAIL_ORDER_SYSCOMMAND 0x0004
-#define RDP_RAIL_ORDER_HANDSHAKE 0x0005
-#define RDP_RAIL_ORDER_NOTIFY_EVENT 0x0006
-#define RDP_RAIL_ORDER_WINDOWMOVE 0x0008
-#define RDP_RAIL_ORDER_LOCALMOVESIZE 0x0009
-#define RDP_RAIL_ORDER_MINMAXINFO 0x000A
-#define RDP_RAIL_ORDER_CLIENTSTATUS 0x000B
-#define RDP_RAIL_ORDER_SYSMENU 0x000C
-#define RDP_RAIL_ORDER_LANGBARINFO 0x000D
-#define RDP_RAIL_ORDER_EXEC_RESULT 0x0080
-#define RDP_RAIL_ORDER_GET_APPID_REQ 0x000E
-#define RDP_RAIL_ORDER_GET_APPID_RESP 0x000F
-#define RDP_RAIL_ORDER_LANGUAGEIMEINFO 0x0011
-#define RDP_RAIL_ORDER_COMPARTMENTINFO 0x0012
-#define RDP_RAIL_ORDER_HANDSHAKE_EX 0x0013
+#define RDP_RAIL_ORDER_EXEC 0x0001
+#define RDP_RAIL_ORDER_ACTIVATE 0x0002
+#define RDP_RAIL_ORDER_SYSPARAM 0x0003
+#define RDP_RAIL_ORDER_SYSCOMMAND 0x0004
+#define RDP_RAIL_ORDER_HANDSHAKE 0x0005
+#define RDP_RAIL_ORDER_NOTIFY_EVENT 0x0006
+#define RDP_RAIL_ORDER_WINDOWMOVE 0x0008
+#define RDP_RAIL_ORDER_LOCALMOVESIZE 0x0009
+#define RDP_RAIL_ORDER_MINMAXINFO 0x000A
+#define RDP_RAIL_ORDER_CLIENTSTATUS 0x000B
+#define RDP_RAIL_ORDER_SYSMENU 0x000C
+#define RDP_RAIL_ORDER_LANGBARINFO 0x000D
+#define RDP_RAIL_ORDER_EXEC_RESULT 0x0080
+#define RDP_RAIL_ORDER_GET_APPID_REQ 0x000E
+#define RDP_RAIL_ORDER_GET_APPID_RESP 0x000F
+#define RDP_RAIL_ORDER_LANGUAGEIMEINFO 0x0011
+#define RDP_RAIL_ORDER_COMPARTMENTINFO 0x0012
+#define RDP_RAIL_ORDER_HANDSHAKE_EX 0x0013
+#define RDP_RAIL_ORDER_ZORDER_SYNC 0x0014
+#define RDP_RAIL_ORDER_CLOAK 0x0015
+#define RDP_RAIL_ORDER_POWER_DISPLAY_REQUEST 0x0016
+#define RDP_RAIL_ORDER_SNAP_ARRANGE 0x0017
+#define RDP_RAIL_ORDER_GET_APPID_RESP_EX 0x0018
#ifdef __cplusplus
*/
/* RemoteApp */
- ALIGN64 BOOL RemoteApplicationMode; /* 2112 */
+ ALIGN64 UINT32 RemoteApplicationMode; /* 2112 */
ALIGN64 char* RemoteApplicationName; /* 2113 */
ALIGN64 char* RemoteApplicationIcon; /* 2114 */
ALIGN64 char* RemoteApplicationProgram; /* 2115 */
return FALSE;
Stream_Read_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
-
- if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0)
- {
- if (settings->RemoteApplicationMode == TRUE)
- {
- /* RemoteApp Failure! */
- settings->RemoteApplicationMode = FALSE;
- }
- }
-
+ settings->RemoteApplicationMode = railSupportLevel;
return TRUE;
}
header = rdp_capability_set_start(s);
railSupportLevel = RAIL_LEVEL_SUPPORTED;
- if (settings->RemoteAppLanguageBarSupported)
- railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
+ if (settings->RemoteApplicationMode & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
+ {
+ if (settings->RemoteAppLanguageBarSupported)
+ railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
+ }
+
+ if (settings->RemoteApplicationMode & RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED)
+ railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
Stream_Write_UINT32(s, railSupportLevel); /* railSupportLevel (4 bytes) */
rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
return FALSE;
}
- if (settings->RemoteApplicationMode)
+ if (settings->RemoteApplicationMode & RAIL_LEVEL_SUPPORTED)
{
numberCapabilities += 2;
}
}
- if (settings->RemoteApplicationMode)
+ if (settings->RemoteApplicationMode & RAIL_LEVEL_SUPPORTED)
{
numberCapabilities += 2;
#define DRAW_GDIPLUS_CACHE_LEVEL_ONE 0x00000001
/* RAIL Support Level */
-#define RAIL_LEVEL_SUPPORTED 0x00000001
-#define RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED 0x00000002
-#define RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED 0x00000004
-#define RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED 0x00000008
+#define RAIL_LEVEL_SUPPORTED 0x00000001
+#define RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED 0x00000002
+#define RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED 0x00000004
+#define RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED 0x00000008
#define RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED 0x00000010
-#define RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED 0x00000020
+#define RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED 0x00000020
+#define RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED 0x00000040
+#define RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED 0x00000080
/* Window Support Level */
#define WINDOW_LEVEL_NOT_SUPPORTED 0x00000000