Merge pull request #1754 from awakecoding/master
Multimon Fix, xfreerdp extensibility, context-specific error handling, Gateway LAN auto-detect
This commit is contained in:
commit
caecf1823b
@ -1091,8 +1091,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
|||||||
|
|
||||||
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
|
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
|
||||||
|
|
||||||
WLog_SetLogLevel(rdpsnd->log, WLOG_TRACE);
|
|
||||||
|
|
||||||
rdpsnd->channelEntryPoints.pVirtualChannelInit(&rdpsnd->InitHandle,
|
rdpsnd->channelEntryPoints.pVirtualChannelInit(&rdpsnd->InitHandle,
|
||||||
&rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpsnd_virtual_channel_init_event);
|
&rdpsnd->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpsnd_virtual_channel_init_event);
|
||||||
|
|
||||||
|
@ -868,7 +868,7 @@ BOOL xf_pre_connect(freerdp* instance)
|
|||||||
xfc->WM_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", False);
|
xfc->WM_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", False);
|
||||||
xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False);
|
xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False);
|
||||||
|
|
||||||
xf_kbd_init(xfc);
|
xf_keyboard_init(xfc);
|
||||||
|
|
||||||
xfc->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA);
|
xfc->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA);
|
||||||
|
|
||||||
@ -972,10 +972,10 @@ BOOL xf_post_connect(freerdp* instance)
|
|||||||
|
|
||||||
ZeroMemory(&gcv, sizeof(gcv));
|
ZeroMemory(&gcv, sizeof(gcv));
|
||||||
|
|
||||||
if (xfc->modifier_map)
|
if (xfc->modifierMap)
|
||||||
XFreeModifiermap(xfc->modifier_map);
|
XFreeModifiermap(xfc->modifierMap);
|
||||||
|
|
||||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
xfc->modifierMap = XGetModifierMapping(xfc->display);
|
||||||
|
|
||||||
xfc->gc = XCreateGC(xfc->display, xfc->drawable, GCGraphicsExposures, &gcv);
|
xfc->gc = XCreateGC(xfc->display, xfc->drawable, GCGraphicsExposures, &gcv);
|
||||||
xfc->primary = XCreatePixmap(xfc->display, xfc->drawable, xfc->width, xfc->height, xfc->depth);
|
xfc->primary = XCreatePixmap(xfc->display, xfc->drawable, xfc->width, xfc->height, xfc->depth);
|
||||||
@ -1161,11 +1161,7 @@ void xf_window_free(xfContext* xfc)
|
|||||||
{
|
{
|
||||||
rdpContext* context = (rdpContext*) xfc;
|
rdpContext* context = (rdpContext*) xfc;
|
||||||
|
|
||||||
if (xfc->modifier_map)
|
xf_keyboard_free(xfc);
|
||||||
{
|
|
||||||
XFreeModifiermap(xfc->modifier_map);
|
|
||||||
xfc->modifier_map = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xfc->gc)
|
if (xfc->gc)
|
||||||
{
|
{
|
||||||
@ -1515,8 +1511,8 @@ void* xf_thread(void* param)
|
|||||||
*/
|
*/
|
||||||
if (freerdp_focus_required(instance))
|
if (freerdp_focus_required(instance))
|
||||||
{
|
{
|
||||||
xf_kbd_focus_in(xfc);
|
xf_keyboard_focus_in(xfc);
|
||||||
xf_kbd_focus_in(xfc);
|
xf_keyboard_focus_in(xfc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!async_transport)
|
if (!async_transport)
|
||||||
|
@ -87,6 +87,99 @@ const char* const X11_EVENT_STRINGS[] =
|
|||||||
#define DEBUG_X11_LMS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
#define DEBUG_X11_LMS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int xf_event_action_script_init(xfContext* xfc)
|
||||||
|
{
|
||||||
|
int exitCode;
|
||||||
|
char* xevent;
|
||||||
|
FILE* actionScript;
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
char command[1024] = { 0 };
|
||||||
|
|
||||||
|
xfc->xevents = ArrayList_New(TRUE);
|
||||||
|
ArrayList_Object(xfc->xevents)->fnObjectFree = free;
|
||||||
|
|
||||||
|
sprintf_s(command, sizeof(command), "%s xevent", xfc->actionScript);
|
||||||
|
|
||||||
|
actionScript = popen(command, "r");
|
||||||
|
|
||||||
|
if (actionScript < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (fgets(buffer, sizeof(buffer), actionScript) != NULL)
|
||||||
|
{
|
||||||
|
strtok(buffer, "\n");
|
||||||
|
xevent = _strdup(buffer);
|
||||||
|
ArrayList_Add(xfc->xevents, xevent);
|
||||||
|
}
|
||||||
|
|
||||||
|
exitCode = pclose(actionScript);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xf_event_action_script_free(xfContext* xfc)
|
||||||
|
{
|
||||||
|
if (xfc->xevents)
|
||||||
|
{
|
||||||
|
ArrayList_Free(xfc->xevents);
|
||||||
|
xfc->xevents = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int xf_event_execute_action_script(xfContext* xfc, XEvent* event)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
int count;
|
||||||
|
char* name;
|
||||||
|
int exitCode;
|
||||||
|
FILE* actionScript;
|
||||||
|
BOOL match = FALSE;
|
||||||
|
const char* xeventName;
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
char command[1024] = { 0 };
|
||||||
|
|
||||||
|
if (!xfc->actionScript)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (event->type > (sizeof(X11_EVENT_STRINGS) / sizeof(const char*)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
xeventName = X11_EVENT_STRINGS[event->type];
|
||||||
|
|
||||||
|
count = ArrayList_Count(xfc->xevents);
|
||||||
|
|
||||||
|
for (index = 0; index < count; index++)
|
||||||
|
{
|
||||||
|
name = (char*) ArrayList_GetItem(xfc->xevents, index);
|
||||||
|
|
||||||
|
if (_stricmp(name, xeventName) == 0)
|
||||||
|
{
|
||||||
|
match = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
sprintf_s(command, sizeof(command), "%s xevent %s %d",
|
||||||
|
xfc->actionScript, xeventName, (int) xfc->window->handle);
|
||||||
|
|
||||||
|
actionScript = popen(command, "r");
|
||||||
|
|
||||||
|
if (actionScript < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (fgets(buffer, sizeof(buffer), actionScript) != NULL)
|
||||||
|
{
|
||||||
|
strtok(buffer, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
exitCode = pclose(actionScript);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
@ -395,34 +488,28 @@ static BOOL xf_event_KeyPress(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
|
|
||||||
XLookupString((XKeyEvent*) event, str, sizeof(str), &keysym, NULL);
|
XLookupString((XKeyEvent*) event, str, sizeof(str), &keysym, NULL);
|
||||||
|
|
||||||
xf_kbd_set_keypress(xfc, event->xkey.keycode, keysym);
|
xf_keyboard_key_press(xfc, event->xkey.keycode, keysym);
|
||||||
|
|
||||||
if (xfc->fullscreen_toggle && xf_kbd_handle_special_keys(xfc, keysym))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
xf_kbd_send_key(xfc, TRUE, event->xkey.keycode);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL xf_event_KeyRelease(xfContext* xfc, XEvent* event, BOOL app)
|
static BOOL xf_event_KeyRelease(xfContext* xfc, XEvent* event, BOOL app)
|
||||||
{
|
{
|
||||||
XEvent next_event;
|
XEvent nextEvent;
|
||||||
|
|
||||||
if (XPending(xfc->display))
|
if (XPending(xfc->display))
|
||||||
{
|
{
|
||||||
ZeroMemory(&next_event, sizeof(next_event));
|
ZeroMemory(&nextEvent, sizeof(nextEvent));
|
||||||
XPeekEvent(xfc->display, &next_event);
|
XPeekEvent(xfc->display, &nextEvent);
|
||||||
|
|
||||||
if (next_event.type == KeyPress)
|
if (nextEvent.type == KeyPress)
|
||||||
{
|
{
|
||||||
if (next_event.xkey.keycode == event->xkey.keycode)
|
if (nextEvent.xkey.keycode == event->xkey.keycode)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xf_kbd_unset_keypress(xfc, event->xkey.keycode);
|
xf_keyboard_key_release(xfc, event->xkey.keycode);
|
||||||
xf_kbd_send_key(xfc, FALSE, event->xkey.keycode);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -451,7 +538,7 @@ static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
xf_rail_adjust_position(xfc, window);
|
xf_rail_adjust_position(xfc, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
xf_kbd_focus_in(xfc);
|
xf_keyboard_focus_in(xfc);
|
||||||
|
|
||||||
if (!app)
|
if (!app)
|
||||||
xf_cliprdr_check_owner(xfc);
|
xf_cliprdr_check_owner(xfc);
|
||||||
@ -469,7 +556,7 @@ static BOOL xf_event_FocusOut(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
if (event->xfocus.mode == NotifyWhileGrabbed)
|
if (event->xfocus.mode == NotifyWhileGrabbed)
|
||||||
XUngrabKeyboard(xfc->display, CurrentTime);
|
XUngrabKeyboard(xfc->display, CurrentTime);
|
||||||
|
|
||||||
xf_kbd_clear(xfc);
|
xf_keyboard_clear(xfc);
|
||||||
|
|
||||||
if (app)
|
if (app)
|
||||||
xf_rail_send_activate(xfc, event->xany.window, FALSE);
|
xf_rail_send_activate(xfc, event->xany.window, FALSE);
|
||||||
@ -481,10 +568,10 @@ static BOOL xf_event_MappingNotify(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
{
|
{
|
||||||
if (event->xmapping.request == MappingModifier)
|
if (event->xmapping.request == MappingModifier)
|
||||||
{
|
{
|
||||||
if (xfc->modifier_map)
|
if (xfc->modifierMap)
|
||||||
XFreeModifiermap(xfc->modifier_map);
|
XFreeModifiermap(xfc->modifierMap);
|
||||||
|
|
||||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
xfc->modifierMap = XGetModifierMapping(xfc->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -681,7 +768,7 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
rdpUpdate* update = xfc->instance->update;
|
rdpUpdate* update = xfc->instance->update;
|
||||||
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
rdpRail* rail = ((rdpContext*) xfc)->rail;
|
||||||
|
|
||||||
xf_kbd_release_all_keypress(xfc);
|
xf_keyboard_release_all_keypress(xfc);
|
||||||
|
|
||||||
if (!app)
|
if (!app)
|
||||||
{
|
{
|
||||||
@ -941,6 +1028,8 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xf_event_execute_action_script(xfc, event);
|
||||||
|
|
||||||
if (event->type != MotionNotify)
|
if (event->type != MotionNotify)
|
||||||
DEBUG_X11("%s Event(%d): wnd=0x%04X", X11_EVENT_STRINGS[event->type], event->type, (UINT32) event->xany.window);
|
DEBUG_X11("%s Event(%d): wnd=0x%04X", X11_EVENT_STRINGS[event->type], event->type, (UINT32) event->xany.window);
|
||||||
|
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
#include "xf_client.h"
|
#include "xf_client.h"
|
||||||
#include "xfreerdp.h"
|
#include "xfreerdp.h"
|
||||||
|
|
||||||
|
int xf_event_action_script_init(xfContext* xfc);
|
||||||
|
void xf_event_action_script_free(xfContext* xfc);
|
||||||
|
|
||||||
BOOL xf_event_process(freerdp* instance, XEvent* event);
|
BOOL xf_event_process(freerdp* instance, XEvent* event);
|
||||||
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
|
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
|
||||||
|
|
||||||
|
@ -236,7 +236,6 @@ void xf_input_save_last_event(XGenericEventCookie* cookie)
|
|||||||
lastEvent.detail = event->detail;
|
lastEvent.detail = event->detail;
|
||||||
lastEvent.event_x = event->event_x;
|
lastEvent.event_x = event->event_x;
|
||||||
lastEvent.event_y = event->event_y;
|
lastEvent.event_y = event->event_y;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_input_detect_pan(xfContext* xfc)
|
void xf_input_detect_pan(xfContext* xfc)
|
||||||
@ -269,13 +268,10 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
|
|
||||||
dist_x = fabs(contacts[0].pos_x - contacts[1].pos_x);
|
dist_x = fabs(contacts[0].pos_x - contacts[1].pos_x);
|
||||||
dist_y = fabs(contacts[0].pos_y - contacts[1].pos_y);
|
dist_y = fabs(contacts[0].pos_y - contacts[1].pos_y);
|
||||||
|
|
||||||
|
if (dist_y > MIN_FINGER_DIST)
|
||||||
//only pan in x if dist_y is greater than something
|
|
||||||
if(dist_y > MIN_FINGER_DIST)
|
|
||||||
{
|
{
|
||||||
|
if (px_vector > PAN_THRESHOLD)
|
||||||
if(px_vector > PAN_THRESHOLD)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -293,7 +289,7 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
py_vector = 0;
|
py_vector = 0;
|
||||||
z_vector = 0;
|
z_vector = 0;
|
||||||
}
|
}
|
||||||
else if(px_vector < -PAN_THRESHOLD)
|
else if (px_vector < -PAN_THRESHOLD)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
@ -313,10 +309,10 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dist_x > MIN_FINGER_DIST)
|
if (dist_x > MIN_FINGER_DIST)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(py_vector > PAN_THRESHOLD)
|
if (py_vector > PAN_THRESHOLD)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
@ -333,7 +329,7 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
py_vector = 0;
|
py_vector = 0;
|
||||||
z_vector = 0;
|
z_vector = 0;
|
||||||
}
|
}
|
||||||
else if(py_vector < -PAN_THRESHOLD)
|
else if (py_vector < -PAN_THRESHOLD)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
@ -351,7 +347,6 @@ void xf_input_detect_pan(xfContext* xfc)
|
|||||||
z_vector = 0;
|
z_vector = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_input_detect_pinch(xfContext* xfc)
|
void xf_input_detect_pinch(xfContext* xfc)
|
||||||
@ -368,7 +363,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* first calculate the distance */
|
/* first calculate the distance */
|
||||||
dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) +
|
dist = sqrt(pow(contacts[1].pos_x - contacts[0].last_x, 2.0) +
|
||||||
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
pow(contacts[1].pos_y - contacts[0].last_y, 2.0));
|
||||||
@ -399,7 +393,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||||||
|
|
||||||
z_vector += delta;
|
z_vector += delta;
|
||||||
|
|
||||||
|
|
||||||
lastDist = dist;
|
lastDist = dist;
|
||||||
|
|
||||||
if (z_vector > ZOOM_THRESHOLD)
|
if (z_vector > ZOOM_THRESHOLD)
|
||||||
@ -451,8 +444,6 @@ void xf_input_detect_pinch(xfContext* xfc)
|
|||||||
void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if(active_contacts == MAX_CONTACTS)
|
|
||||||
printf("Houston, we have a problem!\n\n");
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_CONTACTS; i++)
|
for (i = 0; i < MAX_CONTACTS; i++)
|
||||||
{
|
{
|
||||||
@ -472,6 +463,7 @@ void xf_input_touch_begin(xfContext* xfc, XIDeviceEvent* event)
|
|||||||
void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_CONTACTS; i++)
|
for (i = 0; i < MAX_CONTACTS; i++)
|
||||||
{
|
{
|
||||||
if (contacts[i].id == event->detail)
|
if (contacts[i].id == event->detail)
|
||||||
@ -493,14 +485,13 @@ void xf_input_touch_update(xfContext* xfc, XIDeviceEvent* event)
|
|||||||
void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
void xf_input_touch_end(xfContext* xfc, XIDeviceEvent* event)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_CONTACTS; i++)
|
for (i = 0; i < MAX_CONTACTS; i++)
|
||||||
{
|
{
|
||||||
if (contacts[i].id == event->detail)
|
if (contacts[i].id == event->detail)
|
||||||
{
|
{
|
||||||
contacts[i].id = 0;
|
contacts[i].id = 0;
|
||||||
contacts[i].count = 0;
|
contacts[i].count = 0;
|
||||||
//contacts[i].pos_x = (int)event->event_x;
|
|
||||||
//contacts[i].pos_y = (int)event->event_y;
|
|
||||||
|
|
||||||
active_contacts--;
|
active_contacts--;
|
||||||
break;printf("TouchBegin\n");
|
break;printf("TouchBegin\n");
|
||||||
@ -733,15 +724,15 @@ void xf_process_rdpei_event(xfContext* xfc, wMessage* event)
|
|||||||
int xf_input_handle_event(xfContext* xfc, XEvent* event)
|
int xf_input_handle_event(xfContext* xfc, XEvent* event)
|
||||||
{
|
{
|
||||||
#ifdef WITH_XI
|
#ifdef WITH_XI
|
||||||
//printf("m:%d g:%d\n", (xfc->settings->MultiTouchInput), (xfc->settings->MultiTouchGestures) );
|
|
||||||
if (xfc->settings->MultiTouchInput)
|
if (xfc->settings->MultiTouchInput)
|
||||||
{
|
{
|
||||||
return xf_input_handle_event_remote(xfc, event);
|
return xf_input_handle_event_remote(xfc, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xfc->settings->MultiTouchGestures)
|
if (xfc->settings->MultiTouchGestures)
|
||||||
|
{
|
||||||
return xf_input_handle_event_local(xfc, event);
|
return xf_input_handle_event_local(xfc, event);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/path.h>
|
||||||
|
#include <winpr/collections.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
@ -33,66 +35,153 @@
|
|||||||
|
|
||||||
#include <freerdp/locale/keyboard.h>
|
#include <freerdp/locale/keyboard.h>
|
||||||
|
|
||||||
|
#include "xf_event.h"
|
||||||
|
|
||||||
#include "xf_keyboard.h"
|
#include "xf_keyboard.h"
|
||||||
|
|
||||||
void xf_kbd_init(xfContext* xfc)
|
int xf_keyboard_action_script_init(xfContext* xfc)
|
||||||
{
|
{
|
||||||
xf_kbd_clear(xfc);
|
int exitCode;
|
||||||
|
FILE* keyScript;
|
||||||
|
char* keyCombination;
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
char command[1024] = { 0 };
|
||||||
|
|
||||||
xfc->keyboard_layout_id = xfc->instance->settings->KeyboardLayout;
|
if (xfc->actionScript)
|
||||||
xfc->keyboard_layout_id = freerdp_keyboard_init(xfc->keyboard_layout_id);
|
{
|
||||||
xfc->instance->settings->KeyboardLayout = xfc->keyboard_layout_id;
|
free(xfc->actionScript);
|
||||||
|
xfc->actionScript = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (xfc->modifier_map)
|
if (PathFileExistsA("/usr/share/freerdp/action.sh"))
|
||||||
XFreeModifiermap(xfc->modifier_map);
|
xfc->actionScript = _strdup("/usr/share/freerdp/action.sh");
|
||||||
|
|
||||||
xfc->modifier_map = XGetModifierMapping(xfc->display);
|
if (!xfc->actionScript)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
xfc->keyCombinations = ArrayList_New(TRUE);
|
||||||
|
ArrayList_Object(xfc->keyCombinations)->fnObjectFree = free;
|
||||||
|
|
||||||
|
sprintf_s(command, sizeof(command), "%s key", xfc->actionScript);
|
||||||
|
|
||||||
|
keyScript = popen(command, "r");
|
||||||
|
|
||||||
|
if (keyScript < 0)
|
||||||
|
{
|
||||||
|
free(xfc->actionScript);
|
||||||
|
xfc->actionScript = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(buffer, sizeof(buffer), keyScript) != NULL)
|
||||||
|
{
|
||||||
|
strtok(buffer, "\n");
|
||||||
|
keyCombination = _strdup(buffer);
|
||||||
|
ArrayList_Add(xfc->keyCombinations, keyCombination);
|
||||||
|
}
|
||||||
|
|
||||||
|
exitCode = pclose(keyScript);
|
||||||
|
|
||||||
|
xf_event_action_script_init(xfc);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_kbd_clear(xfContext* xfc)
|
void xf_keyboard_action_script_free(xfContext* xfc)
|
||||||
{
|
{
|
||||||
ZeroMemory(xfc->pressed_keys, 256 * sizeof(BOOL));
|
xf_event_action_script_free(xfc);
|
||||||
|
|
||||||
|
if (xfc->keyCombinations)
|
||||||
|
{
|
||||||
|
ArrayList_Free(xfc->keyCombinations);
|
||||||
|
xfc->keyCombinations = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xfc->actionScript)
|
||||||
|
{
|
||||||
|
free(xfc->actionScript);
|
||||||
|
xfc->actionScript = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_kbd_set_keypress(xfContext* xfc, BYTE keycode, KeySym keysym)
|
void xf_keyboard_init(xfContext* xfc)
|
||||||
{
|
{
|
||||||
if (keycode >= 8)
|
xf_keyboard_clear(xfc);
|
||||||
xfc->pressed_keys[keycode] = keysym;
|
|
||||||
else
|
xfc->KeyboardLayout = xfc->instance->settings->KeyboardLayout;
|
||||||
|
xfc->KeyboardLayout = freerdp_keyboard_init(xfc->KeyboardLayout);
|
||||||
|
xfc->instance->settings->KeyboardLayout = xfc->KeyboardLayout;
|
||||||
|
|
||||||
|
if (xfc->modifierMap)
|
||||||
|
XFreeModifiermap(xfc->modifierMap);
|
||||||
|
|
||||||
|
xfc->modifierMap = XGetModifierMapping(xfc->display);
|
||||||
|
|
||||||
|
xf_keyboard_action_script_init(xfc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xf_keyboard_free(xfContext* xfc)
|
||||||
|
{
|
||||||
|
if (xfc->modifierMap)
|
||||||
|
{
|
||||||
|
XFreeModifiermap(xfc->modifierMap);
|
||||||
|
xfc->modifierMap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
xf_keyboard_action_script_free(xfc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xf_keyboard_clear(xfContext* xfc)
|
||||||
|
{
|
||||||
|
ZeroMemory(xfc->KeyboardState, 256 * sizeof(BOOL));
|
||||||
|
}
|
||||||
|
|
||||||
|
void xf_keyboard_key_press(xfContext* xfc, BYTE keycode, KeySym keysym)
|
||||||
|
{
|
||||||
|
if (keycode < 8)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
void xf_kbd_unset_keypress(xfContext* xfc, BYTE keycode)
|
xfc->KeyboardState[keycode] = keysym;
|
||||||
{
|
|
||||||
if (keycode >= 8)
|
if (xf_keyboard_handle_special_keys(xfc, keysym))
|
||||||
xfc->pressed_keys[keycode] = NoSymbol;
|
|
||||||
else
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
xf_keyboard_send_key(xfc, TRUE, keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_kbd_release_all_keypress(xfContext* xfc)
|
void xf_keyboard_key_release(xfContext* xfc, BYTE keycode)
|
||||||
|
{
|
||||||
|
if (keycode < 8)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xfc->KeyboardState[keycode] = NoSymbol;
|
||||||
|
|
||||||
|
xf_keyboard_send_key(xfc, FALSE, keycode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xf_keyboard_release_all_keypress(xfContext* xfc)
|
||||||
{
|
{
|
||||||
int keycode;
|
int keycode;
|
||||||
DWORD rdp_scancode;
|
DWORD rdp_scancode;
|
||||||
|
|
||||||
for (keycode = 0; keycode < ARRAYSIZE(xfc->pressed_keys); keycode++)
|
for (keycode = 0; keycode < ARRAYSIZE(xfc->KeyboardState); keycode++)
|
||||||
{
|
{
|
||||||
if (xfc->pressed_keys[keycode] != NoSymbol)
|
if (xfc->KeyboardState[keycode] != NoSymbol)
|
||||||
{
|
{
|
||||||
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
|
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
|
||||||
freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, rdp_scancode);
|
freerdp_input_send_keyboard_event_ex(xfc->instance->input, FALSE, rdp_scancode);
|
||||||
xfc->pressed_keys[keycode] = NoSymbol;
|
xfc->KeyboardState[keycode] = NoSymbol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xf_kbd_key_pressed(xfContext* xfc, KeySym keysym)
|
BOOL xf_keyboard_key_pressed(xfContext* xfc, KeySym keysym)
|
||||||
{
|
{
|
||||||
KeyCode keycode = XKeysymToKeycode(xfc->display, keysym);
|
KeyCode keycode = XKeysymToKeycode(xfc->display, keysym);
|
||||||
return (xfc->pressed_keys[keycode] == keysym);
|
return (xfc->KeyboardState[keycode] == keysym);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
||||||
{
|
{
|
||||||
DWORD rdp_scancode;
|
DWORD rdp_scancode;
|
||||||
rdpInput* input;
|
rdpInput* input;
|
||||||
@ -105,7 +194,7 @@ void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
|||||||
fprintf(stderr, "Unknown key with X keycode 0x%02x\n", keycode);
|
fprintf(stderr, "Unknown key with X keycode 0x%02x\n", keycode);
|
||||||
}
|
}
|
||||||
else if (rdp_scancode == RDP_SCANCODE_PAUSE &&
|
else if (rdp_scancode == RDP_SCANCODE_PAUSE &&
|
||||||
!xf_kbd_key_pressed(xfc, XK_Control_L) && !xf_kbd_key_pressed(xfc, XK_Control_R))
|
!xf_keyboard_key_pressed(xfc, XK_Control_L) && !xf_keyboard_key_pressed(xfc, XK_Control_R))
|
||||||
{
|
{
|
||||||
/* Pause without Ctrl has to be sent as Ctrl + NumLock. */
|
/* Pause without Ctrl has to be sent as Ctrl + NumLock. */
|
||||||
if (down)
|
if (down)
|
||||||
@ -123,13 +212,13 @@ void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode)
|
|||||||
if ((rdp_scancode == RDP_SCANCODE_CAPSLOCK) && (down == FALSE))
|
if ((rdp_scancode == RDP_SCANCODE_CAPSLOCK) && (down == FALSE))
|
||||||
{
|
{
|
||||||
UINT32 syncFlags;
|
UINT32 syncFlags;
|
||||||
syncFlags = xf_kbd_get_toggle_keys_state(xfc);
|
syncFlags = xf_keyboard_get_toggle_keys_state(xfc);
|
||||||
input->SynchronizeEvent(input, syncFlags);
|
input->SynchronizeEvent(input, syncFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int xf_kbd_read_keyboard_state(xfContext* xfc)
|
int xf_keyboard_read_keyboard_state(xfContext* xfc)
|
||||||
{
|
{
|
||||||
int dummy;
|
int dummy;
|
||||||
Window wdummy;
|
Window wdummy;
|
||||||
@ -145,10 +234,11 @@ int xf_kbd_read_keyboard_state(xfContext* xfc)
|
|||||||
XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
|
XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
|
||||||
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
|
&wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym)
|
BOOL xf_keyboard_get_key_state(xfContext* xfc, int state, int keysym)
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
int modifierpos, key, keysymMask = 0;
|
int modifierpos, key, keysymMask = 0;
|
||||||
@ -159,11 +249,11 @@ BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym)
|
|||||||
|
|
||||||
for (modifierpos = 0; modifierpos < 8; modifierpos++)
|
for (modifierpos = 0; modifierpos < 8; modifierpos++)
|
||||||
{
|
{
|
||||||
offset = xfc->modifier_map->max_keypermod * modifierpos;
|
offset = xfc->modifierMap->max_keypermod * modifierpos;
|
||||||
|
|
||||||
for (key = 0; key < xfc->modifier_map->max_keypermod; key++)
|
for (key = 0; key < xfc->modifierMap->max_keypermod; key++)
|
||||||
{
|
{
|
||||||
if (xfc->modifier_map->modifiermap[offset + key] == keycode)
|
if (xfc->modifierMap->modifiermap[offset + key] == keycode)
|
||||||
{
|
{
|
||||||
keysymMask |= 1 << modifierpos;
|
keysymMask |= 1 << modifierpos;
|
||||||
}
|
}
|
||||||
@ -173,26 +263,26 @@ BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym)
|
|||||||
return (state & keysymMask) ? TRUE : FALSE;
|
return (state & keysymMask) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xf_kbd_get_toggle_keys_state(xfContext* xfc)
|
UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc)
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
int toggle_keys_state = 0;
|
UINT32 toggleKeysState = 0;
|
||||||
|
|
||||||
state = xf_kbd_read_keyboard_state(xfc);
|
state = xf_keyboard_read_keyboard_state(xfc);
|
||||||
|
|
||||||
if (xf_kbd_get_key_state(xfc, state, XK_Scroll_Lock))
|
if (xf_keyboard_get_key_state(xfc, state, XK_Scroll_Lock))
|
||||||
toggle_keys_state |= KBD_SYNC_SCROLL_LOCK;
|
toggleKeysState |= KBD_SYNC_SCROLL_LOCK;
|
||||||
if (xf_kbd_get_key_state(xfc, state, XK_Num_Lock))
|
if (xf_keyboard_get_key_state(xfc, state, XK_Num_Lock))
|
||||||
toggle_keys_state |= KBD_SYNC_NUM_LOCK;
|
toggleKeysState |= KBD_SYNC_NUM_LOCK;
|
||||||
if (xf_kbd_get_key_state(xfc, state, XK_Caps_Lock))
|
if (xf_keyboard_get_key_state(xfc, state, XK_Caps_Lock))
|
||||||
toggle_keys_state |= KBD_SYNC_CAPS_LOCK;
|
toggleKeysState |= KBD_SYNC_CAPS_LOCK;
|
||||||
if (xf_kbd_get_key_state(xfc, state, XK_Kana_Lock))
|
if (xf_keyboard_get_key_state(xfc, state, XK_Kana_Lock))
|
||||||
toggle_keys_state |= KBD_SYNC_KANA_LOCK;
|
toggleKeysState |= KBD_SYNC_KANA_LOCK;
|
||||||
|
|
||||||
return toggle_keys_state;
|
return toggleKeysState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_kbd_focus_in(xfContext* xfc)
|
void xf_keyboard_focus_in(xfContext* xfc)
|
||||||
{
|
{
|
||||||
rdpInput* input;
|
rdpInput* input;
|
||||||
UINT32 syncFlags;
|
UINT32 syncFlags;
|
||||||
@ -200,39 +290,141 @@ void xf_kbd_focus_in(xfContext* xfc)
|
|||||||
Window wdummy;
|
Window wdummy;
|
||||||
UINT32 state = 0;
|
UINT32 state = 0;
|
||||||
|
|
||||||
if (xfc->display && xfc->window)
|
if (xfc->display && xfc->window)
|
||||||
{
|
{
|
||||||
input = xfc->instance->input;
|
input = xfc->instance->input;
|
||||||
syncFlags = xf_kbd_get_toggle_keys_state(xfc);
|
syncFlags = xf_keyboard_get_toggle_keys_state(xfc);
|
||||||
XQueryPointer(xfc->display, xfc->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state);
|
XQueryPointer(xfc->display, xfc->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state);
|
||||||
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
|
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
int xf_keyboard_execute_action_script(xfContext* xfc, XF_MODIFIER_KEYS* mod, KeySym keysym)
|
||||||
{
|
{
|
||||||
|
int index;
|
||||||
|
int count;
|
||||||
|
int exitCode;
|
||||||
|
int status = 1;
|
||||||
|
FILE* keyScript;
|
||||||
|
const char* keyStr;
|
||||||
|
BOOL match = FALSE;
|
||||||
|
char* keyCombination;
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
char command[1024] = { 0 };
|
||||||
|
char combination[1024] = { 0 };
|
||||||
|
|
||||||
|
if (!xfc->actionScript)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if ((keysym == XK_Shift_L) || (keysym == XK_Shift_R) ||
|
||||||
|
(keysym == XK_Alt_L) || (keysym == XK_Alt_R) ||
|
||||||
|
(keysym == XK_Control_L) || (keysym == XK_Control_R))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyStr = XKeysymToString(keysym);
|
||||||
|
|
||||||
|
if (mod->Shift)
|
||||||
|
strcat(combination, "Shift+");
|
||||||
|
|
||||||
|
if (mod->Ctrl)
|
||||||
|
strcat(combination, "Ctrl+");
|
||||||
|
|
||||||
|
if (mod->Alt)
|
||||||
|
strcat(combination, "Alt+");
|
||||||
|
|
||||||
|
strcat(combination, keyStr);
|
||||||
|
|
||||||
|
count = ArrayList_Count(xfc->keyCombinations);
|
||||||
|
|
||||||
|
for (index = 0; index < count; index++)
|
||||||
|
{
|
||||||
|
keyCombination = (char*) ArrayList_GetItem(xfc->keyCombinations, index);
|
||||||
|
|
||||||
|
if (_stricmp(keyCombination, combination) == 0)
|
||||||
|
{
|
||||||
|
match = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
sprintf_s(command, sizeof(command), "%s key %s",
|
||||||
|
xfc->actionScript, combination);
|
||||||
|
|
||||||
|
keyScript = popen(command, "r");
|
||||||
|
|
||||||
|
if (keyScript < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (fgets(buffer, sizeof(buffer), keyScript) != NULL)
|
||||||
|
{
|
||||||
|
strtok(buffer, "\n");
|
||||||
|
|
||||||
|
if (strcmp(buffer, "key-local") == 0)
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
exitCode = pclose(keyScript);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xk_keyboard_get_modifier_keys(xfContext* xfc, XF_MODIFIER_KEYS* mod)
|
||||||
|
{
|
||||||
|
mod->LeftShift = xf_keyboard_key_pressed(xfc, XK_Shift_L);
|
||||||
|
mod->RightShift = xf_keyboard_key_pressed(xfc, XK_Shift_R);
|
||||||
|
mod->Shift = mod->LeftShift || mod->RightShift;
|
||||||
|
|
||||||
|
mod->LeftAlt = xf_keyboard_key_pressed(xfc, XK_Alt_L);
|
||||||
|
mod->RightAlt = xf_keyboard_key_pressed(xfc, XK_Alt_R);
|
||||||
|
mod->Alt = mod->LeftAlt || mod->RightAlt;
|
||||||
|
|
||||||
|
mod->LeftCtrl = xf_keyboard_key_pressed(xfc, XK_Control_L);
|
||||||
|
mod->RightCtrl = xf_keyboard_key_pressed(xfc, XK_Control_R);
|
||||||
|
mod->Ctrl = mod->LeftCtrl || mod->RightCtrl;
|
||||||
|
|
||||||
|
mod->LeftSuper = xf_keyboard_key_pressed(xfc, XK_Super_L);
|
||||||
|
mod->RightSuper = xf_keyboard_key_pressed(xfc, XK_Super_R);
|
||||||
|
mod->Super = mod->LeftSuper || mod->RightSuper;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
||||||
|
{
|
||||||
|
XF_MODIFIER_KEYS mod = { 0 };
|
||||||
|
|
||||||
|
xk_keyboard_get_modifier_keys(xfc, &mod);
|
||||||
|
|
||||||
|
if (!xf_keyboard_execute_action_script(xfc, &mod, keysym))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (keysym == XK_Return)
|
if (keysym == XK_Return)
|
||||||
{
|
{
|
||||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L) || xf_kbd_key_pressed(xfc, XK_Alt_R))
|
if (mod.Ctrl && mod.Alt)
|
||||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L) || xf_kbd_key_pressed(xfc, XK_Control_R)))
|
|
||||||
{
|
{
|
||||||
/* Ctrl-Alt-Enter: toggle full screen */
|
/* Ctrl-Alt-Enter: toggle full screen */
|
||||||
xf_toggle_fullscreen(xfc);
|
xf_toggle_fullscreen(xfc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keysym == XK_period)
|
if (keysym == XK_period)
|
||||||
{
|
{
|
||||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
if (mod.Ctrl && mod.Alt)
|
||||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
|
||||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
|
||||||
|| xf_kbd_key_pressed(xfc,
|
|
||||||
XK_Control_R)))
|
|
||||||
{
|
{
|
||||||
//Zoom in (scale larger)
|
/* Zoom In (scale larger) */
|
||||||
|
|
||||||
double s = xfc->settings->ScalingFactor;
|
double s = xfc->settings->ScalingFactor;
|
||||||
|
|
||||||
s += 0.1;
|
s += 0.1;
|
||||||
|
|
||||||
if (s > 2.0)
|
if (s > 2.0)
|
||||||
s = 2.0;
|
s = 2.0;
|
||||||
|
|
||||||
@ -258,15 +450,14 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||||||
|
|
||||||
if (keysym == XK_comma)
|
if (keysym == XK_comma)
|
||||||
{
|
{
|
||||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
if (mod.Ctrl && mod.Alt)
|
||||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
|
||||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
|
||||||
|| xf_kbd_key_pressed(xfc,
|
|
||||||
XK_Control_R)))
|
|
||||||
{
|
{
|
||||||
//Zoom out (scale smaller)
|
/* Zoom Out (scale smaller) */
|
||||||
|
|
||||||
double s = xfc->settings->ScalingFactor;
|
double s = xfc->settings->ScalingFactor;
|
||||||
|
|
||||||
s -= 0.1;
|
s -= 0.1;
|
||||||
|
|
||||||
if (s < 0.5)
|
if (s < 0.5)
|
||||||
s = 0.5;
|
s = 0.5;
|
||||||
|
|
||||||
@ -293,11 +484,7 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||||||
|
|
||||||
if (keysym == XK_KP_4)
|
if (keysym == XK_KP_4)
|
||||||
{
|
{
|
||||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
if (mod.Ctrl && mod.Alt)
|
||||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
|
||||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
|
||||||
|| xf_kbd_key_pressed(xfc,
|
|
||||||
XK_Control_R)))
|
|
||||||
{
|
{
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -315,11 +502,7 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||||||
|
|
||||||
if (keysym == XK_KP_6)
|
if (keysym == XK_KP_6)
|
||||||
{
|
{
|
||||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
if (mod.Ctrl && mod.Alt)
|
||||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
|
||||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
|
||||||
|| xf_kbd_key_pressed(xfc,
|
|
||||||
XK_Control_R)))
|
|
||||||
{
|
{
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -336,11 +519,7 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||||||
|
|
||||||
if (keysym == XK_KP_8)
|
if (keysym == XK_KP_8)
|
||||||
{
|
{
|
||||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
if (mod.Ctrl && mod.Alt)
|
||||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
|
||||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
|
||||||
|| xf_kbd_key_pressed(xfc,
|
|
||||||
XK_Control_R)))
|
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
@ -356,11 +535,7 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||||||
|
|
||||||
if (keysym == XK_KP_2)
|
if (keysym == XK_KP_2)
|
||||||
{
|
{
|
||||||
if ((xf_kbd_key_pressed(xfc, XK_Alt_L)
|
if (mod.Ctrl && mod.Alt)
|
||||||
|| xf_kbd_key_pressed(xfc, XK_Alt_R))
|
|
||||||
&& (xf_kbd_key_pressed(xfc, XK_Control_L)
|
|
||||||
|| xf_kbd_key_pressed(xfc,
|
|
||||||
XK_Control_R)))
|
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
PanningChangeEventArgs e;
|
PanningChangeEventArgs e;
|
||||||
@ -374,7 +549,6 @@ BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,17 +25,37 @@
|
|||||||
#include "xf_client.h"
|
#include "xf_client.h"
|
||||||
#include "xfreerdp.h"
|
#include "xfreerdp.h"
|
||||||
|
|
||||||
void xf_kbd_init(xfContext* xfc);
|
#define XF_ACTION_SCRIPT "~/.config/freerdp/action.sh"
|
||||||
void xf_kbd_clear(xfContext* xfc);
|
|
||||||
void xf_kbd_set_keypress(xfContext* xfc, BYTE keycode, KeySym keysym);
|
struct _XF_MODIFIER_KEYS
|
||||||
void xf_kbd_unset_keypress(xfContext* xfc, BYTE keycode);
|
{
|
||||||
void xf_kbd_release_all_keypress(xfContext* xfc);
|
BOOL Shift;
|
||||||
BOOL xf_kbd_key_pressed(xfContext* xfc, KeySym keysym);
|
BOOL LeftShift;
|
||||||
void xf_kbd_send_key(xfContext* xfc, BOOL down, BYTE keycode);
|
BOOL RightShift;
|
||||||
int xf_kbd_read_keyboard_state(xfContext* xfc);
|
BOOL Alt;
|
||||||
BOOL xf_kbd_get_key_state(xfContext* xfc, int state, int keysym);
|
BOOL LeftAlt;
|
||||||
int xf_kbd_get_toggle_keys_state(xfContext* xfc);
|
BOOL RightAlt;
|
||||||
void xf_kbd_focus_in(xfContext* xfc);
|
BOOL Ctrl;
|
||||||
BOOL xf_kbd_handle_special_keys(xfContext* xfc, KeySym keysym);
|
BOOL LeftCtrl;
|
||||||
|
BOOL RightCtrl;
|
||||||
|
BOOL Super;
|
||||||
|
BOOL LeftSuper;
|
||||||
|
BOOL RightSuper;
|
||||||
|
};
|
||||||
|
typedef struct _XF_MODIFIER_KEYS XF_MODIFIER_KEYS;
|
||||||
|
|
||||||
|
void xf_keyboard_init(xfContext* xfc);
|
||||||
|
void xf_keyboard_free(xfContext* xfc);
|
||||||
|
void xf_keyboard_clear(xfContext* xfc);
|
||||||
|
void xf_keyboard_key_press(xfContext* xfc, BYTE keycode, KeySym keysym);
|
||||||
|
void xf_keyboard_key_release(xfContext* xfc, BYTE keycode);
|
||||||
|
void xf_keyboard_release_all_keypress(xfContext* xfc);
|
||||||
|
BOOL xf_keyboard_key_pressed(xfContext* xfc, KeySym keysym);
|
||||||
|
void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode);
|
||||||
|
int xf_keyboard_read_keyboard_state(xfContext* xfc);
|
||||||
|
BOOL xf_keyboard_get_key_state(xfContext* xfc, int state, int keysym);
|
||||||
|
UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc);
|
||||||
|
void xf_keyboard_focus_in(xfContext* xfc);
|
||||||
|
BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym);
|
||||||
|
|
||||||
#endif /* __XF_KEYBOARD_H */
|
#endif /* __XF_KEYBOARD_H */
|
||||||
|
@ -125,9 +125,13 @@ struct xf_context
|
|||||||
BOOL mouse_active;
|
BOOL mouse_active;
|
||||||
BOOL suppress_output;
|
BOOL suppress_output;
|
||||||
BOOL fullscreen_toggle;
|
BOOL fullscreen_toggle;
|
||||||
UINT32 keyboard_layout_id;
|
UINT32 KeyboardLayout;
|
||||||
BOOL pressed_keys[256];
|
BOOL KeyboardState[256];
|
||||||
XModifierKeymap* modifier_map;
|
XModifierKeymap* modifierMap;
|
||||||
|
wArrayList* keyCombinations;
|
||||||
|
wArrayList* xevents;
|
||||||
|
char* actionScript;
|
||||||
|
|
||||||
XSetWindowAttributes attribs;
|
XSetWindowAttributes attribs;
|
||||||
BOOL complex_regions;
|
BOOL complex_regions;
|
||||||
VIRTUAL_SCREEN vscreen;
|
VIRTUAL_SCREEN vscreen;
|
||||||
|
@ -56,6 +56,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
|||||||
{ "pth", COMMAND_LINE_VALUE_REQUIRED, "<password hash>", NULL, NULL, -1, "pass-the-hash", "Pass the hash (restricted admin mode)" },
|
{ "pth", COMMAND_LINE_VALUE_REQUIRED, "<password hash>", NULL, NULL, -1, "pass-the-hash", "Pass the hash (restricted admin mode)" },
|
||||||
{ "client-hostname", COMMAND_LINE_VALUE_REQUIRED, "<name>", NULL, NULL, -1, NULL, "Client Hostname to send to server" },
|
{ "client-hostname", COMMAND_LINE_VALUE_REQUIRED, "<name>", NULL, NULL, -1, NULL, "Client Hostname to send to server" },
|
||||||
{ "multimon", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Use multiple monitors" },
|
{ "multimon", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Use multiple monitors" },
|
||||||
|
{ "span", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Span screen over multiple monitors" },
|
||||||
{ "workarea", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Use available work area" },
|
{ "workarea", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Use available work area" },
|
||||||
{ "monitors", COMMAND_LINE_VALUE_REQUIRED, "<0,1,2...>", NULL, NULL, -1, NULL, "Select monitors to use" },
|
{ "monitors", COMMAND_LINE_VALUE_REQUIRED, "<0,1,2...>", NULL, NULL, -1, NULL, "Select monitors to use" },
|
||||||
{ "monitor-list", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT, NULL, NULL, NULL, -1, NULL, "List detected monitors" },
|
{ "monitor-list", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT, NULL, NULL, NULL, -1, NULL, "List detected monitors" },
|
||||||
@ -1188,13 +1189,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
|||||||
{
|
{
|
||||||
settings->Fullscreen = TRUE;
|
settings->Fullscreen = TRUE;
|
||||||
}
|
}
|
||||||
CommandLineSwitchCase(arg, "span")
|
|
||||||
{
|
|
||||||
settings->SpanMonitors = TRUE;
|
|
||||||
}
|
|
||||||
CommandLineSwitchCase(arg, "multimon")
|
CommandLineSwitchCase(arg, "multimon")
|
||||||
{
|
{
|
||||||
settings->UseMultimon = TRUE;
|
settings->UseMultimon = TRUE;
|
||||||
|
settings->SpanMonitors = FALSE;
|
||||||
settings->Fullscreen = TRUE;
|
settings->Fullscreen = TRUE;
|
||||||
|
|
||||||
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
||||||
@ -1205,6 +1203,12 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CommandLineSwitchCase(arg, "span")
|
||||||
|
{
|
||||||
|
settings->UseMultimon = TRUE;
|
||||||
|
settings->SpanMonitors = TRUE;
|
||||||
|
settings->Fullscreen = TRUE;
|
||||||
|
}
|
||||||
CommandLineSwitchCase(arg, "workarea")
|
CommandLineSwitchCase(arg, "workarea")
|
||||||
{
|
{
|
||||||
settings->Workarea = TRUE;
|
settings->Workarea = TRUE;
|
||||||
@ -1345,9 +1349,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
|||||||
settings->GatewayHostname = _strdup(settings->ServerHostname);
|
settings->GatewayHostname = _strdup(settings->ServerHostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
|
|
||||||
settings->GatewayUseSameCredentials = TRUE;
|
settings->GatewayUseSameCredentials = TRUE;
|
||||||
|
|
||||||
|
settings->GatewayUsageMethod = TSC_PROXY_MODE_DETECT;
|
||||||
settings->GatewayEnabled = TRUE;
|
settings->GatewayEnabled = TRUE;
|
||||||
|
settings->GatewayBypassLocal = TRUE;
|
||||||
}
|
}
|
||||||
CommandLineSwitchCase(arg, "gu")
|
CommandLineSwitchCase(arg, "gu")
|
||||||
{
|
{
|
||||||
|
@ -866,14 +866,36 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
|||||||
{
|
{
|
||||||
freerdp_set_param_uint32(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
|
freerdp_set_param_uint32(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
|
||||||
|
|
||||||
if (file->GatewayUsageMethod == TSC_PROXY_MODE_DIRECT)
|
if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DIRECT)
|
||||||
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
|
{
|
||||||
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DETECT)
|
|
||||||
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
|
|
||||||
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DEFAULT)
|
|
||||||
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
|
|
||||||
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT)
|
|
||||||
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
|
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, FALSE);
|
||||||
|
}
|
||||||
|
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DIRECT)
|
||||||
|
{
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, FALSE);
|
||||||
|
}
|
||||||
|
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DETECT)
|
||||||
|
{
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, TRUE);
|
||||||
|
}
|
||||||
|
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DEFAULT)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This corresponds to "Automatically detect RD Gateway server settings",
|
||||||
|
* which means the client attempts to use gateway group policy settings
|
||||||
|
* http://technet.microsoft.com/en-us/library/cc770601.aspx
|
||||||
|
*/
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, FALSE);
|
||||||
|
}
|
||||||
|
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT)
|
||||||
|
{
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
|
||||||
|
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (~file->PromptCredentialOnce)
|
if (~file->PromptCredentialOnce)
|
||||||
|
@ -176,6 +176,60 @@ FREERDP_API extern int connectErrorCode;
|
|||||||
#define INSUFFICIENTPRIVILEGESERROR ERRORSTART + 10
|
#define INSUFFICIENTPRIVILEGESERROR ERRORSTART + 10
|
||||||
#define CANCELEDBYUSER ERRORSTART + 11
|
#define CANCELEDBYUSER ERRORSTART + 11
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FreeRDP Context Error Codes
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAKE_FREERDP_ERROR(_class, _type) \
|
||||||
|
(((FREERDP_ERROR_ ## _class ## _CLASS) << 16) | (_type))
|
||||||
|
|
||||||
|
#define GET_FREERDP_ERROR_CLASS(_errorCode) \
|
||||||
|
((_errorCode >> 16) & 0xFFFF)
|
||||||
|
|
||||||
|
#define GET_FREERDP_ERROR_TYPE(_errorCode) \
|
||||||
|
(_errorCode & 0xFFFF)
|
||||||
|
|
||||||
|
#define GET_FREERDP_ERROR_SUBCODE
|
||||||
|
|
||||||
|
#define FREERDP_ERROR_BASE 0
|
||||||
|
|
||||||
|
#define FREERDP_ERROR_SUCCESS ERRINFO_SUCCESS
|
||||||
|
#define FREERDP_ERROR_NONE ERRINFO_NONE
|
||||||
|
|
||||||
|
/* Error Info Codes */
|
||||||
|
|
||||||
|
#define FREERDP_ERROR_ERRINFO_CLASS (FREERDP_ERROR_BASE + 1)
|
||||||
|
|
||||||
|
#define FREERDP_ERROR_RPC_INITIATED_DISCONNECT MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_RPC_INITIATED_DISCONNECT)
|
||||||
|
#define FREERDP_ERROR_RPC_INITIATED_LOGOFF MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_RPC_INITIATED_LOGOFF)
|
||||||
|
#define FREERDP_ERROR_IDLE_TIMEOUT MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_IDLE_TIMEOUT)
|
||||||
|
#define FREERDP_ERROR_LOGON_TIMEOUT MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_LOGON_TIMEOUT)
|
||||||
|
#define FREERDP_ERROR_DISCONNECTED_BY_OTHER_CONNECTION MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_DISCONNECTED_BY_OTHER_CONNECTION)
|
||||||
|
#define FREERDP_ERROR_OUT_OF_MEMORY MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_OUT_OF_MEMORY)
|
||||||
|
#define FREERDP_ERROR_SERVER_DENIED_CONNECTION MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_SERVER_DENIED_CONNECTION)
|
||||||
|
#define FREERDP_ERROR_SERVER_INSUFFICIENT_PRIVILEGES MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
|
||||||
|
#define FREERDP_ERROR_SERVER_FRESH_CREDENTIALS_REQUIRED MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_SERVER_FRESH_CREDENTIALS_REQUIRED)
|
||||||
|
#define FREERDP_ERROR_RPC_INITIATED_DISCONNECT_BY_USER MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_RPC_INITIATED_DISCONNECT_BY_USER)
|
||||||
|
#define FREERDP_ERROR_LOGOFF_BY_USER MAKE_FREERDP_ERROR(ERRINFO, ERRINFO_LOGOFF_BY_USER)
|
||||||
|
|
||||||
|
/* Connection Error Codes */
|
||||||
|
|
||||||
|
#define FREERDP_ERROR_CONNECT_CLASS (FREERDP_ERROR_BASE + 2)
|
||||||
|
|
||||||
|
#define FREERDP_ERROR_PRE_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 1)
|
||||||
|
#define FREERDP_ERROR_CONNECT_UNDEFINED MAKE_FREERDP_ERROR(CONNECT, 2)
|
||||||
|
#define FREERDP_ERROR_POST_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 3)
|
||||||
|
#define FREERDP_ERROR_DNS_ERROR MAKE_FREERDP_ERROR(CONNECT, 4)
|
||||||
|
#define FREERDP_ERROR_DNS_NAME_NOT_FOUND MAKE_FREERDP_ERROR(CONNECT, 5)
|
||||||
|
#define FREERDP_ERROR_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 6)
|
||||||
|
#define FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR MAKE_FREERDP_ERROR(CONNECT, 7)
|
||||||
|
#define FREERDP_ERROR_TLS_CONNECT_FAILED MAKE_FREERDP_ERROR(CONNECT, 8)
|
||||||
|
#define FREERDP_ERROR_AUTHENTICATION_FAILED MAKE_FREERDP_ERROR(CONNECT, 9)
|
||||||
|
#define FREERDP_ERROR_INSUFFICIENT_PRIVILEGES MAKE_FREERDP_ERROR(CONNECT, 10)
|
||||||
|
#define FREERDP_ERROR_CONNECT_CANCELLED MAKE_FREERDP_ERROR(CONNECT, 11)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,7 +85,9 @@ struct rdp_context
|
|||||||
This field is used only on the server side. */
|
This field is used only on the server side. */
|
||||||
ALIGN64 BOOL ServerMode; /**< (offset 2) true when context is in server mode */
|
ALIGN64 BOOL ServerMode; /**< (offset 2) true when context is in server mode */
|
||||||
|
|
||||||
UINT64 paddingA[16 - 3]; /* 3 */
|
ALIGN64 UINT32 LastError; /* 3 */
|
||||||
|
|
||||||
|
UINT64 paddingA[16 - 4]; /* 4 */
|
||||||
|
|
||||||
ALIGN64 int argc; /**< (offset 16)
|
ALIGN64 int argc; /**< (offset 16)
|
||||||
Number of arguments given to the program at launch time.
|
Number of arguments given to the program at launch time.
|
||||||
@ -247,6 +249,9 @@ FREERDP_API void freerdp_free(freerdp* instance);
|
|||||||
|
|
||||||
FREERDP_API BOOL freerdp_focus_required(freerdp* instance);
|
FREERDP_API BOOL freerdp_focus_required(freerdp* instance);
|
||||||
|
|
||||||
|
FREERDP_API UINT32 freerdp_get_last_error(rdpContext* context);
|
||||||
|
FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -669,6 +669,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
|||||||
#define FreeRDP_GatewayCredentialsSource 1990
|
#define FreeRDP_GatewayCredentialsSource 1990
|
||||||
#define FreeRDP_GatewayUseSameCredentials 1991
|
#define FreeRDP_GatewayUseSameCredentials 1991
|
||||||
#define FreeRDP_GatewayEnabled 1992
|
#define FreeRDP_GatewayEnabled 1992
|
||||||
|
#define FreeRDP_GatewayBypassLocal 1993
|
||||||
#define FreeRDP_RemoteApplicationMode 2112
|
#define FreeRDP_RemoteApplicationMode 2112
|
||||||
#define FreeRDP_RemoteApplicationName 2113
|
#define FreeRDP_RemoteApplicationName 2113
|
||||||
#define FreeRDP_RemoteApplicationIcon 2114
|
#define FreeRDP_RemoteApplicationIcon 2114
|
||||||
@ -1073,7 +1074,8 @@ struct rdp_settings
|
|||||||
ALIGN64 UINT32 GatewayCredentialsSource; /* 1990 */
|
ALIGN64 UINT32 GatewayCredentialsSource; /* 1990 */
|
||||||
ALIGN64 BOOL GatewayUseSameCredentials; /* 1991 */
|
ALIGN64 BOOL GatewayUseSameCredentials; /* 1991 */
|
||||||
ALIGN64 BOOL GatewayEnabled; /* 1992 */
|
ALIGN64 BOOL GatewayEnabled; /* 1992 */
|
||||||
UINT64 padding2048[2048 - 1993]; /* 1993 */
|
ALIGN64 BOOL GatewayBypassLocal; /* 1993 */
|
||||||
|
UINT64 padding2048[2048 - 1994]; /* 1994 */
|
||||||
UINT64 padding2112[2112 - 2048]; /* 2048 */
|
UINT64 padding2112[2112 - 2048]; /* 2048 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,13 +110,8 @@ int mppc_decompress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE** p
|
|||||||
|
|
||||||
if (!(flags & PACKET_COMPRESSED))
|
if (!(flags & PACKET_COMPRESSED))
|
||||||
{
|
{
|
||||||
CopyMemory(HistoryPtr, pSrcData, SrcSize);
|
|
||||||
HistoryPtr += SrcSize;
|
|
||||||
HistoryOffset += SrcSize;
|
|
||||||
mppc->HistoryPtr = HistoryPtr;
|
|
||||||
mppc->HistoryOffset = HistoryOffset;
|
|
||||||
*ppDstData = HistoryPtr;
|
|
||||||
*pDstSize = SrcSize;
|
*pDstSize = SrcSize;
|
||||||
|
*ppDstData = pSrcData;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,6 +527,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDst
|
|||||||
*pFlags |= PACKET_FLUSHED;
|
*pFlags |= PACKET_FLUSHED;
|
||||||
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
||||||
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
||||||
|
*pDstSize = SrcSize;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,6 +578,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDst
|
|||||||
*pFlags = PACKET_FLUSHED;
|
*pFlags = PACKET_FLUSHED;
|
||||||
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
||||||
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
||||||
|
*pDstSize = SrcSize;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,6 +734,7 @@ int mppc_compress(MPPC_CONTEXT* mppc, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDst
|
|||||||
*pFlags |= PACKET_FLUSHED;
|
*pFlags |= PACKET_FLUSHED;
|
||||||
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
ZeroMemory(HistoryBuffer, HistoryBufferSize);
|
||||||
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
ZeroMemory(mppc->MatchBuffer, sizeof(mppc->MatchBuffer));
|
||||||
|
*pDstSize = SrcSize;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1167,10 +1167,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
|
|||||||
|
|
||||||
if (!(flags & PACKET_COMPRESSED))
|
if (!(flags & PACKET_COMPRESSED))
|
||||||
{
|
{
|
||||||
CopyMemory(HistoryPtr, pSrcData, SrcSize);
|
*ppDstData = pSrcData;
|
||||||
HistoryPtr += SrcSize;
|
|
||||||
ncrush->HistoryPtr = HistoryPtr;
|
|
||||||
*ppDstData = HistoryPtr;
|
|
||||||
*pDstSize = SrcSize;
|
*pDstSize = SrcSize;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -746,6 +746,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
|
|||||||
return settings->GatewayEnabled;
|
return settings->GatewayEnabled;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FreeRDP_GatewayBypassLocal:
|
||||||
|
return settings->GatewayBypassLocal;
|
||||||
|
break;
|
||||||
|
|
||||||
case FreeRDP_RemoteApplicationMode:
|
case FreeRDP_RemoteApplicationMode:
|
||||||
return settings->RemoteApplicationMode;
|
return settings->RemoteApplicationMode;
|
||||||
break;
|
break;
|
||||||
@ -1218,6 +1222,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
|
|||||||
settings->GatewayEnabled = param;
|
settings->GatewayEnabled = param;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FreeRDP_GatewayBypassLocal:
|
||||||
|
settings->GatewayBypassLocal = param;
|
||||||
|
break;
|
||||||
|
|
||||||
case FreeRDP_RemoteApplicationMode:
|
case FreeRDP_RemoteApplicationMode:
|
||||||
settings->RemoteApplicationMode = param;
|
settings->RemoteApplicationMode = param;
|
||||||
break;
|
break;
|
||||||
|
@ -46,29 +46,38 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD
|
|||||||
UINT32 UncompressedBytes;
|
UINT32 UncompressedBytes;
|
||||||
UINT32 type = flags & 0x0F;
|
UINT32 type = flags & 0x0F;
|
||||||
|
|
||||||
switch (type)
|
if (flags & PACKET_COMPRESSED)
|
||||||
{
|
{
|
||||||
case PACKET_COMPR_TYPE_8K:
|
switch (type)
|
||||||
mppc_set_compression_level(bulk->mppcRecv, 0);
|
{
|
||||||
status = mppc_decompress(bulk->mppcRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags);
|
case PACKET_COMPR_TYPE_8K:
|
||||||
break;
|
mppc_set_compression_level(bulk->mppcRecv, 0);
|
||||||
|
status = mppc_decompress(bulk->mppcRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags);
|
||||||
|
break;
|
||||||
|
|
||||||
case PACKET_COMPR_TYPE_64K:
|
case PACKET_COMPR_TYPE_64K:
|
||||||
mppc_set_compression_level(bulk->mppcRecv, 1);
|
mppc_set_compression_level(bulk->mppcRecv, 1);
|
||||||
status = mppc_decompress(bulk->mppcRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags);
|
status = mppc_decompress(bulk->mppcRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_COMPR_TYPE_RDP6:
|
case PACKET_COMPR_TYPE_RDP6:
|
||||||
status = ncrush_decompress(bulk->ncrushRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags);
|
status = ncrush_decompress(bulk->ncrushRecv, pSrcData, SrcSize, ppDstData, pDstSize, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_COMPR_TYPE_RDP61:
|
case PACKET_COMPR_TYPE_RDP61:
|
||||||
status = -1;
|
status = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_COMPR_TYPE_RDP8:
|
case PACKET_COMPR_TYPE_RDP8:
|
||||||
status = -1;
|
status = -1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ppDstData = pSrcData;
|
||||||
|
*pDstSize = SrcSize;
|
||||||
|
status = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status >= 0)
|
if (status >= 0)
|
||||||
@ -87,8 +96,8 @@ int bulk_decompress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstD
|
|||||||
CompressionRatio = ((double) CompressedBytes) / ((double) UncompressedBytes);
|
CompressionRatio = ((double) CompressedBytes) / ((double) UncompressedBytes);
|
||||||
TotalCompressionRatio = ((double) bulk->TotalCompressedBytes) / ((double) bulk->TotalUncompressedBytes);
|
TotalCompressionRatio = ((double) bulk->TotalCompressedBytes) / ((double) bulk->TotalUncompressedBytes);
|
||||||
|
|
||||||
printf("Type: %d Compression Ratio: %f Total: %f %d / %d\n",
|
printf("Type: %d Flags: 0x%04X Compression Ratio: %f Total: %f %d / %d\n",
|
||||||
type, CompressionRatio, TotalCompressionRatio, CompressedBytes, UncompressedBytes);
|
type, flags, CompressionRatio, TotalCompressionRatio, CompressedBytes, UncompressedBytes);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -113,7 +122,7 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat
|
|||||||
mppc_set_compression_level(bulk->mppcSend, bulk->CompressionLevel);
|
mppc_set_compression_level(bulk->mppcSend, bulk->CompressionLevel);
|
||||||
status = mppc_compress(bulk->mppcSend, pSrcData, SrcSize, *ppDstData, pDstSize, pFlags);
|
status = mppc_compress(bulk->mppcSend, pSrcData, SrcSize, *ppDstData, pDstSize, pFlags);
|
||||||
|
|
||||||
if ((status >= 0) && (*pFlags & PACKET_COMPRESSED))
|
if (status >= 0)
|
||||||
{
|
{
|
||||||
CompressedBytes = *pDstSize;
|
CompressedBytes = *pDstSize;
|
||||||
UncompressedBytes = SrcSize;
|
UncompressedBytes = SrcSize;
|
||||||
@ -123,13 +132,17 @@ int bulk_compress(rdpBulk* bulk, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstDat
|
|||||||
|
|
||||||
#ifdef WITH_BULK_DEBUG
|
#ifdef WITH_BULK_DEBUG
|
||||||
{
|
{
|
||||||
|
UINT32 type;
|
||||||
double CompressionRatio;
|
double CompressionRatio;
|
||||||
double TotalCompressionRatio;
|
double TotalCompressionRatio;
|
||||||
|
|
||||||
|
type = bulk->CompressionLevel;
|
||||||
|
|
||||||
CompressionRatio = ((double) CompressedBytes) / ((double) UncompressedBytes);
|
CompressionRatio = ((double) CompressedBytes) / ((double) UncompressedBytes);
|
||||||
TotalCompressionRatio = ((double) bulk->TotalCompressedBytes) / ((double) bulk->TotalUncompressedBytes);
|
TotalCompressionRatio = ((double) bulk->TotalCompressedBytes) / ((double) bulk->TotalUncompressedBytes);
|
||||||
|
|
||||||
printf("Compression Ratio: %f Total: %f\n", CompressionRatio, TotalCompressionRatio);
|
printf("Type: %d Flags: 0x%04X Compression Ratio: %f Total: %f %d / %d\n",
|
||||||
|
type, *pFlags, CompressionRatio, TotalCompressionRatio, CompressedBytes, UncompressedBytes);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -231,6 +231,9 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
|||||||
nego_set_negotiation_enabled(rdp->nego, settings->NegotiateSecurityLayer);
|
nego_set_negotiation_enabled(rdp->nego, settings->NegotiateSecurityLayer);
|
||||||
nego_set_restricted_admin_mode_required(rdp->nego, settings->RestrictedAdminModeRequired);
|
nego_set_restricted_admin_mode_required(rdp->nego, settings->RestrictedAdminModeRequired);
|
||||||
|
|
||||||
|
nego_set_gateway_enabled(rdp->nego, settings->GatewayEnabled);
|
||||||
|
nego_set_gateway_bypass_local(rdp->nego, settings->GatewayBypassLocal);
|
||||||
|
|
||||||
nego_enable_rdp(rdp->nego, settings->RdpSecurity);
|
nego_enable_rdp(rdp->nego, settings->RdpSecurity);
|
||||||
nego_enable_tls(rdp->nego, settings->TlsSecurity);
|
nego_enable_tls(rdp->nego, settings->TlsSecurity);
|
||||||
nego_enable_nla(rdp->nego, settings->NlaSecurity);
|
nego_enable_nla(rdp->nego, settings->NlaSecurity);
|
||||||
@ -268,6 +271,12 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
|||||||
{
|
{
|
||||||
connectErrorCode = MCSCONNECTINITIALERROR;
|
connectErrorCode = MCSCONNECTINITIALERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!freerdp_get_last_error(rdp->context))
|
||||||
|
{
|
||||||
|
freerdp_set_last_error(rdp->context, FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Error: unable to send MCS Connect Initial\n");
|
fprintf(stderr, "Error: unable to send MCS Connect Initial\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -342,6 +342,8 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||||||
BYTE fragmentation;
|
BYTE fragmentation;
|
||||||
BYTE compression;
|
BYTE compression;
|
||||||
BYTE compressionFlags;
|
BYTE compressionFlags;
|
||||||
|
UINT32 DstSize = 0;
|
||||||
|
BYTE* pDstData = NULL;
|
||||||
rdpTransport* transport;
|
rdpTransport* transport;
|
||||||
|
|
||||||
status = 0;
|
status = 0;
|
||||||
@ -363,26 +365,20 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
|
|||||||
cs = s;
|
cs = s;
|
||||||
next_pos = Stream_GetPosition(s) + size;
|
next_pos = Stream_GetPosition(s) + size;
|
||||||
|
|
||||||
if (compressionFlags & PACKET_COMPRESSED)
|
if (bulk_decompress(rdp->bulk, Stream_Pointer(s), size, &pDstData, &DstSize, compressionFlags))
|
||||||
{
|
{
|
||||||
UINT32 DstSize = 0;
|
size = DstSize;
|
||||||
BYTE* pDstData = NULL;
|
cs = StreamPool_Take(transport->ReceivePool, DstSize);
|
||||||
|
|
||||||
if (bulk_decompress(rdp->bulk, Stream_Pointer(s), size, &pDstData, &DstSize, compressionFlags))
|
Stream_SetPosition(cs, 0);
|
||||||
{
|
Stream_Write(cs, pDstData, DstSize);
|
||||||
size = DstSize;
|
Stream_SealLength(cs);
|
||||||
cs = StreamPool_Take(transport->ReceivePool, DstSize);
|
Stream_SetPosition(cs, 0);
|
||||||
|
}
|
||||||
Stream_SetPosition(cs, 0);
|
else
|
||||||
Stream_Write(cs, pDstData, DstSize);
|
{
|
||||||
Stream_SealLength(cs);
|
fprintf(stderr, "bulk_decompress() failed\n");
|
||||||
Stream_SetPosition(cs, 0);
|
Stream_Seek(s, size);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "bulk_decompress() failed\n");
|
|
||||||
Stream_Seek(s, size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fragmentation == FASTPATH_FRAGMENT_SINGLE)
|
if (fragmentation == FASTPATH_FRAGMENT_SINGLE)
|
||||||
@ -855,6 +851,7 @@ BOOL fastpath_send_update_pdu(rdpFastPath* fastpath, BYTE updateCode, wStream* s
|
|||||||
{
|
{
|
||||||
CompressionMaxSize = bulk_compression_max_size(rdp->bulk);
|
CompressionMaxSize = bulk_compression_max_size(rdp->bulk);
|
||||||
maxLength = (maxLength < CompressionMaxSize) ? maxLength : CompressionMaxSize;
|
maxLength = (maxLength < CompressionMaxSize) ? maxLength : CompressionMaxSize;
|
||||||
|
maxLength -= 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalLength = Stream_GetPosition(s);
|
totalLength = Stream_GetPosition(s);
|
||||||
|
@ -65,6 +65,7 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
|
|
||||||
/* We always set the return code to 0 before we start the connect sequence*/
|
/* We always set the return code to 0 before we start the connect sequence*/
|
||||||
connectErrorCode = 0;
|
connectErrorCode = 0;
|
||||||
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS);
|
||||||
|
|
||||||
rdp = instance->context->rdp;
|
rdp = instance->context->rdp;
|
||||||
settings = instance->settings;
|
settings = instance->settings;
|
||||||
@ -87,6 +88,12 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
{
|
{
|
||||||
connectErrorCode = PREECONNECTERROR;
|
connectErrorCode = PREECONNECTERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!freerdp_get_last_error(rdp->context))
|
||||||
|
{
|
||||||
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_PRE_CONNECT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s:%d: freerdp_pre_connect failed\n", __FILE__, __LINE__);
|
fprintf(stderr, "%s:%d: freerdp_pre_connect failed\n", __FILE__, __LINE__);
|
||||||
|
|
||||||
goto freerdp_connect_finally;
|
goto freerdp_connect_finally;
|
||||||
@ -124,6 +131,11 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
connectErrorCode = POSTCONNECTERROR;
|
connectErrorCode = POSTCONNECTERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!freerdp_get_last_error(rdp->context))
|
||||||
|
{
|
||||||
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_POST_CONNECT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
goto freerdp_connect_finally;
|
goto freerdp_connect_finally;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +189,7 @@ BOOL freerdp_connect(freerdp* instance)
|
|||||||
if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
|
if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
|
||||||
{
|
{
|
||||||
connectErrorCode = INSUFFICIENTPRIVILEGESERROR;
|
connectErrorCode = INSUFFICIENTPRIVILEGESERROR;
|
||||||
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!connectErrorCode)
|
if (!connectErrorCode)
|
||||||
@ -465,6 +478,19 @@ UINT32 freerdp_error_info(freerdp* instance)
|
|||||||
return instance->context->rdp->errorInfo;
|
return instance->context->rdp->errorInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT32 freerdp_get_last_error(rdpContext* context)
|
||||||
|
{
|
||||||
|
return context->LastError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freerdp_set_last_error(rdpContext* context, UINT32 lastError)
|
||||||
|
{
|
||||||
|
if (lastError)
|
||||||
|
fprintf(stderr, "freerdp_set_last_error 0x%04X\n", lastError);
|
||||||
|
|
||||||
|
context->LastError = lastError;
|
||||||
|
}
|
||||||
|
|
||||||
/** Allocator function for the rdp_freerdp structure.
|
/** Allocator function for the rdp_freerdp structure.
|
||||||
* @return an allocated structure filled with 0s. Need to be deallocated using freerdp_free()
|
* @return an allocated structure filled with 0s. Need to be deallocated using freerdp_free()
|
||||||
*/
|
*/
|
||||||
|
@ -142,6 +142,7 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel)
|
|||||||
if (!proceed)
|
if (!proceed)
|
||||||
{
|
{
|
||||||
connectErrorCode = CANCELEDBYUSER;
|
connectErrorCode = CANCELEDBYUSER;
|
||||||
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
|
|||||||
if (!proceed)
|
if (!proceed)
|
||||||
{
|
{
|
||||||
connectErrorCode = CANCELEDBYUSER;
|
connectErrorCode = CANCELEDBYUSER;
|
||||||
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,9 +154,17 @@ BOOL rts_connect(rdpRpc* rpc)
|
|||||||
http_response_print(http_response);
|
http_response_print(http_response);
|
||||||
http_response_free(http_response);
|
http_response_free(http_response);
|
||||||
|
|
||||||
if (!connectErrorCode && http_response->StatusCode == HTTP_STATUS_DENIED)
|
if (http_response->StatusCode == HTTP_STATUS_DENIED)
|
||||||
{
|
{
|
||||||
connectErrorCode = AUTHENTICATIONERROR;
|
if (!connectErrorCode)
|
||||||
|
{
|
||||||
|
connectErrorCode = AUTHENTICATIONERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!freerdp_get_last_error(((freerdp*)(rpc->settings->instance))->context))
|
||||||
|
{
|
||||||
|
freerdp_set_last_error(((freerdp*)(rpc->settings->instance))->context, FREERDP_ERROR_AUTHENTICATION_FAILED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -407,16 +407,17 @@ void gcc_write_client_data_blocks(wStream* s, rdpMcs* mcs)
|
|||||||
|
|
||||||
if (settings->NegotiationFlags & EXTENDED_CLIENT_DATA_SUPPORTED)
|
if (settings->NegotiationFlags & EXTENDED_CLIENT_DATA_SUPPORTED)
|
||||||
{
|
{
|
||||||
if (settings->SpanMonitors)
|
if (settings->UseMultimon && !settings->SpanMonitors)
|
||||||
{
|
{
|
||||||
gcc_write_client_monitor_data(s, mcs);
|
gcc_write_client_monitor_data(s, mcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
gcc_write_client_message_channel_data(s, mcs);
|
gcc_write_client_message_channel_data(s, mcs);
|
||||||
gcc_write_client_multitransport_channel_data(s, mcs);
|
gcc_write_client_multitransport_channel_data(s, mcs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (settings->UseMultimon)
|
if (settings->UseMultimon && !settings->SpanMonitors)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WARNING: true multi monitor support was not advertised by server!\n");
|
fprintf(stderr, "WARNING: true multi monitor support was not advertised by server!\n");
|
||||||
|
|
||||||
|
@ -212,7 +212,25 @@ BOOL nego_security_connect(rdpNego* nego)
|
|||||||
BOOL nego_tcp_connect(rdpNego* nego)
|
BOOL nego_tcp_connect(rdpNego* nego)
|
||||||
{
|
{
|
||||||
if (!nego->tcp_connected)
|
if (!nego->tcp_connected)
|
||||||
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
|
{
|
||||||
|
if (nego->GatewayEnabled && nego->GatewayBypassLocal)
|
||||||
|
{
|
||||||
|
/* Attempt a direct connection first, and then fallback to using the gateway */
|
||||||
|
|
||||||
|
transport_set_gateway_enabled(nego->transport, FALSE);
|
||||||
|
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
|
||||||
|
|
||||||
|
if (!nego->tcp_connected)
|
||||||
|
{
|
||||||
|
transport_set_gateway_enabled(nego->transport, TRUE);
|
||||||
|
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nego->tcp_connected;
|
return nego->tcp_connected;
|
||||||
}
|
}
|
||||||
@ -1034,6 +1052,16 @@ void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdmin
|
|||||||
nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
|
nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled)
|
||||||
|
{
|
||||||
|
nego->GatewayEnabled = GatewayEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal)
|
||||||
|
{
|
||||||
|
nego->GatewayBypassLocal = GatewayBypassLocal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable RDP security protocol.
|
* Enable RDP security protocol.
|
||||||
* @param nego pointer to the negotiation structure
|
* @param nego pointer to the negotiation structure
|
||||||
|
@ -110,6 +110,8 @@ struct rdp_nego
|
|||||||
BOOL NegotiateSecurityLayer;
|
BOOL NegotiateSecurityLayer;
|
||||||
BYTE enabled_protocols[16];
|
BYTE enabled_protocols[16];
|
||||||
BOOL RestrictedAdminModeRequired;
|
BOOL RestrictedAdminModeRequired;
|
||||||
|
BOOL GatewayEnabled;
|
||||||
|
BOOL GatewayBypassLocal;
|
||||||
|
|
||||||
rdpTransport* transport;
|
rdpTransport* transport;
|
||||||
};
|
};
|
||||||
@ -142,6 +144,8 @@ void nego_init(rdpNego* nego);
|
|||||||
void nego_set_target(rdpNego* nego, char* hostname, int port);
|
void nego_set_target(rdpNego* nego, char* hostname, int port);
|
||||||
void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer_enabled);
|
void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer_enabled);
|
||||||
void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired);
|
void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired);
|
||||||
|
void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled);
|
||||||
|
void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal);
|
||||||
void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp);
|
void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp);
|
||||||
void nego_enable_tls(rdpNego* nego, BOOL enable_tls);
|
void nego_enable_tls(rdpNego* nego, BOOL enable_tls);
|
||||||
void nego_enable_nla(rdpNego* nego, BOOL enable_nla);
|
void nego_enable_nla(rdpNego* nego, BOOL enable_nla);
|
||||||
|
@ -153,6 +153,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
|
|||||||
if (!proceed)
|
if (!proceed)
|
||||||
{
|
{
|
||||||
connectErrorCode = CANCELEDBYUSER;
|
connectErrorCode = CANCELEDBYUSER;
|
||||||
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,12 +238,17 @@ BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo)
|
|||||||
ErrorInfoEventArgs e;
|
ErrorInfoEventArgs e;
|
||||||
rdpContext* context = rdp->instance->context;
|
rdpContext* context = rdp->instance->context;
|
||||||
|
|
||||||
|
rdp->context->LastError = MAKE_FREERDP_ERROR(ERRINFO, errorInfo);
|
||||||
rdp_print_errinfo(rdp->errorInfo);
|
rdp_print_errinfo(rdp->errorInfo);
|
||||||
|
|
||||||
EventArgsInit(&e, "freerdp");
|
EventArgsInit(&e, "freerdp");
|
||||||
e.code = rdp->errorInfo;
|
e.code = rdp->errorInfo;
|
||||||
PubSub_OnErrorInfo(context->pubSub, context, &e);
|
PubSub_OnErrorInfo(context->pubSub, context, &e);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rdp->context->LastError = FREERDP_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -651,6 +651,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
|||||||
_settings->PlayRemoteFx = settings->PlayRemoteFx; /* 1857 */
|
_settings->PlayRemoteFx = settings->PlayRemoteFx; /* 1857 */
|
||||||
_settings->GatewayUseSameCredentials = settings->GatewayUseSameCredentials; /* 1991 */
|
_settings->GatewayUseSameCredentials = settings->GatewayUseSameCredentials; /* 1991 */
|
||||||
_settings->GatewayEnabled = settings->GatewayEnabled; /* 1992 */
|
_settings->GatewayEnabled = settings->GatewayEnabled; /* 1992 */
|
||||||
|
_settings->GatewayBypassLocal = settings->GatewayBypassLocal; /* 1993 */
|
||||||
_settings->RemoteApplicationMode = settings->RemoteApplicationMode; /* 2112 */
|
_settings->RemoteApplicationMode = settings->RemoteApplicationMode; /* 2112 */
|
||||||
_settings->DisableRemoteAppCapsCheck = settings->DisableRemoteAppCapsCheck; /* 2121 */
|
_settings->DisableRemoteAppCapsCheck = settings->DisableRemoteAppCapsCheck; /* 2121 */
|
||||||
_settings->RemoteAppLanguageBarSupported = settings->RemoteAppLanguageBarSupported; /* 2124 */
|
_settings->RemoteAppLanguageBarSupported = settings->RemoteAppLanguageBarSupported; /* 2124 */
|
||||||
|
@ -71,25 +71,8 @@ void transport_attach(rdpTransport* transport, int sockfd)
|
|||||||
transport->TcpOut = transport->TcpIn;
|
transport->TcpOut = transport->TcpIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL transport_disconnect(rdpTransport* transport)
|
void transport_stop(rdpTransport* transport)
|
||||||
{
|
{
|
||||||
BOOL status = TRUE;
|
|
||||||
|
|
||||||
if (!transport)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (transport->layer == TRANSPORT_LAYER_TLS)
|
|
||||||
status &= tls_disconnect(transport->TlsIn);
|
|
||||||
|
|
||||||
if ((transport->layer == TRANSPORT_LAYER_TSG) || (transport->layer == TRANSPORT_LAYER_TSG_TLS))
|
|
||||||
{
|
|
||||||
status &= tsg_disconnect(transport->tsg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status &= tcp_disconnect(transport->TcpIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transport->async)
|
if (transport->async)
|
||||||
{
|
{
|
||||||
if (transport->stopEvent)
|
if (transport->stopEvent)
|
||||||
@ -104,6 +87,28 @@ BOOL transport_disconnect(rdpTransport* transport)
|
|||||||
transport->stopEvent = NULL;
|
transport->stopEvent = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL transport_disconnect(rdpTransport* transport)
|
||||||
|
{
|
||||||
|
BOOL status = TRUE;
|
||||||
|
|
||||||
|
if (!transport)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
transport_stop(transport);
|
||||||
|
|
||||||
|
if (transport->layer == TRANSPORT_LAYER_TLS)
|
||||||
|
status &= tls_disconnect(transport->TlsIn);
|
||||||
|
|
||||||
|
if ((transport->layer == TRANSPORT_LAYER_TSG) || (transport->layer == TRANSPORT_LAYER_TSG_TLS))
|
||||||
|
{
|
||||||
|
status &= tsg_disconnect(transport->tsg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status &= tcp_disconnect(transport->TcpIn);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -219,6 +224,12 @@ BIO_METHOD* BIO_s_tsg(void)
|
|||||||
|
|
||||||
BOOL transport_connect_tls(rdpTransport* transport)
|
BOOL transport_connect_tls(rdpTransport* transport)
|
||||||
{
|
{
|
||||||
|
freerdp* instance;
|
||||||
|
rdpContext* context;
|
||||||
|
|
||||||
|
instance = (freerdp*) transport->settings->instance;
|
||||||
|
context = instance->context;
|
||||||
|
|
||||||
if (transport->layer == TRANSPORT_LAYER_TSG)
|
if (transport->layer == TRANSPORT_LAYER_TSG)
|
||||||
{
|
{
|
||||||
transport->TsgTls = tls_new(transport->settings);
|
transport->TsgTls = tls_new(transport->settings);
|
||||||
@ -239,6 +250,9 @@ BOOL transport_connect_tls(rdpTransport* transport)
|
|||||||
if (!connectErrorCode)
|
if (!connectErrorCode)
|
||||||
connectErrorCode = TLSCONNECTERROR;
|
connectErrorCode = TLSCONNECTERROR;
|
||||||
|
|
||||||
|
if (!freerdp_get_last_error(context))
|
||||||
|
freerdp_set_last_error(context, FREERDP_ERROR_TLS_CONNECT_FAILED);
|
||||||
|
|
||||||
tls_free(transport->TsgTls);
|
tls_free(transport->TsgTls);
|
||||||
transport->TsgTls = NULL;
|
transport->TsgTls = NULL;
|
||||||
|
|
||||||
@ -268,6 +282,9 @@ BOOL transport_connect_tls(rdpTransport* transport)
|
|||||||
if (!connectErrorCode)
|
if (!connectErrorCode)
|
||||||
connectErrorCode = TLSCONNECTERROR;
|
connectErrorCode = TLSCONNECTERROR;
|
||||||
|
|
||||||
|
if (!freerdp_get_last_error(context))
|
||||||
|
freerdp_set_last_error(context, FREERDP_ERROR_TLS_CONNECT_FAILED);
|
||||||
|
|
||||||
tls_free(transport->TlsIn);
|
tls_free(transport->TlsIn);
|
||||||
|
|
||||||
if (transport->TlsIn == transport->TlsOut)
|
if (transport->TlsIn == transport->TlsOut)
|
||||||
@ -313,6 +330,11 @@ BOOL transport_connect_nla(rdpTransport* transport)
|
|||||||
if (!connectErrorCode)
|
if (!connectErrorCode)
|
||||||
connectErrorCode = AUTHENTICATIONERROR;
|
connectErrorCode = AUTHENTICATIONERROR;
|
||||||
|
|
||||||
|
if (!freerdp_get_last_error(instance->context))
|
||||||
|
{
|
||||||
|
freerdp_set_last_error(instance->context, FREERDP_ERROR_AUTHENTICATION_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Authentication failure, check credentials.\n"
|
fprintf(stderr, "Authentication failure, check credentials.\n"
|
||||||
"If credentials are valid, the NTLMSSP implementation may be to blame.\n");
|
"If credentials are valid, the NTLMSSP implementation may be to blame.\n");
|
||||||
|
|
||||||
@ -374,7 +396,7 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
|
|||||||
|
|
||||||
transport->async = settings->AsyncTransport;
|
transport->async = settings->AsyncTransport;
|
||||||
|
|
||||||
if (transport->settings->GatewayEnabled)
|
if (transport->GatewayEnabled)
|
||||||
{
|
{
|
||||||
transport->layer = TRANSPORT_LAYER_TSG;
|
transport->layer = TRANSPORT_LAYER_TSG;
|
||||||
transport->TcpOut = tcp_new(settings);
|
transport->TcpOut = tcp_new(settings);
|
||||||
@ -1012,6 +1034,11 @@ BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void transport_set_gateway_enabled(rdpTransport* transport, BOOL GatewayEnabled)
|
||||||
|
{
|
||||||
|
transport->GatewayEnabled = GatewayEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
static void* transport_client_thread(void* arg)
|
static void* transport_client_thread(void* arg)
|
||||||
{
|
{
|
||||||
DWORD status;
|
DWORD status;
|
||||||
@ -1055,7 +1082,7 @@ static void* transport_client_thread(void* arg)
|
|||||||
|
|
||||||
transport_get_read_handles(transport, (HANDLE*) &handles, &nCount);
|
transport_get_read_handles(transport, (HANDLE*) &handles, &nCount);
|
||||||
|
|
||||||
status = WaitForMultipleObjects(nCount, handles, FALSE, 100);
|
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||||
if (transport->layer == TRANSPORT_LAYER_CLOSED)
|
if (transport->layer == TRANSPORT_LAYER_CLOSED)
|
||||||
{
|
{
|
||||||
rdpRdp* rdp = (rdpRdp*) transport->rdp;
|
rdpRdp* rdp = (rdpRdp*) transport->rdp;
|
||||||
@ -1107,6 +1134,7 @@ rdpTransport* transport_new(rdpSettings* settings)
|
|||||||
transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
|
||||||
transport->blocking = TRUE;
|
transport->blocking = TRUE;
|
||||||
|
transport->GatewayEnabled = FALSE;
|
||||||
|
|
||||||
InitializeCriticalSectionAndSpinCount(&(transport->ReadLock), 4000);
|
InitializeCriticalSectionAndSpinCount(&(transport->ReadLock), 4000);
|
||||||
InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000);
|
InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000);
|
||||||
@ -1121,20 +1149,7 @@ void transport_free(rdpTransport* transport)
|
|||||||
{
|
{
|
||||||
if (transport)
|
if (transport)
|
||||||
{
|
{
|
||||||
if (transport->async)
|
transport_stop(transport);
|
||||||
{
|
|
||||||
if (transport->stopEvent)
|
|
||||||
{
|
|
||||||
SetEvent(transport->stopEvent);
|
|
||||||
WaitForSingleObject(transport->thread, INFINITE);
|
|
||||||
|
|
||||||
CloseHandle(transport->thread);
|
|
||||||
CloseHandle(transport->stopEvent);
|
|
||||||
|
|
||||||
transport->thread = NULL;
|
|
||||||
transport->stopEvent = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transport->ReceiveBuffer)
|
if (transport->ReceiveBuffer)
|
||||||
Stream_Release(transport->ReceiveBuffer);
|
Stream_Release(transport->ReceiveBuffer);
|
||||||
|
@ -75,6 +75,7 @@ struct rdp_transport
|
|||||||
HANDLE stopEvent;
|
HANDLE stopEvent;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
BOOL async;
|
BOOL async;
|
||||||
|
BOOL GatewayEnabled;
|
||||||
CRITICAL_SECTION ReadLock;
|
CRITICAL_SECTION ReadLock;
|
||||||
CRITICAL_SECTION WriteLock;
|
CRITICAL_SECTION WriteLock;
|
||||||
wLog* log;
|
wLog* log;
|
||||||
@ -88,15 +89,16 @@ BOOL transport_disconnect(rdpTransport* transport);
|
|||||||
BOOL transport_connect_rdp(rdpTransport* transport);
|
BOOL transport_connect_rdp(rdpTransport* transport);
|
||||||
BOOL transport_connect_tls(rdpTransport* transport);
|
BOOL transport_connect_tls(rdpTransport* transport);
|
||||||
BOOL transport_connect_nla(rdpTransport* transport);
|
BOOL transport_connect_nla(rdpTransport* transport);
|
||||||
BOOL transport_connect_tsg(rdpTransport* transport);
|
|
||||||
BOOL transport_accept_rdp(rdpTransport* transport);
|
BOOL transport_accept_rdp(rdpTransport* transport);
|
||||||
BOOL transport_accept_tls(rdpTransport* transport);
|
BOOL transport_accept_tls(rdpTransport* transport);
|
||||||
BOOL transport_accept_nla(rdpTransport* transport);
|
BOOL transport_accept_nla(rdpTransport* transport);
|
||||||
|
void transport_stop(rdpTransport* transport);
|
||||||
int transport_read(rdpTransport* transport, wStream* s);
|
int transport_read(rdpTransport* transport, wStream* s);
|
||||||
int transport_write(rdpTransport* transport, wStream* s);
|
int transport_write(rdpTransport* transport, wStream* s);
|
||||||
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount);
|
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount);
|
||||||
int transport_check_fds(rdpTransport* transport);
|
int transport_check_fds(rdpTransport* transport);
|
||||||
BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking);
|
BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking);
|
||||||
|
void transport_set_gateway_enabled(rdpTransport* transport, BOOL GatewayEnabled);
|
||||||
void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count);
|
void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count);
|
||||||
|
|
||||||
wStream* transport_receive_pool_take(rdpTransport* transport);
|
wStream* transport_receive_pool_take(rdpTransport* transport);
|
||||||
|
@ -787,7 +787,9 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int po
|
|||||||
tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count);
|
tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count);
|
||||||
|
|
||||||
if (instance->VerifyCertificate)
|
if (instance->VerifyCertificate)
|
||||||
|
{
|
||||||
accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint);
|
accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint);
|
||||||
|
}
|
||||||
|
|
||||||
if (!accept_certificate)
|
if (!accept_certificate)
|
||||||
{
|
{
|
||||||
@ -807,7 +809,9 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int po
|
|||||||
tls_print_certificate_error(hostname, fingerprint, tls->certificate_store->file);
|
tls_print_certificate_error(hostname, fingerprint, tls->certificate_store->file);
|
||||||
|
|
||||||
if (instance->VerifyChangedCertificate)
|
if (instance->VerifyChangedCertificate)
|
||||||
|
{
|
||||||
accept_certificate = instance->VerifyChangedCertificate(instance, subject, issuer, fingerprint, "");
|
accept_certificate = instance->VerifyChangedCertificate(instance, subject, issuer, fingerprint, "");
|
||||||
|
}
|
||||||
|
|
||||||
if (!accept_certificate)
|
if (!accept_certificate)
|
||||||
{
|
{
|
||||||
|
@ -90,7 +90,7 @@ int freerdp_tcp_connect(const char* hostname, int port)
|
|||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "tcp_connect: getaddrinfo (%s)\n", gai_strerror(status));
|
//fprintf(stderr, "tcp_connect: getaddrinfo (%s)\n", gai_strerror(status));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,14 +328,14 @@ BOOL CancelWaitableTimer(HANDLE hTimer)
|
|||||||
* http://www.cs.wustl.edu/~schmidt/Timer_Queue.html
|
* http://www.cs.wustl.edu/~schmidt/Timer_Queue.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void timespec_add_ms(struct timespec* tspec, UINT32 ms)
|
void timespec_add_ms(struct timespec* tspec, UINT32 ms)
|
||||||
{
|
{
|
||||||
UINT64 ns = tspec->tv_nsec + (ms * 1000000);
|
UINT64 ns = tspec->tv_nsec + (ms * 1000000);
|
||||||
tspec->tv_sec += (ns / 1000000000);
|
tspec->tv_sec += (ns / 1000000000);
|
||||||
tspec->tv_nsec = (ns % 1000000000);
|
tspec->tv_nsec = (ns % 1000000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT64 timespec_to_ms(struct timespec* tspec)
|
UINT64 timespec_to_ms(struct timespec* tspec)
|
||||||
{
|
{
|
||||||
UINT64 ms;
|
UINT64 ms;
|
||||||
ms = tspec->tv_sec * 1000;
|
ms = tspec->tv_sec * 1000;
|
||||||
|
@ -408,7 +408,7 @@ void InitializeWtsApiStubs(void)
|
|||||||
if (!g_WtsApiModule)
|
if (!g_WtsApiModule)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pInitWtsApi = GetProcAddress(g_WtsApiModule, "InitWtsApi");
|
pInitWtsApi = (INIT_WTSAPI_FN) GetProcAddress(g_WtsApiModule, "InitWtsApi");
|
||||||
|
|
||||||
if (pInitWtsApi)
|
if (pInitWtsApi)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user