diff --git a/client/Sample/freerdp.c b/client/Sample/freerdp.c index 1cc8ae6f3..01eb8d3ae 100644 --- a/client/Sample/freerdp.c +++ b/client/Sample/freerdp.c @@ -135,7 +135,13 @@ static void* tf_client_thread_proc(freerdp* instance) while (!freerdp_shall_disconnect(instance)) { - nCount = freerdp_get_event_handles(instance->context, &handles[0]); + nCount = freerdp_get_event_handles(instance->context, &handles[0], 64); + + if (nCount == 0) + { + WLog_ERR(TAG, "%s: freerdp_get_event_handles failed", __FUNCTION__); + break; + } status = WaitForMultipleObjects(nCount, handles, FALSE, 100); diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index 6c1f9a49c..f8dea65b3 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -682,7 +682,15 @@ DWORD WINAPI wf_client_thread(LPVOID lpParam) if (!async_transport) { - nCount += freerdp_get_event_handles(context, &handles[nCount]); + DWORD tmp = freerdp_get_event_handles(context, &handles[nCount], 64 - nCount); + + if (tmp == 0) + { + WLog_ERR(TAG, "freerdp_get_event_handles failed"); + break; + } + + nCount += tmp; } if (MsgWaitForMultipleObjects(nCount, handles, FALSE, 1000, QS_ALLINPUT) == WAIT_FAILED) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index d581ef1f3..2c73526fb 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1447,7 +1447,15 @@ void* xf_client_thread(void* param) if (!settings->AsyncTransport) { - nCount += freerdp_get_event_handles(context, &handles[nCount]); + DWORD tmp = freerdp_get_event_handles(context, &handles[nCount], 64 - nCount); + + if (tmp == 0) + { + WLog_ERR(TAG, "freerdp_get_event_handles failed"); + break; + } + + nCount += tmp; } waitStatus = WaitForMultipleObjects(nCount, handles, FALSE, 100); diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 3d6a79ded..1fbea1f6f 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -248,7 +248,7 @@ FREERDP_API BOOL freerdp_reconnect(freerdp* instance); FREERDP_API BOOL freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount); FREERDP_API BOOL freerdp_check_fds(freerdp* instance); -FREERDP_API UINT32 freerdp_get_event_handles(rdpContext* context, HANDLE* events); +FREERDP_API DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count); FREERDP_API BOOL freerdp_check_event_handles(rdpContext* context); FREERDP_API wMessageQueue* freerdp_get_message_queue(freerdp* instance, DWORD id); diff --git a/include/freerdp/listener.h b/include/freerdp/listener.h index 9ae1156d6..e7e73f988 100644 --- a/include/freerdp/listener.h +++ b/include/freerdp/listener.h @@ -34,7 +34,7 @@ extern "C" { typedef BOOL (*psListenerOpen)(freerdp_listener* instance, const char* bind_address, UINT16 port); typedef BOOL (*psListenerOpenLocal)(freerdp_listener* instance, const char* path); typedef BOOL (*psListenerGetFileDescriptor)(freerdp_listener* instance, void** rfds, int* rcount); -typedef int (*psListenerGetEventHandles)(freerdp_listener* instance, HANDLE* events, DWORD* nCount); +typedef DWORD (*psListenerGetEventHandles)(freerdp_listener* instance, HANDLE* events, DWORD nCount); typedef BOOL (*psListenerCheckFileDescriptor)(freerdp_listener* instance); typedef void (*psListenerClose)(freerdp_listener* instance); typedef void (*psPeerAccepted)(freerdp_listener* instance, freerdp_peer* client); diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 42e52c8ab..65b25013f 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -222,15 +222,19 @@ BOOL freerdp_check_fds(freerdp* instance) return TRUE; } -UINT32 freerdp_get_event_handles(rdpContext* context, HANDLE* events) +DWORD freerdp_get_event_handles(rdpContext* context, HANDLE* events, DWORD count) { - UINT32 nCount = 0; + DWORD nCount = 0; - nCount += transport_get_event_handles(context->rdp->transport, events); + nCount += transport_get_event_handles(context->rdp->transport, events, count); - if (events) - events[nCount] = freerdp_channels_get_event_handle(context->instance); - nCount++; + if (nCount == 0) + return 0; + + if (events && (nCount < count)) + events[nCount++] = freerdp_channels_get_event_handle(context->instance); + else + return 0; return nCount; } diff --git a/libfreerdp/core/gateway/rdg.c b/libfreerdp/core/gateway/rdg.c index d977f11f9..4682e995f 100644 --- a/libfreerdp/core/gateway/rdg.c +++ b/libfreerdp/core/gateway/rdg.c @@ -686,28 +686,37 @@ BOOL rdg_in_channel_recv(rdpRdg* rdg) return status; } -UINT32 rdg_get_event_handles(rdpRdg* rdg, HANDLE* events) +DWORD rdg_get_event_handles(rdpRdg* rdg, HANDLE* events, DWORD count) { - UINT32 nCount = 0; + DWORD nCount = 0; assert(rdg != NULL); - if (events) - events[nCount] = rdg->readEvent; - nCount++; + if (events && (nCount < count)) + events[nCount++] = rdg->readEvent; + else + return 0; if (rdg->tlsOut && rdg->tlsOut->bio) { - if (events) + if (events && (nCount < count)) + { BIO_get_event(rdg->tlsOut->bio, &events[nCount]); - nCount++; + nCount++; + } + else + return 0; } if (rdg->tlsIn && rdg->tlsIn->bio) { - if (events) + if (events && (nCount < count)) + { BIO_get_event(rdg->tlsIn->bio, &events[nCount]); - nCount++; + nCount++; + } + else + return 0; } return nCount; @@ -964,7 +973,7 @@ BOOL rdg_tls_in_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int time BOOL rdg_out_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout) { BOOL status; - UINT32 nCount; + DWORD nCount; HANDLE events[8]; assert(hostname != NULL); @@ -979,7 +988,10 @@ BOOL rdg_out_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int if (!status) return FALSE; - nCount = rdg_get_event_handles(rdg, events); + nCount = rdg_get_event_handles(rdg, events, 8); + + if (nCount == 0) + return FALSE; while (rdg->state <= RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZE) { @@ -999,7 +1011,7 @@ BOOL rdg_out_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int BOOL rdg_in_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout) { BOOL status; - UINT32 nCount; + DWORD nCount; HANDLE events[8]; assert(hostname != NULL); @@ -1014,7 +1026,10 @@ BOOL rdg_in_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int if (!status) return FALSE; - nCount = rdg_get_event_handles(rdg, events); + nCount = rdg_get_event_handles(rdg, events, 8); + + if (nCount == 0) + return FALSE; while (rdg->state <= RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZE) { @@ -1034,12 +1049,15 @@ BOOL rdg_in_channel_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int BOOL rdg_tunnel_connect(rdpRdg* rdg) { BOOL status; - UINT32 nCount; + DWORD nCount; HANDLE events[8]; rdg_send_handshake(rdg); - nCount = rdg_get_event_handles(rdg, events); + nCount = rdg_get_event_handles(rdg, events, 8); + + if (nCount == 0) + return FALSE; while (rdg->state < RDG_CLIENT_STATE_OPENED) { diff --git a/libfreerdp/core/gateway/rdg.h b/libfreerdp/core/gateway/rdg.h index e6838576d..d4e670a0c 100644 --- a/libfreerdp/core/gateway/rdg.h +++ b/libfreerdp/core/gateway/rdg.h @@ -146,7 +146,7 @@ rdpRdg* rdg_new(rdpTransport* transport); void rdg_free(rdpRdg* rdg); BOOL rdg_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout); -UINT32 rdg_get_event_handles(rdpRdg* rdg, HANDLE* events); +DWORD rdg_get_event_handles(rdpRdg* rdg, HANDLE* events, DWORD count); BOOL rdg_check_event_handles(rdpRdg* rdg); diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 7af675b8e..9a40eb856 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -1625,42 +1625,62 @@ int tsg_check_event_handles(rdpTsg* tsg) return status; } -UINT32 tsg_get_event_handles(rdpTsg* tsg, HANDLE* events) +DWORD tsg_get_event_handles(rdpTsg* tsg, HANDLE* events, DWORD count) { UINT32 nCount = 0; rdpRpc* rpc = tsg->rpc; RpcVirtualConnection* connection = rpc->VirtualConnection; - if (events) + if (events && (nCount < count)) + { events[nCount] = rpc->client->PipeEvent; - nCount++; + nCount++; + } + else + return 0; if (connection->DefaultInChannel && connection->DefaultInChannel->tls) { - if (events) + if (events && (nCount < count)) + { BIO_get_event(connection->DefaultInChannel->tls->bio, &events[nCount]); - nCount++; + nCount++; + } + else + return 0; } if (connection->NonDefaultInChannel && connection->NonDefaultInChannel->tls) { - if (events) + if (events && (nCount < count)) + { BIO_get_event(connection->NonDefaultInChannel->tls->bio, &events[nCount]); - nCount++; + nCount++; + } + else + return 0; } if (connection->DefaultOutChannel && connection->DefaultOutChannel->tls) { - if (events) + if (events && (nCount < count)) + { BIO_get_event(connection->DefaultOutChannel->tls->bio, &events[nCount]); - nCount++; + nCount++; + } + else + return 0; } if (connection->NonDefaultOutChannel && connection->NonDefaultOutChannel->tls) { - if (events) + if (events && (nCount < count)) + { BIO_get_event(connection->NonDefaultOutChannel->tls->bio, &events[nCount]); - nCount++; + nCount++; + } + else + return 0; } return nCount; @@ -1716,7 +1736,10 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port, int timeout) inChannel = connection->DefaultInChannel; outChannel = connection->DefaultOutChannel; - nCount = tsg_get_event_handles(tsg, events); + nCount = tsg_get_event_handles(tsg, events, 64); + + if (nCount == 0) + return FALSE; while (tsg->state != TSG_STATE_PIPE_CREATED) { diff --git a/libfreerdp/core/gateway/tsg.h b/libfreerdp/core/gateway/tsg.h index 8424e001d..b0ec14744 100644 --- a/libfreerdp/core/gateway/tsg.h +++ b/libfreerdp/core/gateway/tsg.h @@ -324,7 +324,7 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length); int tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu); int tsg_check_event_handles(rdpTsg* tsg); -UINT32 tsg_get_event_handles(rdpTsg* tsg, HANDLE* events); +DWORD tsg_get_event_handles(rdpTsg* tsg, HANDLE* events, DWORD count); rdpTsg* tsg_new(rdpTransport* transport); void tsg_free(rdpTsg* tsg); diff --git a/libfreerdp/core/listener.c b/libfreerdp/core/listener.c index 88be8ed54..b38e54fb0 100644 --- a/libfreerdp/core/listener.c +++ b/libfreerdp/core/listener.c @@ -255,21 +255,23 @@ static BOOL freerdp_listener_get_fds(freerdp_listener* instance, void** rfds, in return TRUE; } -int freerdp_listener_get_event_handles(freerdp_listener* instance, HANDLE* events, DWORD* nCount) +DWORD freerdp_listener_get_event_handles(freerdp_listener* instance, HANDLE* events, DWORD nCount) { int index; rdpListener* listener = (rdpListener*) instance->listener; if (listener->num_sockfds < 1) - return -1; + return 0; + + if (listener->num_sockfds > nCount) + return 0; for (index = 0; index < listener->num_sockfds; index++) { - events[*nCount] = listener->events[index]; - (*nCount)++; + events[index] = listener->events[index]; } - return 0; + return listener->num_sockfds; } static BOOL freerdp_listener_check_fds(freerdp_listener* instance) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 23f776438..47b8a90be 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -656,25 +656,38 @@ out_cleanup: return status; } -UINT32 transport_get_event_handles(rdpTransport* transport, HANDLE* events) +DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events, DWORD count) { - UINT32 nCount = 0; + DWORD nCount = 0; + DWORD tmp; if (!transport->GatewayEnabled) { - if (events) + if (events && (nCount < count)) + { BIO_get_event(transport->frontBio, &events[nCount]); - nCount++; + nCount++; + } } else { if (transport->rdg) { - nCount += rdg_get_event_handles(transport->rdg, events); + tmp = rdg_get_event_handles(transport->rdg, events, nCount - count); + + if (tmp == 0) + return 0; + + nCount = tmp; } else if (transport->tsg) { - nCount += tsg_get_event_handles(transport->tsg, events); + tmp = tsg_get_event_handles(transport->tsg, events, nCount - count); + + if (tmp == 0) + return 0; + + nCount = tmp; } } @@ -683,16 +696,17 @@ UINT32 transport_get_event_handles(rdpTransport* transport, HANDLE* events) void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount) { - UINT32 index; - UINT32 nCount; + DWORD index; + DWORD nCount; HANDLE events[64]; - nCount = transport_get_event_handles(transport, events); + nCount = transport_get_event_handles(transport, events, 64); + + *rcount = nCount; for (index = 0; index < nCount; index++) { - rfds[*rcount] = GetEventWaitObject(events[index]); - (*rcount)++; + rfds[index] = GetEventWaitObject(events[index]); } } @@ -858,7 +872,7 @@ static void* transport_client_thread(void* arg) rdpRdp* rdp = context->rdp; WLog_DBG(TAG, "Starting transport thread"); - + nCount = 0; handles[nCount++] = transport->stopEvent; handles[nCount++] = transport->connectedEvent; @@ -876,10 +890,16 @@ static void* transport_client_thread(void* arg) while (1) { - nCount = 0; + nCount = freerdp_get_event_handles(context, &handles[nCount], 64); + + if (nCount == 0) + { + WLog_ERR(TAG, "freerdp_get_event_handles failed"); + break; + } + handles[nCount++] = transport->stopEvent; - nCount += freerdp_get_event_handles(context, &handles[nCount]); - + status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE); if (transport->layer == TRANSPORT_LAYER_CLOSED) diff --git a/libfreerdp/core/transport.h b/libfreerdp/core/transport.h index 0fe989e71..1c6c9dcc0 100644 --- a/libfreerdp/core/transport.h +++ b/libfreerdp/core/transport.h @@ -96,7 +96,7 @@ int transport_write(rdpTransport* transport, wStream* s); void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount); int transport_check_fds(rdpTransport* transport); -UINT32 transport_get_event_handles(rdpTransport* transport, HANDLE* events); +DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events, DWORD nCount); BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking); void transport_set_gateway_enabled(rdpTransport* transport, BOOL GatewayEnabled); diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 19ee553c0..514327ab6 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -744,9 +744,8 @@ static void test_server_mainloop(freerdp_listener* instance) while (1) { - count = 0; - - if (instance->GetEventHandles(instance, handles, &count)) + count = instance->GetEventHandles(instance, handles, 32); + if (0 == count) { WLog_ERR(TAG, "Failed to get FreeRDP event handles"); break; diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c index a0c560a19..dd778916a 100644 --- a/server/shadow/shadow_server.c +++ b/server/shadow/shadow_server.c @@ -313,9 +313,8 @@ void* shadow_server_thread(rdpShadowServer* server) while (1) { - nCount = 0; - - if (listener->GetEventHandles(listener, events, &nCount) < 0) + nCount = listener->GetEventHandles(listener, events, 32); + if (0 == nCount) { WLog_ERR(TAG, "Failed to get FreeRDP file descriptor"); break;