xfreerdp: fix RemoteApp with system message (don't show full desktop on every single connection, just when needed)

This commit is contained in:
Marc-André Moreau
2013-03-28 22:26:28 -04:00
parent d187becc28
commit 066d3384c2
6 changed files with 113 additions and 50 deletions

View File

@@ -34,7 +34,7 @@
void xf_rail_enable_remoteapp_mode(xfInfo* xfi)
{
if (xfi->remote_app == FALSE)
if (!xfi->remote_app)
{
xfi->remote_app = TRUE;
xfi->drawable = DefaultRootWindow(xfi->display);
@@ -45,7 +45,7 @@ void xf_rail_enable_remoteapp_mode(xfInfo* xfi)
void xf_rail_disable_remoteapp_mode(xfInfo* xfi)
{
if (xfi->remote_app == TRUE)
if (xfi->remote_app)
{
xfi->remote_app = FALSE;
xf_create_window(xfi);
@@ -101,9 +101,10 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 u
void xf_rail_DesktopNonMonitored(rdpRail *rail, rdpWindow* window)
{
xfInfo* xfi;
xfi = (xfInfo*) rail->extra;
xf_rail_disable_remoteapp_mode(xfi);
xfInfo* xfi;
xfi = (xfInfo*) rail->extra;
xf_rail_disable_remoteapp_mode(xfi);
}
static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)

View File

@@ -26,8 +26,10 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 u
void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail);
void xf_rail_send_client_system_command(xfInfo* xfi, UINT32 windowId, UINT16 command);
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, BOOL enabled);
void xf_process_rail_event(xfInfo* xfi, rdpChannels* chanman, wMessage* event);
void xf_rail_adjust_position(xfInfo* xfi, rdpWindow *window);
void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window);
void xf_process_rail_event(xfInfo* xfi, rdpChannels* channels, wMessage* event);
void xf_rail_adjust_position(xfInfo* xfi, rdpWindow* window);
void xf_rail_end_local_move(xfInfo* xfi, rdpWindow* window);
void xf_rail_enable_remoteapp_mode(xfInfo* xfi);
void xf_rail_disable_remoteapp_mode(xfInfo* xfi);
#endif /* __XF_RAIL_H */

View File

@@ -397,31 +397,38 @@ void xf_create_window(xfInfo* xfi)
xfi->attribs.bit_gravity = NorthWestGravity;
xfi->attribs.win_gravity = NorthWestGravity;
if (xfi->instance->settings->WindowTitle != NULL)
if (!xfi->remote_app)
{
win_title = _strdup(xfi->instance->settings->WindowTitle);
}
else if (xfi->instance->settings->ServerPort == 3389)
{
win_title = malloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->ServerHostname));
sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->ServerHostname);
if (xfi->instance->settings->WindowTitle != NULL)
{
win_title = _strdup(xfi->instance->settings->WindowTitle);
}
else if (xfi->instance->settings->ServerPort == 3389)
{
win_title = malloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->ServerHostname));
sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->ServerHostname);
}
else
{
win_title = malloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->ServerHostname) + sizeof(":00000"));
sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->ServerHostname, xfi->instance->settings->ServerPort);
}
xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations);
free(win_title);
if (xfi->fullscreen)
xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen);
xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
XSetWMProtocols(xfi->display, xfi->window->handle, &(xfi->WM_DELETE_WINDOW), 1);
xfi->drawable = xfi->window->handle;
}
else
{
win_title = malloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->ServerHostname) + sizeof(":00000"));
sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->ServerHostname, xfi->instance->settings->ServerPort);
xfi->drawable = DefaultRootWindow(xfi->display);
}
xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations);
free(win_title);
if (xfi->fullscreen)
xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen);
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)
@@ -774,12 +781,14 @@ BOOL xf_post_connect(freerdp* instance)
XGCValues gcv;
rdpCache* cache;
rdpChannels* channels;
rdpSettings* settings;
RFX_CONTEXT* rfx_context = NULL;
NSC_CONTEXT* nsc_context = NULL;
xfi = ((xfContext*) instance->context)->xfi;
cache = instance->context->cache;
channels = xfi->_context->channels;
settings = instance->settings;
if (xf_get_pixmap_info(xfi) != TRUE)
return FALSE;
@@ -824,8 +833,11 @@ BOOL xf_post_connect(freerdp* instance)
}
}
xfi->width = instance->settings->DesktopWidth;
xfi->height = instance->settings->DesktopHeight;
xfi->width = settings->DesktopWidth;
xfi->height = settings->DesktopHeight;
if (settings->RemoteApplicationMode)
xfi->remote_app = TRUE;
xf_create_window(xfi);
@@ -961,6 +973,17 @@ BOOL xf_verify_certificate(freerdp* instance, char* subject, char* issuer, char*
return FALSE;
}
int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
{
xfInfo* xfi;
xfi = ((xfContext*) instance->context)->xfi;
xf_rail_disable_remoteapp_mode(xfi);
return 1;
}
int xf_receive_channel_data(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size)
{
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
@@ -1497,6 +1520,7 @@ int main(int argc, char* argv[])
instance->PostConnect = xf_post_connect;
instance->Authenticate = xf_authenticate;
instance->VerifyCertificate = xf_verify_certificate;
instance->LogonErrorInfo = xf_logon_error_info;
instance->ReceiveChannelData = xf_receive_channel_data;
instance->context_size = sizeof(xfContext);

View File

@@ -56,6 +56,8 @@ typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** passwor
typedef BOOL (*pVerifyCertificate)(freerdp* instance, char* subject, char* issuer, char* fingerprint);
typedef BOOL (*pVerifyChangedCertificate)(freerdp* instance, char* subject, char* issuer, char* new_fingerprint, char* old_fingerprint);
typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type);
typedef int (*pSendChannelData)(freerdp* instance, int channelId, BYTE* data, int size);
typedef int (*pReceiveChannelData)(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size);
@@ -175,7 +177,10 @@ struct rdp_freerdp
Callback for changed certificate validation.
Used when a certificate differs from stored fingerprint.
If returns TRUE, the new fingerprint will be trusted and old thrown out. */
UINT32 paddingD[64 - 51]; /* 51 */
pLogonErrorInfo LogonErrorInfo; /**< (offset 53) Callback for logon error info, important for logon system messages with RemoteApp */
UINT32 paddingD[64 - 54]; /* 54 */
pSendChannelData SendChannelData; /* (offset 64)
Callback for sending data to a channel.

View File

@@ -226,6 +226,19 @@ struct _TARGET_NET_ADDRESS
};
typedef struct _TARGET_NET_ADDRESS TARGET_NET_ADDRESS;
/* Logon Error Info */
#define LOGON_MSG_NO_PERMISSION 0xFFFFFFFA
#define LOGON_MSG_BUMP_OPTIONS 0xFFFFFFFB
#define LOGON_MSG_SESSION_RECONNECT 0xFFFFFFFC
#define LOGON_MSG_SESSION_TERMINATE 0xFFFFFFFD
#define LOGON_MSG_SESSION_CONTINUE 0xFFFFFFFE
#define LOGON_FAILED_BAD_PASSWORD 0x00000000
#define LOGON_FAILED_UPDATE_PASSWORD 0x00000001
#define LOGON_FAILED_OTHER 0x00000002
#define LOGON_WARNING 0x00000003
/* SYSTEM_TIME */
typedef struct
{

View File

@@ -54,7 +54,7 @@ BOOL rdp_read_server_auto_reconnect_cookie(wStream* s, rdpSettings* settings)
ARC_SC_PRIVATE_PACKET* autoReconnectCookie;
autoReconnectCookie = settings->ServerAutoReconnectCookie;
if(stream_get_left(s) < 4+4+4+16)
if (stream_get_left(s) < 4+4+4+16)
return FALSE;
stream_read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
stream_read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */
@@ -118,7 +118,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings)
UINT16 cbClientDir;
UINT16 cbAutoReconnectLen;
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_read_UINT16(s, clientAddressFamily); /* clientAddressFamily */
stream_read_UINT16(s, cbClientAddress); /* cbClientAddress */
@@ -131,7 +131,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings)
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), cbClientAddress / 2, &settings->ClientAddress, 0, NULL, NULL);
stream_seek(s, cbClientAddress);
if(stream_get_left(s) < 2)
if (stream_get_left(s) < 2)
return FALSE;
stream_read_UINT16(s, cbClientDir); /* cbClientDir */
@@ -147,7 +147,7 @@ BOOL rdp_read_extended_info_packet(wStream* s, rdpSettings* settings)
if (!rdp_read_client_time_zone(s, settings))
return FALSE;
if(stream_get_left(s) < 10)
if (stream_get_left(s) < 10)
return FALSE;
stream_seek_UINT32(s); /* clientSessionId, should be set to 0 */
stream_read_UINT32(s, settings->PerformanceFlags); /* performanceFlags */
@@ -234,7 +234,7 @@ BOOL rdp_read_info_packet(wStream* s, rdpSettings* settings)
UINT16 cbAlternateShell;
UINT16 cbWorkingDir;
if(stream_get_left(s) < 18) // invalid packet
if (stream_get_left(s) < 18) // invalid packet
return FALSE;
stream_seek_UINT32(s); /* CodePage */
@@ -452,6 +452,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
fprintf(stderr, "Error: SEC_REDIRECTION_PKT unsupported\n");
return FALSE;
}
if (securityFlags & SEC_ENCRYPT)
{
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
@@ -487,13 +488,15 @@ BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s)
UINT32 cbDomain;
UINT32 cbUserName;
if(stream_get_left(s) < 4+52+4+512+4)
if (stream_get_left(s) < (4 + 52 + 4 + 512 + 4))
return FALSE;
stream_read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */
stream_seek(s, 52); /* domain (52 bytes) */
stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
stream_seek(s, 512); /* userName (512 bytes) */
stream_seek_UINT32(s); /* sessionId (4 bytes) */
return TRUE;
}
@@ -502,8 +505,9 @@ BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s)
UINT32 cbDomain;
UINT32 cbUserName;
if(stream_get_left(s) < 2+4+4+4+4+558)
if (stream_get_left(s) < (2 + 4 + 4 + 4 + 4 + 558))
return FALSE;
stream_seek_UINT16(s); /* version (2 bytes) */
stream_seek_UINT32(s); /* size (4 bytes) */
stream_seek_UINT32(s); /* sessionId (4 bytes) */
@@ -511,30 +515,38 @@ BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s)
stream_read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
stream_seek(s, 558); /* pad */
if(stream_get_left(s) < cbDomain+cbUserName)
if (stream_get_left(s) < cbDomain+cbUserName)
return FALSE;
stream_seek(s, cbDomain); /* domain */
stream_seek(s, cbUserName); /* userName */
return TRUE;
}
BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, wStream* s)
{
if(stream_get_left(s) < 576)
if (stream_get_left(s) < 576)
return FALSE;
stream_seek(s, 576); /* pad */
return TRUE;
}
BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s)
{
UINT32 errorNotificationType;
UINT32 errorNotificationData;
UINT32 errorNotificationType;
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */
stream_read_UINT32(s, errorNotificationData); /* errorNotificationData (4 bytes) */
stream_read_UINT32(s, errorNotificationType); /* errorNotificationType (4 bytes) */
IFCALL(rdp->instance->LogonErrorInfo, rdp->instance, errorNotificationData, errorNotificationType);
return TRUE;
}
@@ -544,7 +556,7 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s)
UINT32 fieldsPresent;
UINT16 Length;
if(stream_get_left(s) < 6)
if (stream_get_left(s) < 6)
return FALSE;
stream_read_UINT16(s, Length); /* The total size in bytes of this structure */
@@ -554,25 +566,31 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s)
if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE)
{
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */
if(rdp_read_server_auto_reconnect_cookie(s, rdp->settings) == FALSE)
if (rdp_read_server_auto_reconnect_cookie(s, rdp->settings) == FALSE)
return FALSE;
}
if (fieldsPresent & LOGON_EX_LOGONERRORS)
{
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */
if(rdp_recv_logon_error_info(rdp, s) == FALSE)
if (rdp_recv_logon_error_info(rdp, s) == FALSE)
return FALSE;
}
if(stream_get_left(s) < 570)
if (stream_get_left(s) < 570)
return FALSE;
stream_seek(s, 570); /* pad */
return TRUE;
}
@@ -580,7 +598,7 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s)
{
UINT32 infoType;
if(stream_get_left(s) < 4)
if (stream_get_left(s) < 4)
return FALSE;
stream_read_UINT32(s, infoType); /* infoType (4 bytes) */