From 88c55eab2f634fbea002627c1f6525f82acb12d0 Mon Sep 17 00:00:00 2001 From: Corey C Date: Wed, 19 Sep 2012 17:33:05 -0400 Subject: [PATCH 01/14] wfreerdp-server: fixed linked libs --- server/Windows/CMakeLists.txt | 44 +++++++++++------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/server/Windows/CMakeLists.txt b/server/Windows/CMakeLists.txt index 00e74dc93..971f3ffb7 100644 --- a/server/Windows/CMakeLists.txt +++ b/server/Windows/CMakeLists.txt @@ -45,40 +45,24 @@ else() add_executable(wfreerdp-server ${WFREERDP_SERVER_SRCS}) endif() +if(WITH_WIN8) + set(WFREERDP_SERVER_LIBS + d3d11.lib + dxgi.lib + dxguid.lib) +endif() + if(WITH_MONOLITHIC_BUILD) - set(WFREERDP_SERVER_LIBS freerdp) -else() - - if(WITH_WIN8) - - set(WFREERDP_SERVER_LIBS - freerdp-core - - freerdp-utils - - freerdp-codec - - freerdp-channels - - d3d11.lib - - dxgi.lib - - dxguid.lib) - else() - set(WFREERDP_SERVER_LIBS - freerdp-core - - freerdp-utils - - freerdp-codec - - freerdp-channels) - endif() + set(WFREERDP_SERVER_LIBS ${WFREERDP_SERVER_LIBS} freerdp) +else() + set(WFREERDP_SERVER_LIBS ${WFREERDP_SERVER_LIBS} + freerdp-core + freerdp-utils + freerdp-codec + freerdp-channels) endif() target_link_libraries(wfreerdp-server ${WFREERDP_SERVER_LIBS}) - if(WITH_SERVER_INTERFACE) install(TARGETS wfreerdp-server DESTINATION ${CMAKE_INSTALL_LIBDIR}) From 818942e628dbc8ba68f3e33f6ab8dda3758072cb Mon Sep 17 00:00:00 2001 From: Corey C Date: Thu, 4 Oct 2012 16:51:23 -0400 Subject: [PATCH 02/14] wfreerdp-server: control interface --- server/Windows/wf_interface.c | 39 +++++++++++++++++++++++++++++++++-- server/Windows/wf_interface.h | 2 ++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/server/Windows/wf_interface.c b/server/Windows/wf_interface.c index b144a5655..46de467d2 100644 --- a/server/Windows/wf_interface.c +++ b/server/Windows/wf_interface.c @@ -21,6 +21,7 @@ #include "config.h" #endif + #include #include #include @@ -30,6 +31,16 @@ #include "wf_interface.h" +// +struct rdp_listener +{ + freerdp_listener* instance; + + int sockfds[5]; + int num_sockfds; +}; +// + DWORD WINAPI wf_server_main_loop(LPVOID lpParam) { int i, fds; @@ -38,11 +49,13 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam) void* rfds[32]; fd_set rfds_set; freerdp_listener* instance; + struct rdp_listener* listener; ZeroMemory(rfds, sizeof(rfds)); instance = (freerdp_listener*) lpParam; + listener = (struct rdp_listener*) instance->listener; - while (1) + while (listener->num_sockfds > 0) { rcount = 0; @@ -68,8 +81,9 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam) if (max_fds == 0) break; + select(max_fds + 1, &rfds_set, NULL, NULL, NULL); - + if (instance->CheckFileDescriptor(instance) != true) { printf("Failed to check FreeRDP file descriptor\n"); @@ -77,6 +91,8 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam) } } + printf("wf_server_main_loop terminating\n"); + instance->Close(instance); return 0; @@ -103,6 +119,7 @@ BOOL wfreerdp_server_start(wfServer* server) BOOL wfreerdp_server_stop(wfServer* server) { + server->instance->Close(server->instance); return TRUE; } @@ -132,3 +149,21 @@ void wfreerdp_server_free(wfServer* server) freerdp_wsa_cleanup(); } + + +FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server) +{ + DWORD tStatus; + BOOL bRet; + + bRet = GetExitCodeThread(server->thread, &tStatus); + if (bRet == 0) + { + printf("Error in call to GetExitCodeThread\n"); + return FALSE; + } + + if (tStatus == STILL_ACTIVE) + return TRUE; + return FALSE; +} diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index 587d8305c..092d58b90 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -89,4 +89,6 @@ FREERDP_API BOOL wfreerdp_server_stop(wfServer* server); FREERDP_API wfServer* wfreerdp_server_new(); FREERDP_API void wfreerdp_server_free(wfServer* server); +FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server); + #endif /* WF_INTERFACE_H */ From 4c790d825322d22c9d2b75d31e38eda8c908b654 Mon Sep 17 00:00:00 2001 From: Corey C Date: Fri, 5 Oct 2012 15:25:30 -0400 Subject: [PATCH 03/14] wfreerdp-server: fixed stop server api --- server/Windows/wf_info.c | 18 +++++++++++++++--- server/Windows/wf_input.c | 17 +++++++++++++++++ server/Windows/wf_input.h | 6 ++++++ server/Windows/wf_interface.c | 13 ++++++++++++- server/Windows/wf_interface.h | 3 +++ server/Windows/wf_peer.c | 17 +++++++++++++++++ 6 files changed, 70 insertions(+), 4 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index addd7e132..3b8deeed9 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -138,17 +138,29 @@ wfInfo* wf_info_init() wfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * 32); + //Set FPS wfi->framesPerSecond = 24; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); - if (status == ERROR_SUCCESS) { if (RegQueryValueEx(hKey, _T("FramesPerSecond"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) - wfi->framesPerSecond = dwValue; - + wfi->framesPerSecond = dwValue; } + RegCloseKey(hKey); + //Set input toggle + wfi->input_disabled = FALSE; + + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + if (status == ERROR_SUCCESS) + { + if (RegQueryValueEx(hKey, _T("DisableInput"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + { + if (dwValue != 0) + wfi->input_disabled = TRUE; + } + } RegCloseKey(hKey); //detect windows version diff --git a/server/Windows/wf_input.c b/server/Windows/wf_input.c index a802d2ca2..6f254037f 100644 --- a/server/Windows/wf_input.c +++ b/server/Windows/wf_input.c @@ -164,3 +164,20 @@ void wf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint1 wf_peer_mouse_event(input, flags, x, y); } } + + +void wf_peer_keyboard_event_dummy(rdpInput* input, uint16 flags, uint16 code) +{ +} + +void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, uint16 flags, uint16 code) +{ +} + +void wf_peer_mouse_event_dummy(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ +} + +void wf_peer_extended_mouse_event_dummy(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ +} diff --git a/server/Windows/wf_input.h b/server/Windows/wf_input.h index d06c2ed74..63c047197 100644 --- a/server/Windows/wf_input.h +++ b/server/Windows/wf_input.h @@ -27,4 +27,10 @@ void wf_peer_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code); void wf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); void wf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); +//dummy versions +void wf_peer_keyboard_event_dummy(rdpInput* input, uint16 flags, uint16 code); +void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, uint16 flags, uint16 code); +void wf_peer_mouse_event_dummy(rdpInput* input, uint16 flags, uint16 x, uint16 y); +void wf_peer_extended_mouse_event_dummy(rdpInput* input, uint16 flags, uint16 x, uint16 y); + #endif /* WF_INPUT_H */ diff --git a/server/Windows/wf_interface.c b/server/Windows/wf_interface.c index 46de467d2..98223efb9 100644 --- a/server/Windows/wf_interface.c +++ b/server/Windows/wf_interface.c @@ -28,10 +28,11 @@ #include "wf_peer.h" #include "wf_settings.h" +#include "wf_info.h" #include "wf_interface.h" -// +//todo: remove this struct rdp_listener { freerdp_listener* instance; @@ -50,6 +51,10 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam) fd_set rfds_set; freerdp_listener* instance; struct rdp_listener* listener; + wfInfo* wfi; + + wfi = wf_info_get_instance(); + wfi->force_all_disconnect = FALSE; ZeroMemory(rfds, sizeof(rfds)); instance = (freerdp_listener*) lpParam; @@ -119,6 +124,12 @@ BOOL wfreerdp_server_start(wfServer* server) BOOL wfreerdp_server_stop(wfServer* server) { + wfInfo* wfi; + + wfi = wf_info_get_instance(); + + printf("Stopping server\n"); + wfi->force_all_disconnect = TRUE; server->instance->Close(server->instance); return TRUE; } diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index 092d58b90..173713896 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -60,6 +60,9 @@ struct wf_info unsigned long lastUpdate; unsigned long nextUpdate; SURFACE_BITS_COMMAND cmd; + + BOOL input_disabled; + BOOL force_all_disconnect; }; struct wf_peer_context diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 7a18894a8..4f9c8c06b 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -221,6 +221,16 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) context = (wfPeerContext*) client->context; wfi = context->info; + + if (wfi->input_disabled == TRUE) + { + printf("client input is disabled\n"); + client->input->KeyboardEvent = wf_peer_keyboard_event_dummy; + client->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event_dummy; + client->input->MouseEvent = wf_peer_mouse_event_dummy; + client->input->ExtendedMouseEvent = wf_peer_extended_mouse_event_dummy; + } + context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL); printf("socketEvent created\n"); @@ -268,6 +278,13 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) if (context->socketClose) break; } + + //force disconnect + if(wfi->force_all_disconnect == TRUE) + { + printf("Forcing Disconnect -> "); + break; + } } printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname); From e7a751c930c8662a1e548a16acf77688f807f717 Mon Sep 17 00:00:00 2001 From: Corey C Date: Fri, 5 Oct 2012 18:18:59 -0400 Subject: [PATCH 04/14] wfreerdp-server: added support for getting number of peers and hostname --- server/Windows/wf_interface.c | 33 +++++++++++++++++++++++++++++++++ server/Windows/wf_interface.h | 4 ++++ 2 files changed, 37 insertions(+) diff --git a/server/Windows/wf_interface.c b/server/Windows/wf_interface.c index 98223efb9..1f6825e1f 100644 --- a/server/Windows/wf_interface.c +++ b/server/Windows/wf_interface.c @@ -178,3 +178,36 @@ FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server) return TRUE; return FALSE; } + +FREERDP_API UINT32 wfreerdp_server_num_peers() +{ + wfInfo* wfi; + + wfi = wf_info_get_instance(); + return wfi->peerCount; +} + +FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr) +{ + wfInfo* wfi; + freerdp_peer* peer; + + wfi = wf_info_get_instance(); + peer = wfi->peers[pId]; + + + if (peer) + { + UINT32 sLen; + + sLen = strnlen_s(peer->hostname, 50); + swprintf(dstStr, 50, L"%hs", peer->hostname); + return sLen; + } + else + { + printf("nonexistent peer\n"); + return 0; + } + +} diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index 173713896..d76687189 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -94,4 +94,8 @@ FREERDP_API void wfreerdp_server_free(wfServer* server); FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server); +FREERDP_API UINT32 wfreerdp_server_num_peers(); + +FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr); + #endif /* WF_INTERFACE_H */ From 8074b0b842970a8ad2f7da09552b8094b07b3d6f Mon Sep 17 00:00:00 2001 From: Corey C Date: Fri, 5 Oct 2012 19:22:38 -0400 Subject: [PATCH 05/14] wfreerdp-server: added APIs for more info on peers --- server/Windows/wf_interface.c | 75 +++++++++++++++++++++++++++++++++++ server/Windows/wf_interface.h | 5 ++- 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/server/Windows/wf_interface.c b/server/Windows/wf_interface.c index 1f6825e1f..59566d9fa 100644 --- a/server/Windows/wf_interface.c +++ b/server/Windows/wf_interface.c @@ -211,3 +211,78 @@ FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr) } } + +FREERDP_API BOOL wfreerdp_server_peer_is_local(int pId) +{ + wfInfo* wfi; + freerdp_peer* peer; + + wfi = wf_info_get_instance(); + peer = wfi->peers[pId]; + + + if (peer) + { + return peer->local; + } + else + { + return FALSE; + } +} +FREERDP_API BOOL wfreerdp_server_peer_is_connected(int pId) +{ + wfInfo* wfi; + freerdp_peer* peer; + + wfi = wf_info_get_instance(); + peer = wfi->peers[pId]; + + + if (peer) + { + return peer->connected; + } + else + { + return FALSE; + } +} + +FREERDP_API BOOL wfreerdp_server_peer_is_activated(int pId) +{ + wfInfo* wfi; + freerdp_peer* peer; + + wfi = wf_info_get_instance(); + peer = wfi->peers[pId]; + + + if (peer) + { + return peer->activated; + } + else + { + return FALSE; + } +} + +FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId) +{ + wfInfo* wfi; + freerdp_peer* peer; + + wfi = wf_info_get_instance(); + peer = wfi->peers[pId]; + + + if (peer) + { + return peer->authenticated; + } + else + { + return FALSE; + } +} diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index d76687189..538dd210f 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -95,7 +95,10 @@ FREERDP_API void wfreerdp_server_free(wfServer* server); FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server); FREERDP_API UINT32 wfreerdp_server_num_peers(); - FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr); +FREERDP_API BOOL wfreerdp_server_peer_is_local(int pId); +FREERDP_API BOOL wfreerdp_server_peer_is_connected(int pId); +FREERDP_API BOOL wfreerdp_server_peer_is_activated(int pId); +FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId); #endif /* WF_INTERFACE_H */ From a2cd04e3f715386af2bf85e6c7269a7390bcd149 Mon Sep 17 00:00:00 2001 From: Corey C Date: Fri, 5 Oct 2012 23:25:18 -0400 Subject: [PATCH 06/14] wfreerdp-server: added connect/disconnect event callback support --- server/Windows/wf_info.c | 4 ++++ server/Windows/wf_interface.c | 29 +++++++++++++++++++++++++++++ server/Windows/wf_interface.h | 8 ++++++++ 3 files changed, 41 insertions(+) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 3b8deeed9..f70d24ce2 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -217,6 +217,8 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) printf("Registering Peer: %d\n", wfi->peerCount); wf_info_unlock(wfi); + + wfreerdp_server_peer_connect_event(wfi->peerCount); } } @@ -235,6 +237,8 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) #endif wf_info_unlock(wfi); + + wfreerdp_server_peer_disconnect_event(wfi->peerCount); } } diff --git a/server/Windows/wf_interface.c b/server/Windows/wf_interface.c index 59566d9fa..0ceb46012 100644 --- a/server/Windows/wf_interface.c +++ b/server/Windows/wf_interface.c @@ -42,6 +42,9 @@ struct rdp_listener }; // +cbConEvent cbConnect; +cbConEvent cbDisconnect; + DWORD WINAPI wf_server_main_loop(LPVOID lpParam) { int i, fds; @@ -148,6 +151,9 @@ wfServer* wfreerdp_server_new() server->port = 3389; } + cbConnect = NULL; + cbDisconnect = NULL; + return server; } @@ -286,3 +292,26 @@ FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId) return FALSE; } } + +FREERDP_API void wfreerdp_server_register_connect_event(cbConEvent cb) +{ + cbConnect = cb; +} + +FREERDP_API void wfreerdp_server_register_disconnect_event(cbConEvent cb) +{ + cbDisconnect = cb; +} + + +void wfreerdp_server_peer_connect_event(int pId) +{ + if (cbConnect) + cbConnect(pId); +} +void wfreerdp_server_peer_disconnect_event(int pId) +{ + if (cbDisconnect) + cbDisconnect(pId); +} + diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index 538dd210f..908b48f7a 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -86,6 +86,8 @@ struct wf_server }; typedef struct wf_server wfServer; +typedef void (__stdcall* cbConEvent) (int); + FREERDP_API BOOL wfreerdp_server_start(wfServer* server); FREERDP_API BOOL wfreerdp_server_stop(wfServer* server); @@ -101,4 +103,10 @@ FREERDP_API BOOL wfreerdp_server_peer_is_connected(int pId); FREERDP_API BOOL wfreerdp_server_peer_is_activated(int pId); FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId); +FREERDP_API void wfreerdp_server_register_connect_event(cbConEvent cb); +FREERDP_API void wfreerdp_server_register_disconnect_event(cbConEvent cb); + +void wfreerdp_server_peer_connect_event(int pId); +void wfreerdp_server_peer_disconnect_event(int pId); + #endif /* WF_INTERFACE_H */ From d1e1ee9085a17c49a8356c80850a54723127158f Mon Sep 17 00:00:00 2001 From: Corey C Date: Sat, 6 Oct 2012 16:25:11 -0400 Subject: [PATCH 07/14] wfreerdp-server: added defines for default fps and max peers --- server/Windows/wf_info.c | 4 ++-- server/Windows/wf_info.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index f70d24ce2..54839c7c7 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -136,10 +136,10 @@ wfInfo* wf_info_init() _tprintf(_T("Failed to create update thread\n")); } - wfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * 32); + wfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * WF_INFO_MAXPEERS); //Set FPS - wfi->framesPerSecond = 24; + wfi->framesPerSecond = WF_INFO_DEFAULT_FPS; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); if (status == ERROR_SUCCESS) diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index c23ad872b..ff26275e9 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -22,6 +22,9 @@ #include "wf_interface.h" +#define WF_INFO_DEFAULT_FPS 24 +#define WF_INFO_MAXPEERS 32 + int wf_info_lock(wfInfo* wfi); int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds); int wf_info_unlock(wfInfo* wfi); From 715a172fe84d07b8b2e50d294ea8bb60b74139f3 Mon Sep 17 00:00:00 2001 From: Corey C Date: Sat, 6 Oct 2012 16:57:58 -0400 Subject: [PATCH 08/14] wfreerdp-server: improved tracking of peers by id --- include/freerdp/peer.h | 1 + server/Windows/wf_info.c | 33 +++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/include/freerdp/peer.h b/include/freerdp/peer.h index 635bd4e38..ac87635bb 100644 --- a/include/freerdp/peer.h +++ b/include/freerdp/peer.h @@ -72,6 +72,7 @@ struct rdp_freerdp_peer psPeerSendChannelData SendChannelData; psPeerReceiveChannelData ReceiveChannelData; + int pId; uint32 ack_frame_id; boolean local; boolean connected; diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 54839c7c7..a9d4f6774 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -137,6 +137,7 @@ wfInfo* wf_info_init() } wfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * WF_INFO_MAXPEERS); + memset(wfi->peers, 0, sizeof(freerdp_peer*) * WF_INFO_MAXPEERS); //Set FPS wfi->framesPerSecond = WF_INFO_DEFAULT_FPS; @@ -202,6 +203,11 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) { if (wf_info_lock(wfi) > 0) { + int i; + int peerId; + //todo: reject peer if we have WF_INFO_MAXPEERS connected + + context->info = wfi; context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -211,14 +217,25 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) #else wf_mirror_driver_activate(wfi); #endif + //look trhough the array of peers until an empty slot + for(i=0; ipeers[i] == NULL) + { + peerId = i; + break; + } + } - wfi->peers[wfi->peerCount++] = ((rdpContext*) context)->peer; - - printf("Registering Peer: %d\n", wfi->peerCount); + wfi->peers[peerId] = ((rdpContext*) context)->peer; + wfi->peers[peerId]->pId = peerId; + wfi->peerCount++; + printf("Registering Peer: id=%d #=%d\n", peerId, wfi->peerCount); wf_info_unlock(wfi); - wfreerdp_server_peer_connect_event(wfi->peerCount); + wfreerdp_server_peer_connect_event(peerId); } } @@ -226,7 +243,11 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) { if (wf_info_lock(wfi) > 0) { - wfi->peers[--(wfi->peerCount)] = NULL; + int peerId; + + peerId = ((rdpContext*) context)->peer->pId; + wfi->peers[peerId] = NULL; + wfi->peerCount--; CloseHandle(context->updateEvent); printf("Unregistering Peer: %d\n", wfi->peerCount); @@ -238,7 +259,7 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) wf_info_unlock(wfi); - wfreerdp_server_peer_disconnect_event(wfi->peerCount); + wfreerdp_server_peer_disconnect_event(peerId); } } From ecad702c98c3140b37f1508ed6d3d8a742450197 Mon Sep 17 00:00:00 2001 From: Corey C Date: Sat, 6 Oct 2012 17:09:53 -0400 Subject: [PATCH 09/14] wfreerdp-server: fix parallel send --- server/Windows/wf_info.c | 2 +- server/Windows/wf_update.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index a9d4f6774..7180797b2 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -250,7 +250,7 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) wfi->peerCount--; CloseHandle(context->updateEvent); - printf("Unregistering Peer: %d\n", wfi->peerCount); + printf("Unregistering Peer: id=%d, #=%d\n", peerId, wfi->peerCount); #ifdef WITH_WIN8 if (wfi->peerCount == 0) diff --git a/server/Windows/wf_update.c b/server/Windows/wf_update.c index 70d5a81ca..9ddd47a1d 100644 --- a/server/Windows/wf_update.c +++ b/server/Windows/wf_update.c @@ -37,6 +37,7 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam) { int index; + int peerindex; DWORD fps; wfInfo* wfi; DWORD beg, end; @@ -63,13 +64,17 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam) //printf("Start of parallel sending\n"); - for (index = 0; index < wfi->peerCount; index++) + for (peerindex = 0; peerindex < wfi->peerCount; peerindex++) { - if (wfi->peers[index]->activated) + for (index = 0; index < WF_INFO_MAXPEERS; index++) { - //printf("Setting event for %d of %d\n", index + 1, wfi->activePeerCount); - SetEvent(((wfPeerContext*) wfi->peers[index]->context)->updateEvent); + if (wfi->peers[index] && wfi->peers[index]->activated) + { + //printf("Setting event for %d of %d\n", index + 1, wfi->activePeerCount); + SetEvent(((wfPeerContext*) wfi->peers[index]->context)->updateEvent); + } } + } for (index = 0; index < wfi->activePeerCount; index++) From 5d0a53a3b3d2a256624aeb8a3da67d07e8e56a3c Mon Sep 17 00:00:00 2001 From: Corey C Date: Mon, 8 Oct 2012 15:46:01 -0400 Subject: [PATCH 10/14] wfreerdp-server: improved peer tracking, added ability to disconnect individual peers --- server/Windows/wf_info.c | 7 ++++++- server/Windows/wf_info.h | 2 +- server/Windows/wf_peer.c | 3 +++ server/Windows/wf_update.c | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 7180797b2..da638c5cc 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -206,7 +206,12 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) int i; int peerId; //todo: reject peer if we have WF_INFO_MAXPEERS connected - + if (wfi->peerCount == WF_INFO_MAXPEERS) + { + context->socketClose = TRUE; + wf_info_unlock(wfi); + return; + } context->info = wfi; context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index ff26275e9..3c7ee3c3b 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -23,7 +23,7 @@ #include "wf_interface.h" #define WF_INFO_DEFAULT_FPS 24 -#define WF_INFO_MAXPEERS 32 +#define WF_INFO_MAXPEERS 2 int wf_info_lock(wfInfo* wfi); int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds); diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 4f9c8c06b..c519c0222 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -220,6 +220,9 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) client->Initialize(client); context = (wfPeerContext*) client->context; + if (context->socketClose) + return 0; + wfi = context->info; if (wfi->input_disabled == TRUE) diff --git a/server/Windows/wf_update.c b/server/Windows/wf_update.c index 9ddd47a1d..1fef2d13b 100644 --- a/server/Windows/wf_update.c +++ b/server/Windows/wf_update.c @@ -63,10 +63,10 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam) wf_update_encode(wfi); //printf("Start of parallel sending\n"); - + index = 0; for (peerindex = 0; peerindex < wfi->peerCount; peerindex++) { - for (index = 0; index < WF_INFO_MAXPEERS; index++) + for (; index < WF_INFO_MAXPEERS; index++) { if (wfi->peers[index] && wfi->peers[index]->activated) { From 36394b3c23f0c4f52d2b2353fa225103132653f3 Mon Sep 17 00:00:00 2001 From: Corey C Date: Mon, 8 Oct 2012 22:31:40 -0400 Subject: [PATCH 11/14] wfreerdp-server: generalized managed api callbacks, peer tracking bug fixes, code cleanup --- server/Windows/wf_info.c | 103 +++++++++++++++++----------------- server/Windows/wf_info.h | 2 +- server/Windows/wf_interface.c | 46 ++++----------- server/Windows/wf_interface.h | 53 +++++++++-------- server/Windows/wf_peer.c | 47 +++++++++------- server/Windows/wf_update.c | 51 ++++++++--------- 6 files changed, 147 insertions(+), 155 deletions(-) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index da638c5cc..52b953b77 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -1,21 +1,21 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * FreeRDP Windows Server - * - * Copyright 2012 Corey Clayton - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* FreeRDP: A Remote Desktop Protocol Client +* FreeRDP Windows Server +* +* Copyright 2012 Corey Clayton +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifdef HAVE_CONFIG_H #include "config.h" @@ -41,19 +41,19 @@ int wf_info_lock(wfInfo* wfi) switch (dRes) { - case WAIT_ABANDONED: - case WAIT_OBJECT_0: - return TRUE; - break; + case WAIT_ABANDONED: + case WAIT_OBJECT_0: + return TRUE; + break; - case WAIT_TIMEOUT: - return FALSE; - break; + case WAIT_TIMEOUT: + return FALSE; + break; - case WAIT_FAILED: - printf("wf_info_lock failed with 0x%08X\n", GetLastError()); - return -1; - break; + case WAIT_FAILED: + printf("wf_info_lock failed with 0x%08X\n", GetLastError()); + return -1; + break; } return -1; @@ -67,19 +67,19 @@ int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds) switch (dRes) { - case WAIT_ABANDONED: - case WAIT_OBJECT_0: - return TRUE; - break; + case WAIT_ABANDONED: + case WAIT_OBJECT_0: + return TRUE; + break; - case WAIT_TIMEOUT: - return FALSE; - break; + case WAIT_TIMEOUT: + return FALSE; + break; - case WAIT_FAILED: - printf("wf_info_try_lock failed with 0x%08X\n", GetLastError()); - return -1; - break; + case WAIT_FAILED: + printf("wf_info_try_lock failed with 0x%08X\n", GetLastError()); + return -1; + break; } return -1; @@ -100,7 +100,7 @@ wfInfo* wf_info_init() { wfInfo* wfi; -/* + /* OSVERSIONINFOEX osvi; SYSTEM_INFO si; BOOL bOsVersionInfoEx; @@ -175,15 +175,15 @@ wfInfo* wf_info_init() wfi->win8 = FALSE; if(bOsVersionInfoEx != 0 ) { - if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && - osvi.dwMajorVersion > 4 ) - { - if ( osvi.dwMajorVersion == 6 && - osvi.dwMinorVersion == 2) - { - wfi->win8 = TRUE; - } - } + if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && + osvi.dwMajorVersion > 4 ) + { + if ( osvi.dwMajorVersion == 6 && + osvi.dwMinorVersion == 2) + { + wfi->win8 = TRUE; + } + } } */ } @@ -205,7 +205,6 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) { int i; int peerId; - //todo: reject peer if we have WF_INFO_MAXPEERS connected if (wfi->peerCount == WF_INFO_MAXPEERS) { context->socketClose = TRUE; @@ -240,7 +239,7 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) wf_info_unlock(wfi); - wfreerdp_server_peer_connect_event(peerId); + wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_CONNECT); } } @@ -264,7 +263,7 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) wf_info_unlock(wfi); - wfreerdp_server_peer_disconnect_event(peerId); + wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_DISCONNECT); } } diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index 3c7ee3c3b..ff26275e9 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -23,7 +23,7 @@ #include "wf_interface.h" #define WF_INFO_DEFAULT_FPS 24 -#define WF_INFO_MAXPEERS 2 +#define WF_INFO_MAXPEERS 32 int wf_info_lock(wfInfo* wfi); int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds); diff --git a/server/Windows/wf_interface.c b/server/Windows/wf_interface.c index 0ceb46012..4096a1932 100644 --- a/server/Windows/wf_interface.c +++ b/server/Windows/wf_interface.c @@ -3,6 +3,7 @@ * FreeRDP Windows Server * * Copyright 2012 Marc-Andre Moreau + * Copyright 2012 Corey Clayton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +26,8 @@ #include #include #include +#include +//#include #include "wf_peer.h" #include "wf_settings.h" @@ -32,18 +35,7 @@ #include "wf_interface.h" -//todo: remove this -struct rdp_listener -{ - freerdp_listener* instance; - - int sockfds[5]; - int num_sockfds; -}; -// - -cbConEvent cbConnect; -cbConEvent cbDisconnect; +cbCallback cbEvent; DWORD WINAPI wf_server_main_loop(LPVOID lpParam) { @@ -53,7 +45,6 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam) void* rfds[32]; fd_set rfds_set; freerdp_listener* instance; - struct rdp_listener* listener; wfInfo* wfi; wfi = wf_info_get_instance(); @@ -61,9 +52,8 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam) ZeroMemory(rfds, sizeof(rfds)); instance = (freerdp_listener*) lpParam; - listener = (struct rdp_listener*) instance->listener; - while (listener->num_sockfds > 0) + while(wfi->force_all_disconnect == FALSE) { rcount = 0; @@ -151,8 +141,7 @@ wfServer* wfreerdp_server_new() server->port = 3389; } - cbConnect = NULL; - cbDisconnect = NULL; + cbEvent = NULL; return server; } @@ -212,7 +201,7 @@ FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr) } else { - printf("nonexistent peer\n"); + printf("nonexistent peer id=%d\n", pId); return 0; } @@ -293,25 +282,14 @@ FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId) } } -FREERDP_API void wfreerdp_server_register_connect_event(cbConEvent cb) +FREERDP_API void wfreerdp_server_register_callback_event(cbCallback cb) { - cbConnect = cb; + cbEvent = cb; } -FREERDP_API void wfreerdp_server_register_disconnect_event(cbConEvent cb) +void wfreerdp_server_peer_callback_event(int pId, UINT32 eType) { - cbDisconnect = cb; -} - - -void wfreerdp_server_peer_connect_event(int pId) -{ - if (cbConnect) - cbConnect(pId); -} -void wfreerdp_server_peer_disconnect_event(int pId) -{ - if (cbDisconnect) - cbDisconnect(pId); + if (cbEvent) + cbEvent(pId, eType); } diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index 908b48f7a..8cc327712 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -1,21 +1,22 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * FreeRDP Windows Server - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* FreeRDP: A Remote Desktop Protocol Client +* FreeRDP Windows Server +* +* Copyright 2012 Marc-Andre Moreau +* Copyright 2012 Corey Clayton +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifndef WF_INTERFACE_H #define WF_INTERFACE_H @@ -29,6 +30,11 @@ #include #include +#define WF_SRV_CALLBACK_EVENT_CONNECT 1 +#define WF_SRV_CALLBACK_EVENT_DISCONNECT 2 +#define WF_SRV_CALLBACK_EVENT_ACTIVATE 4 +#define WF_SRV_CALLBACK_EVENT_AUTH 8 + typedef struct wf_info wfInfo; typedef struct wf_peer_context wfPeerContext; @@ -86,7 +92,7 @@ struct wf_server }; typedef struct wf_server wfServer; -typedef void (__stdcall* cbConEvent) (int); +typedef void (__stdcall* cbCallback) (int, UINT32); FREERDP_API BOOL wfreerdp_server_start(wfServer* server); FREERDP_API BOOL wfreerdp_server_stop(wfServer* server); @@ -103,10 +109,13 @@ FREERDP_API BOOL wfreerdp_server_peer_is_connected(int pId); FREERDP_API BOOL wfreerdp_server_peer_is_activated(int pId); FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId); -FREERDP_API void wfreerdp_server_register_connect_event(cbConEvent cb); -FREERDP_API void wfreerdp_server_register_disconnect_event(cbConEvent cb); +//FREERDP_API void wfreerdp_server_register_connect_event(cbConEvent cb); +//FREERDP_API void wfreerdp_server_register_disconnect_event(cbConEvent cb); +FREERDP_API void wfreerdp_server_register_callback_event(cbCallback cb); -void wfreerdp_server_peer_connect_event(int pId); -void wfreerdp_server_peer_disconnect_event(int pId); +//void wfreerdp_server_peer_connect_event(int pId); +//void wfreerdp_server_peer_disconnect_event(int pId); + +void wfreerdp_server_peer_callback_event(int pId, UINT32 eType); #endif /* WF_INTERFACE_H */ diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index c519c0222..e6154d0b9 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -1,21 +1,22 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * FreeRDP Windows Server - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* FreeRDP: A Remote Desktop Protocol Client +* FreeRDP Windows Server +* +* Copyright 2012 Marc-Andre Moreau +* Copyright 2012 Corey Clayton +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifdef HAVE_CONFIG_H #include "config.h" @@ -53,7 +54,7 @@ void wf_peer_init(freerdp_peer* client) client->context_size = sizeof(wfPeerContext); client->ContextNew = (psPeerContextNew) wf_peer_context_new; client->ContextFree = (psPeerContextFree) wf_peer_context_free; - + freerdp_peer_context_new(client); } @@ -92,13 +93,15 @@ boolean wf_peer_activate(freerdp_peer* client) { wfInfo* wfi; wfPeerContext* context = (wfPeerContext*) client->context; - + printf("PeerActivate\n"); wfi = context->info; client->activated = true; wf_update_peer_activate(wfi, context); + wfreerdp_server_peer_callback_event(((rdpContext*) context)->peer->pId, WF_SRV_CALLBACK_EVENT_ACTIVATE); + return true; } @@ -112,6 +115,8 @@ boolean wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, b identity->User, identity->Domain, identity->Password); } + + wfreerdp_server_peer_callback_event(((rdpContext*) client->context)->peer->pId, WF_SRV_CALLBACK_EVENT_AUTH); return true; } @@ -162,10 +167,10 @@ DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam) FD_SET(fds, &rfds_set); } - + if (max_fds == 0) break; - + select(max_fds + 1, &rfds_set, NULL, NULL, NULL); SetEvent(context->socketEvent); diff --git a/server/Windows/wf_update.c b/server/Windows/wf_update.c index 1fef2d13b..21454dd96 100644 --- a/server/Windows/wf_update.c +++ b/server/Windows/wf_update.c @@ -1,21 +1,22 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * FreeRDP Windows Server - * - * Copyright 2012 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +* FreeRDP: A Remote Desktop Protocol Client +* FreeRDP Windows Server +* +* Copyright 2012 Marc-Andre Moreau +* Copyright 2012 Corey Clayton +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ #ifdef HAVE_CONFIG_H #include "config.h" @@ -74,7 +75,7 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam) SetEvent(((wfPeerContext*) wfi->peers[index]->context)->updateEvent); } } - + } for (index = 0; index < wfi->activePeerCount; index++) @@ -109,12 +110,12 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam) void wf_update_encode(wfInfo* wfi) { - + RFX_RECT rect; long height, width; uint8* pDataBits = NULL; int stride; - + SURFACE_BITS_COMMAND* cmd; wf_info_find_invalid_region(wfi); @@ -133,7 +134,7 @@ void wf_update_encode(wfInfo* wfi) //printf("x:%d y:%d w:%d h:%d\n", wfi->invalid.left, wfi->invalid.top, width, height); rfx_compose_message(wfi->rfx_context, wfi->s, &rect, 1, - pDataBits, width, height, stride); + pDataBits, width, height, stride); wfi->frame_idx = wfi->rfx_context->frame_idx; @@ -160,10 +161,10 @@ void wf_update_peer_send(wfInfo* wfi, wfPeerContext* context) context->frame_idx = 0; /* - * When a new client connects, it is possible that old frames from - * from a previous encoding state remain. Those frames should be discarded - * as they will cause an error condition in mstsc. - */ + * When a new client connects, it is possible that old frames from + * from a previous encoding state remain. Those frames should be discarded + * as they will cause an error condition in mstsc. + */ if ((context->frame_idx + 1) != wfi->frame_idx) { From 9e2b53a72b3f9a9105e49110c8a7e5dd91a2d9cc Mon Sep 17 00:00:00 2001 From: Corey C Date: Thu, 11 Oct 2012 18:15:34 -0400 Subject: [PATCH 12/14] wfreerdp-server: fixed compilation --- server/Windows/wf_input.c | 8 ++++---- server/Windows/wf_input.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/server/Windows/wf_input.c b/server/Windows/wf_input.c index 56cb6a7cc..7124f2049 100644 --- a/server/Windows/wf_input.c +++ b/server/Windows/wf_input.c @@ -166,18 +166,18 @@ void wf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1 } -void wf_peer_keyboard_event_dummy(rdpInput* input, uint16 flags, uint16 code) +void wf_peer_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code) { } -void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, uint16 flags, uint16 code) +void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code) { } -void wf_peer_mouse_event_dummy(rdpInput* input, uint16 flags, uint16 x, uint16 y) +void wf_peer_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { } -void wf_peer_extended_mouse_event_dummy(rdpInput* input, uint16 flags, uint16 x, uint16 y) +void wf_peer_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { } diff --git a/server/Windows/wf_input.h b/server/Windows/wf_input.h index f6a472dfb..d185f2bf9 100644 --- a/server/Windows/wf_input.h +++ b/server/Windows/wf_input.h @@ -28,9 +28,9 @@ void wf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); void wf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); //dummy versions -void wf_peer_keyboard_event_dummy(rdpInput* input, uint16 flags, uint16 code); -void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, uint16 flags, uint16 code); -void wf_peer_mouse_event_dummy(rdpInput* input, uint16 flags, uint16 x, uint16 y); -void wf_peer_extended_mouse_event_dummy(rdpInput* input, uint16 flags, uint16 x, uint16 y); +void wf_peer_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code); +void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code); +void wf_peer_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); +void wf_peer_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); #endif /* WF_INPUT_H */ From c4960d55f1b375d16b16e668a2f9dad66388e5e3 Mon Sep 17 00:00:00 2001 From: Corey C Date: Fri, 12 Oct 2012 10:37:19 -0400 Subject: [PATCH 13/14] wfreerdp-server: initial rdpsnd support --- server/Windows/CMakeLists.txt | 2 +- server/Windows/wf_rdpsnd.c | 158 ++++++++++++++++++++++++++++++++++ server/Windows/wf_rdpsnd.h | 2 + 3 files changed, 161 insertions(+), 1 deletion(-) diff --git a/server/Windows/CMakeLists.txt b/server/Windows/CMakeLists.txt index 33a5e4650..5f27d4364 100644 --- a/server/Windows/CMakeLists.txt +++ b/server/Windows/CMakeLists.txt @@ -54,7 +54,7 @@ if(WITH_WIN8) endif() -set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-channels-server) +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-channels-server dsound) if(MONOLITHIC_BUILD) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp) diff --git a/server/Windows/wf_rdpsnd.c b/server/Windows/wf_rdpsnd.c index 54ea83c64..da063f50f 100644 --- a/server/Windows/wf_rdpsnd.c +++ b/server/Windows/wf_rdpsnd.c @@ -24,10 +24,27 @@ #include #include +#include +#define CINTERFACE +#include +#include + #include #include "wf_rdpsnd.h" + +/* + * Here are some temp things that shall be moved + * + */ +IDirectSoundCapture8 * cap; +IDirectSoundCaptureBuffer8* capBuf; +DSCBUFFERDESC dscbd; +DWORD capturePos; + +#define BYTESPERSEC 176400 + static const rdpsndFormat test_audio_formats[] = { { 0x11, 2, 22050, 1024, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 2 channels */ @@ -44,7 +61,54 @@ static const rdpsndFormat test_audio_formats[] = static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context) { + HRESULT hr; + + LPDIRECTSOUNDCAPTUREBUFFER pDSCB; + WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, 2, 44100, BYTESPERSEC, 4, 16, 0}; + + printf("RDPSND Activated\n"); + + hr = DirectSoundCaptureCreate8(NULL, &cap, NULL); + + if (FAILED(hr)) + { + _tprintf(_T("Failed to create sound capture device\n")); + return; + } + _tprintf(_T("Created sound capture device\n")); + + dscbd.dwSize = sizeof(DSCBUFFERDESC); + dscbd.dwFlags = 0; + dscbd.dwBufferBytes = BYTESPERSEC; + dscbd.dwReserved = 0; + dscbd.lpwfxFormat = &wfx; + dscbd.dwFXCount = 0; + dscbd.lpDSCFXDesc = NULL; + + hr = cap->lpVtbl->CreateCaptureBuffer(cap, &dscbd, &pDSCB, NULL); + + if (FAILED(hr)) + { + _tprintf(_T("Failed to create capture buffer\n")); + } + _tprintf(_T("Created capture buffer")); + + hr = pDSCB->lpVtbl->QueryInterface(pDSCB, &IID_IDirectSoundCaptureBuffer8, (LPVOID*)&capBuf); + if (FAILED(hr)) + { + _tprintf(_T("Failed to QI capture buffer\n")); + } + _tprintf(_T("Created IDirectSoundCaptureBuffer8\n")); + pDSCB->lpVtbl->Release(pDSCB); + + context->SelectFormat(context, 4); + context->SetVolume(context, 0x7FFF, 0x7FFF); + capturePos = 0; + + CreateThread(NULL, 0, wf_rdpsnd_thread, context, 0, NULL); + + } BOOL wf_peer_rdpsnd_init(wfPeerContext* context) @@ -67,3 +131,97 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context) return TRUE; } + +DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam) +{ + HRESULT hr; + DWORD beg, end; + DWORD diff, rate; + rdpsnd_server_context* context; + + context = (rdpsnd_server_context*)lpParam; + + rate = 1000 / 5; + + _tprintf(_T("Trying to start capture\n")); + hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING); + if (FAILED(hr)) + { + _tprintf(_T("Failed to start capture\n")); + } + _tprintf(_T("Capture started\n")); + + while (1) + { + VOID* pbCaptureData = NULL; + DWORD dwCaptureLength; + VOID* pbCaptureData2 = NULL; + DWORD dwCaptureLength2; + VOID* pbPlayData = NULL; + DWORD dwReadPos; + LONG lLockSize; + beg = GetTickCount(); + + + + hr = capBuf->lpVtbl->GetCurrentPosition(capBuf, NULL, &dwReadPos); + if (FAILED(hr)) + { + _tprintf(_T("Failed to get read pos\n")); + break; + } + + lLockSize = dwReadPos - capturePos;//dscbd.dwBufferBytes; + if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes; + + if (lLockSize == 0) continue; + + hr = capBuf->lpVtbl->Lock(capBuf, capturePos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L); + if (FAILED(hr)) + { + _tprintf(_T("Failed to lock sound capture buffer\n")); + break; + } + + //fwrite(pbCaptureData, 1, dwCaptureLength, pFile); + //fwrite(pbCaptureData2, 1, dwCaptureLength2, pFile); + + //FIXME: frames = bytes/(bytespersample * channels) + + context->SendSamples(context, pbCaptureData, dwCaptureLength/4); + context->SendSamples(context, pbCaptureData2, dwCaptureLength2/4); + + + hr = capBuf->lpVtbl->Unlock(capBuf, pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2); + if (FAILED(hr)) + { + _tprintf(_T("Failed to unlock sound capture buffer\n")); + return 0; + } + + //TODO keep track of location in buffer + capturePos += dwCaptureLength; + capturePos %= dscbd.dwBufferBytes; + capturePos += dwCaptureLength2; + capturePos %= dscbd.dwBufferBytes; + + end = GetTickCount(); + diff = end - beg; + + if (diff < rate) + { + Sleep(rate - diff); + } + } + + _tprintf(_T("Trying to stop sound capture\n")); + hr = capBuf->lpVtbl->Stop(capBuf); + if (FAILED(hr)) + { + _tprintf(_T("Failed to stop capture\n")); + } + _tprintf(_T("Capture stopped\n")); + + + return 0; +} diff --git a/server/Windows/wf_rdpsnd.h b/server/Windows/wf_rdpsnd.h index 0289cd245..482cdcfd8 100644 --- a/server/Windows/wf_rdpsnd.h +++ b/server/Windows/wf_rdpsnd.h @@ -28,5 +28,7 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context); +DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam); + #endif /* WF_RDPSND_H */ From 270a562b773d1bd3711a2ffc2fc06cebafff496c Mon Sep 17 00:00:00 2001 From: Corey C Date: Fri, 12 Oct 2012 21:02:42 -0400 Subject: [PATCH 14/14] wfreerdp-server: fixed crash after disconnect --- server/Windows/wf_interface.h | 3 + server/Windows/wf_peer.c | 6 ++ server/Windows/wf_rdpsnd.c | 160 +++++++++++++++++++++++++--------- server/Windows/wf_rdpsnd.h | 2 + 4 files changed, 128 insertions(+), 43 deletions(-) diff --git a/server/Windows/wf_interface.h b/server/Windows/wf_interface.h index a3b89ef84..e7400010c 100644 --- a/server/Windows/wf_interface.h +++ b/server/Windows/wf_interface.h @@ -57,6 +57,9 @@ struct wf_info BOOL mirrorDriverActive; UINT framesWaiting; + HANDLE snd_mutex; + BOOL snd_stop; + RECT invalid; HANDLE mutex; BOOL updatePending; diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 77ffb53d6..c0216114c 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -51,7 +51,13 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) wf_info_peer_unregister(context->info, context); if (context->rdpsnd) + { + printf("snd_free\n"); + wf_rdpsnd_lock(); + context->info->snd_stop = TRUE; rdpsnd_server_context_free(context->rdpsnd); + wf_rdpsnd_unlock(); + } WTSDestroyVirtualChannelManager(context->vcm); } diff --git a/server/Windows/wf_rdpsnd.c b/server/Windows/wf_rdpsnd.c index da063f50f..8ef5b2775 100644 --- a/server/Windows/wf_rdpsnd.c +++ b/server/Windows/wf_rdpsnd.c @@ -32,7 +32,7 @@ #include #include "wf_rdpsnd.h" - +#include "wf_info.h" /* * Here are some temp things that shall be moved @@ -45,6 +45,9 @@ DWORD capturePos; #define BYTESPERSEC 176400 +//FIXME support multiple clients +wfPeerContext* latestPeer; + static const rdpsndFormat test_audio_formats[] = { { 0x11, 2, 22050, 1024, 4, 0, NULL }, /* IMA ADPCM, 22050 Hz, 2 channels */ @@ -106,13 +109,62 @@ static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context) context->SetVolume(context, 0x7FFF, 0x7FFF); capturePos = 0; - CreateThread(NULL, 0, wf_rdpsnd_thread, context, 0, NULL); + CreateThread(NULL, 0, wf_rdpsnd_thread, latestPeer, 0, NULL); } +int wf_rdpsnd_lock() +{ + DWORD dRes; + wfInfo* wfi; + + wfi = wf_info_get_instance(); + + dRes = WaitForSingleObject(wfi->snd_mutex, INFINITE); + + switch (dRes) + { + case WAIT_ABANDONED: + case WAIT_OBJECT_0: + return TRUE; + break; + + case WAIT_TIMEOUT: + return FALSE; + break; + + case WAIT_FAILED: + printf("wf_rdpsnd_lock failed with 0x%08X\n", GetLastError()); + return -1; + break; + } + + return -1; +} + +int wf_rdpsnd_unlock() +{ + wfInfo* wfi; + + wfi = wf_info_get_instance(); + + if (ReleaseMutex(wfi->snd_mutex) == 0) + { + printf("wf_rdpsnd_unlock failed with 0x%08X\n", GetLastError()); + return -1; + } + + return TRUE; +} + BOOL wf_peer_rdpsnd_init(wfPeerContext* context) { + wfInfo* wfi; + + wfi = wf_info_get_instance(); + + wfi->snd_mutex = CreateMutex(NULL, FALSE, NULL); context->rdpsnd = rdpsnd_server_context_new(context->vcm); context->rdpsnd->data = context; @@ -129,6 +181,8 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context) context->rdpsnd->Initialize(context->rdpsnd); + latestPeer = context; + wfi->snd_stop = FALSE; return TRUE; } @@ -137,10 +191,12 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam) HRESULT hr; DWORD beg, end; DWORD diff, rate; - rdpsnd_server_context* context; + wfPeerContext* context; + wfInfo* wfi; - context = (rdpsnd_server_context*)lpParam; + wfi = wf_info_get_instance(); + context = (wfPeerContext*)lpParam; rate = 1000 / 5; _tprintf(_T("Trying to start capture\n")); @@ -162,49 +218,67 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam) LONG lLockSize; beg = GetTickCount(); + if (wf_rdpsnd_lock() > 0) + { + //check for main exit condition + if (wfi->snd_stop == TRUE) + { + wf_rdpsnd_unlock(); + break; + } + + hr = capBuf->lpVtbl->GetCurrentPosition(capBuf, NULL, &dwReadPos); + if (FAILED(hr)) + { + _tprintf(_T("Failed to get read pos\n")); + wf_rdpsnd_unlock(); + break; + } + + lLockSize = dwReadPos - capturePos;//dscbd.dwBufferBytes; + if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes; + + if (lLockSize == 0) + { + wf_rdpsnd_unlock(); + continue; + } + + + hr = capBuf->lpVtbl->Lock(capBuf, capturePos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L); + if (FAILED(hr)) + { + _tprintf(_T("Failed to lock sound capture buffer\n")); + wf_rdpsnd_unlock(); + break; + } + + //fwrite(pbCaptureData, 1, dwCaptureLength, pFile); + //fwrite(pbCaptureData2, 1, dwCaptureLength2, pFile); + + //FIXME: frames = bytes/(bytespersample * channels) + context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData, dwCaptureLength/4); + context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData2, dwCaptureLength2/4); - hr = capBuf->lpVtbl->GetCurrentPosition(capBuf, NULL, &dwReadPos); - if (FAILED(hr)) - { - _tprintf(_T("Failed to get read pos\n")); - break; + + hr = capBuf->lpVtbl->Unlock(capBuf, pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2); + if (FAILED(hr)) + { + _tprintf(_T("Failed to unlock sound capture buffer\n")); + wf_rdpsnd_unlock(); + return 0; + } + + //TODO keep track of location in buffer + capturePos += dwCaptureLength; + capturePos %= dscbd.dwBufferBytes; + capturePos += dwCaptureLength2; + capturePos %= dscbd.dwBufferBytes; + + wf_rdpsnd_unlock(); } - lLockSize = dwReadPos - capturePos;//dscbd.dwBufferBytes; - if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes; - - if (lLockSize == 0) continue; - - hr = capBuf->lpVtbl->Lock(capBuf, capturePos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L); - if (FAILED(hr)) - { - _tprintf(_T("Failed to lock sound capture buffer\n")); - break; - } - - //fwrite(pbCaptureData, 1, dwCaptureLength, pFile); - //fwrite(pbCaptureData2, 1, dwCaptureLength2, pFile); - - //FIXME: frames = bytes/(bytespersample * channels) - - context->SendSamples(context, pbCaptureData, dwCaptureLength/4); - context->SendSamples(context, pbCaptureData2, dwCaptureLength2/4); - - - hr = capBuf->lpVtbl->Unlock(capBuf, pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2); - if (FAILED(hr)) - { - _tprintf(_T("Failed to unlock sound capture buffer\n")); - return 0; - } - - //TODO keep track of location in buffer - capturePos += dwCaptureLength; - capturePos %= dscbd.dwBufferBytes; - capturePos += dwCaptureLength2; - capturePos %= dscbd.dwBufferBytes; - end = GetTickCount(); diff = end - beg; diff --git a/server/Windows/wf_rdpsnd.h b/server/Windows/wf_rdpsnd.h index 482cdcfd8..d54c4172d 100644 --- a/server/Windows/wf_rdpsnd.h +++ b/server/Windows/wf_rdpsnd.h @@ -26,6 +26,8 @@ #include "wf_interface.h" +int wf_rdpsnd_lock(); +int wf_rdpsnd_unlock(); BOOL wf_peer_rdpsnd_init(wfPeerContext* context); DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam);