xfreerdp: a quick workaround for some issues with TS Remote App.

Currently in Remote App mode we have no option to interact with the
remote desktop host before the first RAIL window is created.

In many situations this interaction possibility is absolutely required.
One example is that screen which gets displayed if another user is logged on.
It requires clicking a button in pre-RAIL mode so that the currently logged
on user gets notified to confirm or deny the connection.

Another example is the option to log on graphically (e.g. for hosts that
don't support NLA) without predefined credentials.

Also if the administrator sets the "User must change password at next logon"
option there is currently no way to do this in TS Remote App mode.

This change basically lets xfreerdp create the main window in Remote App mode
like in a normal session and xfi->remote_app is not set to true initially.

As soon as the rail exec result event or the first rail window creation
request is received (whatever comes first) the main window gets destroyed and
xfi->remote_app is set to true.

The second change is to disconnect immediately if the rail exec result event
reports an error, e.g. if the specified app cannot be found or if it is not
in the list of allowed applications.

This fixes FreeRDP github issue #143 and issue #308.

I'm aware that this is not the most elegant solution but it is definitely an
improvement and probably good enough for 1.0.
A nicer solution would be hiding the main window and only displaying it if
no rail exec result or rail window creation event is received after a certain
timeout ...
This commit is contained in:
Norbert Federa 2012-01-02 10:27:04 +01:00
parent 2a9d9c681d
commit cf3c03c60e
3 changed files with 57 additions and 44 deletions

View File

@ -28,6 +28,17 @@
#include "xf_window.h"
#include "xf_rail.h"
void xf_rail_enable_remoteapp_mode(xfInfo* xfi)
{
if (xfi->remote_app == false)
{
xfi->remote_app = true;
xfi->drawable = DefaultRootWindow(xfi->display);
xf_DestroyWindow(xfi, xfi->window);
xfi->window = NULL;
}
}
void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom)
{
xfWindow* xfw;
@ -75,6 +86,8 @@ void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
xfi = (xfInfo*) rail->extra;
xf_rail_enable_remoteapp_mode(xfi);
xfw = xf_CreateWindow((xfInfo*) rail->extra, window,
window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight,
@ -365,6 +378,11 @@ void xf_process_rail_exec_result_event(xfInfo* xfi, rdpChannels* channels, RDP_E
{
printf("RAIL exec error: execResult=%s NtError=0x%X\n",
error_code_names[exec_result->execResult], exec_result->rawResult);
xfi->disconnect = True;
}
else
{
xf_rail_enable_remoteapp_mode(xfi);
}
}

View File

@ -291,49 +291,42 @@ void xf_create_window(xfInfo* xfi)
xfi->attribs.bit_gravity = ForgetGravity;
xfi->attribs.win_gravity = StaticGravity;
if (xfi->remote_app != true)
if (xfi->instance->settings->window_title != NULL)
{
if (xfi->instance->settings->window_title != NULL)
{
win_title = xmalloc(sizeof(xfi->instance->settings->window_title));
sprintf(win_title, "%s", xfi->instance->settings->window_title);
}
else if (xfi->instance->settings->port == 3389)
{
win_title = xmalloc(sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname));
sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->hostname);
}
else
{
win_title = xmalloc(sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname) + sizeof(":00000"));
sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->hostname, xfi->instance->settings->port);
}
xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations);
xfree(win_title);
if (xfi->parent_window)
XReparentWindow(xfi->display, xfi->window->handle, xfi->parent_window, 0, 0);
if (xfi->fullscreen)
xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen);
/* wait for VisibilityNotify */
do
{
XMaskEvent(xfi->display, VisibilityChangeMask, &xevent);
}
while (xevent.type != VisibilityNotify);
xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
XSetWMProtocols(xfi->display, xfi->window->handle, &(xfi->WM_DELETE_WINDOW), 1);
xfi->drawable = xfi->window->handle;
win_title = xmalloc(sizeof(xfi->instance->settings->window_title));
sprintf(win_title, "%s", xfi->instance->settings->window_title);
}
else if (xfi->instance->settings->port == 3389)
{
win_title = xmalloc(sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname));
sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->hostname);
}
else
{
xfi->drawable = DefaultRootWindow(xfi->display);
win_title = xmalloc(sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname) + sizeof(":00000"));
sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->hostname, xfi->instance->settings->port);
}
xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations);
xfree(win_title);
if (xfi->parent_window)
XReparentWindow(xfi->display, xfi->window->handle, xfi->parent_window, 0, 0);
if (xfi->fullscreen)
xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen);
/* wait for VisibilityNotify */
do
{
XMaskEvent(xfi->display, VisibilityChangeMask, &xevent);
}
while (xevent.type != VisibilityNotify);
xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
XSetWMProtocols(xfi->display, xfi->window->handle, &(xfi->WM_DELETE_WINDOW), 1);
xfi->drawable = xfi->window->handle;
}
void xf_toggle_fullscreen(xfInfo* xfi)
@ -567,7 +560,6 @@ boolean xf_pre_connect(freerdp* instance)
xfi->mouse_motion = settings->mouse_motion;
xfi->complex_regions = true;
xfi->decorations = settings->decorations;
xfi->remote_app = settings->remote_app;
xfi->fullscreen = settings->fullscreen;
xfi->grab_keyboard = settings->grab_keyboard;
xfi->fullscreen_toggle = true;
@ -742,8 +734,7 @@ boolean xf_post_connect(freerdp* instance)
xf_tsmf_init(xfi, xv_port);
if (xfi->remote_app != true)
xf_cliprdr_init(xfi, channels);
xf_cliprdr_init(xfi, channels);
return true;
}
@ -889,8 +880,11 @@ void xf_window_free(xfInfo* xfi)
XFreeGC(xfi->display, xfi->gc);
xfi->gc = 0;
xf_DestroyWindow(xfi, xfi->window);
xfi->window = NULL;
if (xfi->window != NULL)
{
xf_DestroyWindow(xfi, xfi->window);
xfi->window = NULL;
}
if (xfi->primary)
{
@ -965,7 +959,7 @@ int xfreerdp_run(freerdp* instance)
xfi = ((xfContext*) instance->context)->xfi;
channels = instance->context->channels;
while (1)
while (!xfi->disconnect)
{
rcount = 0;
wcount = 0;

View File

@ -107,6 +107,7 @@ struct xf_info
xfWorkArea workArea;
int current_desktop;
boolean remote_app;
boolean disconnect;
HCLRCONV clrconv;
Window parent_window;