From 30dd40e10a72a6a7031a17847179e9867591ca63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 7 May 2015 14:20:49 -0400 Subject: [PATCH] wfreerdp: fix and improve remote assistance --- client/Windows/wf_client.c | 6 +- client/Windows/wf_graphics.c | 6 +- include/freerdp/gdi/gdi.h | 2 + libfreerdp/core/tcp.c | 134 ++++++++++++++++++++++++++++++++- libfreerdp/gdi/gdi.c | 4 +- server/shadow/Win/win_shadow.c | 1 - 6 files changed, 146 insertions(+), 7 deletions(-) diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index e639b31e4..ff90603b2 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -133,7 +133,7 @@ BOOL wf_sw_desktop_resize(wfContext* wfc) rdpGdi* gdi; rdpContext* context; rdpSettings* settings; - freerdp *instance = wfc->instance; + freerdp* instance = wfc->instance; context = (rdpContext*) wfc; settings = wfc->instance->settings; @@ -142,15 +142,19 @@ BOOL wf_sw_desktop_resize(wfContext* wfc) wfc->width = settings->DesktopWidth; wfc->height = settings->DesktopHeight; + gdi->primary->bitmap->data = NULL; gdi_free(instance); + if (wfc->primary) { wf_image_free(wfc->primary); wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, NULL); } + gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, wfc->primary->pdata); gdi = instance->context->gdi; wfc->hdc = gdi->primary->hdc; + return TRUE; } diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index 895471edc..faaa9ea69 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -49,18 +49,20 @@ HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data negHeight = (height < 0) ? height : height * (-1); hdc = GetDC(NULL); + bmi.bmiHeader.biSize = sizeof(BITMAPINFO); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = negHeight; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = wfc->dstBpp; bmi.bmiHeader.biCompression = BI_RGB; + bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0); - if (data != NULL) + if (data) freerdp_image_convert(data, cdata, width, height, bpp, wfc->dstBpp, wfc->clrconv); - if (pdata != NULL) + if (pdata) *pdata = cdata; ReleaseDC(NULL, hdc); diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h index a3a4cade8..1dd14158e 100644 --- a/include/freerdp/gdi/gdi.h +++ b/include/freerdp/gdi/gdi.h @@ -129,9 +129,11 @@ #define GDIOBJECT_REGION 0x05 /* Region return values */ +#ifndef NULLREGION #define NULLREGION 0x01 #define SIMPLEREGION 0x02 #define COMPLEXREGION 0x03 +#endif struct _GDIOBJECT { diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index fd978e355..6fd46f5ff 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -995,6 +995,137 @@ int freerdp_tcp_connect_multi(char** hostnames, UINT32* ports, int count, int po return sockfd; } +#else + +int freerdp_tcp_connect_multi(char** hostnames, UINT32* ports, int count, int port, int timeout) +{ + int index; + int sindex; + int status; + SOCKET sockfd; + SOCKET* sockfds; + HANDLE* events; + DWORD waitStatus; + char port_str[16]; + struct addrinfo hints; + struct addrinfo* addr; + struct addrinfo* result; + struct addrinfo** addrs; + struct addrinfo** results; + + sindex = -1; + + sprintf_s(port_str, sizeof(port_str) - 1, "%u", port); + + sockfds = (SOCKET*) calloc(count, sizeof(SOCKET)); + events = (HANDLE*) calloc(count, sizeof(HANDLE)); + addrs = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*)); + results = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*)); + + if (!sockfds || !events || !addrs || !results) + return -1; + + for (index = 0; index < count; index++) + { + ZeroMemory(&hints, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if (ports) + sprintf_s(port_str, sizeof(port_str) - 1, "%u", ports[index]); + + status = getaddrinfo(hostnames[index], port_str, &hints, &result); + + if (status) + { + continue; + } + + addr = result; + + if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0)) + { + while ((addr = addr->ai_next)) + { + if (addr->ai_family == AF_INET) + break; + } + + if (!addr) + addr = result; + } + + sockfds[index] = _socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + + if (sockfds[index] < 0) + { + freeaddrinfo(result); + sockfds[index] = 0; + continue; + } + + addrs[index] = addr; + results[index] = result; + } + + for (index = 0; index < count; index++) + { + if (!sockfds[index]) + continue; + + sockfd = sockfds[index]; + addr = addrs[index]; + + /* set socket in non-blocking mode */ + + WSAEventSelect(sockfd, events[index], FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE); + + /* non-blocking tcp connect */ + + status = _connect(sockfd, addr->ai_addr, addr->ai_addrlen); + + if (status >= 0) + { + /* connection success */ + break; + } + } + + waitStatus = WaitForMultipleObjects(count, events, FALSE, timeout * 1000); + + sindex = waitStatus - WAIT_OBJECT_0; + + for (index = 0; index < count; index++) + { + if (!sockfds[index]) + continue; + + sockfd = sockfds[index]; + + /* set socket in blocking mode */ + + WSAEventSelect(sockfd, NULL, 0); + } + + if (sindex >= 0) + { + sockfd = sockfds[sindex]; + } + + for (index = 0; index < count; index++) + { + if (results[index]) + freeaddrinfo(results[index]); + } + + free(addrs); + free(results); + free(sockfds); + free(events); + + return sockfd; +} + #endif BOOL freerdp_tcp_set_keep_alive_mode(int sockfd) @@ -1095,7 +1226,8 @@ int freerdp_tcp_connect(rdpSettings* settings, const char* hostname, int port, i { if (settings->TargetNetAddressCount > 0) { -#ifndef _WIN32 +//#ifndef _WIN32 +#if 1 sockfd = freerdp_tcp_connect_multi(settings->TargetNetAddresses, settings->TargetNetPorts, settings->TargetNetAddressCount, port, timeout); #else diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 5f75611a9..2b1692a00 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -471,7 +471,7 @@ static BOOL gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) compressed = bitmap->compressed; bitsPerPixel = bitmap->bitsPerPixel; - if (gdi->bitmap_size < (nWidth * nHeight * 4)) + if (gdi->bitmap_size < (UINT32) (nWidth * nHeight * 4)) { gdi->bitmap_size = nWidth * nHeight * 4; gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16); @@ -546,7 +546,7 @@ static BOOL gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) palette32 = (UINT32*) gdi->palette; - for (index = 0; index < palette->number; index++) + for (index = 0; index < (int) palette->number; index++) { pe = &(palette->entries[index]); palette32[index] = RGB32(pe->red, pe->green, pe->blue); diff --git a/server/shadow/Win/win_shadow.c b/server/shadow/Win/win_shadow.c index b70b61f79..263e3177f 100644 --- a/server/shadow/Win/win_shadow.c +++ b/server/shadow/Win/win_shadow.c @@ -408,7 +408,6 @@ int win_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors) DWORD iDevNum = 0; int numMonitors = 0; MONITOR_DEF* monitor; - MONITOR_DEF* virtualScreen; DISPLAY_DEVICE displayDevice; ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));