From 20c677ddaae0487a3c86bf87a1ccef3e41db1ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Fri, 20 Dec 2013 11:54:18 -0500 Subject: [PATCH 01/16] mac CLI: call freerdp_stop on applicaiton close --- client/Mac/cli/AppDelegate.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/Mac/cli/AppDelegate.m b/client/Mac/cli/AppDelegate.m index 351111b97..2312b8366 100644 --- a/client/Mac/cli/AppDelegate.m +++ b/client/Mac/cli/AppDelegate.m @@ -59,8 +59,13 @@ void mac_set_view_size(rdpContext* context, MRDPView* view); - (void) applicationWillTerminate:(NSNotification*)notification { + NSLog(@"Stopping...\n"); + freerdp_client_stop(context); + [mrdpView releaseResources]; _singleDelegate = nil; + + NSLog(@"Stopped.\n"); } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender From 44e7d2f36cc3ba302e079e12060b8aeee7724ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Fri, 20 Dec 2013 17:56:59 -0500 Subject: [PATCH 02/16] error handling in rpc and transport functions --- libfreerdp/core/gateway/rpc.c | 4 +++- libfreerdp/core/gateway/rpc_bind.c | 6 ++++-- libfreerdp/core/transport.c | 15 ++++++++++----- libfreerdp/crypto/tls.c | 7 ++++++- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libfreerdp/core/gateway/rpc.c b/libfreerdp/core/gateway/rpc.c index 5a3760f35..f58a3a55c 100644 --- a/libfreerdp/core/gateway/rpc.c +++ b/libfreerdp/core/gateway/rpc.c @@ -447,7 +447,9 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) offset += Buffers[1].cbBuffer; free(Buffers[1].pvBuffer); - rpc_send_enqueue_pdu(rpc, buffer, request_pdu->frag_length); + if (rpc_send_enqueue_pdu(rpc, buffer, request_pdu->frag_length) != 0) + length = -1; + free(request_pdu); return length; diff --git a/libfreerdp/core/gateway/rpc_bind.c b/libfreerdp/core/gateway/rpc_bind.c index 108d7ff14..df33de191 100644 --- a/libfreerdp/core/gateway/rpc_bind.c +++ b/libfreerdp/core/gateway/rpc_bind.c @@ -215,7 +215,8 @@ int rpc_send_bind_pdu(rdpRpc* rpc) clientCall = rpc_client_call_new(bind_pdu->call_id, 0); ArrayList_Add(rpc->client->ClientCallList, clientCall); - rpc_send_enqueue_pdu(rpc, buffer, length); + if (rpc_send_enqueue_pdu(rpc, buffer, length) != 0) + length = -1; free(bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes); free(bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes); @@ -330,7 +331,8 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) clientCall = rpc_client_call_new(auth_3_pdu->call_id, 0); ArrayList_Add(rpc->client->ClientCallList, clientCall); - rpc_send_enqueue_pdu(rpc, buffer, length); + if (rpc_send_enqueue_pdu(rpc, buffer, length) != 0) + length = -1; free(auth_3_pdu); diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 567fc169e..aaab6d358 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -82,7 +82,7 @@ BOOL transport_disconnect(rdpTransport* transport) if ((transport->layer == TRANSPORT_LAYER_TSG) || (transport->layer == TRANSPORT_LAYER_TSG_TLS)) { - tsg_disconnect(transport->tsg); + status &= tsg_disconnect(transport->tsg); } else { @@ -129,12 +129,12 @@ static int transport_bio_tsg_write(BIO* bio, const char* buf, int num) BIO_clear_retry_flags(bio); - if (status <= 0) + if (status == 0) { BIO_set_retry_write(bio); } - return num; + return status < 0 ? 0 : num; } static int transport_bio_tsg_read(BIO* bio, char* buf, int size) @@ -147,12 +147,17 @@ static int transport_bio_tsg_read(BIO* bio, char* buf, int size) BIO_clear_retry_flags(bio); - if (status <= 0) + if (status == 0) { BIO_set_retry_read(bio); + status = -1; + } + else if (status == -1) + { + status = 0; } - return status > 0 ? status : -1; + return status >= 0 ? status : -1; } static int transport_bio_tsg_puts(BIO* bio, const char* str) diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 4fe93ee94..6053a292a 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -464,7 +464,12 @@ int tls_write(rdpTls* tls, BYTE* data, int length) status = SSL_write(tls->ssl, data, length); - if (status <= 0) + if (status == 0) + { + return -1; /* peer disconnected */ + } + + if (status < 0) { error = SSL_get_error(tls->ssl, status); From ad4d5c1ce7e79f9007e93ba11bc8e38bcf7396dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Fri, 20 Dec 2013 18:22:29 -0500 Subject: [PATCH 03/16] Added timeout on blocking send, receive operations --- libfreerdp/core/gateway/rpc_client.c | 35 ++++++++++++++++++++++++---- libfreerdp/core/gateway/tsg.c | 6 +++++ libfreerdp/core/transport.c | 20 ++++++++++++---- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 502ea9dad..15e01e382 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -25,6 +25,8 @@ #include #include +#include + #include #include #include @@ -37,6 +39,8 @@ #include "../rdp.h" +#define SYNCHRONOUS_TIMEOUT 5000 + wStream* rpc_client_fragment_pool_take(rdpRpc* rpc) { wStream* fragment = NULL; @@ -360,6 +364,7 @@ void rpc_client_call_free(RpcClientCall* clientCall) int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) { RPC_PDU* pdu; + int status; pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU)); pdu->s = Stream_New(buffer, length); @@ -368,7 +373,13 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) if (rpc->client->SynchronousSend) { - WaitForSingleObject(rpc->client->PduSentEvent, INFINITE); + status = WaitForSingleObject(rpc->client->PduSentEvent, SYNCHRONOUS_TIMEOUT); + if (status == WAIT_TIMEOUT) + { + fprintf(stderr, "rpc_send_enqueue_pdu: timed out waiting for pdu sent event\n"); + return -1; + } + ResetEvent(rpc->client->PduSentEvent); } @@ -425,9 +436,16 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc) DWORD dwMilliseconds; pdu = NULL; - dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0; + dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0; - if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0) + DWORD result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds); + if (result == WAIT_TIMEOUT) + { + fprintf(stderr, "rpc_recv_dequeue_pdu: timed out waiting for receive event\n"); + return NULL; + } + + if (result == WAIT_OBJECT_0) { pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->ReceiveQueue); @@ -450,11 +468,18 @@ RPC_PDU* rpc_recv_peek_pdu(rdpRpc* rpc) { RPC_PDU* pdu; DWORD dwMilliseconds; + DWORD result; pdu = NULL; - dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0; + dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0; - if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0) + result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds); + if (result == WAIT_TIMEOUT) + { + return NULL; + } + + if (result == WAIT_OBJECT_0) { pdu = (RPC_PDU*) Queue_Peek(rpc->client->ReceiveQueue); return pdu; diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index b8bbb552c..aebd6b16e 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -1486,6 +1486,12 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) rpc = tsg->rpc; + if (rpc->transport->layer == TRANSPORT_LAYER_CLOSED) + { + fprintf(stderr, "tsg_read error: connection lost\n"); + return -1; + } + if (tsg->PendingPdu) { CopyLength = (length < tsg->BytesAvailable) ? length : tsg->BytesAvailable; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index aaab6d358..6ff2ce683 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -553,7 +553,11 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes) return status; if (status < 0) + { + /* A read error indicates that the peer has dropped the connection */ + transport->layer = TRANSPORT_LAYER_CLOSED; return status; + } read += status; @@ -1032,13 +1036,19 @@ static void* transport_client_thread(void* arg) transport_get_read_handles(transport, (HANDLE*) &handles, &nCount); - status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE); - - if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0) + status = WaitForMultipleObjects(nCount, handles, FALSE, 100); + if (transport->layer == TRANSPORT_LAYER_CLOSED) + { break; + } + else if (status != WAIT_TIMEOUT) + { + if (WaitForSingleObject(transport->stopEvent, 0) == WAIT_OBJECT_0) + break; - if (!freerdp_check_fds(instance)) - break; + if (!freerdp_check_fds(instance)) + break; + } } WLog_Print(transport->log, WLOG_DEBUG, "Terminating transport thread"); From 3dddce811c71053317a553214b4688a84f2b5dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Fri, 20 Dec 2013 18:23:57 -0500 Subject: [PATCH 04/16] rpc client thread: added periodic check on transport layer state, replacing an infinite wait operation. --- libfreerdp/core/gateway/rpc_client.c | 29 +++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 15e01e382..04f952317 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -505,24 +505,27 @@ static void* rpc_client_thread(void* arg) events[nCount++] = Queue_Event(rpc->client->SendQueue); events[nCount++] = ReadEvent; - while (1) + while (rpc->transport->layer != TRANSPORT_LAYER_CLOSED) { - status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); + status = WaitForMultipleObjects(nCount, events, FALSE, 100); - if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0) + if (status != WAIT_TIMEOUT) { - break; - } - - if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0) - { - if (rpc_client_on_read_event(rpc) < 0) + if (WaitForSingleObject(rpc->client->StopEvent, 0) == WAIT_OBJECT_0) + { break; - } + } - if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0) - { - rpc_send_dequeue_pdu(rpc); + if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0) + { + if (rpc_client_on_read_event(rpc) < 0) + break; + } + + if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0) + { + rpc_send_dequeue_pdu(rpc); + } } } From ac6385448b93a9f7b1136411affba0529fbb2ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Fri, 20 Dec 2013 18:24:29 -0500 Subject: [PATCH 05/16] tsg_write: return error when transport layer is closed --- libfreerdp/core/gateway/tsg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index aebd6b16e..2ae781b00 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -1544,6 +1544,12 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) int tsg_write(rdpTsg* tsg, BYTE* data, UINT32 length) { + if (tsg->rpc->transport->layer == TRANSPORT_LAYER_CLOSED) + { + fprintf(stderr, "tsg_write error: connection lost\n"); + return -1; + } + return TsProxySendToServer((handle_t) tsg, data, 1, &length); } From 70cc837eaf284c185c33f602b34e2c1cad00ce11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Fri, 20 Dec 2013 18:26:07 -0500 Subject: [PATCH 06/16] Transport: trigger OnErrorInfo if a read/write error forced the thread to closed. --- include/freerdp/error.h | 1 + libfreerdp/core/errinfo.c | 4 ++++ libfreerdp/core/rdp.c | 2 ++ libfreerdp/core/rdp.h | 2 ++ libfreerdp/core/transport.c | 3 +++ libfreerdp/core/transport.h | 1 + 6 files changed, 13 insertions(+) diff --git a/include/freerdp/error.h b/include/freerdp/error.h index a5733bb8a..2f284b4f7 100755 --- a/include/freerdp/error.h +++ b/include/freerdp/error.h @@ -146,6 +146,7 @@ extern "C" { #define ERRINFO_ENCRYPT_FAILED 0x00001193 #define ERRINFO_ENCRYPTION_PACKAGE_MISMATCH 0x00001194 #define ERRINFO_DECRYPT_FAILED2 0x00001195 +#define ERRINFO_PEER_DISCONNECTED 0x00001196 #define ERRINFO_SUCCESS 0x00000000 #define ERRINFO_NONE 0xFFFFFFFF diff --git a/libfreerdp/core/errinfo.c b/libfreerdp/core/errinfo.c index ab8550c7d..7096a6e23 100644 --- a/libfreerdp/core/errinfo.c +++ b/libfreerdp/core/errinfo.c @@ -385,6 +385,9 @@ int connectErrorCode; #define ERRINFO_DECRYPT_FAILED2_STRING \ "Unencrypted data was encountered in a protocol stream which is meant to be encrypted with Standard RDP Security mechanisms (section 5.3.6)." +#define ERRINFO_PEER_DISCONNECTED_STRING \ + "The peer connection was lost." + /* Special codes */ #define ERRINFO_SUCCESS_STRING "Success." #define ERRINFO_NONE_STRING "" @@ -507,6 +510,7 @@ static const ERRINFO ERRINFO_CODES[] = ERRINFO_DEFINE(ENCRYPT_FAILED), ERRINFO_DEFINE(ENCRYPTION_PACKAGE_MISMATCH), ERRINFO_DEFINE(DECRYPT_FAILED2), + ERRINFO_DEFINE(PEER_DISCONNECTED), ERRINFO_DEFINE(NONE) }; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 01423bdb7..7ca758b0b 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -1042,6 +1042,7 @@ rdpRdp* rdp_new(rdpContext* context) rdp->extension = extension_new(context->instance); rdp->transport = transport_new(rdp->settings); + rdp->transport->rdp = rdp; rdp->license = license_new(rdp); rdp->input = input_new(rdp); rdp->update = update_new(rdp); @@ -1088,6 +1089,7 @@ void rdp_reset(rdpRdp* rdp) settings->ClientAddress = NULL; rdp->transport = transport_new(rdp->settings); + rdp->transport->rdp = rdp; rdp->license = license_new(rdp); rdp->nego = nego_new(rdp->transport); rdp->mcs = mcs_new(rdp->transport); diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index 9fece7007..ae7a4be27 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -208,4 +208,6 @@ void rdp_free(rdpRdp* rdp); BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags); +BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo); + #endif /* __RDP_H */ diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 6ff2ce683..4134c5dd1 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -46,6 +46,7 @@ #include "tpkt.h" #include "fastpath.h" #include "transport.h" +#include "rdp.h" #define BUFFER_SIZE 16384 @@ -1039,6 +1040,8 @@ static void* transport_client_thread(void* arg) status = WaitForMultipleObjects(nCount, handles, FALSE, 100); if (transport->layer == TRANSPORT_LAYER_CLOSED) { + rdpRdp* rdp = (rdpRdp*) transport->rdp; + rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED); break; } else if (status != WAIT_TIMEOUT) diff --git a/libfreerdp/core/transport.h b/libfreerdp/core/transport.h index 1525b19ee..1ba273f7a 100644 --- a/libfreerdp/core/transport.h +++ b/libfreerdp/core/transport.h @@ -78,6 +78,7 @@ struct rdp_transport CRITICAL_SECTION ReadLock; CRITICAL_SECTION WriteLock; wLog* log; + void* rdp; }; wStream* transport_send_stream_init(rdpTransport* transport, int size); From bb9fa6979d460f5308bd699d8e4cc2ccf3a19236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20LeBlanc?= Date: Wed, 8 Jan 2014 21:02:40 -0500 Subject: [PATCH 07/16] Fix compilation on windows (variable declaration was not in standard C) --- libfreerdp/core/gateway/rpc_client.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 04f952317..fb20fecb6 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -434,11 +434,12 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc) { RPC_PDU* pdu; DWORD dwMilliseconds; + DWORD result; pdu = NULL; dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0; - DWORD result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds); + result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds); if (result == WAIT_TIMEOUT) { fprintf(stderr, "rpc_recv_dequeue_pdu: timed out waiting for receive event\n"); From 018df2a6eecc70c88dfe4d57f3861eb3de424bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20LeBlanc?= Date: Fri, 10 Jan 2014 19:20:27 -0500 Subject: [PATCH 08/16] Only install cli binary if VENDOR is FreeRDP --- client/Windows/cli/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/Windows/cli/CMakeLists.txt b/client/Windows/cli/CMakeLists.txt index 7a0437279..2a5c32e1b 100644 --- a/client/Windows/cli/CMakeLists.txt +++ b/client/Windows/cli/CMakeLists.txt @@ -31,6 +31,8 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} wfreerdp-client) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) +if(VENDOR MATCHES "FreeRDP") + install(TARGETS ${MODULE_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client) +endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Windows") From 6a7e4ba48a4f40edc1ff7acd1b2a4673e7265edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20LeBlanc?= Date: Tue, 14 Jan 2014 11:26:00 -0500 Subject: [PATCH 09/16] Remove CMAKE policy warning --- client/common/CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/common/CMakeLists.txt b/client/common/CMakeLists.txt index 3f1b29780..f05dd53d9 100644 --- a/client/common/CMakeLists.txt +++ b/client/common/CMakeLists.txt @@ -21,6 +21,13 @@ set(MODULE_PREFIX "FREERDP_CLIENT") include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${ZLIB_INCLUDE_DIRS}) +# Policy CMP0022: INTERFACE_LINK_LIBRARIES defines the link +# interface. Run "cmake --help-policy CMP0022" for policy details. Use the +# cmake_policy command to set the policy and suppress this warning. +if(POLICY CMP0022) + cmake_policy(SET CMP0022 NEW) +endif() + set(${MODULE_PREFIX}_SRCS client.c cmdline.c @@ -53,8 +60,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHI MODULE winpr MODULES winpr-crt winpr-utils) -set_target_properties(${MODULE_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "") - target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libraries EXPORT FreeRDPTargets) From b142bd4e4d5a28e1c9872031ce60cc7aee5a5370 Mon Sep 17 00:00:00 2001 From: Benoit LeBlanc Date: Fri, 17 Jan 2014 18:17:10 -0500 Subject: [PATCH 10/16] Added PubSub notification on mouse events (only triggered in Windows) --- client/Windows/wf_event.c | 9 +++++++++ include/freerdp/event.h | 6 ++++++ libfreerdp/core/freerdp.c | 1 + 3 files changed, 16 insertions(+) diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index cb2b952a9..29a729f67 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -31,6 +31,7 @@ #include "wf_gdi.h" #include "wf_event.h" +#include "freerdp/event.h" static HWND g_focus_hWnd; @@ -576,6 +577,8 @@ BOOL wf_scale_blt(wfContext* wfc, HDC hdc, int x, int y, int w, int h, HDC hdcSr void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { int ww, wh, dw, dh; + rdpContext* context; + MouseEventEventArgs eventArgs; if (!wfc->client_width) wfc->client_width = wfc->width; @@ -592,4 +595,10 @@ void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 input->MouseEvent(input, flags, x + wfc->xCurrentScroll, y + wfc->yCurrentScroll); else input->MouseEvent(input, flags, x * dw / ww + wfc->xCurrentScroll, y * dh / wh + wfc->yCurrentScroll); + + eventArgs.flags = flags; + eventArgs.x = x; + eventArgs.y = y; + context = (rdpContext*) wfc; + PubSub_OnMouseEvent(context->pubSub, context, &eventArgs); } diff --git a/include/freerdp/event.h b/include/freerdp/event.h index 633ea79d5..0100d6988 100644 --- a/include/freerdp/event.h +++ b/include/freerdp/event.h @@ -83,6 +83,12 @@ DEFINE_EVENT_BEGIN(ChannelDisconnected) void* pInterface; DEFINE_EVENT_END(ChannelDisconnected) +DEFINE_EVENT_BEGIN(MouseEvent) + UINT16 flags; + UINT16 x; + UINT16 y; +DEFINE_EVENT_END(MouseEvent) + #ifdef __cplusplus } #endif diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 2910a0eff..224a1ad83 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -368,6 +368,7 @@ static wEventType FreeRDP_Events[] = DEFINE_EVENT_ENTRY(ConnectionResult) DEFINE_EVENT_ENTRY(ChannelConnected) DEFINE_EVENT_ENTRY(ChannelDisconnected) + DEFINE_EVENT_ENTRY(MouseEvent) }; /** Allocator function for a rdp context. From 04734d8f37862af93f258a957e3ab7225e12b517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20LeBlanc?= Date: Tue, 4 Feb 2014 11:35:16 -0500 Subject: [PATCH 11/16] ts_add_ms: replaced while() that could result in infinite lock --- winpr/libwinpr/synch/wait.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 017d59353..abc932bb5 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -155,11 +155,8 @@ static void ts_add_ms(struct timespec *ts, DWORD dwMilliseconds) ts->tv_sec += dwMilliseconds / 1000L; ts->tv_nsec += (dwMilliseconds % 1000L) * 1000000L; - while(ts->tv_nsec >= 1000000000L) - { - ts->tv_sec ++; - ts->tv_nsec -= 1000000000L; - } + ts->tv_sec += ts->tv_nsec / 1000000000L; + ts->tv_nsec = ts->tv_nsec % 1000000000L; } DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) From e6efe7c6784f71de43344bd43413a8f3e3cbed60 Mon Sep 17 00:00:00 2001 From: vworkspace Date: Fri, 7 Feb 2014 13:16:41 -0500 Subject: [PATCH 12/16] Added creation of rdpei events and added processing of received 'suspend/resume touches' event from the server in the rdpei plugin. --- channels/rdpei/client/rdpei_main.c | 43 +++++++++++++++++++++++++-- libfreerdp/utils/event.c | 47 ++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index b332cec5e..0bd813900 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -35,6 +35,7 @@ #include #include +#include #include "rdpei_common.h" @@ -118,6 +119,20 @@ const char* RDPEI_EVENTID_STRINGS[] = "EVENTID_DISMISS_HOVERING_CONTACT" }; +BOOL rdpei_push_event(RDPEI_CHANNEL_CALLBACK* callback, wMessage* event) +{ + int status; + + status = callback->channel_mgr->PushEvent(callback->channel_mgr, event); + + if (status) + { + DEBUG_WARN("response error %d", status); + return FALSE; + } + + return TRUE; +} int rdpei_add_frame(RdpeiClientContext* context) { int i; @@ -379,11 +394,35 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) int rdpei_recv_suspend_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) { + wMessage* event; + BOOL status; + + event = freerdp_event_new(RdpeiChannel_Class, RdpeiChannel_SuspendTouch, NULL, NULL); + + status = rdpei_push_event(callback, event); + + if (!status) + { + return -1; + } + return 0; } int rdpei_recv_resume_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) { + wMessage* event; + BOOL status; + + event = freerdp_event_new(RdpeiChannel_Class, RdpeiChannel_ResumeTouch, NULL, NULL); + + status = rdpei_push_event(callback, event); + + if (!status) + { + return -1; + } + return 0; } @@ -490,7 +529,7 @@ static int rdpei_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManage (IWTSListenerCallback*) rdpei->listener_callback, &(rdpei->listener)); rdpei->listener->pInterface = rdpei->iface.pInterface; - + InitializeCriticalSection(&rdpei->lock); rdpei->event = CreateEvent(NULL, TRUE, FALSE, NULL); rdpei->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -675,7 +714,7 @@ int rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y) int i; int contactId = -1; RDPINPUT_CONTACT_DATA contact; - RDPINPUT_CONTACT_POINT* contactPoint; + RDPINPUT_CONTACT_POINT* contactPoint = NULL; RDPEI_PLUGIN* rdpei = (RDPEI_PLUGIN*) context->handle; for (i = 0; i < rdpei->maxTouchContacts; i++) diff --git a/libfreerdp/utils/event.c b/libfreerdp/utils/event.c index 738aa1c29..7a8042ef4 100644 --- a/libfreerdp/utils/event.c +++ b/libfreerdp/utils/event.c @@ -73,6 +73,30 @@ static wMessage* freerdp_cliprdr_event_new(UINT16 event_type) ZeroMemory(event.v, sizeof(RDP_CB_CLIP_CAPS)); event.m->id = MakeMessageId(CliprdrChannel, ClipCaps); break; + + case CliprdrChannel_FileContentsRequest: + event.v = malloc(sizeof(RDP_CB_FILE_CONTENTS_REQUEST_EVENT)); + ZeroMemory(event.v, sizeof(RDP_CB_FILE_CONTENTS_REQUEST_EVENT)); + event.m->id = MakeMessageId(CliprdrChannel, FileContentsRequest); + break; + + case CliprdrChannel_FileContentsResponse: + event.v = malloc(sizeof(RDP_CB_FILE_CONTENTS_RESPONSE_EVENT)); + ZeroMemory(event.v, sizeof(RDP_CB_FILE_CONTENTS_RESPONSE_EVENT)); + event.m->id = MakeMessageId(CliprdrChannel, FileContentsResponse); + break; + + case CliprdrChannel_Capabilities: + event.v = malloc(sizeof(RDP_CB_CAPS_EVENT)); + ZeroMemory(event.v, sizeof(RDP_CB_CAPS_EVENT)); + event.m->id = MakeMessageId(CliprdrChannel, Capabilities); + break; + + case CliprdrChannel_TemporaryDirectory: + event.v = malloc(sizeof(RDP_CB_TEMPORARY_DIRECTORY_EVENT)); + ZeroMemory(event.v, sizeof(RDP_CB_TEMPORARY_DIRECTORY_EVENT)); + event.m->id = MakeMessageId(CliprdrChannel, TemporaryDirectory); + break; } return event.v; @@ -115,6 +139,16 @@ static wMessage* freerdp_rail_event_new(UINT16 event_type) return event; } +static wMessage* freerdp_rdpei_event_new(UINT16 event_type) +{ + wMessage* event; + + event = (wMessage*) malloc(sizeof(wMessage)); + ZeroMemory(event, sizeof(wMessage)); + + return event; +} + wMessage* freerdp_event_new(UINT16 event_class, UINT16 event_type, MESSAGE_FREE_FN on_event_free_callback, void* user_data) { @@ -138,6 +172,10 @@ wMessage* freerdp_event_new(UINT16 event_class, UINT16 event_type, case RailChannel_Class: event = freerdp_rail_event_new(event_type); break; + + case RdpeiChannel_Class: + event = freerdp_rdpei_event_new(event_type); + break; } if (event) @@ -190,6 +228,11 @@ static void freerdp_rail_event_free(wMessage* event) } +static void freerdp_rdpei_event_free(wMessage* event) +{ + +} + void freerdp_event_free(wMessage* event) { if (event) @@ -210,6 +253,10 @@ void freerdp_event_free(wMessage* event) case RailChannel_Class: freerdp_rail_event_free(event); break; + + case RdpeiChannel_Class: + freerdp_rdpei_event_free(event); + break; } free(event); From 914a54f1fdd51381e6a9f656bdd81a38d9e8df88 Mon Sep 17 00:00:00 2001 From: vworkspace Date: Fri, 7 Feb 2014 16:21:20 -0500 Subject: [PATCH 13/16] Removed code corresponding to new cliprdr events. A separate pull request will be issued to request a merge of new cliprdr features. --- libfreerdp/utils/event.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/libfreerdp/utils/event.c b/libfreerdp/utils/event.c index 7a8042ef4..cc450a20e 100644 --- a/libfreerdp/utils/event.c +++ b/libfreerdp/utils/event.c @@ -73,30 +73,6 @@ static wMessage* freerdp_cliprdr_event_new(UINT16 event_type) ZeroMemory(event.v, sizeof(RDP_CB_CLIP_CAPS)); event.m->id = MakeMessageId(CliprdrChannel, ClipCaps); break; - - case CliprdrChannel_FileContentsRequest: - event.v = malloc(sizeof(RDP_CB_FILE_CONTENTS_REQUEST_EVENT)); - ZeroMemory(event.v, sizeof(RDP_CB_FILE_CONTENTS_REQUEST_EVENT)); - event.m->id = MakeMessageId(CliprdrChannel, FileContentsRequest); - break; - - case CliprdrChannel_FileContentsResponse: - event.v = malloc(sizeof(RDP_CB_FILE_CONTENTS_RESPONSE_EVENT)); - ZeroMemory(event.v, sizeof(RDP_CB_FILE_CONTENTS_RESPONSE_EVENT)); - event.m->id = MakeMessageId(CliprdrChannel, FileContentsResponse); - break; - - case CliprdrChannel_Capabilities: - event.v = malloc(sizeof(RDP_CB_CAPS_EVENT)); - ZeroMemory(event.v, sizeof(RDP_CB_CAPS_EVENT)); - event.m->id = MakeMessageId(CliprdrChannel, Capabilities); - break; - - case CliprdrChannel_TemporaryDirectory: - event.v = malloc(sizeof(RDP_CB_TEMPORARY_DIRECTORY_EVENT)); - ZeroMemory(event.v, sizeof(RDP_CB_TEMPORARY_DIRECTORY_EVENT)); - event.m->id = MakeMessageId(CliprdrChannel, TemporaryDirectory); - break; } return event.v; From 1daea0d0dc9eb63b6bb1e525e49de82800d34751 Mon Sep 17 00:00:00 2001 From: Mike McDonald Date: Mon, 10 Mar 2014 15:35:14 -0400 Subject: [PATCH 14/16] Modified transport_check_fds to deliver all available PDUs before returning to the caller. This prevents the caller from waiting indefinitely for a socket to get signalled that data is available. It fixes a problem with Microsoft mobile clients connecting to FreeRDS whereby the client places both the MCS Erect Domain and MCS Attach User PDUs into the same ethernet frame. As a result, FreeRDS was only processing the first PDU and then blocking indefinitely waiting for data to arrive on the socket. --- libfreerdp/core/transport.c | 222 +++++++++++++++++++----------------- 1 file changed, 116 insertions(+), 106 deletions(-) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index f0fe28d50..b5d6efe19 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -853,115 +853,125 @@ int transport_check_fds(rdpTransport* transport) #endif ResetEvent(transport->ReceiveEvent); - status = transport_read_nonblocking(transport); - - if (status < 0) - return status; - - while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0) + /** + * Loop through and read all available PDUs. Since multiple + * PDUs can exist, it's important to deliver them all before + * returning. Otherwise we run the risk of having a thread + * wait for a socket to get signalled that data is available + * (which may never happen). + */ + for (;;) { - Stream_SetPosition(transport->ReceiveBuffer, 0); + status = transport_read_nonblocking(transport); - if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */ - { - /* Ensure the TPKT header is available. */ - if (pos <= 4) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - length = tpkt_read_header(transport->ReceiveBuffer); - } - else if (nla_verify_header(transport->ReceiveBuffer)) - { - /* TSRequest */ - - /* Ensure the TSRequest header is available. */ - if (pos <= 4) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - /* TSRequest header can be 2, 3 or 4 bytes long */ - length = nla_header_length(transport->ReceiveBuffer); - - if (pos < length) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - length = nla_read_header(transport->ReceiveBuffer); - } - else /* Fast Path */ - { - /* Ensure the Fast Path header is available. */ - if (pos <= 2) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - /* Fastpath header can be two or three bytes long. */ - length = fastpath_header_length(transport->ReceiveBuffer); - - if (pos < length) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; - } - - length = fastpath_read_header(NULL, transport->ReceiveBuffer); - } - - if (length == 0) - { - fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); - winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos); - return -1; - } - - if (pos < length) - { - Stream_SetPosition(transport->ReceiveBuffer, pos); - return 0; /* Packet is not yet completely received. */ - } - - received = transport->ReceiveBuffer; - transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0); - - Stream_SetPosition(received, length); - Stream_SealLength(received); - Stream_SetPosition(received, 0); - - /** - * status: - * -1: error - * 0: success - * 1: redirection - */ - - recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); - - if (recv_status == 1) - { - /** - * Last call to ReceiveCallback resulted in a session redirection, - * which means the current rdpTransport* transport pointer has been freed. - * Return 0 for success, the rest of this function is meant for non-redirected cases. - */ - return 0; - } - - Stream_Release(received); - - if (recv_status < 0) - status = -1; - - if (status < 0) + if (status <= 0) return status; + + while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0) + { + Stream_SetPosition(transport->ReceiveBuffer, 0); + + if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */ + { + /* Ensure the TPKT header is available. */ + if (pos <= 4) + { + Stream_SetPosition(transport->ReceiveBuffer, pos); + return 0; + } + + length = tpkt_read_header(transport->ReceiveBuffer); + } + else if (nla_verify_header(transport->ReceiveBuffer)) + { + /* TSRequest */ + + /* Ensure the TSRequest header is available. */ + if (pos <= 4) + { + Stream_SetPosition(transport->ReceiveBuffer, pos); + return 0; + } + + /* TSRequest header can be 2, 3 or 4 bytes long */ + length = nla_header_length(transport->ReceiveBuffer); + + if (pos < length) + { + Stream_SetPosition(transport->ReceiveBuffer, pos); + return 0; + } + + length = nla_read_header(transport->ReceiveBuffer); + } + else /* Fast Path */ + { + /* Ensure the Fast Path header is available. */ + if (pos <= 2) + { + Stream_SetPosition(transport->ReceiveBuffer, pos); + return 0; + } + + /* Fastpath header can be two or three bytes long. */ + length = fastpath_header_length(transport->ReceiveBuffer); + + if (pos < length) + { + Stream_SetPosition(transport->ReceiveBuffer, pos); + return 0; + } + + length = fastpath_read_header(NULL, transport->ReceiveBuffer); + } + + if (length == 0) + { + fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); + winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos); + return -1; + } + + if (pos < length) + { + Stream_SetPosition(transport->ReceiveBuffer, pos); + return 0; /* Packet is not yet completely received. */ + } + + received = transport->ReceiveBuffer; + transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0); + + Stream_SetPosition(received, length); + Stream_SealLength(received); + Stream_SetPosition(received, 0); + + /** + * status: + * -1: error + * 0: success + * 1: redirection + */ + + recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); + + if (recv_status == 1) + { + /** + * Last call to ReceiveCallback resulted in a session redirection, + * which means the current rdpTransport* transport pointer has been freed. + * Return 0 for success, the rest of this function is meant for non-redirected cases. + */ + return 0; + } + + Stream_Release(received); + + if (recv_status < 0) + status = -1; + + if (status < 0) + return status; + } } return 0; From 3808705652bcf7405d497fb7398dd4e4158e8f04 Mon Sep 17 00:00:00 2001 From: Martin Haimberger Date: Tue, 11 Mar 2014 06:34:41 -0700 Subject: [PATCH 15/16] WriteFile and ReadFile does not check for INVALID_HANDLE_VALUE --- winpr/libwinpr/file/file.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 7d8fb3ab0..95a71887f 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -311,6 +311,10 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, PVOID Object; BOOL status = TRUE; + if (hFile == INVALID_HANDLE_VALUE) { + return FALSE; + } + /* * from http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx * lpNumberOfBytesRead can be NULL only when the lpOverlapped parameter is not NULL. @@ -464,6 +468,10 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, PVOID Object; BOOL status = TRUE; + if (hFile == INVALID_HANDLE_VALUE) { + return FALSE; + } + if (!winpr_Handle_GetInfo(hFile, &Type, &Object)) return FALSE; From b245dea4a80306b84bc8a875444e47fe76cde64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 11 Mar 2014 11:55:38 -0400 Subject: [PATCH 16/16] channels/rdpei: make use of callback interface for Suspend/Resume touch events --- channels/rdpei/client/rdpei_main.c | 41 +++++------------------------- include/freerdp/client/rdpei.h | 6 +++++ libfreerdp/utils/event.c | 23 ----------------- 3 files changed, 12 insertions(+), 58 deletions(-) diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 08ba4bca4..d0b17377d 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -35,7 +35,6 @@ #include #include -#include #include "rdpei_common.h" @@ -119,20 +118,6 @@ const char* RDPEI_EVENTID_STRINGS[] = "EVENTID_DISMISS_HOVERING_CONTACT" }; -BOOL rdpei_push_event(RDPEI_CHANNEL_CALLBACK* callback, wMessage* event) -{ - int status; - - status = callback->channel_mgr->PushEvent(callback->channel_mgr, event); - - if (status) - { - DEBUG_WARN("response error %d", status); - return FALSE; - } - - return TRUE; -} int rdpei_add_frame(RdpeiClientContext* context) { int i; @@ -394,34 +379,20 @@ int rdpei_recv_sc_ready_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) int rdpei_recv_suspend_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) { - wMessage* event; - BOOL status; + RdpeiClientContext* rdpei = (RdpeiClientContext*) callback->plugin->pInterface; - event = freerdp_event_new(RdpeiChannel_Class, RdpeiChannel_SuspendTouch, NULL, NULL); - - status = rdpei_push_event(callback, event); - - if (!status) - { - return -1; - } + if (rdpei->SuspendTouch) + rdpei->SuspendTouch(rdpei); return 0; } int rdpei_recv_resume_touch_pdu(RDPEI_CHANNEL_CALLBACK* callback, wStream* s) { - wMessage* event; - BOOL status; + RdpeiClientContext* rdpei = (RdpeiClientContext*) callback->plugin->pInterface; - event = freerdp_event_new(RdpeiChannel_Class, RdpeiChannel_ResumeTouch, NULL, NULL); - - status = rdpei_push_event(callback, event); - - if (!status) - { - return -1; - } + if (rdpei->ResumeTouch) + rdpei->ResumeTouch(rdpei); return 0; } diff --git a/include/freerdp/client/rdpei.h b/include/freerdp/client/rdpei.h index d7881b11c..76b889829 100644 --- a/include/freerdp/client/rdpei.h +++ b/include/freerdp/client/rdpei.h @@ -70,6 +70,9 @@ typedef int (*pcRdpeiTouchBegin)(RdpeiClientContext* context, int externalId, in typedef int (*pcRdpeiTouchUpdate)(RdpeiClientContext* context, int externalId, int x, int y); typedef int (*pcRdpeiTouchEnd)(RdpeiClientContext* context, int externalId, int x, int y); +typedef int (*pcRdpeiSuspendTouch)(RdpeiClientContext* context); +typedef int (*pcRdpeiResumeTouch)(RdpeiClientContext* context); + struct _rdpei_client_context { void* handle; @@ -82,6 +85,9 @@ struct _rdpei_client_context pcRdpeiTouchBegin TouchBegin; pcRdpeiTouchUpdate TouchUpdate; pcRdpeiTouchEnd TouchEnd; + + pcRdpeiSuspendTouch SuspendTouch; + pcRdpeiResumeTouch ResumeTouch; }; #endif /* FREERDP_CHANNEL_CLIENT_RDPEI_H */ diff --git a/libfreerdp/utils/event.c b/libfreerdp/utils/event.c index 003736058..d8cd80d80 100644 --- a/libfreerdp/utils/event.c +++ b/libfreerdp/utils/event.c @@ -146,16 +146,6 @@ static wMessage* freerdp_rail_event_new(UINT16 event_type) return event; } -static wMessage* freerdp_rdpei_event_new(UINT16 event_type) -{ - wMessage* event; - - event = (wMessage*) malloc(sizeof(wMessage)); - ZeroMemory(event, sizeof(wMessage)); - - return event; -} - wMessage* freerdp_event_new(UINT16 event_class, UINT16 event_type, MESSAGE_FREE_FN on_event_free_callback, void* user_data) { @@ -179,10 +169,6 @@ wMessage* freerdp_event_new(UINT16 event_class, UINT16 event_type, case RailChannel_Class: event = freerdp_rail_event_new(event_type); break; - - case RdpeiChannel_Class: - event = freerdp_rdpei_event_new(event_type); - break; } if (event) @@ -235,11 +221,6 @@ static void freerdp_rail_event_free(wMessage* event) } -static void freerdp_rdpei_event_free(wMessage* event) -{ - -} - void freerdp_event_free(wMessage* event) { if (event) @@ -260,10 +241,6 @@ void freerdp_event_free(wMessage* event) case RailChannel_Class: freerdp_rail_event_free(event); break; - - case RdpeiChannel_Class: - freerdp_rdpei_event_free(event); - break; } free(event);