From 71a4349928e7fb753e7b14d7d861f728f9840c04 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Fri, 8 May 2015 21:39:23 +0200 Subject: [PATCH] fixed multiple missing gdi return value checks mainly gdi_Create* functions --- CMakeLists.txt | 2 +- client/Android/FreeRDPCore/jni/android_freerdp.c | 3 +- client/DirectFB/dfreerdp.c | 4 +- client/Mac/MRDPView.m | 9 +- client/Sample/freerdp.c | 3 +- client/Wayland/wlfreerdp.c | 4 +- client/Windows/wf_client.c | 12 +- client/X11/xf_client.c | 46 +++++--- client/X11/xf_graphics.c | 42 ++++--- client/X11/xf_graphics.h | 2 +- include/freerdp/gdi/gdi.h | 4 +- libfreerdp/core/connection.c | 10 +- libfreerdp/gdi/dc.c | 45 +++++--- libfreerdp/gdi/gdi.c | 139 ++++++++++++++++------- libfreerdp/gdi/graphics.c | 2 +- libfreerdp/gdi/test/TestGdiBitBlt.c | 40 ++++++- libfreerdp/gdi/test/TestGdiClip.c | 14 ++- libfreerdp/gdi/test/TestGdiCreate.c | 51 +++++++-- libfreerdp/gdi/test/TestGdiEllipse.c | 7 +- libfreerdp/gdi/test/TestGdiLine.c | 7 +- libfreerdp/gdi/test/TestGdiRect.c | 7 +- server/shadow/Win/win_rdp.c | 4 +- 22 files changed, 330 insertions(+), 127 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63bd72c..db8ac33 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 "3") +set(FREERDP_VERSION_REVISION "4") set(FREERDP_VERSION_SUFFIX "dev") set(FREERDP_API_VERSION "${FREERDP_VERSION_MAJOR}.${FREERDP_VERSION_MINOR}") set(FREERDP_VERSION "${FREERDP_API_VERSION}.${FREERDP_VERSION_REVISION}") diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 82685257..54a89c7 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -240,7 +240,8 @@ static BOOL android_post_connect(freerdp* instance) else gdi_flags = CLRBUF_16BPP; - gdi_init(instance, gdi_flags, NULL); + if (!gdi_init(instance, gdi_flags, NULL)) + return FALSE; instance->update->BeginPaint = android_begin_paint; instance->update->EndPaint = android_end_paint; diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c index 5e26078..2c6d1ef 100644 --- a/client/DirectFB/dfreerdp.c +++ b/client/DirectFB/dfreerdp.c @@ -193,7 +193,9 @@ BOOL df_post_connect(freerdp* instance) context = ((dfContext*) instance->context); dfi = context->dfi; - gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL); + if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL)) + return FALSE; + gdi = instance->context->gdi; dfi->err = DirectFBCreate(&(dfi->dfb)); diff --git a/client/Mac/MRDPView.m b/client/Mac/MRDPView.m index ce18f3c..0946d3d 100644 --- a/client/Mac/MRDPView.m +++ b/client/Mac/MRDPView.m @@ -967,9 +967,11 @@ BOOL mac_post_connect(freerdp* instance) //else // flags |= CLRBUF_16BPP; - gdi_init(instance, flags, NULL); - gdi = instance->context->gdi; + if (!gdi_init(instance, flags, NULL)) + return FALSE; + gdi = instance->context->gdi; + view->bitmap_context = mac_create_bitmap_context(instance->context); pointer_cache_register_callbacks(instance->update); @@ -1245,7 +1247,8 @@ BOOL mac_desktop_resize(rdpContext* context) mfc->width = settings->DesktopWidth; mfc->height = settings->DesktopHeight; - gdi_resize(context->gdi, mfc->width, mfc->height); + if (!gdi_resize(context->gdi, mfc->width, mfc->height)) + return FALSE; view->bitmap_context = mac_create_bitmap_context(context); if (!view->bitmap_context) diff --git a/client/Sample/freerdp.c b/client/Sample/freerdp.c index 70722f6..4784e4b 100644 --- a/client/Sample/freerdp.c +++ b/client/Sample/freerdp.c @@ -116,7 +116,8 @@ static BOOL tf_pre_connect(freerdp* instance) static BOOL tf_post_connect(freerdp* instance) { - gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL); + if (!gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL)) + return FALSE; instance->update->BeginPaint = tf_begin_paint; instance->update->EndPaint = tf_end_paint; diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 5d96f27..d29ce2c 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -118,7 +118,9 @@ static BOOL wl_post_connect(freerdp* instance) wlfWindow* window; wlfContext* context; - gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, NULL); + if (!gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, NULL)) + return FALSE; + gdi = instance->context->gdi; if (!gdi) return FALSE; diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index f07e2ab..3e992d2 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -148,7 +148,10 @@ BOOL wf_sw_desktop_resize(wfContext* wfc) wf_image_free(wfc->primary); wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, NULL); } - gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, wfc->primary->pdata); + + if (!gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, wfc->primary->pdata)) + return FALSE; + gdi = instance->context->gdi; wfc->hdc = gdi->primary->hdc; return TRUE; @@ -378,7 +381,8 @@ BOOL wf_post_connect(freerdp* instance) { wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, NULL); - gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, wfc->primary->pdata); + if (!gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, wfc->primary->pdata)) + return FALSE; gdi = instance->context->gdi; wfc->hdc = gdi->primary->hdc; @@ -389,7 +393,9 @@ BOOL wf_post_connect(freerdp* instance) wfc->srcBpp = instance->settings->ColorDepth; wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, NULL); - wfc->hdc = gdi_GetDC(); + if (!(wfc->hdc = gdi_GetDC())) + return FALSE; + wfc->hdc->bitsPerPixel = wfc->dstBpp; wfc->hdc->bytesPerPixel = wfc->dstBpp / 8; diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 4338842..70b9f79 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -222,7 +222,7 @@ void xf_draw_screen(xfContext* xfc, int x, int y, int w, int h) XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y); } -static void xf_desktop_resize(rdpContext* context) +static BOOL xf_desktop_resize(rdpContext* context) { rdpSettings* settings; xfContext* xfc = (xfContext*) context; @@ -232,7 +232,8 @@ static void xf_desktop_resize(rdpContext* context) { BOOL same = (xfc->primary == xfc->drawing) ? TRUE : FALSE; XFreePixmap(xfc->display, xfc->primary); - xfc->primary = XCreatePixmap(xfc->display, xfc->drawable, xfc->sessionWidth, xfc->sessionHeight, xfc->depth); + if (!(xfc->primary = XCreatePixmap(xfc->display, xfc->drawable, xfc->sessionWidth, xfc->sessionHeight, xfc->depth))) + return FALSE; if (same) xfc->drawing = xfc->primary; } @@ -265,6 +266,8 @@ static void xf_desktop_resize(rdpContext* context) XSetForeground(xfc->display, xfc->gc, 0); XFillRectangle(xfc->display, xfc->drawable, xfc->gc, 0, 0, xfc->window->width, xfc->window->height); } + + return TRUE; } BOOL xf_sw_begin_paint(rdpContext* context) @@ -350,27 +353,33 @@ BOOL xf_sw_desktop_resize(rdpContext* context) { rdpGdi* gdi = context->gdi; xfContext* xfc = (xfContext*) context; + BOOL ret = FALSE; xf_lock_x11(xfc, TRUE); xfc->sessionWidth = context->settings->DesktopWidth; xfc->sessionHeight = context->settings->DesktopHeight; - gdi_resize(gdi, xfc->sessionWidth, xfc->sessionHeight); + if (!gdi_resize(gdi, xfc->sessionWidth, xfc->sessionHeight)) + goto out; if (xfc->image) { xfc->image->data = NULL; XDestroyImage(xfc->image); - xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, - (char*) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0); + if (!(xfc->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0, + (char*) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0))) + { + goto out; + } } - xf_desktop_resize(context); + ret = xf_desktop_resize(context); +out: xf_unlock_x11(xfc, TRUE); - return TRUE; + return ret; } BOOL xf_hw_begin_paint(rdpContext* context) @@ -457,16 +466,17 @@ BOOL xf_hw_desktop_resize(rdpContext* context) { xfContext* xfc = (xfContext*) context; rdpSettings* settings = xfc->settings; + BOOL ret; xf_lock_x11(xfc, TRUE); xfc->sessionWidth = settings->DesktopWidth; xfc->sessionHeight = settings->DesktopHeight; - xf_desktop_resize(context); + ret = xf_desktop_resize(context); xf_unlock_x11(xfc, TRUE); - return TRUE; + return ret; } BOOL xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) @@ -521,7 +531,8 @@ BOOL xf_create_window(xfContext* xfc) height = xfc->sessionHeight; if (!xfc->hdc) - xfc->hdc = gdi_CreateDC(CLRBUF_32BPP, xfc->bpp); + if (!(xfc->hdc = gdi_CreateDC(CLRBUF_32BPP, xfc->bpp))) + return FALSE; if (!xfc->remote_app) { @@ -1060,7 +1071,11 @@ BOOL xf_post_connect(freerdp* instance) settings = instance->settings; update = context->update; - xf_register_graphics(context->graphics); + if (!xf_register_graphics(context->graphics)) + { + WLog_ERR(TAG, "failed to register graphics"); + return FALSE; + } flags = CLRCONV_ALPHA; @@ -1073,7 +1088,8 @@ BOOL xf_post_connect(freerdp* instance) { rdpGdi* gdi; - gdi_init(instance, flags, NULL); + if (!gdi_init(instance, flags, NULL)) + return FALSE; gdi = context->gdi; xfc->primary_buffer = gdi->primary_buffer; @@ -1112,7 +1128,11 @@ BOOL xf_post_connect(freerdp* instance) if (settings->RemoteApplicationMode) xfc->remote_app = TRUE; - xf_create_window(xfc); + if (!xf_create_window(xfc)) + { + WLog_ERR(TAG, "xf_create_window failed"); + return FALSE; + } if (settings->SoftwareGdi) { diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 8a6b4eb..4ea4bb0 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -469,19 +469,23 @@ BOOL xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, /* Graphics Module */ -void xf_register_graphics(rdpGraphics* graphics) +BOOL xf_register_graphics(rdpGraphics* graphics) { - rdpBitmap* bitmap; - rdpPointer* pointer; - rdpGlyph* glyph; + rdpBitmap* bitmap = NULL; + rdpPointer* pointer = NULL; + rdpGlyph* glyph = NULL; + BOOL ret = FALSE; + + if (!(bitmap = (rdpBitmap*) calloc(1, sizeof(rdpBitmap)))) + goto out; - bitmap = (rdpBitmap*) calloc(1, sizeof(rdpBitmap)); + if (!(pointer = (rdpPointer*) calloc(1, sizeof(rdpPointer)))) + goto out; - if (!bitmap) - return; + if (!(glyph = (rdpGlyph*) calloc(1, sizeof(rdpGlyph)))) + goto out; bitmap->size = sizeof(xfBitmap); - bitmap->New = xf_Bitmap_New; bitmap->Free = xf_Bitmap_Free; bitmap->Paint = xf_Bitmap_Paint; @@ -489,15 +493,8 @@ void xf_register_graphics(rdpGraphics* graphics) bitmap->SetSurface = xf_Bitmap_SetSurface; graphics_register_bitmap(graphics, bitmap); - free(bitmap); - - pointer = (rdpPointer*) calloc(1, sizeof(rdpPointer)); - - if (!pointer) - return; pointer->size = sizeof(xfPointer); - pointer->New = xf_Pointer_New; pointer->Free = xf_Pointer_Free; pointer->Set = xf_Pointer_Set; @@ -506,15 +503,8 @@ void xf_register_graphics(rdpGraphics* graphics) pointer->SetPosition = xf_Pointer_SetPosition; graphics_register_pointer(graphics, pointer); - free(pointer); - - glyph = (rdpGlyph*) calloc(1, sizeof(rdpGlyph)); - - if (!glyph) - return; glyph->size = sizeof(xfGlyph); - glyph->New = xf_Glyph_New; glyph->Free = xf_Glyph_Free; glyph->Draw = xf_Glyph_Draw; @@ -522,5 +512,13 @@ void xf_register_graphics(rdpGraphics* graphics) glyph->EndDraw = xf_Glyph_EndDraw; graphics_register_glyph(graphics, glyph); + + ret = TRUE; + +out: + free(bitmap); + free(pointer); free(glyph); + + return ret; } diff --git a/client/X11/xf_graphics.h b/client/X11/xf_graphics.h index 8363bf5..b5871d5 100644 --- a/client/X11/xf_graphics.h +++ b/client/X11/xf_graphics.h @@ -23,6 +23,6 @@ #include "xf_client.h" #include "xfreerdp.h" -void xf_register_graphics(rdpGraphics* graphics); +BOOL xf_register_graphics(rdpGraphics* graphics); #endif /* __XF_GRAPHICS_H */ diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h index a3a4cad..f00c256 100644 --- a/include/freerdp/gdi/gdi.h +++ b/include/freerdp/gdi/gdi.h @@ -317,9 +317,9 @@ FREERDP_API UINT32 gdi_rop3_code(BYTE code); FREERDP_API UINT32 gdi_get_pixel_format(UINT32 bitsPerPixel, BOOL vFlip); FREERDP_API BYTE* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y); FREERDP_API BYTE* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y); -FREERDP_API void gdi_resize(rdpGdi* gdi, int width, int height); +FREERDP_API BOOL gdi_resize(rdpGdi* gdi, int width, int height); -FREERDP_API int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer); +FREERDP_API BOOL gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer); FREERDP_API void gdi_free(freerdp* instance); #ifdef __cplusplus diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index 9832959..93622fc 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -825,7 +825,15 @@ int rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s) */ if (width != rdp->settings->DesktopWidth || height != rdp->settings->DesktopHeight) { - IFCALL(rdp->update->DesktopResize, rdp->update->context); + BOOL status = TRUE; + + IFCALLRET(rdp->update->DesktopResize, status, rdp->update->context); + + if (!status) + { + WLog_ERR(TAG, "client desktop resize callback failed"); + return -1; + } } rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION); diff --git a/libfreerdp/gdi/dc.c b/libfreerdp/gdi/dc.c index 5a05f7a..037cfdb 100644 --- a/libfreerdp/gdi/dc.c +++ b/libfreerdp/gdi/dc.c @@ -66,10 +66,16 @@ HGDI_DC gdi_GetDC() HGDI_DC gdi_CreateDC(UINT32 flags, int bpp) { - HGDI_DC hDC = (HGDI_DC) malloc(sizeof(GDI_DC)); + HGDI_DC hDC; + + if (!(hDC = (HGDI_DC) calloc(1, sizeof(GDI_DC)))) + return NULL; hDC->drawMode = GDI_R2_BLACK; - hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0); + + if (!(hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0))) + goto fail; + hDC->clip->null = 1; hDC->hwnd = NULL; @@ -80,15 +86,26 @@ HGDI_DC gdi_CreateDC(UINT32 flags, int bpp) hDC->invert = (flags & CLRCONV_INVERT) ? TRUE : FALSE; hDC->rgb555 = (flags & CLRCONV_RGB555) ? TRUE : FALSE; - hDC->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); - hDC->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + if (!(hDC->hwnd = (HGDI_WND) calloc(1, sizeof(GDI_WND)))) + goto fail; + + if (!(hDC->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0))) + goto fail; + hDC->hwnd->invalid->null = 1; hDC->hwnd->count = 32; - hDC->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * hDC->hwnd->count); + if (!(hDC->hwnd->cinvalid = (HGDI_RGN) calloc(hDC->hwnd->count, sizeof(GDI_RGN)))) + goto fail; + hDC->hwnd->ninvalid = 0; return hDC; + +fail: + gdi_DeleteDC(hDC); + free(hDC); + return NULL; } /** @@ -233,17 +250,17 @@ int gdi_DeleteObject(HGDIOBJECT hgdiobject) int gdi_DeleteDC(HGDI_DC hdc) { - if (hdc && hdc->hwnd) + if (hdc) { - free(hdc->hwnd->cinvalid); - - free(hdc->hwnd->invalid); - - free(hdc->hwnd); + if (hdc->hwnd) + { + free(hdc->hwnd->cinvalid); + free(hdc->hwnd->invalid); + free(hdc->hwnd); + } + free(hdc->clip); + free(hdc); } - free(hdc->clip); - free(hdc); - return 1; } diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 5f75611..14430f4 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -402,9 +402,10 @@ gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, BYTE* bitmap = (gdiBitmap*) malloc(sizeof(gdiBitmap)); if (!bitmap) - return NULL; + goto fail_bitmap; - bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc); + if (!(bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc))) + goto fail_hdc; DEBUG_GDI("gdi_bitmap_new: width:%d height:%d bpp:%d", width, height, bpp); @@ -413,10 +414,20 @@ gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, BYTE* else bitmap->bitmap = gdi_create_bitmap(gdi, width, height, bpp, data); + if (!bitmap->bitmap) + goto fail_bitmap_bitmap; + gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->bitmap); bitmap->org_bitmap = NULL; return bitmap; + +fail_bitmap_bitmap: + gdi_DeleteDC(bitmap->hdc); +fail_hdc: + free(bitmap); +fail_bitmap: + return NULL; } void gdi_bitmap_free_ex(gdiBitmap* bitmap) @@ -1173,53 +1184,75 @@ void gdi_register_update_callbacks(rdpUpdate* update) update->altsec->FrameMarker = gdi_frame_marker; } -void gdi_init_primary(rdpGdi* gdi) +BOOL gdi_init_primary(rdpGdi* gdi) { - gdi->primary = (gdiBitmap*) malloc(sizeof(gdiBitmap)); + gdi->primary = (gdiBitmap*) calloc(1, sizeof(gdiBitmap)); if (!gdi->primary) - return; + goto fail_primary; - gdi->primary->hdc = gdi_CreateCompatibleDC(gdi->hdc); + if (!(gdi->primary->hdc = gdi_CreateCompatibleDC(gdi->hdc))) + goto fail_hdc; if (!gdi->primary_buffer) gdi->primary->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, gdi->width, gdi->height); else gdi->primary->bitmap = gdi_CreateBitmap(gdi->width, gdi->height, gdi->dstBpp, gdi->primary_buffer); + if (!gdi->primary->bitmap) + goto fail_bitmap; + gdi_SelectObject(gdi->primary->hdc, (HGDIOBJECT) gdi->primary->bitmap); gdi->primary->org_bitmap = NULL; gdi->primary_buffer = gdi->primary->bitmap->data; - if (!gdi->drawing) - gdi->drawing = gdi->primary; - - gdi->primary->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); - gdi->primary->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + if (!(gdi->primary->hdc->hwnd = (HGDI_WND) calloc(1, sizeof(GDI_WND)))) + goto fail_hwnd; + if (!(gdi->primary->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0))) + goto fail_hwnd; gdi->primary->hdc->hwnd->invalid->null = 1; gdi->primary->hdc->hwnd->count = 32; - gdi->primary->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * gdi->primary->hdc->hwnd->count); + if (!(gdi->primary->hdc->hwnd->cinvalid = (HGDI_RGN) calloc(gdi->primary->hdc->hwnd->count, sizeof(GDI_RGN)))) + goto fail_hwnd; gdi->primary->hdc->hwnd->ninvalid = 0; + + if (!gdi->drawing) + gdi->drawing = gdi->primary; + + return TRUE; + +fail_hwnd: + gdi_DeleteObject((HGDIOBJECT) gdi->primary->bitmap); +fail_bitmap: + gdi_DeleteDC(gdi->primary->hdc); +fail_hdc: + free(gdi->primary); + gdi->primary = NULL; +fail_primary: + return FALSE; } -void gdi_resize(rdpGdi* gdi, int width, int height) +BOOL gdi_resize(rdpGdi* gdi, int width, int height) { - if (gdi && gdi->primary) - { - if (gdi->width != width || gdi->height != height) - { - if (gdi->drawing == gdi->primary) - gdi->drawing = NULL; - - gdi->width = width; - gdi->height = height; - gdi_bitmap_free_ex(gdi->primary); - gdi->primary_buffer = NULL; - gdi_init_primary(gdi); - } - } + if (!gdi || !gdi->primary) + return FALSE; + + if (gdi->width == width && gdi->height == height) + return TRUE; + + if (gdi->drawing == gdi->primary) + gdi->drawing = NULL; + + gdi->width = width; + gdi->height = height; + gdi_bitmap_free_ex(gdi->primary); + + gdi->primary = NULL; + gdi->primary_buffer = NULL; + + return gdi_init_primary(gdi); } /** @@ -1228,21 +1261,19 @@ void gdi_resize(rdpGdi* gdi, int width, int height) * @return */ -int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer) +BOOL gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer) { BOOL rgb555; rdpGdi* gdi; - rdpCache* cache; + rdpCache* cache = NULL; gdi = (rdpGdi*) calloc(1, sizeof(rdpGdi)); if (!gdi) - return -1; + goto fail_gdi; instance->context->gdi = gdi; gdi->context = instance->context; - cache = instance->context->cache; - gdi->codecs = instance->context->codecs; gdi->width = instance->settings->DesktopWidth; gdi->height = instance->settings->DesktopHeight; @@ -1305,7 +1336,9 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer) gdi->format = PIXEL_FORMAT_BGR555; } - gdi->hdc = gdi_GetDC(); + if (!(gdi->hdc = gdi_GetDC())) + goto fail_get_hdc; + gdi->hdc->bitsPerPixel = gdi->dstBpp; gdi->hdc->bytesPerPixel = gdi->bytesPerPixel; @@ -1313,16 +1346,19 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer) gdi->hdc->invert = (flags & CLRCONV_INVERT) ? TRUE : FALSE; gdi->hdc->rgb555 = (flags & CLRCONV_RGB555) ? TRUE : FALSE; - gdi_init_primary(gdi); + if (!gdi_init_primary(gdi)) + goto fail_init_primary; - gdi->tile = gdi_bitmap_new_ex(gdi, 64, 64, 32, NULL); - gdi->image = gdi_bitmap_new_ex(gdi, 64, 64, 32, NULL); + if (!(gdi->tile = gdi_bitmap_new_ex(gdi, 64, 64, 32, NULL))) + goto fail_tile_bitmap; + if (!(gdi->image = gdi_bitmap_new_ex(gdi, 64, 64, 32, NULL))) + goto fail_image_bitmap; - if (!cache) - { - cache = cache_new(instance->settings); - instance->context->cache = cache; - } + if (!instance->context->cache) + if (!(cache = cache_new(instance->settings))) + goto fail_cache; + + instance->context->cache = cache; gdi_register_update_callbacks(instance->update); @@ -1332,11 +1368,28 @@ int gdi_init(freerdp* instance, UINT32 flags, BYTE* buffer) offscreen_cache_register_callbacks(instance->update); palette_cache_register_callbacks(instance->update); - gdi_register_graphics(instance->context->graphics); + if (!gdi_register_graphics(instance->context->graphics)) + goto fail_register_graphics; instance->update->BitmapUpdate = gdi_bitmap_update; - return 0; + return TRUE; + +fail_register_graphics: + free(cache); +fail_cache: + gdi_bitmap_free_ex(gdi->image); +fail_image_bitmap: + gdi_bitmap_free_ex(gdi->tile); +fail_tile_bitmap: + gdi_bitmap_free_ex(gdi->primary); +fail_init_primary: + gdi_DeleteDC(gdi->hdc); +fail_get_hdc: + free(gdi); +fail_gdi: + WLog_ERR(TAG, "failed to initialize gdi"); + return FALSE; } void gdi_free(freerdp* instance) diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 603237e..4ca1374 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -114,7 +114,7 @@ BOOL gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) if (!gdi_bitmap->bitmap) { - gdi_DeleteDC(gdi->hdc); + gdi_DeleteDC(gdi_bitmap->hdc); return FALSE; } diff --git a/libfreerdp/gdi/test/TestGdiBitBlt.c b/libfreerdp/gdi/test/TestGdiBitBlt.c index 45b2244..1ff1c08 100644 --- a/libfreerdp/gdi/test/TestGdiBitBlt.c +++ b/libfreerdp/gdi/test/TestGdiBitBlt.c @@ -565,11 +565,19 @@ int test_gdi_BitBlt_32bpp(void) int bytesPerPixel = 4; int bitsPerPixel = 32; - hdcSrc = gdi_GetDC(); + if (!(hdcSrc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } hdcSrc->bytesPerPixel = bytesPerPixel; hdcSrc->bitsPerPixel = bitsPerPixel; - hdcDst = gdi_GetDC(); + if (!(hdcDst = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } hdcDst->bytesPerPixel = bytesPerPixel; hdcDst->bitsPerPixel = bitsPerPixel; @@ -853,11 +861,21 @@ int test_gdi_BitBlt_16bpp(void) int bytesPerPixel = 2; int bitsPerPixel = 16; - hdcSrc = gdi_GetDC(); + if (!(hdcSrc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdcSrc->bytesPerPixel = bytesPerPixel; hdcSrc->bitsPerPixel = bitsPerPixel; - hdcDst = gdi_GetDC(); + if (!(hdcDst = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdcDst->bytesPerPixel = bytesPerPixel; hdcDst->bitsPerPixel = bitsPerPixel; @@ -1141,11 +1159,21 @@ int test_gdi_BitBlt_8bpp(void) int bytesPerPixel = 1; int bitsPerPixel = 8; - hdcSrc = gdi_GetDC(); + if (!(hdcSrc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdcSrc->bytesPerPixel = bytesPerPixel; hdcSrc->bitsPerPixel = bitsPerPixel; - hdcDst = gdi_GetDC(); + if (!(hdcDst = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdcDst->bytesPerPixel = bytesPerPixel; hdcDst->bitsPerPixel = bitsPerPixel; diff --git a/libfreerdp/gdi/test/TestGdiClip.c b/libfreerdp/gdi/test/TestGdiClip.c index 667f640..98a62ef 100644 --- a/libfreerdp/gdi/test/TestGdiClip.c +++ b/libfreerdp/gdi/test/TestGdiClip.c @@ -20,7 +20,12 @@ int test_gdi_ClipCoords(void) HGDI_RGN rgn2; HGDI_BITMAP bmp; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bytesPerPixel = 4; hdc->bitsPerPixel = 32; bmp = gdi_CreateBitmap(1024, 768, 4, NULL); @@ -173,7 +178,12 @@ int test_gdi_InvalidateRegion(void) HGDI_RGN invalid; HGDI_BITMAP bmp; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bytesPerPixel = 4; hdc->bitsPerPixel = 32; bmp = gdi_CreateBitmap(1024, 768, 4, NULL); diff --git a/libfreerdp/gdi/test/TestGdiCreate.c b/libfreerdp/gdi/test/TestGdiCreate.c index 1203ff3..6dd55df 100644 --- a/libfreerdp/gdi/test/TestGdiCreate.c +++ b/libfreerdp/gdi/test/TestGdiCreate.c @@ -13,7 +13,13 @@ int test_gdi_GetDC(void) { - HGDI_DC hdc = gdi_GetDC(); + HGDI_DC hdc; + + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } if (hdc->bytesPerPixel != 4) return -1; @@ -32,7 +38,12 @@ int test_gdi_CreateCompatibleDC(void) HGDI_DC hdc; HGDI_DC chdc; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bytesPerPixel = 2; hdc->bitsPerPixel = 16; hdc->drawMode = GDI_R2_XORPEN; @@ -92,7 +103,12 @@ int test_gdi_CreateCompatibleBitmap(void) int height; HGDI_BITMAP hBitmap; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bytesPerPixel = 4; hdc->bitsPerPixel = 32; @@ -251,7 +267,12 @@ int test_gdi_GetPixel(void) int height = 64; HGDI_BITMAP hBitmap; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bytesPerPixel = 4; hdc->bitsPerPixel = 32; @@ -278,7 +299,12 @@ int test_gdi_SetPixel(void) int height = 64; HGDI_BITMAP hBitmap; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bytesPerPixel = 4; hdc->bitsPerPixel = 32; @@ -302,7 +328,13 @@ int test_gdi_SetPixel(void) int test_gdi_SetROP2(void) { - HGDI_DC hdc = gdi_GetDC(); + HGDI_DC hdc; + + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } gdi_SetROP2(hdc, GDI_R2_BLACK); @@ -318,7 +350,12 @@ int test_gdi_MoveToEx(void) HGDI_PEN hPen; HGDI_POINT prevPoint; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hPen = gdi_CreatePen(GDI_PS_SOLID, 8, 0xAABBCCDD); gdi_SelectObject(hdc, (HGDIOBJECT) hPen); gdi_MoveToEx(hdc, 128, 256, NULL); diff --git a/libfreerdp/gdi/test/TestGdiEllipse.c b/libfreerdp/gdi/test/TestGdiEllipse.c index 9f2323b..fcebb9f 100644 --- a/libfreerdp/gdi/test/TestGdiEllipse.c +++ b/libfreerdp/gdi/test/TestGdiEllipse.c @@ -91,7 +91,12 @@ int TestGdiEllipse(int argc, char* argv[]) int bitsPerPixel = 8; int bytesPerPixel = 1; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bitsPerPixel = bitsPerPixel; hdc->bytesPerPixel = bytesPerPixel; gdi_SetNullClipRgn(hdc); diff --git a/libfreerdp/gdi/test/TestGdiLine.c b/libfreerdp/gdi/test/TestGdiLine.c index 1c2c132..77ca2fe 100644 --- a/libfreerdp/gdi/test/TestGdiLine.c +++ b/libfreerdp/gdi/test/TestGdiLine.c @@ -638,7 +638,12 @@ int TestGdiLine(int argc, char* argv[]) int bitsPerPixel = 8; int bytesPerPixel = 1; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bitsPerPixel = bitsPerPixel; hdc->bytesPerPixel = bytesPerPixel; gdi_SetNullClipRgn(hdc); diff --git a/libfreerdp/gdi/test/TestGdiRect.c b/libfreerdp/gdi/test/TestGdiRect.c index e4a87bb..e5f7dfa 100644 --- a/libfreerdp/gdi/test/TestGdiRect.c +++ b/libfreerdp/gdi/test/TestGdiRect.c @@ -77,7 +77,12 @@ int test_gdi_FillRect(void) int right = 60; int bottom = 80; - hdc = gdi_GetDC(); + if (!(hdc = gdi_GetDC())) + { + printf("failed to get gdi device context\n"); + return -1; + } + hdc->bytesPerPixel = 4; hdc->bitsPerPixel = 32; diff --git a/server/shadow/Win/win_rdp.c b/server/shadow/Win/win_rdp.c index e0e672b..bda1877 100644 --- a/server/shadow/Win/win_rdp.c +++ b/server/shadow/Win/win_rdp.c @@ -147,7 +147,9 @@ BOOL shw_post_connect(freerdp* instance) shw = (shwContext*) instance->context; settings = instance->settings; - gdi_init(instance, CLRBUF_32BPP, NULL); + if (!gdi_init(instance, CLRBUF_32BPP, NULL)) + return FALSE; + gdi = instance->context->gdi; instance->update->BeginPaint = shw_begin_paint; -- 2.7.4