From ef1fd12b15a24047d6211091c7d4362f59654cf7 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Tue, 28 Apr 2015 17:00:41 +0200 Subject: [PATCH 1/2] Fix unchecked CreateEvent calls and misc fixes 1) Added missing checks for CreateEvent which also required the following related changes: - changed freerdp_context_new API to BOOL - changed freerdp_peer_context_new API to BOOL - changed pRdpClientNew callback to BOOL - changed pContextNew callback to BOOL - changed psPeerAccepted callback to BOOL - changed psPeerContextNew callback to BOOL 2) Fixed lots of missing alloc and error checks in the changed code's neighbourhood. 3) Check freerdp_client_codecs_prepare result to avoid segfaults caused by using non-initialized codecs. 4) Fixed deadlocks in x11 caused by missing xf_unlock_x11() calls in some error handlers 5) Some fixes in thread pool: - DEFAULT_POOL assignment did not match TP_POOL definition - don't free the pool pointer if it points to the static DEFAULT_POOL - added error handling and cleanup in InitializeThreadpool --- .../Android/FreeRDPCore/jni/android_cliprdr.c | 19 ++- .../Android/FreeRDPCore/jni/android_freerdp.c | 25 ++-- client/DirectFB/dfreerdp.c | 22 +++- client/Sample/freerdp.c | 12 +- client/Wayland/wlfreerdp.c | 8 +- client/Windows/wf_client.c | 27 +++-- client/Windows/wf_cliprdr.c | 71 ++++++++---- client/Windows/wf_gdi.c | 14 ++- client/Windows/wf_graphics.c | 6 +- client/X11/xf_client.c | 52 +++++++-- client/X11/xf_gdi.c | 30 ++++- client/X11/xf_gfx.c | 18 ++- client/X11/xf_graphics.c | 20 ++-- client/common/client.c | 4 +- include/freerdp/client.h | 2 +- include/freerdp/codecs.h | 4 +- include/freerdp/freerdp.h | 4 +- include/freerdp/listener.h | 2 +- include/freerdp/peer.h | 4 +- libfreerdp/codec/rfx.c | 3 + libfreerdp/core/client.c | 3 + libfreerdp/core/codecs.c | 59 ++++++---- libfreerdp/core/freerdp.c | 13 ++- libfreerdp/core/listener.c | 11 +- libfreerdp/core/peer.c | 54 +++++---- libfreerdp/core/transport.c | 20 +++- libfreerdp/gdi/gdi.c | 12 +- libfreerdp/gdi/gfx.c | 18 ++- libfreerdp/gdi/graphics.c | 6 +- server/Mac/mf_peer.c | 56 +++++++-- server/Mac/mf_peer.h | 6 +- server/Mac/mfreerdp.c | 3 +- server/Sample/sfreerdp.c | 63 ++++++++-- server/Windows/wf_info.c | 109 ++++++++++-------- server/Windows/wf_info.h | 8 +- server/Windows/wf_peer.c | 104 +++++++++++------ server/Windows/wf_peer.h | 6 +- server/shadow/Win/win_rdp.c | 38 ++++-- server/shadow/shadow.c | 35 +++--- server/shadow/shadow_client.c | 55 +++++++-- server/shadow/shadow_client.h | 2 +- server/shadow/shadow_server.c | 43 +++++-- server/shadow/shadow_subsystem.c | 38 ++++-- winpr/libwinpr/comm/test/TestCommMonitor.c | 12 +- .../pipe/test/TestPipeCreateNamedPipe.c | 24 +++- .../test/TestPipeCreateNamedPipeOverlapped.c | 39 ++++++- winpr/libwinpr/pool/pool.c | 104 ++++++++++++----- winpr/libwinpr/pool/test/TestPoolThread.c | 6 +- winpr/libwinpr/pool/test/TestPoolWork.c | 6 +- winpr/libwinpr/smartcard/smartcard_pcsc.c | 10 +- winpr/libwinpr/synch/test/TestSynchBarrier.c | 18 ++- .../libwinpr/synch/test/TestSynchTimerQueue.c | 5 + .../synch/test/TestSynchWaitableTimerAPC.c | 9 +- .../utils/collections/CountdownEvent.c | 32 +++-- 54 files changed, 975 insertions(+), 399 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_cliprdr.c b/client/Android/FreeRDPCore/jni/android_cliprdr.c index f3278b3bf..82c2c6bdc 100644 --- a/client/Android/FreeRDPCore/jni/android_cliprdr.c +++ b/client/Android/FreeRDPCore/jni/android_cliprdr.c @@ -326,12 +326,23 @@ int android_cliprdr_server_file_contents_response(CliprdrClientContext* cliprdr, int android_cliprdr_init(androidContext* afc, CliprdrClientContext* cliprdr) { - cliprdr->custom = (void*) afc; + wClipboard* clipboard; + HANDLE hevent; + + if (!(hevent = CreateEvent(NULL, TRUE, FALSE, NULL))) + return 0; + + if (!(clipboard = ClipboardCreate())) + { + CloseHandle(hevent); + return 0; + } + afc->cliprdr = cliprdr; + afc->clipboard = clipboard; + afc->clipboardRequestEvent = hevent; - afc->clipboard = ClipboardCreate(); - afc->clipboardRequestEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - + cliprdr->custom = (void*) afc; cliprdr->MonitorReady = android_cliprdr_monitor_ready; cliprdr->ServerCapabilities = android_cliprdr_server_capabilities; cliprdr->ServerFormatList = android_cliprdr_server_format_list; diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index d2602fbe4..81260a14e 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -48,17 +48,22 @@ #include "jni/prof.h" #endif -int android_context_new(freerdp* instance, rdpContext* context) +BOOL android_context_new(freerdp* instance, rdpContext* context) { - context->channels = freerdp_channels_new(); + if (!(context->channels = freerdp_channels_new())) + return FALSE; android_event_queue_init(instance); - return 0; + return TRUE; } void android_context_free(freerdp* instance, rdpContext* context) { - freerdp_channels_close(instance->context->channels, instance); - freerdp_channels_free(context->channels); + if (context && context->channels) + { + freerdp_channels_close(context->channels, instance); + freerdp_channels_free(context->channels); + context->channels = NULL; + } android_event_queue_uninit(instance); } @@ -622,7 +627,8 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls) #endif // create instance - instance = freerdp_new(); + if (!(instance = freerdp_new())) + return NULL; instance->PreConnect = android_pre_connect; instance->PostConnect = android_post_connect; instance->PostDisconnect = android_post_disconnect; @@ -634,7 +640,12 @@ JNIEXPORT jint JNICALL jni_freerdp_new(JNIEnv *env, jclass cls) instance->ContextSize = sizeof(androidContext); instance->ContextNew = android_context_new; instance->ContextFree = android_context_free; - freerdp_context_new(instance); + + if (!freerdp_context_new(instance)) + { + freerdp_free(instance); + instance = NULL; + } return (jint) instance; } diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c index d86da92ed..f32f3acc6 100644 --- a/client/DirectFB/dfreerdp.c +++ b/client/DirectFB/dfreerdp.c @@ -49,15 +49,22 @@ struct thread_data freerdp* instance; }; -int df_context_new(freerdp* instance, rdpContext* context) +BOOL df_context_new(freerdp* instance, rdpContext* context) { - context->channels = freerdp_channels_new(); - return 0; + if (!(context->channels = freerdp_channels_new())) + return FALSE; + + return TRUE; } void df_context_free(freerdp* instance, rdpContext* context) { - + if (context && context->channels) + { + freerdp_channels_close(context->channels, instance); + freerdp_channels_free(context->channels); + context->channels = NULL; + } } void df_begin_paint(rdpContext* context) @@ -458,7 +465,12 @@ int main(int argc, char* argv[]) instance->ContextSize = sizeof(dfContext); instance->ContextNew = df_context_new; instance->ContextFree = df_context_free; - freerdp_context_new(instance); + + if (!freerdp_context_new(instance)) + { + WLog_ERR(TAG, "Failed to create FreeRDP context"); + exit(1); + } context = (dfContext*) instance->context; channels = instance->context->channels; diff --git a/client/Sample/freerdp.c b/client/Sample/freerdp.c index 1b529e6e9..e4614a249 100644 --- a/client/Sample/freerdp.c +++ b/client/Sample/freerdp.c @@ -45,10 +45,12 @@ struct tf_context }; typedef struct tf_context tfContext; -static int tf_context_new(freerdp* instance, rdpContext* context) +static BOOL tf_context_new(freerdp* instance, rdpContext* context) { - context->channels = freerdp_channels_new(); - return 0; + if (!(context->channels = freerdp_channels_new())) + return FALSE; + + return TRUE; } static void tf_context_free(freerdp* instance, rdpContext* context) @@ -57,6 +59,7 @@ static void tf_context_free(freerdp* instance, rdpContext* context) { freerdp_channels_close(context->channels, instance); freerdp_channels_free(context->channels); + context->channels = NULL; } } @@ -184,7 +187,8 @@ int main(int argc, char* argv[]) instance->ContextSize = sizeof(tfContext); instance->ContextNew = tf_context_new; instance->ContextFree = tf_context_free; - if (freerdp_context_new(instance) != 0) + + if (!freerdp_context_new(instance)) { WLog_ERR(TAG, "Couldn't create context"); exit(1); diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 7ce1eb040..fff00a190 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -26,11 +26,12 @@ #include "wlfreerdp.h" -static int wl_context_new(freerdp* instance, rdpContext* context) +static BOOL wl_context_new(freerdp* instance, rdpContext* context) { - context->channels = freerdp_channels_new(); + if (!(context->channels = freerdp_channels_new())) + return FALSE; - return 0; + return TRUE; } static void wl_context_free(freerdp* instance, rdpContext* context) @@ -39,6 +40,7 @@ static void wl_context_free(freerdp* instance, rdpContext* context) { freerdp_channels_close(context->channels, instance); freerdp_channels_free(context->channels); + context->channels = NULL; } } diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index e1dc8ca3f..e639b31e4 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -1012,11 +1012,15 @@ void wfreerdp_client_global_uninit(void) WSACleanup(); } -int wfreerdp_client_new(freerdp* instance, rdpContext* context) +BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context) { wfContext* wfc = (wfContext*) context; - wfreerdp_client_global_init(); + if (!(wfreerdp_client_global_init())) + return FALSE; + + if (!(context->channels = freerdp_channels_new())) + return FALSE; instance->PreConnect = wf_pre_connect; instance->PostConnect = wf_post_connect; @@ -1025,20 +1029,27 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context) wfc->instance = instance; wfc->settings = instance->settings; - context->channels = freerdp_channels_new(); - return 0; + return TRUE; } void wfreerdp_client_free(freerdp* instance, rdpContext* context) { - rdpChannels* channels = context->channels; + if (!context) + return; + + if (context->channels) + { + freerdp_channels_close(context->channels, instance); + freerdp_channels_free(context->channels); + context->channels = NULL; + } if (context->cache) + { cache_free(context->cache); - - freerdp_channels_close(channels, instance); - freerdp_channels_free(context->channels); + context->cache = NULL; + } } int wfreerdp_client_start(rdpContext* context) diff --git a/client/Windows/wf_cliprdr.c b/client/Windows/wf_cliprdr.c index 6bcd94bf6..e52470620 100644 --- a/client/Windows/wf_cliprdr.c +++ b/client/Windows/wf_cliprdr.c @@ -1975,10 +1975,36 @@ void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr) clipboard = wfc->clipboard; clipboard->wfc = wfc; clipboard->context = cliprdr; - - cliprdr->custom = (void*) wfc->clipboard; - clipboard->context = cliprdr; + clipboard->channels = context->channels; + clipboard->sync = FALSE; + + clipboard->map_capacity = 32; + clipboard->map_size = 0; + + if (!(clipboard->format_mappings = (formatMapping*) calloc(1, sizeof(formatMapping) * clipboard->map_capacity))) + goto fail_format_mappings; + + clipboard->file_array_size = 32; + if (!(clipboard->file_names = (WCHAR**) calloc(1, clipboard->file_array_size * sizeof(WCHAR*)))) + goto fail_file_names; + + if (!(clipboard->fileDescriptor = (FILEDESCRIPTORW**) calloc(1, clipboard->file_array_size * sizeof(FILEDESCRIPTORW*)))) + goto fail_file_descriptor; + + if (!(clipboard->response_data_event = CreateEvent(NULL, TRUE, FALSE, _T("response_data_event")))) + goto fail_data_event; + + if (!(clipboard->req_fevent = CreateEvent(NULL, TRUE, FALSE, _T("request_filecontents_event")))) + goto fail_filecontents_event; + + clipboard->ID_FILEDESCRIPTORW = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW); + clipboard->ID_FILECONTENTS = RegisterClipboardFormatW(CFSTR_FILECONTENTS); + clipboard->ID_PREFERREDDROPEFFECT = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT); + + if (!(clipboard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) cliprdr_thread_func, clipboard, 0, NULL))) + goto fail_clipboard_thread; + cliprdr->MonitorReady = wf_cliprdr_monitor_ready; cliprdr->ServerCapabilities = wf_cliprdr_server_capabilities; cliprdr->ServerFormatList = wf_cliprdr_server_format_list; @@ -1989,27 +2015,30 @@ void wf_cliprdr_init(wfContext* wfc, CliprdrClientContext* cliprdr) cliprdr->ServerFormatDataResponse = wf_cliprdr_server_format_data_response; cliprdr->ServerFileContentsRequest = wf_cliprdr_server_file_contents_request; cliprdr->ServerFileContentsResponse = wf_cliprdr_server_file_contents_response; + cliprdr->custom = (void*) wfc->clipboard; - clipboard->channels = context->channels; - clipboard->sync = FALSE; + return; - clipboard->map_capacity = 32; - clipboard->map_size = 0; +fail_clipboard_thread: + CloseHandle(clipboard->req_fevent); + clipboard->req_fevent = NULL; +fail_filecontents_event: + CloseHandle(clipboard->response_data_event); + clipboard->response_data_event = NULL; +fail_data_event: + free(clipboard->fileDescriptor); + clipboard->fileDescriptor = NULL; +fail_file_descriptor: + free(clipboard->file_names); + clipboard->file_names = NULL; +fail_file_names: + free(clipboard->format_mappings); + clipboard->format_mappings = NULL; +fail_format_mappings: + free(wfc->clipboard); + wfc->clipboard = NULL; - clipboard->format_mappings = (formatMapping*) calloc(1, sizeof(formatMapping) * clipboard->map_capacity); - - clipboard->file_array_size = 32; - clipboard->file_names = (WCHAR**) calloc(1, clipboard->file_array_size * sizeof(WCHAR*)); - clipboard->fileDescriptor = (FILEDESCRIPTORW**) calloc(1, clipboard->file_array_size * sizeof(FILEDESCRIPTORW*)); - - clipboard->response_data_event = CreateEvent(NULL, TRUE, FALSE, _T("response_data_event")); - - clipboard->req_fevent = CreateEvent(NULL, TRUE, FALSE, _T("request_filecontents_event")); - clipboard->ID_FILEDESCRIPTORW = RegisterClipboardFormatW(CFSTR_FILEDESCRIPTORW); - clipboard->ID_FILECONTENTS = RegisterClipboardFormatW(CFSTR_FILECONTENTS); - clipboard->ID_PREFERREDDROPEFFECT = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT); - - clipboard->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) cliprdr_thread_func, clipboard, 0, NULL); + return; } void wf_cliprdr_uninit(wfContext* wfc, CliprdrClientContext* cliprdr) diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index 4da886db7..b422f470f 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -406,14 +406,16 @@ BOOL wf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) if (bitsPerPixel < 32) { - freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); + if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED)) + return FALSE; status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel, &pDstData, PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight, NULL); } else { - freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); + if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR)) + return FALSE; status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData, PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight, TRUE); @@ -675,7 +677,9 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX) { - freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_REMOTEFX); + if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_REMOTEFX)) + return; + if (!(message = rfx_process_message(wfc->codecs->rfx, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength))) { WLog_ERR(TAG, "Failed to process RemoteFX message"); @@ -715,7 +719,9 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm } else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC) { - freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_NSCODEC); + if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_NSCODEC)) + return; + nsc_process_message(wfc->codecs->nsc, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); ZeroMemory(&bitmap_info, sizeof(bitmap_info)); diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index ab3f3b5f6..895471edc 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -171,14 +171,16 @@ void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap, { if (bpp < 32) { - freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_INTERLEAVED); + if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_INTERLEAVED)) + return; status = interleaved_decompress(wfc->codecs->interleaved, pSrcData, SrcSize, bpp, &pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, NULL); } else { - freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR); + if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR)) + return; status = planar_decompress(wfc->codecs->planar, pSrcData, SrcSize, &pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, TRUE); diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index b4aac8b58..3209b3d05 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1658,19 +1658,27 @@ static int xfreerdp_client_stop(rdpContext* context) return 0; } -static int xfreerdp_client_new(freerdp* instance, rdpContext* context) +static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) { rdpSettings* settings; xfContext* xfc = (xfContext*) instance->context; + assert(context); + assert(xfc); + assert(!context->channels); + assert(!xfc->display); + assert(!xfc->mutex); + assert(!xfc->x11event); + + if (!(context->channels = freerdp_channels_new())) + goto fail_channels_new; + instance->PreConnect = xf_pre_connect; instance->PostConnect = xf_post_connect; instance->PostDisconnect = xf_post_disconnect; instance->Authenticate = xf_authenticate; instance->VerifyCertificate = xf_verify_certificate; instance->LogonErrorInfo = xf_logon_error_info; - assert(!context->channels); - context->channels = freerdp_channels_new(); settings = instance->settings; xfc->settings = instance->context->settings; @@ -1693,23 +1701,21 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context) } } - assert(!xfc->display); xfc->display = XOpenDisplay(NULL); if (!xfc->display) { WLog_ERR(TAG, "failed to open display: %s", XDisplayName(NULL)); WLog_ERR(TAG, "Please check that the $DISPLAY environment variable is properly set."); - return -1; + goto fail_open_display; } - assert(!xfc->mutex); xfc->mutex = CreateMutex(NULL, FALSE, NULL); if (!xfc->mutex) { WLog_ERR(TAG, "Could not create mutex!"); - return -1; + goto fail_create_mutex; } xfc->_NET_WM_ICON = XInternAtom(xfc->display, "_NET_WM_ICON", False); @@ -1741,8 +1747,13 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context) xfc->invert = (ImageByteOrder(xfc->display) == MSBFirst) ? TRUE : FALSE; xfc->complex_regions = TRUE; - assert(!xfc->x11event); xfc->x11event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); + if (!xfc->x11event) + { + WLog_ERR(TAG, "Could not create xfds event"); + goto fail_xfds_event; + } + xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number); xfc->format = PIXEL_FORMAT_XRGB32; @@ -1767,14 +1778,33 @@ static int xfreerdp_client_new(freerdp* instance, rdpContext* context) xf_check_extensions(xfc); if (!xf_get_pixmap_info(xfc)) - return -1; + { + WLog_ERR(TAG, "Failed to get pixmap info"); + goto fail_pixmap_info; + } xfc->vscreen.monitors = calloc(16, sizeof(MONITOR_INFO)); if (!xfc->vscreen.monitors) - return -1; + goto fail_vscreen_monitors; - return 0; + return TRUE; + +fail_vscreen_monitors: +fail_pixmap_info: + CloseHandle(xfc->x11event); + xfc->x11event = NULL; +fail_xfds_event: + CloseHandle(xfc->mutex); + xfc->mutex = NULL; +fail_create_mutex: + XCloseDisplay(xfc->display); + xfc->display = NULL; +fail_open_display: + freerdp_channels_free(context->channels); + context->channels = NULL; +fail_channels_new: + return FALSE; } static void xfreerdp_client_free(freerdp* instance, rdpContext* context) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index b3446a9a4..f4088d1cb 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -385,14 +385,16 @@ BOOL xf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) if (bitsPerPixel < 32) { - freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); + if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED)) + return FALSE; status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel, &pDstData, xfc->format, -1, 0, 0, nWidth, nHeight, xfc->palette); } else { - freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); + if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR)) + return FALSE; status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData, xfc->format, -1, 0, 0, nWidth, nHeight, TRUE); @@ -1176,11 +1178,16 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) if (cmd->codecID == RDP_CODEC_ID_REMOTEFX) { - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX)) + { + xf_unlock_x11(xfc, FALSE); + return FALSE; + } if (!(message = rfx_process_message(xfc->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength))) { WLog_ERR(TAG, "Failed to process RemoteFX message"); + xf_unlock_x11(xfc, FALSE); return FALSE; } @@ -1196,7 +1203,12 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) + { + rfx_message_free(xfc->codecs->rfx, message); + XSetClipMask(xfc->display, xfc->gc, None); + xf_unlock_x11(xfc, FALSE); return FALSE; + } } /* Draw the tiles to primary surface, each is 64x64. */ @@ -1241,7 +1253,11 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) } else if (cmd->codecID == RDP_CODEC_ID_NSCODEC) { - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC)) + { + xf_unlock_x11(xfc, FALSE); + return FALSE; + } nsc_process_message(xfc->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength); @@ -1254,7 +1270,10 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) + { + xf_unlock_x11(xfc, FALSE); return FALSE; + } } pSrcData = xfc->codecs->nsc->BitmapData; @@ -1286,7 +1305,10 @@ BOOL xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16); if (!xfc->bitmap_buffer) + { + xf_unlock_x11(xfc, FALSE); return FALSE; + } } pSrcData = cmd->bitmapData; diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index e457bcf7b..cce37106f 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -263,7 +263,8 @@ int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDP REGION16 clippingRects; RECTANGLE_16 clippingRect; - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX)) + return -1; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -337,7 +338,8 @@ int xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, R xfGfxSurface* surface; RECTANGLE_16 invalidRect; - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC)) + return -1; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -375,7 +377,8 @@ int xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGF xfGfxSurface* surface; RECTANGLE_16 invalidRect; - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR)) + return -1; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -410,7 +413,8 @@ int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_ RDPGFX_H264_METABLOCK* meta; RDPGFX_H264_BITMAP_STREAM* bs; - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_H264); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_H264)) + return -1; h264 = xfc->codecs->h264; @@ -455,7 +459,8 @@ int xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGFX xfGfxSurface* surface; RECTANGLE_16 invalidRect; - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_ALPHACODEC); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_ALPHACODEC)) + return -1; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -500,7 +505,8 @@ int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RFX_PROGRESSIVE_TILE* tile; PROGRESSIVE_BLOCK_REGION* region; - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PROGRESSIVE); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PROGRESSIVE)) + return -1; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index c7c292f4a..8a6b4eb97 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -64,10 +64,11 @@ BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) if (depth != xfc->depth) { - data = _aligned_malloc(bitmap->width * bitmap->height * 4, 16); - - if (!data) + if (!(data = _aligned_malloc(bitmap->width * bitmap->height * 4, 16))) + { + xf_unlock_x11(xfc, FALSE); return FALSE; + } SrcFormat = gdi_get_pixel_format(bitmap->bpp, TRUE); @@ -162,14 +163,16 @@ BOOL xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, { if (bpp < 32) { - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_INTERLEAVED); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_INTERLEAVED)) + return FALSE; status = interleaved_decompress(xfc->codecs->interleaved, pSrcData, SrcSize, bpp, &pDstData, xfc->format, -1, 0, 0, width, height, xfc->palette); } else { - freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR); + if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_PLANAR)) + return FALSE; status = planar_decompress(xfc->codecs->planar, pSrcData, SrcSize, &pDstData, xfc->format, -1, 0, 0, width, height, TRUE); @@ -228,10 +231,11 @@ BOOL xf_Pointer_New(rdpContext* context, rdpPointer* pointer) ci.xhot = pointer->xPos; ci.yhot = pointer->yPos; - ci.pixels = (XcursorPixel*) calloc(1, ci.width * ci.height * 4); - - if (!ci.pixels) + if (!(ci.pixels = (XcursorPixel*) calloc(1, ci.width * ci.height * 4))) + { + xf_unlock_x11(xfc, FALSE); return FALSE; + } if ((pointer->andMaskData != 0) && (pointer->xorMaskData != 0)) { diff --git a/client/common/client.c b/client/common/client.c index 8a738c67a..2c68514de 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -29,7 +29,7 @@ #include #include -int freerdp_client_common_new(freerdp* instance, rdpContext* context) +BOOL freerdp_client_common_new(freerdp* instance, rdpContext* context) { RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints; return pEntryPoints->ClientNew(instance, context); @@ -64,7 +64,7 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) CopyMemory(instance->pClientEntryPoints, pEntryPoints, pEntryPoints->Size); - if (freerdp_context_new(instance) != 0) + if (!freerdp_context_new(instance)) goto out_fail2; context = instance->context; diff --git a/include/freerdp/client.h b/include/freerdp/client.h index cedc29239..39708c77e 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -34,7 +34,7 @@ extern "C" { typedef BOOL (*pRdpGlobalInit)(void); typedef void (*pRdpGlobalUninit)(void); -typedef int (*pRdpClientNew)(freerdp* instance, rdpContext* context); +typedef BOOL (*pRdpClientNew)(freerdp* instance, rdpContext* context); typedef void (*pRdpClientFree)(freerdp* instance, rdpContext* context); typedef int (*pRdpClientStart)(rdpContext* context); diff --git a/include/freerdp/codecs.h b/include/freerdp/codecs.h index 0e8b2f41d..5298d148e 100644 --- a/include/freerdp/codecs.h +++ b/include/freerdp/codecs.h @@ -59,8 +59,8 @@ struct rdp_codecs extern "C" { #endif -FREERDP_API int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags); -FREERDP_API int freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags); +FREERDP_API BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags); +FREERDP_API BOOL freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags); FREERDP_API rdpCodecs* codecs_new(rdpContext* context); FREERDP_API void codecs_free(rdpCodecs* codecs); diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 1fbea1f6f..c953d8a41 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -59,7 +59,7 @@ typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS; extern "C" { #endif -typedef int (*pContextNew)(freerdp* instance, rdpContext* context); +typedef BOOL (*pContextNew)(freerdp* instance, rdpContext* context); typedef void (*pContextFree)(freerdp* instance, rdpContext* context); typedef BOOL (*pPreConnect)(freerdp* instance); @@ -237,7 +237,7 @@ struct rdp_freerdp UINT64 paddingE[80 - 66]; /* 66 */ }; -FREERDP_API int freerdp_context_new(freerdp* instance); +FREERDP_API BOOL freerdp_context_new(freerdp* instance); FREERDP_API void freerdp_context_free(freerdp* instance); FREERDP_API BOOL freerdp_connect(freerdp* instance); diff --git a/include/freerdp/listener.h b/include/freerdp/listener.h index e7e73f988..e502a41a8 100644 --- a/include/freerdp/listener.h +++ b/include/freerdp/listener.h @@ -37,7 +37,7 @@ typedef BOOL (*psListenerGetFileDescriptor)(freerdp_listener* instance, void** r 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); +typedef BOOL (*psPeerAccepted)(freerdp_listener* instance, freerdp_peer* client); struct rdp_freerdp_listener { diff --git a/include/freerdp/peer.h b/include/freerdp/peer.h index 4ec383529..a08b7f739 100644 --- a/include/freerdp/peer.h +++ b/include/freerdp/peer.h @@ -29,7 +29,7 @@ #include -typedef void (*psPeerContextNew)(freerdp_peer* client, rdpContext* context); +typedef BOOL (*psPeerContextNew)(freerdp_peer* client, rdpContext* context); typedef void (*psPeerContextFree)(freerdp_peer* client, rdpContext* context); typedef BOOL (*psPeerInitialize)(freerdp_peer* client); @@ -112,7 +112,7 @@ struct rdp_freerdp_peer extern "C" { #endif -FREERDP_API void freerdp_peer_context_new(freerdp_peer* client); +FREERDP_API BOOL freerdp_peer_context_new(freerdp_peer* client); FREERDP_API void freerdp_peer_context_free(freerdp_peer* client); FREERDP_API freerdp_peer* freerdp_peer_new(int sockfd); diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index affd1f4a3..6f5a4651f 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -989,6 +989,9 @@ RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length BOOL ok = TRUE; UINT16 expectedDataBlockType = WBT_FRAME_BEGIN; + if (!context || !data || !length) + goto fail; + if (!(s = Stream_New(data, length))) goto fail; diff --git a/libfreerdp/core/client.c b/libfreerdp/core/client.c index e7ddde579..63969fd85 100644 --- a/libfreerdp/core/client.c +++ b/libfreerdp/core/client.c @@ -103,6 +103,9 @@ void freerdp_channels_free(rdpChannels* channels) ULONG_PTR* pKeys = NULL; CHANNEL_OPEN_DATA* pChannelOpenData; + if (!channels) + return; + if (channels->queue) { MessageQueue_Free(channels->queue); diff --git a/libfreerdp/core/codecs.c b/libfreerdp/core/codecs.c index a29024245..21d5d962d 100644 --- a/libfreerdp/core/codecs.c +++ b/libfreerdp/core/codecs.c @@ -25,45 +25,52 @@ #include -int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) +#define TAG FREERDP_TAG("core.codecs") + +BOOL freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) { - if (flags & FREERDP_CODEC_INTERLEAVED) + if (flags & FREERDP_CODEC_INTERLEAVED && !codecs->interleaved) { - if (!codecs->interleaved) + if (!(codecs->interleaved = bitmap_interleaved_context_new(FALSE))) { - codecs->interleaved = bitmap_interleaved_context_new(FALSE); + WLog_ERR(TAG, "Failed to create interleaved codec context"); + return FALSE; } } - if (flags & FREERDP_CODEC_PLANAR) + if (flags & FREERDP_CODEC_PLANAR && !codecs->planar) { - if (!codecs->planar) + if (!(codecs->planar = freerdp_bitmap_planar_context_new(FALSE, 64, 64))) { - codecs->planar = freerdp_bitmap_planar_context_new(FALSE, 64, 64); + WLog_ERR(TAG, "Failed to create planar bitmap codec context"); + return FALSE; } } - if (flags & FREERDP_CODEC_NSCODEC) + if (flags & FREERDP_CODEC_NSCODEC && !codecs->nsc) { - if (!codecs->nsc) + if (!(codecs->nsc = nsc_context_new())) { - codecs->nsc = nsc_context_new(); + WLog_ERR(TAG, "Failed to create nsc codec context"); + return FALSE; } } - if (flags & FREERDP_CODEC_REMOTEFX) + if (flags & FREERDP_CODEC_REMOTEFX && !codecs->rfx) { - if (!codecs->rfx) + if (!(codecs->rfx = rfx_context_new(FALSE))) { - codecs->rfx = rfx_context_new(FALSE); + WLog_ERR(TAG, "Failed to create rfx codec context"); + return FALSE; } } - if (flags & FREERDP_CODEC_CLEARCODEC) + if (flags & FREERDP_CODEC_CLEARCODEC && !codecs->clear) { - if (!codecs->clear) + if (!(codecs->clear = clear_context_new(FALSE))) { - codecs->clear = clear_context_new(FALSE); + WLog_ERR(TAG, "Failed to create clear codec context"); + return FALSE; } } @@ -72,26 +79,28 @@ int freerdp_client_codecs_prepare(rdpCodecs* codecs, UINT32 flags) } - if (flags & FREERDP_CODEC_PROGRESSIVE) + if (flags & FREERDP_CODEC_PROGRESSIVE && !codecs->progressive) { - if (!codecs->progressive) + if (!(codecs->progressive = progressive_context_new(FALSE))) { - codecs->progressive = progressive_context_new(FALSE); + WLog_ERR(TAG, "Failed to create progressive codec context"); + return FALSE; } } - if (flags & FREERDP_CODEC_H264) + if (flags & FREERDP_CODEC_H264 && !codecs->h264) { - if (!codecs->h264) + if (!(codecs->h264 = h264_context_new(FALSE))) { - codecs->h264 = h264_context_new(FALSE); + WLog_ERR(TAG, "Failed to create h264 codec context"); + return FALSE; } } - return 1; + return TRUE; } -int freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags) +BOOL freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags) { if (flags & FREERDP_CODEC_INTERLEAVED) { @@ -154,7 +163,7 @@ int freerdp_client_codecs_reset(rdpCodecs* codecs, UINT32 flags) } } - return 1; + return TRUE; } rdpCodecs* codecs_new(rdpContext* context) diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 65b25013f..77ed203d6 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -441,14 +441,15 @@ static wEventType FreeRDP_Events[] = * * @param instance - Pointer to the rdp_freerdp structure that will be initialized with the new context. */ -int freerdp_context_new(freerdp* instance) +BOOL freerdp_context_new(freerdp* instance) { rdpRdp* rdp; rdpContext* context; + BOOL ret = TRUE; instance->context = (rdpContext*) calloc(1, instance->ContextSize); if (!instance->context) - return -1; + return FALSE; context = instance->context; context->instance = instance; @@ -497,8 +498,10 @@ int freerdp_context_new(freerdp* instance) update_register_client_callbacks(rdp->update); - IFCALL(instance->ContextNew, instance, instance->context); - return 0; + IFCALLRET(instance->ContextNew, ret, instance, instance->context); + + if (ret) + return TRUE; out_error_graphics_new: rdp_free(rdp); @@ -508,7 +511,7 @@ out_error_metrics_new: PubSub_Free(context->pubSub); out_error_pubsub: free(instance->context); - return -1; + return FALSE; } /** Deallocator function for a rdp context. diff --git a/libfreerdp/core/listener.c b/libfreerdp/core/listener.c index b38e54fb0..b649ac593 100644 --- a/libfreerdp/core/listener.c +++ b/libfreerdp/core/listener.c @@ -284,6 +284,7 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) struct sockaddr_storage peer_addr; rdpListener* listener = (rdpListener*) instance->listener; static const BYTE localhost6_bytes[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + BOOL peer_accepted; if (listener->num_sockfds < 1) return FALSE; @@ -292,6 +293,7 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) { peer_addr_size = sizeof(peer_addr); peer_sockfd = accept(listener->sockfds[i], (struct sockaddr*) &peer_addr, &peer_addr_size); + peer_accepted = FALSE; if (peer_sockfd == -1) { @@ -340,7 +342,14 @@ static BOOL freerdp_listener_check_fds(freerdp_listener* instance) if (sin_addr) inet_ntop(peer_addr.ss_family, sin_addr, client->hostname, sizeof(client->hostname)); - IFCALL(instance->PeerAccepted, instance, client); + IFCALLRET(instance->PeerAccepted, peer_accepted, instance, client); + + if (!peer_accepted) + { + WLog_ERR(TAG, "PeerAccepted callback failed"); + closesocket((SOCKET) peer_sockfd); + freerdp_peer_free(client); + } } return TRUE; diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 434feb01f..6ee2ce975 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -621,36 +621,27 @@ static int freerdp_peer_drain_output_buffer(freerdp_peer* peer) return transport_drain_output_buffer(transport); } -void freerdp_peer_context_new(freerdp_peer* client) +BOOL freerdp_peer_context_new(freerdp_peer* client) { rdpRdp* rdp; rdpContext* context; + BOOL ret = TRUE; - context = client->context = (rdpContext*) calloc(1, client->ContextSize); + if (!client) + return FALSE; - if (!context) - return; + if (!(context = (rdpContext*) calloc(1, client->ContextSize))) + goto fail_context; + + client->context = context; context->ServerMode = TRUE; - context->metrics = metrics_new(context); + if (!(context->metrics = metrics_new(context))) + goto fail_metrics; - if (!context->metrics) - { - client->context = NULL; - free(context); - return; - } - - rdp = rdp_new(context); - - if (!rdp) - { - metrics_free(context->metrics); - free(context); - client->context = NULL; - return; - } + if (!(rdp = rdp_new(context))) + goto fail_rdp; client->input = rdp->input; client->update = rdp->update; @@ -671,7 +662,8 @@ void freerdp_peer_context_new(freerdp_peer* client) update_register_server_callbacks(client->update); autodetect_register_server_callbacks(client->autodetect); - transport_attach(rdp->transport, client->sockfd); + if (!transport_attach(rdp->transport, client->sockfd)) + goto fail_transport_attach; rdp->transport->ReceiveCallback = peer_recv_callback; rdp->transport->ReceiveExtra = client; @@ -680,8 +672,24 @@ void freerdp_peer_context_new(freerdp_peer* client) client->IsWriteBlocked = freerdp_peer_is_write_blocked; client->DrainOutputBuffer = freerdp_peer_drain_output_buffer; - IFCALL(client->ContextNew, client, client->context); + IFCALLRET(client->ContextNew, ret, client, client->context); + if (ret) + return TRUE; + + WLog_ERR(TAG, "ContextNew callback failed"); + +fail_transport_attach: + rdp_free(client->context->rdp); +fail_rdp: + metrics_free(context->metrics); +fail_metrics: + free(client->context); +fail_context: + client->context = NULL; + + WLog_ERR(TAG, "Failed to create new peer context"); + return FALSE; } void freerdp_peer_context_free(freerdp_peer* client) diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 47b8a90be..d345052ed 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -264,7 +264,8 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por if (sockfd < 1) return FALSE; - transport_attach(transport, sockfd); + if (!transport_attach(transport, sockfd)) + return FALSE; status = TRUE; } @@ -273,9 +274,20 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por { if (transport->async) { - transport->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - transport->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL); + if (!(transport->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + WLog_ERR(TAG, "Failed to create transport stop event"); + return FALSE; + } + + if (!(transport->thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL))) + { + WLog_ERR(TAG, "Failed to create transport client thread"); + CloseHandle(transport->stopEvent); + transport->stopEvent = NULL; + return FALSE; + } } } diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 521f258ea..5f75611a9 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -486,14 +486,16 @@ static BOOL gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) if (bitsPerPixel < 32) { - freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); + if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED)) + return FALSE; status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel, &pDstData, gdi->format, -1, 0, 0, nWidth, nHeight, gdi->palette); } else { - freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); + if (!freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR)) + return FALSE; status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData, gdi->format, -1, 0, 0, nWidth, nHeight, TRUE); @@ -1023,7 +1025,8 @@ static BOOL gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) if (cmd->codecID == RDP_CODEC_ID_REMOTEFX) { - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX)) + return FALSE; if (!(message = rfx_process_message(gdi->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength))) { @@ -1068,7 +1071,8 @@ static BOOL gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd) } else if (cmd->codecID == RDP_CODEC_ID_NSCODEC) { - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_NSCODEC); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_NSCODEC)) + return FALSE; nsc_process_message(gdi->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength); diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c index b38e44e16..e5fe996e8 100644 --- a/libfreerdp/gdi/gfx.c +++ b/libfreerdp/gdi/gfx.c @@ -192,7 +192,8 @@ int gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, RDPGF REGION16 clippingRects; RECTANGLE_16 clippingRect; - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX)) + return -1; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -264,7 +265,8 @@ int gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi, RdpgfxClientContext* context, RDP gdiGfxSurface* surface; RECTANGLE_16 invalidRect; - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_CLEARCODEC); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_CLEARCODEC)) + return -1; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -303,7 +305,8 @@ int gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_ gdiGfxSurface* surface; RECTANGLE_16 invalidRect; - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR)) + return -1; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -337,7 +340,8 @@ int gdi_SurfaceCommand_H264(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SU RDPGFX_H264_METABLOCK* meta; RDPGFX_H264_BITMAP_STREAM* bs; - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_H264); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_H264)) + return -1; bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; @@ -380,7 +384,8 @@ int gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_S gdiGfxSurface* surface; RECTANGLE_16 invalidRect; - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_ALPHACODEC); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_ALPHACODEC)) + return -1; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); @@ -426,7 +431,8 @@ int gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* context, RD RFX_PROGRESSIVE_TILE* tile; PROGRESSIVE_BLOCK_REGION* region; - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PROGRESSIVE); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PROGRESSIVE)) + return -1; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 2b98a92b5..603237e18 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -175,14 +175,16 @@ BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, { if (bpp < 32) { - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_INTERLEAVED); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_INTERLEAVED)) + return FALSE; status = interleaved_decompress(gdi->codecs->interleaved, pSrcData, SrcSize, bpp, &pDstData, gdi->format, -1, 0, 0, width, height, gdi->palette); } else { - freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR); + if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR)) + return FALSE; status = planar_decompress(gdi->codecs->planar, pSrcData, SrcSize, &pDstData, gdi->format, -1, 0, 0, width, height, TRUE); diff --git a/server/Mac/mf_peer.c b/server/Mac/mf_peer.c index d9d8b90f7..9a837e528 100644 --- a/server/Mac/mf_peer.c +++ b/server/Mac/mf_peer.c @@ -175,25 +175,44 @@ void mf_peer_rfx_update(freerdp_peer* client) } /* Called when we have a new peer connecting */ -int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context) +BOOL mf_peer_context_new(freerdp_peer* client, mfPeerContext* context) { - context->info = mf_info_get_instance(); - context->rfx_context = rfx_context_new(TRUE); + if (!(context->info = mf_info_get_instance())) + return FALSE; + + if (!(context->rfx_context = rfx_context_new(TRUE))) + goto fail_rfx_context; + context->rfx_context->mode = RLGR3; context->rfx_context->width = client->settings->DesktopWidth; context->rfx_context->height = client->settings->DesktopHeight; rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); - //context->nsc_context = nsc_context_new(); + //if (!(context->nsc_context = nsc_context_new())) + // goto fail_nsc_context; //nsc_context_set_pixel_format(context->nsc_context, RDP_PIXEL_FORMAT_B8G8R8A8); - context->s = Stream_New(NULL, 0xFFFF); + if (!(context->s = Stream_New(NULL, 0xFFFF))) + goto fail_stream_new; context->vcm = WTSOpenServerA((LPSTR) client->context); + + if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE) + goto fail_open_server; mf_info_peer_register(context->info, context); - return 0; + return TRUE; + +fail_open_server: + Stream_Free(context->s, TRUE); + context->s = NULL; +fail_stream_new: + rfx_context_free(context->rfx_context); + context->rfx_context = NULL; +fail_rfx_context: + + return FALSE; } /* Called after a peer disconnects */ @@ -226,12 +245,14 @@ void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context) } /* Called when a new client connects */ -void mf_peer_init(freerdp_peer* client) +BOOL mf_peer_init(freerdp_peer* client) { client->ContextSize = sizeof(mfPeerContext); client->ContextNew = (psPeerContextNew) mf_peer_context_new; client->ContextFree = (psPeerContextFree) mf_peer_context_free; - freerdp_peer_context_new(client); + + if (!freerdp_peer_context_new(client)) + return FALSE; info_event_queue = mf_event_queue_new(); @@ -249,6 +270,8 @@ void mf_peer_init(freerdp_peer* client) ); dispatch_resume(info_timer); } + + return TRUE; } BOOL mf_peer_post_connect(freerdp_peer* client) @@ -330,12 +353,17 @@ static void mf_peer_suppress_output(rdpContext* context, BYTE allow, RECTANGLE_1 } -void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) +BOOL mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) { pthread_t th; - pthread_create(&th, 0, mf_peer_main_loop, client); - pthread_detach(th); + if (pthread_create(&th, 0, mf_peer_main_loop, client) == 0) + { + pthread_detach(th); + return TRUE; + } + + return FALSE; } void* mf_peer_main_loop(void* arg) @@ -351,7 +379,11 @@ void* mf_peer_main_loop(void* arg) memset(rfds, 0, sizeof(rfds)); - mf_peer_init(client); + if (!mf_peer_init(client)) + { + freerdp_peer_free(client); + return NULL; + } /* Initialize the real server settings here */ client->settings->CertificateFile = _strdup("server.crt"); diff --git a/server/Mac/mf_peer.h b/server/Mac/mf_peer.h index f5249affe..02a6b1730 100644 --- a/server/Mac/mf_peer.h +++ b/server/Mac/mf_peer.h @@ -27,17 +27,17 @@ BOOL mf_peer_check_fds(freerdp_peer* client); void mf_peer_rfx_update(freerdp_peer* client); -int mf_peer_context_new(freerdp_peer* client, mfPeerContext* context); +BOOL mf_peer_context_new(freerdp_peer* client, mfPeerContext* context); void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context); -void mf_peer_init(freerdp_peer* client); +BOOL mf_peer_init(freerdp_peer* client); BOOL mf_peer_post_connect(freerdp_peer* client); BOOL mf_peer_activate(freerdp_peer* client); void mf_peer_synchronize_event(rdpInput* input, UINT32 flags); -void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); +BOOL mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); void* mf_peer_main_loop(void* arg); diff --git a/server/Mac/mfreerdp.c b/server/Mac/mfreerdp.c index ad6233c5c..0bcbe71d0 100644 --- a/server/Mac/mfreerdp.c +++ b/server/Mac/mfreerdp.c @@ -108,7 +108,8 @@ int main(int argc, char* argv[]) WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi()); - instance = freerdp_listener_new(); + if (!(instance = freerdp_listener_new())) + return 1; instance->PeerAccepted = mf_peer_accepted; diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 95b99f549..42cf3b147 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -52,23 +52,46 @@ static char* test_pcap_file = NULL; static BOOL test_dump_rfx_realtime = TRUE; -void test_peer_context_new(freerdp_peer* client, testPeerContext* context) +BOOL test_peer_context_new(freerdp_peer* client, testPeerContext* context) { - context->rfx_context = rfx_context_new(TRUE); + if (!(context->rfx_context = rfx_context_new(TRUE))) + goto fail_rfx_context; + context->rfx_context->mode = RLGR3; context->rfx_context->width = SAMPLE_SERVER_DEFAULT_WIDTH; context->rfx_context->height = SAMPLE_SERVER_DEFAULT_HEIGHT; rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_R8G8B8); - context->nsc_context = nsc_context_new(); + if (!(context->nsc_context = nsc_context_new())) + goto fail_nsc_context; + nsc_context_set_pixel_format(context->nsc_context, RDP_PIXEL_FORMAT_R8G8B8); - context->s = Stream_New(NULL, 65536); + if (!(context->s = Stream_New(NULL, 65536))) + goto fail_stream_new; context->icon_x = -1; context->icon_y = -1; context->vcm = WTSOpenServerA((LPSTR) client->context); + + if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE) + goto fail_open_server; + + return TRUE; + +fail_open_server: + context->vcm = NULL; + Stream_Free(context->s, TRUE); + context->s = NULL; +fail_stream_new: + nsc_context_free(context->nsc_context); + context->nsc_context = NULL; +fail_nsc_context: + rfx_context_free(context->rfx_context); + context->rfx_context = NULL; +fail_rfx_context: + return FALSE; } void test_peer_context_free(freerdp_peer* client, testPeerContext* context) @@ -105,12 +128,12 @@ void test_peer_context_free(freerdp_peer* client, testPeerContext* context) } } -static void test_peer_init(freerdp_peer* client) +static BOOL test_peer_init(freerdp_peer* client) { client->ContextSize = sizeof(testPeerContext); client->ContextNew = (psPeerContextNew) test_peer_context_new; client->ContextFree = (psPeerContextFree) test_peer_context_free; - freerdp_peer_context_new(client); + return freerdp_peer_context_new(client); } static wStream* test_peer_stream_init(testPeerContext* context) @@ -509,10 +532,20 @@ BOOL tf_peer_post_connect(freerdp_peer* client) if (context->debug_channel != NULL) { WLog_DBG(TAG, "Open channel rdpdbg."); - context->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!(context->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + WLog_ERR(TAG, "Failed to create stop event"); + return FALSE; + } - context->debug_channel_thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) tf_debug_channel_thread_func, (void*) context, 0, NULL); + if (!(context->debug_channel_thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) tf_debug_channel_thread_func, (void*) context, 0, NULL))) + { + WLog_ERR(TAG, "Failed to create debug channel thread"); + CloseHandle(context->stopEvent); + context->stopEvent = NULL; + return FALSE; + } } } @@ -674,7 +707,11 @@ static void* test_peer_mainloop(void* arg) testPeerContext* context; freerdp_peer* client = (freerdp_peer*) arg; - test_peer_init(client); + if (!test_peer_init(client)) + { + freerdp_peer_free(client); + return NULL; + } /* Initialize the real server settings here */ client->settings->CertificateFile = _strdup("server.crt"); @@ -740,12 +777,16 @@ static void* test_peer_mainloop(void* arg) return NULL; } -static void test_peer_accepted(freerdp_listener* instance, freerdp_peer* client) +static BOOL test_peer_accepted(freerdp_listener* instance, freerdp_peer* client) { HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_peer_mainloop, (void*) client, 0, NULL); + if (hThread != NULL) { CloseHandle(hThread); + return TRUE; } + + return FALSE; } static void test_server_mainloop(freerdp_listener* instance) diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index 96f7e80cf..1194b5098 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -37,7 +37,7 @@ static wfInfo* wfInfoInstance = NULL; static int _IDcount = 0; -int wf_info_lock(wfInfo* wfi) +BOOL wf_info_lock(wfInfo* wfi) { DWORD dRes; @@ -54,13 +54,13 @@ int wf_info_lock(wfInfo* wfi) case WAIT_FAILED: WLog_ERR(TAG, "wf_info_lock failed with 0x%08X", GetLastError()); - return -1; + return FALSE; } - return -1; + return FALSE; } -int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds) +BOOL wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds) { DWORD dRes; @@ -77,18 +77,18 @@ int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds) case WAIT_FAILED: WLog_ERR(TAG, "wf_info_try_lock failed with 0x%08X", GetLastError()); - return -1; + return FALSE; } - return -1; + return FALSE; } -int wf_info_unlock(wfInfo* wfi) +BOOL wf_info_unlock(wfInfo* wfi) { - if (ReleaseMutex(wfi->mutex) == 0) + if (!ReleaseMutex(wfi->mutex)) { WLog_ERR(TAG, "wf_info_unlock failed with 0x%08X", GetLastError()); - return -1; + return FALSE; } return TRUE; @@ -185,61 +185,70 @@ wfInfo* wf_info_get_instance() return wfInfoInstance; } -void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) +BOOL wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) { - if (wf_info_lock(wfi) > 0) - { - int i; - int peerId; - if (wfi->peerCount == WF_INFO_MAXPEERS) - { - context->socketClose = TRUE; - wf_info_unlock(wfi); - return; - } + int i; + int peerId; - context->info = wfi; - context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!wfi || !context) + return FALSE; - //get the offset of the top left corner of selected screen - EnumDisplayMonitors(NULL, NULL, wf_info_monEnumCB, 0); - _IDcount = 0; + if (!wf_info_lock(wfi)) + return FALSE; + + if (wfi->peerCount == WF_INFO_MAXPEERS) + goto fail_peer_count; + + context->info = wfi; + if (!(context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail_update_event; + + //get the offset of the top left corner of selected screen + EnumDisplayMonitors(NULL, NULL, wf_info_monEnumCB, 0); + _IDcount = 0; #ifdef WITH_DXGI_1_2 - if (wfi->peerCount == 0) - wf_dxgi_init(wfi); + if (wfi->peerCount == 0) + if (wf_dxgi_init(wfi) != 0) + goto fail_driver_init; #else - if (wf_mirror_driver_activate(wfi) == FALSE) - { - context->socketClose = TRUE; - wf_info_unlock(wfi); - return; - } + if (!wf_mirror_driver_activate(wfi)) + goto fail_driver_init; #endif - //look through the array of peers until an empty slot - for(i=0; ipeers[i] == NULL) { - //empty index will be our peer id - if (wfi->peers[i] == NULL) - { - peerId = i; - break; - } + peerId = i; + break; } - - wfi->peers[peerId] = ((rdpContext*) context)->peer; - wfi->peers[peerId]->pId = peerId; - wfi->peerCount++; - WLog_INFO(TAG, "Registering Peer: id=%d #=%d", peerId, wfi->peerCount); - wf_info_unlock(wfi); - - wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_CONNECT); } + + wfi->peers[peerId] = ((rdpContext*) context)->peer; + wfi->peers[peerId]->pId = peerId; + wfi->peerCount++; + + WLog_INFO(TAG, "Registering Peer: id=%d #=%d", peerId, wfi->peerCount); + wf_info_unlock(wfi); + wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_CONNECT); + + return TRUE; + +fail_driver_init: + CloseHandle(context->updateEvent); + context->updateEvent = NULL; +fail_update_event: +fail_peer_count: + context->socketClose = TRUE; + wf_info_unlock(wfi); + return FALSE; } void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context) { - if (wf_info_lock(wfi) > 0) + if (wf_info_lock(wfi)) { int peerId; diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index 38a3ae6c6..14ea6ea5c 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -25,12 +25,12 @@ #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); +BOOL wf_info_lock(wfInfo* wfi); +BOOL wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds); +BOOL wf_info_unlock(wfInfo* wfi); wfInfo* wf_info_get_instance(void); -void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context); +BOOL wf_info_peer_register(wfInfo* wfi, wfPeerContext* context); void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context); BOOL wf_info_have_updates(wfInfo* wfi); diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index c8cb3847f..a1ef07cec 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -38,11 +38,24 @@ #include "wf_peer.h" -void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context) +BOOL wf_peer_context_new(freerdp_peer* client, wfPeerContext* context) { - context->info = wf_info_get_instance(); + if (!(context->info = wf_info_get_instance())) + return FALSE; + context->vcm = WTSOpenServerA((LPSTR) client->context); - wf_info_peer_register(context->info, context); + + if (!context->vcm || context->vcm == INVALID_HANDLE_VALUE) + return FALSE; + + if (!wf_info_peer_register(context->info, context)) + { + WTSCloseServer(context->vcm); + context->vcm = NULL; + return FALSE; + } + + return TRUE; } void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) @@ -60,13 +73,13 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) WTSCloseServer(context->vcm); } -void wf_peer_init(freerdp_peer* client) +BOOL wf_peer_init(freerdp_peer* client) { client->ContextSize = sizeof(wfPeerContext); client->ContextNew = (psPeerContextNew) wf_peer_context_new; client->ContextFree = (psPeerContextFree) wf_peer_context_free; - - freerdp_peer_context_new(client); + + return freerdp_peer_context_new(client); } BOOL wf_peer_post_connect(freerdp_peer* client) @@ -75,14 +88,14 @@ BOOL wf_peer_post_connect(freerdp_peer* client) wfInfo* wfi; rdpSettings* settings; wfPeerContext* context = (wfPeerContext*) client->context; - + wfi = context->info; settings = client->settings; if ((get_screen_info(wfi->screenID, NULL, &wfi->servscreen_width, &wfi->servscreen_height, &wfi->bitsPerPixel) == 0) || - (wfi->servscreen_width == 0) || - (wfi->servscreen_height == 0) || - (wfi->bitsPerPixel == 0) ) + (wfi->servscreen_width == 0) || + (wfi->servscreen_height == 0) || + (wfi->bitsPerPixel == 0) ) { WLog_ERR(TAG, "postconnect: error getting screen info for screen %d", wfi->screenID); WLog_ERR(TAG, "\t%dx%dx%d", wfi->servscreen_height, wfi->servscreen_width, wfi->bitsPerPixel); @@ -95,11 +108,11 @@ BOOL wf_peer_post_connect(freerdp_peer* client) WLog_DBG(TAG, "Client requested resolution %dx%d, but will resize to %dx%d", settings->DesktopWidth, settings->DesktopHeight, wfi->servscreen_width, wfi->servscreen_height); */ - + settings->DesktopWidth = wfi->servscreen_width; settings->DesktopHeight = wfi->servscreen_height; settings->ColorDepth = wfi->bitsPerPixel; - + client->update->DesktopResize(client->update->context); } @@ -115,13 +128,13 @@ BOOL wf_peer_activate(freerdp_peer* client) { wfInfo* wfi; wfPeerContext* context = (wfPeerContext*) client->context; - + 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; } @@ -133,12 +146,15 @@ BOOL wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL void wf_peer_synchronize_event(rdpInput* input, UINT32 flags) { - + } -void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) +BOOL wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) { - CreateThread(NULL, 0, wf_peer_main_loop, client, 0, NULL); + if (!CreateThread(NULL, 0, wf_peer_main_loop, client, 0, NULL)) + return FALSE; + + return TRUE; } DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam) @@ -150,7 +166,7 @@ DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam) fd_set rfds_set; wfPeerContext* context; freerdp_peer* client = (freerdp_peer*) lpParam; - + ZeroMemory(rfds, sizeof(rfds)); context = (wfPeerContext*) client->context; @@ -181,7 +197,7 @@ DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam) break; select(max_fds + 1, &rfds_set, NULL, NULL, NULL); - + SetEvent(context->socketEvent); WaitForSingleObject(context->socketSemaphore, INFINITE); @@ -219,30 +235,33 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) _putenv(home); } - wf_peer_init(client); - + if (!wf_peer_init(client)) + goto fail_peer_init; + settings = client->settings; settings->RemoteFxCodec = TRUE; settings->ColorDepth = 32; settings->NSCodec = FALSE; settings->JpegCodec = FALSE; wf_peer_read_settings(client); - + client->PostConnect = wf_peer_post_connect; client->Activate = wf_peer_activate; client->Logon = wf_peer_logon; - + client->input->SynchronizeEvent = wf_peer_synchronize_event; client->input->KeyboardEvent = wf_peer_keyboard_event; client->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event; client->input->MouseEvent = wf_peer_mouse_event; client->input->ExtendedMouseEvent = wf_peer_extended_mouse_event; - - client->Initialize(client); - context = (wfPeerContext*) client->context; + + if (!client->Initialize(client)) + goto fail_client_initialize; if (context->socketClose) - return 0; + goto fail_socked_closed; + + context = (wfPeerContext*) client->context; wfi = context->info; @@ -255,10 +274,15 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) client->input->ExtendedMouseEvent = wf_peer_extended_mouse_event_dummy; } - context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL); - context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL); + if (!(context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail_socket_event; + + if (!(context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL))) + goto fail_socket_semaphore; + + if (!(context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL))) + goto fail_socket_thread; + WLog_INFO(TAG, "We've got a client %s", client->local ? "(local)" : client->hostname); nCount = 0; handles[nCount++] = context->updateEvent; @@ -319,11 +343,21 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam) } wf_update_peer_deactivate(wfi, context); - + client->Disconnect(client); - + +fail_socket_thread: + CloseHandle(context->socketSemaphore); + context->socketSemaphore = NULL; +fail_socket_semaphore: + CloseHandle(context->socketEvent); + context->socketEvent = NULL; +fail_socket_event: +fail_socked_closed: +fail_client_initialize: freerdp_peer_context_free(client); +fail_peer_init: freerdp_peer_free(client); - + return 0; } diff --git a/server/Windows/wf_peer.h b/server/Windows/wf_peer.h index 7d96d9146..7d8f1d0ea 100644 --- a/server/Windows/wf_peer.h +++ b/server/Windows/wf_peer.h @@ -26,10 +26,10 @@ -void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context); +BOOL wf_peer_context_new(freerdp_peer* client, wfPeerContext* context); void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context); -void wf_peer_init(freerdp_peer* client); +BOOL wf_peer_init(freerdp_peer* client); void wf_dxgi_encode(freerdp_peer* client, UINT timeout); void wf_rfx_encode(freerdp_peer* client); @@ -43,7 +43,7 @@ void wf_peer_send_changes(freerdp_peer* client); void wf_detect_win_ver(void); -void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); +BOOL wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); DWORD WINAPI wf_peer_main_loop(LPVOID lpParam); diff --git a/server/shadow/Win/win_rdp.c b/server/shadow/Win/win_rdp.c index c0a7789b1..7783a47d2 100644 --- a/server/shadow/Win/win_rdp.c +++ b/server/shadow/Win/win_rdp.c @@ -285,23 +285,29 @@ int shw_freerdp_client_stop(rdpContext* context) return 0; } -int shw_freerdp_client_new(freerdp* instance, rdpContext* context) +BOOL shw_freerdp_client_new(freerdp* instance, rdpContext* context) { shwContext* shw; rdpSettings* settings; shw = (shwContext*) instance->context; + if (!(shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + return FALSE; + + if (!(context->channels = freerdp_channels_new())) + { + CloseHandle(shw->StopEvent); + shw->StopEvent = NULL; + return FALSE; + } + instance->PreConnect = shw_pre_connect; instance->PostConnect = shw_post_connect; instance->Authenticate = shw_authenticate; instance->VerifyCertificate = shw_verify_certificate; instance->VerifyX509Certificate = shw_verify_x509_certificate; - context->channels = freerdp_channels_new(); - - shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - settings = instance->settings; shw->settings = instance->context->settings; @@ -355,7 +361,7 @@ int shw_freerdp_client_new(freerdp* instance, rdpContext* context) settings->RedirectClipboard = TRUE; settings->SupportDynamicChannels = TRUE; - return 0; + return TRUE; } void shw_freerdp_client_free(freerdp* instance, rdpContext* context) @@ -392,16 +398,28 @@ int win_shadow_rdp_init(winShadowSubsystem* subsystem) shw_RdpClientEntry(&clientEntryPoints); - context = freerdp_client_context_new(&clientEntryPoints); + if (!(subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail_enter_event; + + if (!(subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail_leave_event; + + if (!(context = freerdp_client_context_new(&clientEntryPoints))) + goto fail_context; subsystem->shw = (shwContext*) context; subsystem->shw->settings = context->settings; subsystem->shw->subsystem = subsystem; - subsystem->RdpUpdateEnterEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - subsystem->RdpUpdateLeaveEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - return 1; + +fail_context: + CloseHandle(subsystem->RdpUpdateLeaveEvent); +fail_leave_event: + CloseHandle(subsystem->RdpUpdateEnterEvent); +fail_enter_event: + + return -1; } int win_shadow_rdp_start(winShadowSubsystem* subsystem) diff --git a/server/shadow/shadow.c b/server/shadow/shadow.c index fa59c799b..0bba8d8ee 100644 --- a/server/shadow/shadow.c +++ b/server/shadow/shadow.c @@ -47,20 +47,19 @@ int main(int argc, char** argv) server = shadow_server_new(); if (!server) - return 0; + goto fail_server_new; - status = shadow_server_parse_command_line(server, argc, argv); + if ((status = shadow_server_parse_command_line(server, argc, argv)) < 0) + { + shadow_server_command_line_status_print(server, argc, argv, status); + goto fail_parse_command_line; + } - status = shadow_server_command_line_status_print(server, argc, argv, status); + if ((status = shadow_server_init(server)) < 0) + goto fail_server_init; - if (status < 0) - return 0; - - if (shadow_server_init(server) < 0) - return 0; - - if (shadow_server_start(server) < 0) - return 0; + if ((status = shadow_server_start(server)) < 0) + goto fail_server_start; if (g_MessagePump) { @@ -73,10 +72,18 @@ int main(int argc, char** argv) WaitForSingleObject(server->thread, INFINITE); - GetExitCodeThread(server->thread, &dwExitCode); + if (!GetExitCodeThread(server->thread, &dwExitCode)) + status = -1; + else + status = (int)dwExitCode; + +fail_server_start: + shadow_server_uninit(server); +fail_server_init: +fail_parse_command_line: shadow_server_free(server); - - return 0; +fail_server_new: + return status; } diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 757317034..15ee9de46 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -33,7 +33,7 @@ #define TAG CLIENT_TAG("shadow") -void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client) +BOOL shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client) { rdpSettings* settings; rdpShadowServer* server; @@ -62,10 +62,13 @@ void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client) settings->TlsSecurity = TRUE; settings->NlaSecurity = FALSE; - settings->CertificateFile = _strdup(server->CertificateFile); - settings->PrivateKeyFile = _strdup(server->PrivateKeyFile); + if (!(settings->CertificateFile = _strdup(server->CertificateFile))) + goto fail_cert_file; + if (!(settings->PrivateKeyFile = _strdup(server->PrivateKeyFile))) + goto fail_privkey_file; + if (!(settings->RdpKeyFile = _strdup(settings->PrivateKeyFile))) + goto fail_rdpkey_file; - settings->RdpKeyFile = _strdup(settings->PrivateKeyFile); if (server->ipcSocket) { @@ -77,17 +80,45 @@ void shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client) client->mayView = server->mayView; client->mayInteract = server->mayInteract; - InitializeCriticalSectionAndSpinCount(&(client->lock), 4000); + if (!InitializeCriticalSectionAndSpinCount(&(client->lock), 4000)) + goto fail_client_lock; region16_init(&(client->invalidRegion)); client->vcm = WTSOpenServerA((LPSTR) peer->context); + if (!client->vcm || client->vcm == INVALID_HANDLE_VALUE) + goto fail_open_server; - client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!(client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail_stop_event; - client->encoder = shadow_encoder_new(client); + if (!(client->encoder = shadow_encoder_new(client))) + goto fail_encoder_new; ArrayList_Add(server->clients, (void*) client); + + return TRUE; + +fail_encoder_new: + CloseHandle(client->encoder); + client->encoder = NULL; +fail_stop_event: + WTSCloseServer((HANDLE) client->vcm); + client->vcm = NULL; +fail_open_server: + DeleteCriticalSection(&(client->lock)); +fail_client_lock: + free(settings->RdpKeyFile); + settings->RdpKeyFile = NULL; +fail_rdpkey_file: + free(settings->PrivateKeyFile); + settings->PrivateKeyFile = NULL; +fail_privkey_file: + free(settings->CertificateFile); + settings->CertificateFile = NULL; +fail_cert_file: + + return FALSE; } void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client) @@ -1035,13 +1066,11 @@ void* shadow_client_thread(rdpShadowClient* client) freerdp_peer_context_free(peer); freerdp_peer_free(peer); - ExitThread(0); - return NULL; } -void shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer) +BOOL shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer) { rdpShadowClient* client; rdpShadowServer* server; @@ -1052,10 +1081,14 @@ void shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer) peer->ContextSize = sizeof(rdpShadowClient); peer->ContextNew = (psPeerContextNew) shadow_client_context_new; peer->ContextFree = (psPeerContextFree) shadow_client_context_free; - freerdp_peer_context_new(peer); + + if (!freerdp_peer_context_new(peer)) + return FALSE; client = (rdpShadowClient*) peer->context; client->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) shadow_client_thread, client, 0, NULL); + + return TRUE; } diff --git a/server/shadow/shadow_client.h b/server/shadow/shadow_client.h index d067554f0..a78e5411a 100644 --- a/server/shadow/shadow_client.h +++ b/server/shadow/shadow_client.h @@ -26,7 +26,7 @@ extern "C" { #endif int shadow_client_surface_update(rdpShadowClient* client, REGION16* region); -void shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client); +BOOL shadow_client_accepted(freerdp_listener* instance, freerdp_peer* client); #ifdef __cplusplus } diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c index dd778916a..6d8315d9b 100644 --- a/server/shadow/shadow_server.c +++ b/server/shadow/shadow_server.c @@ -534,26 +534,29 @@ int shadow_server_init(rdpShadowServer* server) WTSRegisterWtsApiFunctionTable(FreeRDP_InitWtsApi()); - server->clients = ArrayList_New(TRUE); + if (!(server->clients = ArrayList_New(TRUE))) + goto fail_client_array; - server->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!(server->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail_stop_event; - InitializeCriticalSectionAndSpinCount(&(server->lock), 4000); + if (!InitializeCriticalSectionAndSpinCount(&(server->lock), 4000)) + goto fail_server_lock; status = shadow_server_init_config_path(server); if (status < 0) - return -1; + goto fail_config_path; status = shadow_server_init_certificate(server); if (status < 0) - return -1; + goto fail_certificate; server->listener = freerdp_listener_new(); if (!server->listener) - return -1; + goto fail_listener; server->listener->info = (void*) server; server->listener->PeerAccepted = shadow_client_accepted; @@ -561,11 +564,35 @@ int shadow_server_init(rdpShadowServer* server) server->subsystem = shadow_subsystem_new(NULL); if (!server->subsystem) - return -1; + goto fail_subsystem_new; status = shadow_subsystem_init(server->subsystem, server); - return status; + if (status >= 0) + return status; + +fail_subsystem_new: + freerdp_listener_free(server->listener); + server->listener = NULL; +fail_listener: + free(server->CertificateFile); + server->CertificateFile = NULL; + free(server->PrivateKeyFile); + server->PrivateKeyFile = NULL; +fail_certificate: + free(server->ConfigPath); + server->ConfigPath = NULL; +fail_config_path: + DeleteCriticalSection(&(server->lock)); +fail_server_lock: + CloseHandle(server->StopEvent); + server->StopEvent = NULL; +fail_stop_event: + ArrayList_Free(server->clients); + server->clients = NULL; +fail_client_array: + WLog_ERR(TAG, "Failed to initialize shadow server"); + return -1; } int shadow_server_uninit(rdpShadowServer* server) diff --git a/server/shadow/shadow_subsystem.c b/server/shadow/shadow_subsystem.c index ac4fd70ce..5ec0fdf0b 100644 --- a/server/shadow/shadow_subsystem.c +++ b/server/shadow/shadow_subsystem.c @@ -126,32 +126,52 @@ rdpShadowSubsystem* shadow_subsystem_new(const char* name) void shadow_subsystem_free(rdpShadowSubsystem* subsystem) { - if (subsystem->ep.Free) + if (subsystem && subsystem->ep.Free) subsystem->ep.Free(subsystem); } int shadow_subsystem_init(rdpShadowSubsystem* subsystem, rdpShadowServer* server) { - int status; + int status = -1; + + if (!subsystem || !subsystem->ep.Init) + return -1; subsystem->server = server; subsystem->selectedMonitor = server->selectedMonitor; - subsystem->MsgPipe = MessagePipe_New(); - subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!(subsystem->MsgPipe = MessagePipe_New())) + goto fail; + + if (!(subsystem->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail; region16_init(&(subsystem->invalidRegion)); - if (!subsystem->ep.Init) - return -1; + if ((status = subsystem->ep.Init(subsystem)) >= 0) + return status; - status = subsystem->ep.Init(subsystem); +fail: + if (subsystem->MsgPipe) + { + MessagePipe_Free(subsystem->MsgPipe); + subsystem->MsgPipe = NULL; + } + + if (subsystem->updateEvent) + { + CloseHandle(subsystem->updateEvent); + subsystem->updateEvent = NULL; + } return status; } void shadow_subsystem_uninit(rdpShadowSubsystem* subsystem) { + if (!subsystem) + return; + if (subsystem->ep.Uninit) subsystem->ep.Uninit(subsystem); @@ -175,7 +195,7 @@ int shadow_subsystem_start(rdpShadowSubsystem* subsystem) { int status; - if (!subsystem->ep.Start) + if (!subsystem || !subsystem->ep.Start) return -1; status = subsystem->ep.Start(subsystem); @@ -187,7 +207,7 @@ int shadow_subsystem_stop(rdpShadowSubsystem* subsystem) { int status; - if (!subsystem->ep.Stop) + if (!subsystem || !subsystem->ep.Stop) return -1; status = subsystem->ep.Stop(subsystem); diff --git a/winpr/libwinpr/comm/test/TestCommMonitor.c b/winpr/libwinpr/comm/test/TestCommMonitor.c index 1154b2789..41c20812a 100644 --- a/winpr/libwinpr/comm/test/TestCommMonitor.c +++ b/winpr/libwinpr/comm/test/TestCommMonitor.c @@ -21,7 +21,7 @@ int TestCommMonitor(int argc, char* argv[]) if (!hComm || (hComm == INVALID_HANDLE_VALUE)) { printf("CreateFileA failure: %s\n", lpFileName); - return 0; + return -1; } fSuccess = SetCommMask(hComm, EV_CTS | EV_DSR); @@ -29,11 +29,15 @@ int TestCommMonitor(int argc, char* argv[]) if (!fSuccess) { printf("SetCommMask failure: GetLastError() = %d\n", (int) GetLastError()); - return 0; + return -1; } ZeroMemory(&overlapped, sizeof(OVERLAPPED)); - overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!(overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + printf("CreateEvent failed: GetLastError() = %d\n", (int) GetLastError()); + return -1; + } if (WaitCommEvent(hComm, &dwEvtMask, &overlapped)) { @@ -58,7 +62,7 @@ int TestCommMonitor(int argc, char* argv[]) else { printf("WaitCommEvent failure: GetLastError() = %d\n", (int) dwError); - return 0; + return -1; } } diff --git a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c index d55f78b39..c9e7b2bc9 100644 --- a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c +++ b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipe.c @@ -439,10 +439,26 @@ int TestPipeCreateNamedPipe(int argc, char* argv[]) #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); #endif - ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - SingleThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_single_thread, NULL, 0, NULL); - ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL); - ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL); + if (!(ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + printf("CreateEvent failure: (%d)\n", GetLastError()); + return -1; + } + if (!(SingleThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_single_thread, NULL, 0, NULL))) + { + printf("CreateThread (SingleThread) failure: (%d)\n", GetLastError()); + return -1; + } + if (!(ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL))) + { + printf("CreateThread (ClientThread) failure: (%d)\n", GetLastError()); + return -1; + } + if (!(ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL))) + { + printf("CreateThread (ServerThread) failure: (%d)\n", GetLastError()); + return -1; + } WaitForSingleObject(SingleThread, INFINITE); WaitForSingleObject(ClientThread, INFINITE); WaitForSingleObject(ServerThread, INFINITE); diff --git a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c index 584c0f730..6bda1f35e 100644 --- a/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c +++ b/winpr/libwinpr/pipe/test/TestPipeCreateNamedPipeOverlapped.c @@ -53,7 +53,13 @@ static void* named_pipe_client_thread(void* arg) return NULL; } ZeroMemory(&overlapped, sizeof(OVERLAPPED)); - hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + printf("CreateEvent failure: (%d)\n", GetLastError()); + return NULL; + } + overlapped.hEvent = hEvent; nNumberOfBytesToWrite = PIPE_BUFFER_SIZE; FillMemory(lpWriteBuffer, PIPE_BUFFER_SIZE, 0x59); @@ -137,7 +143,13 @@ static void* named_pipe_server_thread(void* arg) SetEvent(ReadyEvent); ZeroMemory(&overlapped, sizeof(OVERLAPPED)); - hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + printf("CreateEvent failure: (%d)\n", GetLastError()); + return NULL; + } + overlapped.hEvent = hEvent; fConnected = ConnectNamedPipe(hNamedPipe, &overlapped); printf("ConnectNamedPipe status: %d\n", GetLastError()); @@ -222,11 +234,26 @@ int TestPipeCreateNamedPipeOverlapped(int argc, char* argv[]) { HANDLE ClientThread; HANDLE ServerThread; - ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL); - ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL); + + if (!(ReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + printf("CreateEvent failed: %d\n", GetLastError()); + return -1; + } + if (!(ClientThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_client_thread, NULL, 0, NULL))) + { + printf("CreateThread (client) failed: %d\n", GetLastError()); + return -1; + } + if (!(ServerThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) named_pipe_server_thread, NULL, 0, NULL))) + { + printf("CreateThread (server) failed: %d\n", GetLastError()); + return -1; + } + WaitForSingleObject(ClientThread, INFINITE); WaitForSingleObject(ServerThread, INFINITE); + + /* FIXME: Since this function always returns 0 this test is very much useless */ return 0; } - diff --git a/winpr/libwinpr/pool/pool.c b/winpr/libwinpr/pool/pool.c index 0b097e81d..978caaef0 100644 --- a/winpr/libwinpr/pool/pool.c +++ b/winpr/libwinpr/pool/pool.c @@ -60,10 +60,12 @@ static void module_init() static TP_POOL DEFAULT_POOL = { - 0, /* Minimum */ - 500, /* Maximum */ - NULL, /* Threads */ - 0, /* ThreadCount */ + 0, /* DWORD Minimum */ + 500, /* DWORD Maximum */ + NULL, /* wArrayList* Threads */ + NULL, /* wQueue* PendingQueue */ + NULL, /* HANDLE TerminateEvent */ + NULL, /* wCountdownEvent* WorkComplete */ }; static void* thread_pool_work_func(void* arg) @@ -110,33 +112,62 @@ static void threads_close(void *thread) CloseHandle(thread); } -void InitializeThreadpool(PTP_POOL pool) +static BOOL InitializeThreadpool(PTP_POOL pool) { int index; HANDLE thread; - if (!pool->Threads) + if (pool->Threads) + return TRUE; + + pool->Minimum = 0; + pool->Maximum = 500; + + if (!(pool->PendingQueue = Queue_New(TRUE, -1, -1))) + goto fail_queue_new; + + if (!(pool->WorkComplete = CountdownEvent_New(0))) + goto fail_countdown_event; + + if (!(pool->TerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail_terminate_event; + + if (!(pool->Threads = ArrayList_New(TRUE))) + goto fail_thread_array; + + pool->Threads->object.fnObjectFree = threads_close; + + for (index = 0; index < 4; index++) { - pool->Minimum = 0; - pool->Maximum = 500; - - pool->Threads = ArrayList_New(TRUE); - pool->Threads->object.fnObjectFree = threads_close; - - pool->PendingQueue = Queue_New(TRUE, -1, -1); - pool->WorkComplete = CountdownEvent_New(0); - - pool->TerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - - for (index = 0; index < 4; index++) - { - thread = CreateThread(NULL, 0, + if (!(thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_pool_work_func, - (void*) pool, 0, NULL); - - ArrayList_Add(pool->Threads, thread); + (void*) pool, 0, NULL))) + { + goto fail_create_threads; } + + ArrayList_Add(pool->Threads, thread); } + + return TRUE; + +fail_create_threads: + SetEvent(pool->TerminateEvent); + ArrayList_Free(pool->Threads); + pool->Threads = NULL; +fail_thread_array: + CloseHandle(pool->TerminateEvent); + pool->TerminateEvent = NULL; +fail_terminate_event: + CountdownEvent_Free(pool->WorkComplete); + pool->WorkComplete = NULL; +fail_countdown_event: + Queue_Free(pool->PendingQueue); + pool->WorkComplete = NULL; +fail_queue_new: + + return FALSE; + } PTP_POOL GetDefaultThreadpool() @@ -145,7 +176,8 @@ PTP_POOL GetDefaultThreadpool() pool = &DEFAULT_POOL; - InitializeThreadpool(pool); + if (!InitializeThreadpool(pool)) + return NULL; return pool; } @@ -164,13 +196,17 @@ PTP_POOL CreateThreadpool(PVOID reserved) if (pCreateThreadpool) return pCreateThreadpool(reserved); #else - pool = (PTP_POOL) calloc(1, sizeof(TP_POOL)); + if (!(pool = (PTP_POOL) calloc(1, sizeof(TP_POOL)))) + return NULL; - if (pool) - InitializeThreadpool(pool); -#endif + if (!InitializeThreadpool(pool)) + { + free(pool); + return NULL; + } return pool; +#endif } VOID CloseThreadpool(PTP_POOL ptpp) @@ -188,7 +224,17 @@ VOID CloseThreadpool(PTP_POOL ptpp) CountdownEvent_Free(ptpp->WorkComplete); CloseHandle(ptpp->TerminateEvent); - free(ptpp); + if (ptpp == &DEFAULT_POOL) + { + ptpp->Threads = NULL; + ptpp->PendingQueue = NULL; + ptpp->WorkComplete = NULL; + ptpp->TerminateEvent = NULL; + } + else + { + free(ptpp); + } #endif } diff --git a/winpr/libwinpr/pool/test/TestPoolThread.c b/winpr/libwinpr/pool/test/TestPoolThread.c index d842beaed..a26562484 100644 --- a/winpr/libwinpr/pool/test/TestPoolThread.c +++ b/winpr/libwinpr/pool/test/TestPoolThread.c @@ -18,7 +18,11 @@ int TestPoolThread(int argc, char* argv[]) { TP_POOL* pool; - pool = CreateThreadpool(NULL); + if (!(pool = CreateThreadpool(NULL))) + { + printf("CreateThreadpool failed\n"); + return -1; + } SetThreadpoolThreadMinimum(pool, 8); /* default is 0 */ SetThreadpoolThreadMaximum(pool, 64); /* default is 500 */ diff --git a/winpr/libwinpr/pool/test/TestPoolWork.c b/winpr/libwinpr/pool/test/TestPoolWork.c index 2a8f3116d..64680b727 100644 --- a/winpr/libwinpr/pool/test/TestPoolWork.c +++ b/winpr/libwinpr/pool/test/TestPoolWork.c @@ -58,7 +58,11 @@ int TestPoolWork(int argc, char* argv[]) printf("Private Thread Pool\n"); - pool = CreateThreadpool(NULL); + if (!(pool = CreateThreadpool(NULL))) + { + printf("CreateThreadpool failure\n"); + return -1; + } SetThreadpoolThreadMinimum(pool, 4); SetThreadpoolThreadMaximum(pool, 8); diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index 38d013f31..81c244285 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -1398,8 +1398,14 @@ WINSCARDAPI HANDLE WINAPI PCSC_SCardAccessStartedEvent(void) if (!g_StartedEvent) { - g_StartedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - SetEvent(g_StartedEvent); + if (!(g_StartedEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) + return NULL; + + if (!SetEvent(g_StartedEvent)) + { + CloseHandle(g_StartedEvent); + return NULL; + } } g_StartedEventRefCount++; diff --git a/winpr/libwinpr/synch/test/TestSynchBarrier.c b/winpr/libwinpr/synch/test/TestSynchBarrier.c index 6b2258016..9835ff500 100644 --- a/winpr/libwinpr/synch/test/TestSynchBarrier.c +++ b/winpr/libwinpr/synch/test/TestSynchBarrier.c @@ -36,12 +36,26 @@ int TestSynchBarrier(int argc, char* argv[]) g_Count = 0; - g_Event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!(g_Event = CreateEvent(NULL, TRUE, FALSE, NULL))) + { + printf("%s: CreateEvent failed. GetLastError() = 0x%08x", __FUNCTION__, GetLastError()); + return -1; + } - InitializeCriticalSectionAndSpinCount(&g_Lock, 4000); + if (!InitializeCriticalSectionAndSpinCount(&g_Lock, 4000)) + { + printf("%s: InitializeCriticalSectionAndSpinCount failed. GetLastError() = 0x%08x", __FUNCTION__, GetLastError()); + CloseHandle(g_Event); + return -1; + } if (!InitializeSynchronizationBarrier(&g_Barrier, 5, -1)) + { + printf("%s: InitializeSynchronizationBarrier failed. GetLastError() = 0x%08x", __FUNCTION__, GetLastError()); + DeleteCriticalSection(&g_Lock); + CloseHandle(g_Event); return -1; + } for (index = 0; index < 5; index++) { diff --git a/winpr/libwinpr/synch/test/TestSynchTimerQueue.c b/winpr/libwinpr/synch/test/TestSynchTimerQueue.c index db1261aa9..e6822a898 100644 --- a/winpr/libwinpr/synch/test/TestSynchTimerQueue.c +++ b/winpr/libwinpr/synch/test/TestSynchTimerQueue.c @@ -57,6 +57,11 @@ int TestSynchTimerQueue(int argc, char* argv[]) APC_DATA apcData[TIMER_COUNT]; g_Event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!g_Event) + { + printf("CreateEvent failed (%d)\n", (int) GetLastError()); + return -1; + } hTimerQueue = CreateTimerQueue(); diff --git a/winpr/libwinpr/synch/test/TestSynchWaitableTimerAPC.c b/winpr/libwinpr/synch/test/TestSynchWaitableTimerAPC.c index cff535da2..a7120d1aa 100644 --- a/winpr/libwinpr/synch/test/TestSynchWaitableTimerAPC.c +++ b/winpr/libwinpr/synch/test/TestSynchWaitableTimerAPC.c @@ -44,9 +44,16 @@ int TestSynchWaitableTimerAPC(int argc, char* argv[]) if (!apcData) { printf("Memory allocation failed\n"); - return -1; + goto cleanup; } + g_Event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!g_Event) + { + printf("Failed to create event\n"); + goto cleanup; + } + hTimer = CreateWaitableTimer(NULL, FALSE, NULL); if (!hTimer) diff --git a/winpr/libwinpr/utils/collections/CountdownEvent.c b/winpr/libwinpr/utils/collections/CountdownEvent.c index ea50f4219..a29121a88 100644 --- a/winpr/libwinpr/utils/collections/CountdownEvent.c +++ b/winpr/libwinpr/utils/collections/CountdownEvent.c @@ -152,20 +152,32 @@ wCountdownEvent* CountdownEvent_New(DWORD initialCount) { wCountdownEvent* countdown = NULL; - countdown = (wCountdownEvent*) malloc(sizeof(wCountdownEvent)); + if (!(countdown = (wCountdownEvent*) calloc(1, sizeof(wCountdownEvent)))) + return NULL; - if (countdown) - { - countdown->count = initialCount; - countdown->initialCount = initialCount; - InitializeCriticalSectionAndSpinCount(&countdown->lock, 4000); - countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL); + countdown->count = initialCount; + countdown->initialCount = initialCount; - if (countdown->count == 0) - SetEvent(countdown->event); - } + if (!InitializeCriticalSectionAndSpinCount(&countdown->lock, 4000)) + goto fail_critical_section; + + if (!(countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL))) + goto fail_create_event; + + if (countdown->count == 0) + if (!SetEvent(countdown->event)) + goto fail_set_event; return countdown; + +fail_set_event: + CloseHandle(countdown->event); +fail_create_event: + DeleteCriticalSection(&countdown->lock); +fail_critical_section: + free(countdown); + + return NULL; } void CountdownEvent_Free(wCountdownEvent* countdown) From 7edb38df8421c84c6dbe1a90a915852155d64a12 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Thu, 30 Apr 2015 09:20:34 +0200 Subject: [PATCH 2/2] Increase API version to 1.2.3 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0acd44ea..2dd76a5f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ endif() set(WITH_LIBRARY_VERSIONING "ON") set(FREERDP_VERSION_MAJOR "1") set(FREERDP_VERSION_MINOR "2") -set(FREERDP_VERSION_REVISION "2") +set(FREERDP_VERSION_REVISION "3") set(FREERDP_VERSION_SUFFIX "dev") set(FREERDP_API_VERSION "${FREERDP_VERSION_MAJOR}.${FREERDP_VERSION_MINOR}") set(FREERDP_VERSION "${FREERDP_API_VERSION}.${FREERDP_VERSION_REVISION}")