From e5767f07ac311888e388e51ca78c3dd34249d951 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 30 Mar 2018 10:43:20 +0200 Subject: [PATCH] Refactored order updates Unified order creation/copy/delete to avoid memory leaks. --- include/freerdp/api.h | 2 +- include/freerdp/pointer.h | 8 - include/freerdp/secondary.h | 25 +- libfreerdp/cache/CMakeLists.txt | 8 +- libfreerdp/cache/bitmap.c | 245 +++++++++++-- libfreerdp/cache/bitmap.h | 41 +++ libfreerdp/cache/brush.c | 48 ++- libfreerdp/cache/brush.h | 31 ++ libfreerdp/cache/cache.c | 22 ++ libfreerdp/cache/cache.h | 32 ++ libfreerdp/cache/glyph.c | 119 ++++++ libfreerdp/cache/glyph.h | 35 ++ libfreerdp/cache/palette.c | 34 +- libfreerdp/cache/palette.h | 30 ++ libfreerdp/cache/pointer.c | 154 ++++++++ libfreerdp/cache/pointer.h | 49 +++ libfreerdp/core/fastpath.c | 153 +++++--- libfreerdp/core/message.c | 620 +++++++++++--------------------- libfreerdp/core/orders.c | 377 ++++++++++--------- libfreerdp/core/update.c | 269 ++++++++++---- libfreerdp/core/update.h | 24 +- 21 files changed, 1520 insertions(+), 806 deletions(-) create mode 100644 libfreerdp/cache/bitmap.h create mode 100644 libfreerdp/cache/brush.h create mode 100644 libfreerdp/cache/cache.h create mode 100644 libfreerdp/cache/glyph.h create mode 100644 libfreerdp/cache/palette.h create mode 100644 libfreerdp/cache/pointer.h diff --git a/include/freerdp/api.h b/include/freerdp/api.h index a084252f1..a4164beab 100644 --- a/include/freerdp/api.h +++ b/include/freerdp/api.h @@ -82,6 +82,6 @@ #define IFCALL(_cb, ...) do { if (_cb != NULL) { _cb( __VA_ARGS__ ); } } while (0) #define IFCALLRET(_cb, _ret, ...) do { if (_cb != NULL) { _ret = _cb( __VA_ARGS__ ); } } while (0) -#define IFCALLRESULT(_default_return, _cb, ...) (_cb != NULL) ? _cb( __VA_ARGS__ ) : (_default_return) +#define IFCALLRESULT(_default_return, _cb, ...) ((_cb != NULL) ? _cb( __VA_ARGS__ ) : (_default_return)) #endif /* FREERDP_API */ diff --git a/include/freerdp/pointer.h b/include/freerdp/pointer.h index 8fc340efb..6e2047eb7 100644 --- a/include/freerdp/pointer.h +++ b/include/freerdp/pointer.h @@ -93,14 +93,6 @@ struct rdp_pointer_update pPointerNew PointerNew; /* 19 */ pPointerCached PointerCached; /* 20 */ UINT32 paddingB[32 - 21]; /* 21 */ - - /* internal */ - - POINTER_POSITION_UPDATE pointer_position; - POINTER_SYSTEM_UPDATE pointer_system; - POINTER_COLOR_UPDATE pointer_color; - POINTER_NEW_UPDATE pointer_new; - POINTER_CACHED_UPDATE pointer_cached; }; typedef struct rdp_pointer_update rdpPointerUpdate; diff --git a/include/freerdp/secondary.h b/include/freerdp/secondary.h index f7b3d1ba6..ddaf514ee 100644 --- a/include/freerdp/secondary.h +++ b/include/freerdp/secondary.h @@ -137,7 +137,7 @@ struct _CACHE_GLYPH_ORDER UINT32 cacheId; UINT32 cGlyphs; GLYPH_DATA glyphData[256]; - BYTE* unicodeCharacters; + WCHAR* unicodeCharacters; }; typedef struct _CACHE_GLYPH_ORDER CACHE_GLYPH_ORDER; @@ -147,7 +147,7 @@ struct _CACHE_GLYPH_V2_ORDER UINT32 flags; UINT32 cGlyphs; GLYPH_DATA_V2 glyphData[256]; - BYTE* unicodeCharacters; + WCHAR* unicodeCharacters; }; typedef struct _CACHE_GLYPH_V2_ORDER CACHE_GLYPH_V2_ORDER; @@ -164,19 +164,19 @@ struct _CACHE_BRUSH_ORDER typedef struct _CACHE_BRUSH_ORDER CACHE_BRUSH_ORDER; typedef BOOL (*pCacheBitmap)(rdpContext* context, - const CACHE_BITMAP_ORDER* cache_bitmap_order); + const CACHE_BITMAP_ORDER* cache_bitmap_order); typedef BOOL (*pCacheBitmapV2)(rdpContext* context, - CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order); + CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order); typedef BOOL (*pCacheBitmapV3)(rdpContext* context, - CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order); + CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order); typedef BOOL (*pCacheColorTable)(rdpContext* context, - const CACHE_COLOR_TABLE_ORDER* cache_color_table_order); + const CACHE_COLOR_TABLE_ORDER* cache_color_table_order); typedef BOOL (*pCacheGlyph)(rdpContext* context, - const CACHE_GLYPH_ORDER* cache_glyph_order); + const CACHE_GLYPH_ORDER* cache_glyph_order); typedef BOOL (*pCacheGlyphV2)(rdpContext* context, - const CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order); + const CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order); typedef BOOL (*pCacheBrush)(rdpContext* context, - const CACHE_BRUSH_ORDER* cache_brush_order); + const CACHE_BRUSH_ORDER* cache_brush_order); struct rdp_secondary_update { @@ -195,13 +195,6 @@ struct rdp_secondary_update /* internal */ BOOL glyph_v2; - CACHE_BITMAP_ORDER cache_bitmap_order; - CACHE_BITMAP_V2_ORDER cache_bitmap_v2_order; - CACHE_BITMAP_V3_ORDER cache_bitmap_v3_order; - CACHE_COLOR_TABLE_ORDER cache_color_table_order; - CACHE_GLYPH_ORDER cache_glyph_order; - CACHE_GLYPH_V2_ORDER cache_glyph_v2_order; - CACHE_BRUSH_ORDER cache_brush_order; }; typedef struct rdp_secondary_update rdpSecondaryUpdate; diff --git a/libfreerdp/cache/CMakeLists.txt b/libfreerdp/cache/CMakeLists.txt index d1cf5b37e..28f47a07e 100644 --- a/libfreerdp/cache/CMakeLists.txt +++ b/libfreerdp/cache/CMakeLists.txt @@ -20,11 +20,17 @@ set(MODULE_PREFIX "FREERDP_CACHE") freerdp_module_add( brush.c + brush.h pointer.c + pointer.h bitmap.c + bitmap.h nine_grid.c offscreen.c palette.c + palette.h glyph.c - cache.c) + glyph.h + cache.c + cache.h) diff --git a/libfreerdp/cache/bitmap.c b/libfreerdp/cache/bitmap.c index 41fdefa49..0cc336afd 100644 --- a/libfreerdp/cache/bitmap.c +++ b/libfreerdp/cache/bitmap.c @@ -36,15 +36,17 @@ #include "../gdi/gdi.h" #include "../core/graphics.h" +#include "bitmap.h" + #define TAG FREERDP_TAG("cache.bitmap") static rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, - UINT32 index); + UINT32 index); static BOOL bitmap_cache_put(rdpBitmapCache* bitmap_cache, UINT32 id, - UINT32 index, rdpBitmap* bitmap); + UINT32 index, rdpBitmap* bitmap); static BOOL update_gdi_memblt(rdpContext* context, - MEMBLT_ORDER* memblt) + MEMBLT_ORDER* memblt) { rdpBitmap* bitmap; rdpCache* cache = context->cache; @@ -53,7 +55,7 @@ static BOOL update_gdi_memblt(rdpContext* context, bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex); else bitmap = bitmap_cache_get(cache->bitmap, (BYTE) memblt->cacheId, - memblt->cacheIndex); + memblt->cacheIndex); /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */ if (bitmap == NULL) @@ -64,7 +66,7 @@ static BOOL update_gdi_memblt(rdpContext* context, } static BOOL update_gdi_mem3blt(rdpContext* context, - MEM3BLT_ORDER* mem3blt) + MEM3BLT_ORDER* mem3blt) { BYTE style; rdpBitmap* bitmap; @@ -76,7 +78,7 @@ static BOOL update_gdi_mem3blt(rdpContext* context, bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex); else bitmap = bitmap_cache_get(cache->bitmap, (BYTE) mem3blt->cacheId, - mem3blt->cacheIndex); + mem3blt->cacheIndex); /* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */ if (!bitmap) @@ -101,7 +103,7 @@ static BOOL update_gdi_mem3blt(rdpContext* context, } static BOOL update_gdi_cache_bitmap(rdpContext* context, - const CACHE_BITMAP_ORDER* cacheBitmap) + const CACHE_BITMAP_ORDER* cacheBitmap) { rdpBitmap* bitmap; rdpBitmap* prevBitmap; @@ -112,13 +114,13 @@ static BOOL update_gdi_cache_bitmap(rdpContext* context, return FALSE; Bitmap_SetDimensions(bitmap, cacheBitmap->bitmapWidth, - cacheBitmap->bitmapHeight); + cacheBitmap->bitmapHeight); if (!bitmap->Decompress(context, bitmap, - cacheBitmap->bitmapDataStream, cacheBitmap->bitmapWidth, - cacheBitmap->bitmapHeight, - cacheBitmap->bitmapBpp, cacheBitmap->bitmapLength, - cacheBitmap->compressed, RDP_CODEC_ID_NONE)) + cacheBitmap->bitmapDataStream, cacheBitmap->bitmapWidth, + cacheBitmap->bitmapHeight, + cacheBitmap->bitmapBpp, cacheBitmap->bitmapLength, + cacheBitmap->compressed, RDP_CODEC_ID_NONE)) { Bitmap_Free(context, bitmap); return FALSE; @@ -131,15 +133,15 @@ static BOOL update_gdi_cache_bitmap(rdpContext* context, } prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmap->cacheId, - cacheBitmap->cacheIndex); + cacheBitmap->cacheIndex); Bitmap_Free(context, prevBitmap); return bitmap_cache_put(cache->bitmap, cacheBitmap->cacheId, - cacheBitmap->cacheIndex, - bitmap); + cacheBitmap->cacheIndex, + bitmap); } static BOOL update_gdi_cache_bitmap_v2(rdpContext* context, - CACHE_BITMAP_V2_ORDER* cacheBitmapV2) + CACHE_BITMAP_V2_ORDER* cacheBitmapV2) { rdpBitmap* bitmap; @@ -158,23 +160,23 @@ static BOOL update_gdi_cache_bitmap_v2(rdpContext* context, cacheBitmapV2->bitmapBpp = settings->ColorDepth; Bitmap_SetDimensions(bitmap, cacheBitmapV2->bitmapWidth, - cacheBitmapV2->bitmapHeight); + cacheBitmapV2->bitmapHeight); if (!bitmap->Decompress(context, bitmap, - cacheBitmapV2->bitmapDataStream, - cacheBitmapV2->bitmapWidth, - cacheBitmapV2->bitmapHeight, - cacheBitmapV2->bitmapBpp, - cacheBitmapV2->bitmapLength, - cacheBitmapV2->compressed, - RDP_CODEC_ID_NONE)) + cacheBitmapV2->bitmapDataStream, + cacheBitmapV2->bitmapWidth, + cacheBitmapV2->bitmapHeight, + cacheBitmapV2->bitmapBpp, + cacheBitmapV2->bitmapLength, + cacheBitmapV2->compressed, + RDP_CODEC_ID_NONE)) { Bitmap_Free(context, bitmap); return FALSE; } prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmapV2->cacheId, - cacheBitmapV2->cacheIndex); + cacheBitmapV2->cacheIndex); if (!bitmap->New(context, bitmap)) { @@ -184,11 +186,11 @@ static BOOL update_gdi_cache_bitmap_v2(rdpContext* context, Bitmap_Free(context, prevBitmap); return bitmap_cache_put(cache->bitmap, cacheBitmapV2->cacheId, - cacheBitmapV2->cacheIndex, bitmap); + cacheBitmapV2->cacheIndex, bitmap); } static BOOL update_gdi_cache_bitmap_v3(rdpContext* context, - CACHE_BITMAP_V3_ORDER* cacheBitmapV3) + CACHE_BITMAP_V3_ORDER* cacheBitmapV3) { rdpBitmap* bitmap; rdpBitmap* prevBitmap; @@ -208,9 +210,9 @@ static BOOL update_gdi_cache_bitmap_v3(rdpContext* context, Bitmap_SetDimensions(bitmap, bitmapData->width, bitmapData->height); if (!bitmap->Decompress(context, bitmap, - bitmapData->data, bitmapData->width, bitmapData->height, - bitmapData->bpp, bitmapData->length, compressed, - bitmapData->codecID)) + bitmapData->data, bitmapData->width, bitmapData->height, + bitmapData->bpp, bitmapData->length, compressed, + bitmapData->codecID)) { Bitmap_Free(context, bitmap); return FALSE; @@ -223,14 +225,14 @@ static BOOL update_gdi_cache_bitmap_v3(rdpContext* context, } prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmapV3->cacheId, - cacheBitmapV3->cacheIndex); + cacheBitmapV3->cacheIndex); Bitmap_Free(context, prevBitmap); return bitmap_cache_put(cache->bitmap, cacheBitmapV3->cacheId, - cacheBitmapV3->cacheIndex, bitmap); + cacheBitmapV3->cacheIndex, bitmap); } rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, - UINT32 index) + UINT32 index) { rdpBitmap* bitmap; @@ -255,7 +257,7 @@ rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id, } BOOL bitmap_cache_put(rdpBitmapCache* bitmapCache, UINT32 id, UINT32 index, - rdpBitmap* bitmap) + rdpBitmap* bitmap) { if (id > bitmapCache->maxCells) { @@ -304,7 +306,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) bitmapCache->context = bitmapCache->update->context; bitmapCache->maxCells = settings->BitmapCacheV2NumCells; bitmapCache->cells = (BITMAP_V2_CELL*) calloc(bitmapCache->maxCells, - sizeof(BITMAP_V2_CELL)); + sizeof(BITMAP_V2_CELL)); if (!bitmapCache->cells) goto fail; @@ -314,7 +316,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) bitmapCache->cells[i].number = settings->BitmapCacheV2CellInfo[i].numEntries; /* allocate an extra entry for BITMAP_CACHE_WAITING_LIST_INDEX */ bitmapCache->cells[i].entries = (rdpBitmap**) calloc(( - bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*)); + bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*)); if (!bitmapCache->cells[i].entries) goto fail; @@ -355,3 +357,174 @@ void bitmap_cache_free(rdpBitmapCache* bitmapCache) free(bitmapCache); } } + +static void free_bitmap_data(BITMAP_DATA* data, size_t count) +{ + size_t x; + + if (!data) + return; + + for (x = 0; x < count; x++) + free(data[x].bitmapDataStream); + + free(data); +} + +static BITMAP_DATA* copy_bitmap_data(const BITMAP_DATA* data, size_t count) +{ + size_t x; + BITMAP_DATA* dst = (BITMAP_DATA*) calloc(count, sizeof(BITMAP_DATA)); + + if (!dst) + goto fail; + + for (x = 0; x < count; x++) + { + dst[x] = data[x]; + + if (data[x].bitmapLength > 0) + { + dst[x].bitmapDataStream = malloc(data[x].bitmapLength); + + if (!dst[x].bitmapDataStream) + goto fail; + + memcpy(dst[x].bitmapDataStream, data[x].bitmapDataStream, data[x].bitmapLength); + } + } + + return dst; +fail: + free_bitmap_data(dst, count); + return NULL; +} + +void free_bitmap_update(rdpContext* context, BITMAP_UPDATE* pointer) +{ + if (!pointer) + return; + + free_bitmap_data(pointer->rectangles, pointer->number); + free(pointer); +} + +BITMAP_UPDATE* copy_bitmap_update(rdpContext* context, const BITMAP_UPDATE* pointer) +{ + BITMAP_UPDATE* dst = calloc(1, sizeof(BITMAP_UPDATE)); + + if (!dst || !pointer) + goto fail; + + *dst = *pointer; + dst->rectangles = copy_bitmap_data(pointer->rectangles, pointer->number); + + if (!dst->rectangles) + goto fail; + + return dst; +fail: + free_bitmap_update(context, dst); + return NULL; +} + +CACHE_BITMAP_ORDER* copy_cache_bitmap_order(rdpContext* context, const CACHE_BITMAP_ORDER* order) +{ + CACHE_BITMAP_ORDER* dst = calloc(1, sizeof(CACHE_BITMAP_ORDER)); + + if (!dst || !order) + goto fail; + + *dst = *order; + + if (order->bitmapLength > 0) + { + dst->bitmapDataStream = malloc(order->bitmapLength); + + if (!dst->bitmapDataStream) + goto fail; + + memcpy(dst->bitmapDataStream, order->bitmapDataStream, order->bitmapLength); + } + + return dst; +fail: + free_cache_bitmap_order(context, dst); + return NULL; +} + +void free_cache_bitmap_order(rdpContext* context, CACHE_BITMAP_ORDER* order) +{ + if (order) + free(order->bitmapDataStream); + + free(order); +} + +CACHE_BITMAP_V2_ORDER* copy_cache_bitmap_v2_order(rdpContext* context, + const CACHE_BITMAP_V2_ORDER* order) +{ + CACHE_BITMAP_V2_ORDER* dst = calloc(1, sizeof(CACHE_BITMAP_V2_ORDER)); + + if (!dst || !order) + goto fail; + + *dst = *order; + + if (order->bitmapLength > 0) + { + dst->bitmapDataStream = malloc(order->bitmapLength); + + if (!dst->bitmapDataStream) + goto fail; + + memcpy(dst->bitmapDataStream, order->bitmapDataStream, order->bitmapLength); + } + + return dst; +fail: + free_cache_bitmap_v2_order(context, dst); + return NULL; +} + +void free_cache_bitmap_v2_order(rdpContext* context, CACHE_BITMAP_V2_ORDER* order) +{ + if (order) + free(order->bitmapDataStream); + + free(order); +} + +CACHE_BITMAP_V3_ORDER* copy_cache_bitmap_v3_order(rdpContext* context, + const CACHE_BITMAP_V3_ORDER* order) +{ + CACHE_BITMAP_V3_ORDER* dst = calloc(1, sizeof(CACHE_BITMAP_V3_ORDER)); + + if (!dst || !order) + goto fail; + + *dst = *order; + + if (order->bitmapData.length > 0) + { + dst->bitmapData.data = malloc(order->bitmapData.length); + + if (!dst->bitmapData.data) + goto fail; + + memcpy(dst->bitmapData.data, order->bitmapData.data, order->bitmapData.length); + } + + return dst; +fail: + free_cache_bitmap_v3_order(context, dst); + return NULL; +} + +void free_cache_bitmap_v3_order(rdpContext* context, CACHE_BITMAP_V3_ORDER* order) +{ + if (order) + free(order->bitmapData.data); + + free(order); +} diff --git a/libfreerdp/cache/bitmap.h b/libfreerdp/cache/bitmap.h new file mode 100644 index 000000000..ed54f72b4 --- /dev/null +++ b/libfreerdp/cache/bitmap.h @@ -0,0 +1,41 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2018 Armin Novak + * Copyright 2018 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_LIB_CACHE_BITMAP_H +#define FREERDP_LIB_CACHE_BITMAP_H + +#include +#include + +FREERDP_LOCAL BITMAP_UPDATE* copy_bitmap_update(rdpContext* context, const BITMAP_UPDATE* pointer); +FREERDP_LOCAL void free_bitmap_update(rdpContext* context, BITMAP_UPDATE* pointer); + +FREERDP_LOCAL CACHE_BITMAP_ORDER* copy_cache_bitmap_order(rdpContext* context, + const CACHE_BITMAP_ORDER* order); +FREERDP_LOCAL void free_cache_bitmap_order(rdpContext* context, CACHE_BITMAP_ORDER* order); + +FREERDP_LOCAL CACHE_BITMAP_V2_ORDER* copy_cache_bitmap_v2_order(rdpContext* context, + const CACHE_BITMAP_V2_ORDER* order); +FREERDP_LOCAL void free_cache_bitmap_v2_order(rdpContext* context, CACHE_BITMAP_V2_ORDER* order); + +FREERDP_LOCAL CACHE_BITMAP_V3_ORDER* copy_cache_bitmap_v3_order(rdpContext* context, + const CACHE_BITMAP_V3_ORDER* order); +FREERDP_LOCAL void free_cache_bitmap_v3_order(rdpContext* context, CACHE_BITMAP_V3_ORDER* order); + +#endif /* FREERDP_LIB_CACHE_BITMAP_H */ diff --git a/libfreerdp/cache/brush.c b/libfreerdp/cache/brush.c index 1048c770e..e048fd8d8 100644 --- a/libfreerdp/cache/brush.c +++ b/libfreerdp/cache/brush.c @@ -29,19 +29,19 @@ #include #include - #include +#include "brush.h" + #define TAG FREERDP_TAG("cache.brush") static BOOL update_gdi_patblt(rdpContext* context, - PATBLT_ORDER* patblt) + PATBLT_ORDER* patblt) { BYTE style; BOOL ret = TRUE; rdpBrush* brush = &patblt->brush; const rdpCache* cache = context->cache; - style = brush->style; if (brush->style & CACHED_BRUSH) @@ -56,20 +56,19 @@ static BOOL update_gdi_patblt(rdpContext* context, } static BOOL update_gdi_polygon_sc(rdpContext* context, - const POLYGON_SC_ORDER* polygon_sc) + const POLYGON_SC_ORDER* polygon_sc) { rdpCache* cache = context->cache; return IFCALLRESULT(TRUE, cache->brush->PolygonSC, context, polygon_sc); } static BOOL update_gdi_polygon_cb(rdpContext* context, - POLYGON_CB_ORDER* polygon_cb) + POLYGON_CB_ORDER* polygon_cb) { BYTE style; rdpBrush* brush = &polygon_cb->brush; rdpCache* cache = context->cache; BOOL ret = TRUE; - style = brush->style; if (brush->style & CACHED_BRUSH) @@ -80,24 +79,22 @@ static BOOL update_gdi_polygon_cb(rdpContext* context, IFCALLRET(cache->brush->PolygonCB, ret, context, polygon_cb); brush->style = style; - return ret; } static BOOL update_gdi_cache_brush(rdpContext* context, - const CACHE_BRUSH_ORDER* cacheBrush) + const CACHE_BRUSH_ORDER* cacheBrush) { UINT32 length; void* data = NULL; rdpCache* cache = context->cache; - length = cacheBrush->bpp * 64 / 8; - data = malloc(length); + if (!data) return FALSE; - CopyMemory(data, cacheBrush->data, length); + CopyMemory(data, cacheBrush->data, length); brush_cache_put(cache->brush, cacheBrush->index, data, cacheBrush->bpp); return TRUE; } @@ -156,7 +153,6 @@ void brush_cache_put(rdpBrushCache* brushCache, UINT32 index, void* entry, UINT3 } free(brushCache->monoEntries[index].entry); - brushCache->monoEntries[index].bpp = bpp; brushCache->monoEntries[index].entry = entry; } @@ -170,7 +166,6 @@ void brush_cache_put(rdpBrushCache* brushCache, UINT32 index, void* entry, UINT3 } free(brushCache->entries[index].entry); - brushCache->entries[index].bpp = bpp; brushCache->entries[index].entry = entry; } @@ -179,11 +174,9 @@ void brush_cache_put(rdpBrushCache* brushCache, UINT32 index, void* entry, UINT3 void brush_cache_register_callbacks(rdpUpdate* update) { rdpCache* cache = update->context->cache; - cache->brush->PatBlt = update->primary->PatBlt; cache->brush->PolygonSC = update->primary->PolygonSC; cache->brush->PolygonCB = update->primary->PolygonCB; - update->primary->PatBlt = update_gdi_patblt; update->primary->PolygonSC = update_gdi_polygon_sc; update->primary->PolygonCB = update_gdi_polygon_cb; @@ -193,27 +186,25 @@ void brush_cache_register_callbacks(rdpUpdate* update) rdpBrushCache* brush_cache_new(rdpSettings* settings) { rdpBrushCache* brushCache; - brushCache = (rdpBrushCache*) calloc(1, sizeof(rdpBrushCache)); if (!brushCache) return NULL; brushCache->settings = settings; - brushCache->maxEntries = 64; brushCache->maxMonoEntries = 64; - brushCache->entries = (BRUSH_ENTRY*)calloc(brushCache->maxEntries, sizeof(BRUSH_ENTRY)); + if (!brushCache->entries) goto error_entries; brushCache->monoEntries = (BRUSH_ENTRY*) calloc(brushCache->maxMonoEntries, sizeof(BRUSH_ENTRY)); + if (!brushCache->monoEntries) goto error_mono; return brushCache; - error_mono: free(brushCache->entries); error_entries: @@ -246,3 +237,22 @@ void brush_cache_free(rdpBrushCache* brushCache) free(brushCache); } } + +void free_cache_brush_order(rdpContext* context, CACHE_BRUSH_ORDER* order) +{ + free(order); +} + +CACHE_BRUSH_ORDER* copy_cache_brush_order(rdpContext* context, const CACHE_BRUSH_ORDER* order) +{ + CACHE_BRUSH_ORDER* dst = calloc(1, sizeof(CACHE_BRUSH_ORDER)); + + if (!dst || !order) + goto fail; + + *dst = *order; + return dst; +fail: + free_cache_brush_order(context, dst); + return NULL; +} diff --git a/libfreerdp/cache/brush.h b/libfreerdp/cache/brush.h new file mode 100644 index 000000000..712ac3577 --- /dev/null +++ b/libfreerdp/cache/brush.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2018 Armin Novak + * Copyright 2018 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_LIB_CACHE_BRUSH_H +#define FREERDP_LIB_CACHE_BRUSH_H + +#include +#include +#include + +FREERDP_LOCAL CACHE_BRUSH_ORDER* copy_cache_brush_order(rdpContext* context, + const CACHE_BRUSH_ORDER* order); +FREERDP_LOCAL void free_cache_brush_order(rdpContext* context, CACHE_BRUSH_ORDER* order); + +#endif /* FREERDP_LIB_CACHE_BRUSH_H */ diff --git a/libfreerdp/cache/cache.c b/libfreerdp/cache/cache.c index a0da79e8c..69050398c 100644 --- a/libfreerdp/cache/cache.c +++ b/libfreerdp/cache/cache.c @@ -27,6 +27,8 @@ #include +#include "cache.h" + rdpCache* cache_new(rdpSettings* settings) { rdpCache* cache; @@ -90,3 +92,23 @@ void cache_free(rdpCache* cache) free(cache); } } + +CACHE_COLOR_TABLE_ORDER* copy_cache_color_table_order(rdpContext* context, + const CACHE_COLOR_TABLE_ORDER* order) +{ + CACHE_COLOR_TABLE_ORDER* dst = calloc(1, sizeof(CACHE_COLOR_TABLE_ORDER)); + + if (!dst || !order) + goto fail; + + *dst = *order; + return dst; +fail: + free_cache_color_table_order(context, dst); + return NULL; +} + +void free_cache_color_table_order(rdpContext* context, CACHE_COLOR_TABLE_ORDER* order) +{ + free(order); +} diff --git a/libfreerdp/cache/cache.h b/libfreerdp/cache/cache.h new file mode 100644 index 000000000..5109e2c2c --- /dev/null +++ b/libfreerdp/cache/cache.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2018 Armin Novak + * Copyright 2018 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_LIB_CACHE_CACHE_H +#define FREERDP_LIB_CACHE_CACHE_H + +#include +#include +#include + +FREERDP_LOCAL CACHE_COLOR_TABLE_ORDER* copy_cache_color_table_order(rdpContext* context, + const CACHE_COLOR_TABLE_ORDER* order); +FREERDP_LOCAL void free_cache_color_table_order(rdpContext* context, + CACHE_COLOR_TABLE_ORDER* order); + +#endif /* FREERDP_LIB_CACHE_CACHE_H */ diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index 80cfa6b8d..550eaa5dd 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -31,6 +31,8 @@ #include #include +#include "glyph.h" + #define TAG FREERDP_TAG("cache.glyph") static rdpGlyph* glyph_cache_get(rdpGlyphCache* glyph_cache, UINT32 id, @@ -761,3 +763,120 @@ void glyph_cache_free(rdpGlyphCache* glyphCache) free(glyphCache); } } + +CACHE_GLYPH_ORDER* copy_cache_glyph_order(rdpContext* context, const CACHE_GLYPH_ORDER* glyph) +{ + size_t x; + CACHE_GLYPH_ORDER* dst = calloc(1, sizeof(CACHE_GLYPH_ORDER)); + + if (!dst || !glyph) + goto fail; + + *dst = *glyph; + + for (x = 0; x < glyph->cGlyphs; x++) + { + const GLYPH_DATA* src = &glyph->glyphData[x]; + GLYPH_DATA* data = &dst->glyphData[x]; + + if (src->aj) + { + const size_t size = src->cb; + data->aj = malloc(size); + + if (!data->aj) + goto fail; + + memcpy(data->aj, src->aj, size); + } + } + + if (glyph->unicodeCharacters) + { + dst->unicodeCharacters = calloc(glyph->cGlyphs, sizeof(WCHAR)); + + if (!dst->unicodeCharacters) + goto fail; + + memcpy(dst->unicodeCharacters, glyph->unicodeCharacters, sizeof(WCHAR) * glyph->cGlyphs); + } + + return dst; +fail: + free_cache_glyph_order(context, dst); + return NULL; +} + +void free_cache_glyph_order(rdpContext* context, CACHE_GLYPH_ORDER* glyph) +{ + if (glyph) + { + size_t x; + + for (x = 0; x < ARRAYSIZE(glyph->glyphData); x++) + free(glyph->glyphData[x].aj); + + free(glyph->unicodeCharacters); + } + + free(glyph); +} + +CACHE_GLYPH_V2_ORDER* copy_cache_glyph_v2_order(rdpContext* context, + const CACHE_GLYPH_V2_ORDER* glyph) +{ + size_t x; + CACHE_GLYPH_V2_ORDER* dst = calloc(1, sizeof(CACHE_GLYPH_V2_ORDER)); + + if (!dst || !glyph) + goto fail; + + *dst = *glyph; + + for (x = 0; x < glyph->cGlyphs; x++) + { + const GLYPH_DATA_V2* src = &glyph->glyphData[x]; + GLYPH_DATA_V2* data = &dst->glyphData[x]; + + if (src->aj) + { + const size_t size = src->cb; + data->aj = malloc(size); + + if (!data->aj) + goto fail; + + memcpy(data->aj, src->aj, size); + } + } + + if (glyph->unicodeCharacters) + { + dst->unicodeCharacters = calloc(glyph->cGlyphs, sizeof(WCHAR)); + + if (!dst->unicodeCharacters) + goto fail; + + memcpy(dst->unicodeCharacters, glyph->unicodeCharacters, sizeof(WCHAR) * glyph->cGlyphs); + } + + return dst; +fail: + free_cache_glyph_v2_order(context, dst); + return NULL; +} + +void free_cache_glyph_v2_order(rdpContext* context, CACHE_GLYPH_V2_ORDER* glyph) +{ + if (glyph) + { + size_t x; + + for (x = 0; x < ARRAYSIZE(glyph->glyphData); x++) + free(glyph->glyphData[x].aj); + + free(glyph->unicodeCharacters); + } + + free(glyph); +} diff --git a/libfreerdp/cache/glyph.h b/libfreerdp/cache/glyph.h new file mode 100644 index 000000000..9f8d1b1d4 --- /dev/null +++ b/libfreerdp/cache/glyph.h @@ -0,0 +1,35 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2018 Armin Novak + * Copyright 2018 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_LIB_CACHE_GLYPH_H +#define FREERDP_LIB_CACHE_GLYPH_H + +#include +#include +#include + +FREERDP_LOCAL CACHE_GLYPH_ORDER* copy_cache_glyph_order(rdpContext* context, + const CACHE_GLYPH_ORDER* glyph); +FREERDP_LOCAL void free_cache_glyph_order(rdpContext* context, CACHE_GLYPH_ORDER* glyph); + +FREERDP_LOCAL CACHE_GLYPH_V2_ORDER* copy_cache_glyph_v2_order(rdpContext* context, + const CACHE_GLYPH_V2_ORDER* glyph); +FREERDP_LOCAL void free_cache_glyph_v2_order(rdpContext* context, CACHE_GLYPH_V2_ORDER* glyph); + +#endif /* FREERDP_LIB_CACHE_GLYPH_H */ diff --git a/libfreerdp/cache/palette.c b/libfreerdp/cache/palette.c index d5d5732c9..644888f6f 100644 --- a/libfreerdp/cache/palette.c +++ b/libfreerdp/cache/palette.c @@ -28,6 +28,8 @@ #include #include +#include "palette.h" + #define TAG FREERDP_TAG("cache.palette") static void* palette_cache_get(rdpPaletteCache* palette, UINT32 index); @@ -35,16 +37,16 @@ static void* palette_cache_get(rdpPaletteCache* palette, UINT32 index); static void palette_cache_put(rdpPaletteCache* palette, UINT32 index, void* entry); static BOOL update_gdi_cache_color_table(rdpContext* context, - const CACHE_COLOR_TABLE_ORDER* cacheColorTable) + const CACHE_COLOR_TABLE_ORDER* cacheColorTable) { UINT32* colorTable; rdpCache* cache = context->cache; - colorTable = (UINT32*) malloc(sizeof(UINT32) * 256); + if (!colorTable) return FALSE; - CopyMemory(colorTable, cacheColorTable->colorTable, sizeof(UINT32) * 256); + CopyMemory(colorTable, cacheColorTable->colorTable, sizeof(UINT32) * 256); palette_cache_put(cache->palette, cacheColorTable->cacheIndex, (void*) colorTable); return TRUE; } @@ -80,7 +82,6 @@ void palette_cache_put(rdpPaletteCache* paletteCache, UINT32 index, void* entry) } free(paletteCache->entries[index].entry); - paletteCache->entries[index].entry = entry; } @@ -92,14 +93,14 @@ void palette_cache_register_callbacks(rdpUpdate* update) rdpPaletteCache* palette_cache_new(rdpSettings* settings) { rdpPaletteCache* paletteCache; - paletteCache = (rdpPaletteCache*) calloc(1, sizeof(rdpPaletteCache)); if (paletteCache) { paletteCache->settings = settings; paletteCache->maxEntries = 6; - paletteCache->entries = (PALETTE_TABLE_ENTRY*) calloc(paletteCache->maxEntries, sizeof(PALETTE_TABLE_ENTRY)); + paletteCache->entries = (PALETTE_TABLE_ENTRY*) calloc(paletteCache->maxEntries, + sizeof(PALETTE_TABLE_ENTRY)); } return paletteCache; @@ -111,10 +112,29 @@ void palette_cache_free(rdpPaletteCache* paletteCache) { UINT32 i; - for (i = 0; i< paletteCache->maxEntries; i++) + for (i = 0; i < paletteCache->maxEntries; i++) free(paletteCache->entries[i].entry); free(paletteCache->entries); free(paletteCache); } } + +void free_palette_update(rdpContext* context, PALETTE_UPDATE* pointer) +{ + free(pointer); +} + +PALETTE_UPDATE* copy_palette_update(rdpContext* context, const PALETTE_UPDATE* pointer) +{ + PALETTE_UPDATE* dst = calloc(1, sizeof(PALETTE_UPDATE)); + + if (!dst || !pointer) + goto fail; + + *dst = *pointer; + return dst; +fail: + free_palette_update(context, dst); + return NULL; +} diff --git a/libfreerdp/cache/palette.h b/libfreerdp/cache/palette.h new file mode 100644 index 000000000..21edaafbf --- /dev/null +++ b/libfreerdp/cache/palette.h @@ -0,0 +1,30 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2018 Armin Novak + * Copyright 2018 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_LIB_CACHE_PALETTE_H +#define FREERDP_LIB_CACHE_PALETTE_H + +#include +#include + +FREERDP_LOCAL PALETTE_UPDATE* copy_palette_update(rdpContext* context, + const PALETTE_UPDATE* pointer); +FREERDP_LOCAL void free_palette_update(rdpContext* context, PALETTE_UPDATE* pointer); + +#endif /* FREERDP_LIB_CACHE_PALETTE_H */ diff --git a/libfreerdp/cache/pointer.c b/libfreerdp/cache/pointer.c index 8cc8dfaf7..b8477a6a3 100644 --- a/libfreerdp/cache/pointer.c +++ b/libfreerdp/cache/pointer.c @@ -30,6 +30,7 @@ #include #include +#include "pointer.h" #define TAG FREERDP_TAG("cache.pointer") @@ -312,3 +313,156 @@ void pointer_cache_free(rdpPointerCache* pointer_cache) free(pointer_cache); } } + +POINTER_COLOR_UPDATE* copy_pointer_color_update(rdpContext* context, + const POINTER_COLOR_UPDATE* src) +{ + POINTER_COLOR_UPDATE* dst = calloc(1, sizeof(POINTER_COLOR_UPDATE)); + + if (!dst || !src) + goto fail; + + *dst = *src; + + if (src->lengthAndMask > 0) + { + dst->andMaskData = calloc(src->lengthAndMask, sizeof(BYTE)); + + if (!dst->andMaskData) + goto fail; + + memcpy(dst->andMaskData, src->andMaskData, src->lengthAndMask); + } + + if (src->lengthXorMask > 0) + { + dst->xorMaskData = calloc(src->lengthXorMask, sizeof(BYTE)); + + if (!dst->xorMaskData) + goto fail; + + memcpy(dst->xorMaskData, src->xorMaskData, src->lengthXorMask); + } + + return dst; +fail: + free_pointer_color_update(context, dst); + return NULL; +} + +void free_pointer_color_update(rdpContext* context, POINTER_COLOR_UPDATE* pointer) +{ + if (!pointer) + return; + + free(pointer->xorMaskData); + free(pointer->andMaskData); + free(pointer); +} + +POINTER_NEW_UPDATE* copy_pointer_new_update(rdpContext* context, const POINTER_NEW_UPDATE* src) +{ + POINTER_NEW_UPDATE* dst = calloc(1, sizeof(POINTER_NEW_UPDATE)); + + if (!dst || !src) + goto fail; + + *dst = *src; + + if (src->colorPtrAttr.lengthAndMask > 0) + { + dst->colorPtrAttr.andMaskData = calloc(src->colorPtrAttr.lengthAndMask, sizeof(BYTE)); + + if (!dst->colorPtrAttr.andMaskData) + goto fail; + + memcpy(dst->colorPtrAttr.andMaskData, src->colorPtrAttr.andMaskData, + src->colorPtrAttr.lengthAndMask); + } + + if (src->colorPtrAttr.lengthXorMask > 0) + { + dst->colorPtrAttr.xorMaskData = calloc(src->colorPtrAttr.lengthXorMask, sizeof(BYTE)); + + if (!dst->colorPtrAttr.xorMaskData) + goto fail; + + memcpy(dst->colorPtrAttr.xorMaskData, src->colorPtrAttr.xorMaskData, + src->colorPtrAttr.lengthXorMask); + } + + return dst; +fail: + free_pointer_new_update(context, dst); + return NULL; +} + +void free_pointer_new_update(rdpContext* context, POINTER_NEW_UPDATE* pointer) +{ + if (!pointer) + return; + + free(pointer->colorPtrAttr.xorMaskData); + free(pointer->colorPtrAttr.andMaskData); + free(pointer); +} + +POINTER_CACHED_UPDATE* copy_pointer_cached_update(rdpContext* context, + const POINTER_CACHED_UPDATE* pointer) +{ + POINTER_CACHED_UPDATE* dst = calloc(1, sizeof(POINTER_CACHED_UPDATE)); + + if (!dst) + goto fail; + + *dst = *pointer; + return dst; +fail: + free_pointer_cached_update(context, dst); + return NULL; +} + +void free_pointer_cached_update(rdpContext* context, POINTER_CACHED_UPDATE* pointer) +{ + free(pointer); +} + +void free_pointer_position_update(rdpContext* context, POINTER_POSITION_UPDATE* pointer) +{ + free(pointer); +} + +POINTER_POSITION_UPDATE* copy_pointer_position_update(rdpContext* context, + const POINTER_POSITION_UPDATE* pointer) +{ + POINTER_POSITION_UPDATE* dst = calloc(1, sizeof(POINTER_POSITION_UPDATE)); + + if (!dst || !pointer) + goto fail; + + *dst = *pointer; + return dst; +fail: + free_pointer_position_update(context, dst); + return NULL; +} + +void free_pointer_system_update(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer) +{ + free(pointer); +} + +POINTER_SYSTEM_UPDATE* copy_pointer_system_update(rdpContext* context, + const POINTER_SYSTEM_UPDATE* pointer) +{ + POINTER_SYSTEM_UPDATE* dst = calloc(1, sizeof(POINTER_SYSTEM_UPDATE)); + + if (!dst || !pointer) + goto fail; + + *dst = *pointer; + return dst; +fail: + free_pointer_system_update(context, dst); + return NULL; +} diff --git a/libfreerdp/cache/pointer.h b/libfreerdp/cache/pointer.h new file mode 100644 index 000000000..acf1307ac --- /dev/null +++ b/libfreerdp/cache/pointer.h @@ -0,0 +1,49 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * + * Copyright 2018 Armin Novak + * Copyright 2018 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_LIB_CACHE_POINTER_H +#define FREERDP_LIB_CACHE_POINTER_H + +#include +#include +#include + +FREERDP_LOCAL POINTER_COLOR_UPDATE* copy_pointer_color_update(rdpContext* context, + const POINTER_COLOR_UPDATE* pointer); +FREERDP_LOCAL void free_pointer_color_update(rdpContext* context, POINTER_COLOR_UPDATE* pointer); + +FREERDP_LOCAL POINTER_NEW_UPDATE* copy_pointer_new_update(rdpContext* context, + const POINTER_NEW_UPDATE* pointer); +FREERDP_LOCAL void free_pointer_new_update(rdpContext* context, POINTER_NEW_UPDATE* pointer); + +FREERDP_LOCAL POINTER_CACHED_UPDATE* copy_pointer_cached_update(rdpContext* context, + const POINTER_CACHED_UPDATE* pointer); +FREERDP_LOCAL void free_pointer_cached_update(rdpContext* context, POINTER_CACHED_UPDATE* pointer); + +FREERDP_LOCAL POINTER_POSITION_UPDATE* copy_pointer_position_update(rdpContext* context, + const POINTER_POSITION_UPDATE* pointer); +FREERDP_LOCAL void free_pointer_position_update(rdpContext* context, + POINTER_POSITION_UPDATE* pointer); + +FREERDP_LOCAL POINTER_SYSTEM_UPDATE* copy_pointer_system_update(rdpContext* context, + const POINTER_SYSTEM_UPDATE* pointer); +FREERDP_LOCAL void free_pointer_system_update(rdpContext* context, + POINTER_SYSTEM_UPDATE* pointer); + +#endif /* FREERDP_LIB_CACHE_POINTER_H */ diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 353e01874..aedee0efb 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -41,6 +41,10 @@ #include "fastpath.h" #include "rdp.h" +#include "../cache/pointer.h" +#include "../cache/palette.h" +#include "../cache/bitmap.h" + #define TAG FREERDP_TAG("core.fastpath") /** @@ -72,6 +76,14 @@ static const char* const FASTPATH_UPDATETYPE_STRINGS[] = }; #endif +static const char* fastpath_update_to_string(UINT8 update) +{ + if (update >= ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS)) + return "UNKNOWN"; + + return FASTPATH_UPDATETYPE_STRINGS[update]; +} + /* * The fastpath header may be two or three bytes long. * This function assumes that at least two bytes are available in the stream @@ -281,6 +293,7 @@ static BOOL fastpath_recv_orders(rdpFastPath* fastpath, wStream* s) static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s) { + BOOL rc = FALSE; UINT16 updateType; rdpUpdate* update; rdpContext* context; @@ -303,21 +316,34 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s) switch (updateType) { case UPDATE_TYPE_BITMAP: - if (!update_read_bitmap_update(update, s, &update->bitmap_update)) - return FALSE; + { + BITMAP_UPDATE* bitmap_update = update_read_bitmap_update(update, s); - IFCALL(update->BitmapUpdate, context, &update->bitmap_update); + if (!bitmap_update) + return FALSE; + + rc = IFCALLRESULT(FALSE, update->BitmapUpdate, context, &update->bitmap_update); + free_bitmap_update(context, bitmap_update); + } break; case UPDATE_TYPE_PALETTE: - if (!update_read_palette(update, s, &update->palette_update)) - return FALSE; + { + PALETTE_UPDATE* palette_update = update_read_palette(update, s); - IFCALL(update->Palette, context, &update->palette_update); + if (!palette_update) + return FALSE; + + rc = IFCALLRESULT(FALSE, update->Palette, context, &update->palette_update); + free_palette_update(context, palette_update); + } + break; + + default: break; } - return TRUE; + return rc; } static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s) @@ -328,8 +354,9 @@ static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s) return TRUE; } -static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, wStream* s) +static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 size, wStream* s) { + BOOL rc = FALSE; int status = 0; rdpUpdate* update; rdpContext* context; @@ -346,103 +373,109 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, wStream* context = update->context; pointer = update->pointer; #ifdef WITH_DEBUG_RDP - DEBUG_RDP("recv Fast-Path %s Update (0x%02"PRIX8"), length:%"PRIuz"", - updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] : - "???", updateCode, Stream_Length(s)); + DEBUG_RDP("recv Fast-Path %s Update (0x%02"PRIX8"), length:%"PRIu32"", + fastpath_update_to_string(updateCode), updateCode, size); #endif switch (updateCode) { case FASTPATH_UPDATETYPE_ORDERS: - if (!fastpath_recv_orders(fastpath, s)) - { - WLog_ERR(TAG, "FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_orders()"); - return -1; - } - + rc = fastpath_recv_orders(fastpath, s); break; case FASTPATH_UPDATETYPE_BITMAP: case FASTPATH_UPDATETYPE_PALETTE: - if (!fastpath_recv_update_common(fastpath, s)) - { - WLog_ERR(TAG, "FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_update_common()"); - return -1; - } - + rc = fastpath_recv_update_common(fastpath, s); break; case FASTPATH_UPDATETYPE_SYNCHRONIZE: if (!fastpath_recv_update_synchronize(fastpath, s)) WLog_ERR(TAG, "fastpath_recv_update_synchronize failure but we continue"); else - IFCALL(update->Synchronize, context); + rc = IFCALLRESULT(TRUE, update->Synchronize, context); break; case FASTPATH_UPDATETYPE_SURFCMDS: status = update_recv_surfcmds(update, s); - - if (status < 0) - WLog_ERR(TAG, "FASTPATH_UPDATETYPE_SURFCMDS - update_recv_surfcmds() - %i", status); - + rc = (status < 0) ? FALSE : TRUE; break; case FASTPATH_UPDATETYPE_PTR_NULL: - pointer->pointer_system.type = SYSPTR_NULL; - IFCALL(pointer->PointerSystem, context, &pointer->pointer_system); + { + POINTER_SYSTEM_UPDATE pointer_system; + pointer_system.type = SYSPTR_NULL; + rc = IFCALLRESULT(FALSE, pointer->PointerSystem, context, &pointer_system); + } break; case FASTPATH_UPDATETYPE_PTR_DEFAULT: - update->pointer->pointer_system.type = SYSPTR_DEFAULT; - IFCALL(pointer->PointerSystem, context, &pointer->pointer_system); + { + POINTER_SYSTEM_UPDATE pointer_system; + pointer_system.type = SYSPTR_DEFAULT; + rc = IFCALLRESULT(FALSE, pointer->PointerSystem, context, &pointer_system); + } break; case FASTPATH_UPDATETYPE_PTR_POSITION: - if (!update_read_pointer_position(s, &pointer->pointer_position)) { - WLog_ERR(TAG, "FASTPATH_UPDATETYPE_PTR_POSITION - update_read_pointer_position()"); - return -1; - } + POINTER_POSITION_UPDATE* pointer_position = update_read_pointer_position(update, s); - IFCALL(pointer->PointerPosition, context, &pointer->pointer_position); + if (pointer_position) + { + rc = IFCALLRESULT(FALSE, pointer->PointerPosition, context, pointer_position); + free_pointer_position_update(context, pointer_position); + } + } break; case FASTPATH_UPDATETYPE_COLOR: - if (!update_read_pointer_color(s, &pointer->pointer_color, 24)) { - WLog_ERR(TAG, "FASTPATH_UPDATETYPE_COLOR - update_read_pointer_color()"); - return -1; - } + POINTER_COLOR_UPDATE* pointer_color = update_read_pointer_color(update, s, 24); - IFCALL(pointer->PointerColor, context, &pointer->pointer_color); + if (pointer_color) + { + rc = IFCALLRESULT(FALSE, pointer->PointerColor, context, pointer_color); + free_pointer_color_update(context, pointer_color); + } + } break; case FASTPATH_UPDATETYPE_CACHED: - if (!update_read_pointer_cached(s, &pointer->pointer_cached)) { - WLog_ERR(TAG, "FASTPATH_UPDATETYPE_CACHED - update_read_pointer_cached()"); - return -1; - } + POINTER_CACHED_UPDATE* pointer_cached = update_read_pointer_cached(update, s); - IFCALL(pointer->PointerCached, context, &pointer->pointer_cached); + if (pointer_cached) + { + rc = IFCALLRESULT(FALSE, pointer->PointerCached, context, pointer_cached); + free_pointer_cached_update(context, pointer_cached); + } + } break; case FASTPATH_UPDATETYPE_POINTER: - if (!update_read_pointer_new(s, &pointer->pointer_new)) { - WLog_ERR(TAG, "FASTPATH_UPDATETYPE_POINTER - update_read_pointer_new()"); - return -1; - } + POINTER_NEW_UPDATE* pointer_new = update_read_pointer_new(update, s); - IFCALL(pointer->PointerNew, context, &pointer->pointer_new); + if (pointer_new) + { + rc = IFCALLRESULT(FALSE, pointer->PointerNew, context, pointer_new); + free_pointer_new_update(context, pointer_new); + } + } break; default: - WLog_ERR(TAG, "unknown updateCode 0x%02"PRIX8"", updateCode); break; } + if (!rc) + { + WLog_ERR(TAG, "Fastpath update %s [%"PRIx8"] failed, status %d", + fastpath_update_to_string(updateCode), updateCode, status); + return -1; + } + return status; } @@ -603,18 +636,22 @@ int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s) return -1; update = fastpath->rdp->update; - IFCALL(update->BeginPaint, update->context); + + if (!IFCALLRESULT(FALSE, update->BeginPaint, update->context)) + return -2; while (Stream_GetRemainingLength(s) >= 3) { if (fastpath_recv_update_data(fastpath, s) < 0) { WLog_ERR(TAG, "fastpath_recv_update_data() fail"); - return -1; + return -3; } } - IFCALL(update->EndPaint, update->context); + if (!IFCALLRESULT(FALSE, update->EndPaint, update->context)) + return -4; + return 0; } @@ -734,8 +771,8 @@ static BOOL fastpath_recv_input_event_unicode(rdpFastPath* fastpath, wStream* s, else flags |= KBD_FLAGS_DOWN; - IFCALL(fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, flags, unicodeCode); - return TRUE; + return IFCALLRESULT(FALSE, fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, flags, + unicodeCode); } static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, wStream* s) diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index bb5edbf9c..d08976ffe 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -36,6 +36,13 @@ #include #include +#include "../cache/pointer.h" +#include "../cache/bitmap.h" +#include "../cache/palette.h" +#include "../cache/glyph.h" +#include "../cache/brush.h" +#include "../cache/cache.h" + #define TAG FREERDP_TAG("core.message") #define WITH_STREAM_POOL 1 @@ -102,51 +109,16 @@ static BOOL update_message_DesktopResize(rdpContext* context) static BOOL update_message_BitmapUpdate(rdpContext* context, const BITMAP_UPDATE* bitmap) { - UINT32 index; BITMAP_UPDATE* wParam; if (!context || !context->update || !bitmap) return FALSE; - wParam = (BITMAP_UPDATE*) malloc(sizeof(BITMAP_UPDATE)); + wParam = copy_bitmap_update(context, bitmap); if (!wParam) return FALSE; - wParam->number = bitmap->number; - wParam->count = wParam->number; - wParam->rectangles = (BITMAP_DATA*) calloc(wParam->number, sizeof(BITMAP_DATA)); - - if (!wParam->rectangles) - { - free(wParam); - return FALSE; - } - - CopyMemory(wParam->rectangles, bitmap->rectangles, sizeof(BITMAP_DATA) * wParam->number); - - for (index = 0; index < wParam->number; index++) - { -#ifdef WITH_STREAM_POOL - StreamPool_AddRef(context->rdp->transport->ReceivePool, bitmap->rectangles[index].bitmapDataStream); -#else - wParam->rectangles[index].bitmapDataStream = (BYTE*) malloc(wParam->rectangles[index].bitmapLength); - - if (!wParam->rectangles[index].bitmapDataStream) - { - while (index) - free(wParam->rectangles[--index].bitmapDataStream); - - free(wParam->rectangles); - free(wParam); - return FALSE; - } - - CopyMemory(wParam->rectangles[index].bitmapDataStream, bitmap->rectangles[index].bitmapDataStream, - wParam->rectangles[index].bitmapLength); -#endif - } - return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, BitmapUpdate), (void*) wParam, NULL); } @@ -159,12 +131,11 @@ static BOOL update_message_Palette(rdpContext* context, if (!context || !context->update || !palette) return FALSE; - wParam = (PALETTE_UPDATE*) malloc(sizeof(PALETTE_UPDATE)); + wParam = copy_palette_update(context, palette); if (!wParam) return FALSE; - CopyMemory(wParam, palette, sizeof(PALETTE_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, Palette), (void*) wParam, NULL); } @@ -290,7 +261,8 @@ static BOOL update_message_SurfaceBits(rdpContext* context, return FALSE; } - CopyMemory(wParam->bmp.bitmapData, surfaceBitsCommand->bmp.bitmapData, wParam->bmp.bitmapDataLength); + CopyMemory(wParam->bmp.bitmapData, surfaceBitsCommand->bmp.bitmapData, + wParam->bmp.bitmapDataLength); #endif return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(Update, SurfaceBits), (void*) wParam, NULL); @@ -781,21 +753,11 @@ static BOOL update_message_CacheBitmap(rdpContext* context, if (!context || !context->update || !cacheBitmapOrder) return FALSE; - wParam = (CACHE_BITMAP_ORDER*) malloc(sizeof(CACHE_BITMAP_ORDER)); + wParam = copy_cache_bitmap_order(context, cacheBitmapOrder); if (!wParam) return FALSE; - CopyMemory(wParam, cacheBitmapOrder, sizeof(CACHE_BITMAP_ORDER)); - wParam->bitmapDataStream = (BYTE*) malloc(wParam->bitmapLength); - - if (!wParam->bitmapDataStream) - { - free(wParam); - return FALSE; - } - - CopyMemory(wParam->bitmapDataStream, cacheBitmapOrder, wParam->bitmapLength); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheBitmap), (void*) wParam, NULL); } @@ -808,21 +770,11 @@ static BOOL update_message_CacheBitmapV2(rdpContext* context, if (!context || !context->update || !cacheBitmapV2Order) return FALSE; - wParam = (CACHE_BITMAP_V2_ORDER*) malloc(sizeof(CACHE_BITMAP_V2_ORDER)); + wParam = copy_cache_bitmap_v2_order(context, cacheBitmapV2Order); if (!wParam) return FALSE; - CopyMemory(wParam, cacheBitmapV2Order, sizeof(CACHE_BITMAP_V2_ORDER)); - wParam->bitmapDataStream = (BYTE*) malloc(wParam->bitmapLength); - - if (!wParam->bitmapDataStream) - { - free(wParam); - return FALSE; - } - - CopyMemory(wParam->bitmapDataStream, cacheBitmapV2Order->bitmapDataStream, wParam->bitmapLength); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheBitmapV2), (void*) wParam, NULL); } @@ -835,21 +787,11 @@ static BOOL update_message_CacheBitmapV3(rdpContext* context, if (!context || !context->update || !cacheBitmapV3Order) return FALSE; - wParam = (CACHE_BITMAP_V3_ORDER*) malloc(sizeof(CACHE_BITMAP_V3_ORDER)); + wParam = copy_cache_bitmap_v3_order(context, cacheBitmapV3Order); if (!wParam) return FALSE; - CopyMemory(wParam, cacheBitmapV3Order, sizeof(CACHE_BITMAP_V3_ORDER)); - wParam->bitmapData.data = (BYTE*) malloc(wParam->bitmapData.length); - - if (!wParam->bitmapData.data) - { - free(wParam); - return FALSE; - } - - CopyMemory(wParam->bitmapData.data, cacheBitmapV3Order->bitmapData.data, wParam->bitmapData.length); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheBitmapV3), (void*) wParam, NULL); } @@ -863,12 +805,11 @@ static BOOL update_message_CacheColorTable( if (!context || !context->update || !cacheColorTableOrder) return FALSE; - wParam = (CACHE_COLOR_TABLE_ORDER*) malloc(sizeof(CACHE_COLOR_TABLE_ORDER)); + wParam = copy_cache_color_table_order(context, cacheColorTableOrder); if (!wParam) return FALSE; - CopyMemory(wParam, cacheColorTableOrder, sizeof(CACHE_COLOR_TABLE_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheColorTable), (void*) wParam, NULL); } @@ -882,12 +823,11 @@ static BOOL update_message_CacheGlyph( if (!context || !context->update || !cacheGlyphOrder) return FALSE; - wParam = (CACHE_GLYPH_ORDER*) malloc(sizeof(CACHE_GLYPH_ORDER)); + wParam = copy_cache_glyph_order(context, cacheGlyphOrder); if (!wParam) return FALSE; - CopyMemory(wParam, cacheGlyphOrder, sizeof(CACHE_GLYPH_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheGlyph), (void*) wParam, NULL); } @@ -901,12 +841,11 @@ static BOOL update_message_CacheGlyphV2( if (!context || !context->update || !cacheGlyphV2Order) return FALSE; - wParam = (CACHE_GLYPH_V2_ORDER*) malloc(sizeof(CACHE_GLYPH_V2_ORDER)); + wParam = copy_cache_glyph_v2_order(context, cacheGlyphV2Order); if (!wParam) return FALSE; - CopyMemory(wParam, cacheGlyphV2Order, sizeof(CACHE_GLYPH_V2_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheGlyphV2), (void*) wParam, NULL); } @@ -920,12 +859,11 @@ static BOOL update_message_CacheBrush( if (!context || !context->update || !cacheBrushOrder) return FALSE; - wParam = (CACHE_BRUSH_ORDER*) malloc(sizeof(CACHE_BRUSH_ORDER)); + wParam = copy_cache_brush_order(context, cacheBrushOrder); if (!wParam) return FALSE; - CopyMemory(wParam, cacheBrushOrder, sizeof(CACHE_BRUSH_ORDER)); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(SecondaryUpdate, CacheBrush), (void*) wParam, NULL); } @@ -1489,12 +1427,11 @@ static BOOL update_message_PointerPosition(rdpContext* context, if (!context || !context->update || !pointerPosition) return FALSE; - wParam = (POINTER_POSITION_UPDATE*) malloc(sizeof(POINTER_POSITION_UPDATE)); + wParam = copy_pointer_position_update(context, pointerPosition); if (!wParam) return FALSE; - CopyMemory(wParam, pointerPosition, sizeof(POINTER_POSITION_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerPosition), (void*) wParam, NULL); } @@ -1507,12 +1444,11 @@ static BOOL update_message_PointerSystem(rdpContext* context, if (!context || !context->update || !pointerSystem) return FALSE; - wParam = (POINTER_SYSTEM_UPDATE*) malloc(sizeof(POINTER_SYSTEM_UPDATE)); + wParam = copy_pointer_system_update(context, pointerSystem); if (!wParam) return FALSE; - CopyMemory(wParam, pointerSystem, sizeof(POINTER_SYSTEM_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerSystem), (void*) wParam, NULL); } @@ -1525,41 +1461,13 @@ static BOOL update_message_PointerColor(rdpContext* context, if (!context || !context->update || !pointerColor) return FALSE; - wParam = (POINTER_COLOR_UPDATE*) malloc(sizeof(POINTER_COLOR_UPDATE)); + wParam = copy_pointer_color_update(context, pointerColor); if (!wParam) return FALSE; - CopyMemory(wParam, pointerColor, sizeof(POINTER_COLOR_UPDATE)); - wParam->andMaskData = wParam->xorMaskData = NULL; - - if (wParam->lengthAndMask) - { - wParam->andMaskData = (BYTE*) malloc(wParam->lengthAndMask); - - if (!wParam->andMaskData) - goto out_fail; - - CopyMemory(wParam->andMaskData, pointerColor->andMaskData, wParam->lengthAndMask); - } - - if (wParam->lengthXorMask) - { - wParam->xorMaskData = (BYTE*) malloc(wParam->lengthXorMask); - - if (!wParam->xorMaskData) - goto out_fail; - - CopyMemory(wParam->xorMaskData, pointerColor->xorMaskData, wParam->lengthXorMask); - } - return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerColor), (void*) wParam, NULL); -out_fail: - free(wParam->andMaskData); - free(wParam->xorMaskData); - free(wParam); - return FALSE; } static BOOL update_message_PointerNew(rdpContext* context, @@ -1570,43 +1478,13 @@ static BOOL update_message_PointerNew(rdpContext* context, if (!context || !context->update || !pointerNew) return FALSE; - wParam = (POINTER_NEW_UPDATE*) malloc(sizeof(POINTER_NEW_UPDATE)); + wParam = copy_pointer_new_update(context, pointerNew); if (!wParam) return FALSE; - CopyMemory(wParam, pointerNew, sizeof(POINTER_NEW_UPDATE)); - wParam->colorPtrAttr.andMaskData = wParam->colorPtrAttr.xorMaskData = NULL; - - if (wParam->colorPtrAttr.lengthAndMask) - { - wParam->colorPtrAttr.andMaskData = (BYTE*) malloc(wParam->colorPtrAttr.lengthAndMask); - - if (!wParam->colorPtrAttr.andMaskData) - goto out_fail; - - CopyMemory(wParam->colorPtrAttr.andMaskData, pointerNew->colorPtrAttr.andMaskData, - wParam->colorPtrAttr.lengthAndMask); - } - - if (wParam->colorPtrAttr.lengthXorMask) - { - wParam->colorPtrAttr.xorMaskData = (BYTE*) malloc(wParam->colorPtrAttr.lengthXorMask); - - if (!wParam->colorPtrAttr.xorMaskData) - goto out_fail; - - CopyMemory(wParam->colorPtrAttr.xorMaskData, pointerNew->colorPtrAttr.xorMaskData, - wParam->colorPtrAttr.lengthXorMask); - } - return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerNew), (void*) wParam, NULL); -out_fail: - free(wParam->colorPtrAttr.andMaskData); - free(wParam->colorPtrAttr.xorMaskData); - free(wParam); - return FALSE; } static BOOL update_message_PointerCached(rdpContext* context, @@ -1617,23 +1495,25 @@ static BOOL update_message_PointerCached(rdpContext* context, if (!context || !context->update || !pointerCached) return FALSE; - wParam = (POINTER_CACHED_UPDATE*) malloc(sizeof(POINTER_CACHED_UPDATE)); + wParam = copy_pointer_cached_update(context, pointerCached); if (!wParam) return FALSE; - CopyMemory(wParam, pointerCached, sizeof(POINTER_CACHED_UPDATE)); return MessageQueue_Post(context->update->queue, (void*) context, MakeMessageId(PointerUpdate, PointerCached), (void*) wParam, NULL); } /* Message Queue */ -static int update_message_free_update_class(wMessage* msg, int type) +static BOOL update_message_free_update_class(wMessage* msg, int type) { int status = 0; + rdpContext* context; if (!msg) - return -1; + return FALSE; + + context = (rdpContext*) msg->context; switch (type) { @@ -1655,27 +1535,16 @@ static int update_message_free_update_class(wMessage* msg, int type) case Update_BitmapUpdate: { - UINT32 index; BITMAP_UPDATE* wParam = (BITMAP_UPDATE*) msg->wParam; - - for (index = 0; index < wParam->number; index++) - { -#ifdef WITH_STREAM_POOL - rdpContext* context = (rdpContext*) msg->context; - StreamPool_Release(context->rdp->transport->ReceivePool, - wParam->rectangles[index].bitmapDataStream); -#else - free(wParam->rectangles[index].bitmapDataStream); -#endif - } - - free(wParam->rectangles); - free(wParam); + free_bitmap_update(context, wParam); } break; case Update_Palette: - free(msg->wParam); + { + PALETTE_UPDATE* palette = (PALETTE_UPDATE*)msg->wParam; + free_palette_update(context, palette); + } break; case Update_PlaySound: @@ -1721,17 +1590,16 @@ static int update_message_free_update_class(wMessage* msg, int type) break; default: - status = -1; - break; + return FALSE; } - return status; + return TRUE; } -static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static BOOL update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) { - int status = 0; + BOOL rc = FALSE; if (!proxy || !msg) return -1; @@ -1739,65 +1607,67 @@ static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* switch (type) { case Update_BeginPaint: - IFCALL(proxy->BeginPaint, msg->context); + rc = IFCALLRESULT(FALSE, proxy->BeginPaint, msg->context); break; case Update_EndPaint: - IFCALL(proxy->EndPaint, msg->context); + rc = IFCALLRESULT(FALSE, proxy->EndPaint, msg->context); break; case Update_SetBounds: - IFCALL(proxy->SetBounds, msg->context, (rdpBounds*) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->SetBounds, msg->context, (rdpBounds*) msg->wParam); break; case Update_Synchronize: - IFCALL(proxy->Synchronize, msg->context); + rc = IFCALLRESULT(FALSE, proxy->Synchronize, msg->context); break; case Update_DesktopResize: - IFCALL(proxy->DesktopResize, msg->context); + rc = IFCALLRESULT(FALSE, proxy->DesktopResize, msg->context); break; case Update_BitmapUpdate: - IFCALL(proxy->BitmapUpdate, msg->context, (BITMAP_UPDATE*) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->BitmapUpdate, msg->context, (BITMAP_UPDATE*) msg->wParam); break; case Update_Palette: - IFCALL(proxy->Palette, msg->context, (PALETTE_UPDATE*) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->Palette, msg->context, (PALETTE_UPDATE*) msg->wParam); break; case Update_PlaySound: - IFCALL(proxy->PlaySound, msg->context, (PLAY_SOUND_UPDATE*) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->PlaySound, msg->context, (PLAY_SOUND_UPDATE*) msg->wParam); break; case Update_RefreshRect: - IFCALL(proxy->RefreshRect, msg->context, - (BYTE)(size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); + rc = IFCALLRESULT(FALSE, proxy->RefreshRect, msg->context, + (BYTE)(size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); break; case Update_SuppressOutput: - IFCALL(proxy->SuppressOutput, msg->context, - (BYTE)(size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); + rc = IFCALLRESULT(FALSE, proxy->SuppressOutput, msg->context, + (BYTE)(size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); break; case Update_SurfaceCommand: - IFCALL(proxy->SurfaceCommand, msg->context, (wStream*) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->SurfaceCommand, msg->context, (wStream*) msg->wParam); break; case Update_SurfaceBits: - IFCALL(proxy->SurfaceBits, msg->context, (SURFACE_BITS_COMMAND*) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->SurfaceBits, msg->context, (SURFACE_BITS_COMMAND*) msg->wParam); break; case Update_SurfaceFrameMarker: - IFCALL(proxy->SurfaceFrameMarker, msg->context, (SURFACE_FRAME_MARKER*) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->SurfaceFrameMarker, msg->context, + (SURFACE_FRAME_MARKER*) msg->wParam); break; case Update_SurfaceFrameAcknowledge: - IFCALL(proxy->SurfaceFrameAcknowledge, msg->context, (UINT32)(size_t) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->SurfaceFrameAcknowledge, msg->context, + (UINT32)(size_t) msg->wParam); break; case Update_SetKeyboardIndicators: - IFCALL(proxy->SetKeyboardIndicators, msg->context, (UINT16)(size_t) msg->wParam); + rc = IFCALLRESULT(FALSE, proxy->SetKeyboardIndicators, msg->context, (UINT16)(size_t) msg->wParam); break; case Update_SetKeyboardImeStatus: @@ -1805,24 +1675,21 @@ static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* const UINT16 imeId = ((size_t)msg->wParam) >> 16 & 0xFFFF; const UINT32 imeState = ((size_t)msg->wParam) & 0xFFFF; const UINT32 imeConvMode = ((size_t)msg->lParam); - IFCALL(proxy->SetKeyboardImeStatus, msg->context, imeId, imeState, imeConvMode); + rc = IFCALLRESULT(FALSE, proxy->SetKeyboardImeStatus, msg->context, imeId, imeState, imeConvMode); } break; default: - status = -1; break; } - return status; + return rc; } -static int update_message_free_primary_update_class(wMessage* msg, int type) +static BOOL update_message_free_primary_update_class(wMessage* msg, int type) { - int status = 0; - if (!msg) - return -1; + return FALSE; switch (type) { @@ -1931,242 +1798,203 @@ static int update_message_free_primary_update_class(wMessage* msg, int type) break; default: - status = -1; - break; + return FALSE; } - return status; + return TRUE; } -static int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg, +static BOOL update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) { - int status = 0; - if (!proxy || !msg) - return -1; + return FALSE; switch (type) { case PrimaryUpdate_DstBlt: - IFCALL(proxy->DstBlt, msg->context, (DSTBLT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->DstBlt, msg->context, (DSTBLT_ORDER*) msg->wParam); case PrimaryUpdate_PatBlt: - IFCALL(proxy->PatBlt, msg->context, (PATBLT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->PatBlt, msg->context, (PATBLT_ORDER*) msg->wParam); case PrimaryUpdate_ScrBlt: - IFCALL(proxy->ScrBlt, msg->context, (SCRBLT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->ScrBlt, msg->context, (SCRBLT_ORDER*) msg->wParam); case PrimaryUpdate_OpaqueRect: - IFCALL(proxy->OpaqueRect, msg->context, (OPAQUE_RECT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->OpaqueRect, msg->context, (OPAQUE_RECT_ORDER*) msg->wParam); case PrimaryUpdate_DrawNineGrid: - IFCALL(proxy->DrawNineGrid, msg->context, (DRAW_NINE_GRID_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->DrawNineGrid, msg->context, (DRAW_NINE_GRID_ORDER*) msg->wParam); case PrimaryUpdate_MultiDstBlt: - IFCALL(proxy->MultiDstBlt, msg->context, (MULTI_DSTBLT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->MultiDstBlt, msg->context, (MULTI_DSTBLT_ORDER*) msg->wParam); case PrimaryUpdate_MultiPatBlt: - IFCALL(proxy->MultiPatBlt, msg->context, (MULTI_PATBLT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->MultiPatBlt, msg->context, (MULTI_PATBLT_ORDER*) msg->wParam); case PrimaryUpdate_MultiScrBlt: - IFCALL(proxy->MultiScrBlt, msg->context, (MULTI_SCRBLT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->MultiScrBlt, msg->context, (MULTI_SCRBLT_ORDER*) msg->wParam); case PrimaryUpdate_MultiOpaqueRect: - IFCALL(proxy->MultiOpaqueRect, msg->context, (MULTI_OPAQUE_RECT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->MultiOpaqueRect, msg->context, + (MULTI_OPAQUE_RECT_ORDER*) msg->wParam); case PrimaryUpdate_MultiDrawNineGrid: - IFCALL(proxy->MultiDrawNineGrid, msg->context, (MULTI_DRAW_NINE_GRID_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->MultiDrawNineGrid, msg->context, + (MULTI_DRAW_NINE_GRID_ORDER*) msg->wParam); case PrimaryUpdate_LineTo: - IFCALL(proxy->LineTo, msg->context, (LINE_TO_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->LineTo, msg->context, (LINE_TO_ORDER*) msg->wParam); case PrimaryUpdate_Polyline: - IFCALL(proxy->Polyline, msg->context, (POLYLINE_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->Polyline, msg->context, (POLYLINE_ORDER*) msg->wParam); case PrimaryUpdate_MemBlt: - IFCALL(proxy->MemBlt, msg->context, (MEMBLT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->MemBlt, msg->context, (MEMBLT_ORDER*) msg->wParam); case PrimaryUpdate_Mem3Blt: - IFCALL(proxy->Mem3Blt, msg->context, (MEM3BLT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->Mem3Blt, msg->context, (MEM3BLT_ORDER*) msg->wParam); case PrimaryUpdate_SaveBitmap: - IFCALL(proxy->SaveBitmap, msg->context, (SAVE_BITMAP_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->SaveBitmap, msg->context, (SAVE_BITMAP_ORDER*) msg->wParam); case PrimaryUpdate_GlyphIndex: - IFCALL(proxy->GlyphIndex, msg->context, (GLYPH_INDEX_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->GlyphIndex, msg->context, (GLYPH_INDEX_ORDER*) msg->wParam); case PrimaryUpdate_FastIndex: - IFCALL(proxy->FastIndex, msg->context, (FAST_INDEX_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->FastIndex, msg->context, (FAST_INDEX_ORDER*) msg->wParam); case PrimaryUpdate_FastGlyph: - IFCALL(proxy->FastGlyph, msg->context, (FAST_GLYPH_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->FastGlyph, msg->context, (FAST_GLYPH_ORDER*) msg->wParam); case PrimaryUpdate_PolygonSC: - IFCALL(proxy->PolygonSC, msg->context, (POLYGON_SC_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->PolygonSC, msg->context, (POLYGON_SC_ORDER*) msg->wParam); case PrimaryUpdate_PolygonCB: - IFCALL(proxy->PolygonCB, msg->context, (POLYGON_CB_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->PolygonCB, msg->context, (POLYGON_CB_ORDER*) msg->wParam); case PrimaryUpdate_EllipseSC: - IFCALL(proxy->EllipseSC, msg->context, (ELLIPSE_SC_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->EllipseSC, msg->context, (ELLIPSE_SC_ORDER*) msg->wParam); case PrimaryUpdate_EllipseCB: - IFCALL(proxy->EllipseCB, msg->context, (ELLIPSE_CB_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->EllipseCB, msg->context, (ELLIPSE_CB_ORDER*) msg->wParam); default: - status = -1; - break; + return FALSE; } - - return status; } -static int update_message_free_secondary_update_class(wMessage* msg, int type) +static BOOL update_message_free_secondary_update_class(wMessage* msg, int type) { - int status = 0; + rdpContext* context; if (!msg) - return -1; + return FALSE; + + context = msg->context; switch (type) { case SecondaryUpdate_CacheBitmap: { CACHE_BITMAP_ORDER* wParam = (CACHE_BITMAP_ORDER*) msg->wParam; - free(wParam->bitmapDataStream); - free(wParam); + free_cache_bitmap_order(context, wParam); } break; case SecondaryUpdate_CacheBitmapV2: { CACHE_BITMAP_V2_ORDER* wParam = (CACHE_BITMAP_V2_ORDER*) msg->wParam; - free(wParam->bitmapDataStream); - free(wParam); + free_cache_bitmap_v2_order(context, wParam); } break; case SecondaryUpdate_CacheBitmapV3: { CACHE_BITMAP_V3_ORDER* wParam = (CACHE_BITMAP_V3_ORDER*) msg->wParam; - free(wParam->bitmapData.data); - free(wParam); + free_cache_bitmap_v3_order(context, wParam); } break; case SecondaryUpdate_CacheColorTable: { CACHE_COLOR_TABLE_ORDER* wParam = (CACHE_COLOR_TABLE_ORDER*) msg->wParam; - free(wParam); + free_cache_color_table_order(context, wParam); } break; case SecondaryUpdate_CacheGlyph: { CACHE_GLYPH_ORDER* wParam = (CACHE_GLYPH_ORDER*) msg->wParam; - free(wParam); + free_cache_glyph_order(context, wParam); } break; case SecondaryUpdate_CacheGlyphV2: { CACHE_GLYPH_V2_ORDER* wParam = (CACHE_GLYPH_V2_ORDER*) msg->wParam; - free(wParam); + free_cache_glyph_v2_order(context, wParam); } break; case SecondaryUpdate_CacheBrush: { CACHE_BRUSH_ORDER* wParam = (CACHE_BRUSH_ORDER*) msg->wParam; - free(wParam); + free_cache_brush_order(context, wParam); } break; default: - status = -1; - break; + return FALSE; } - return status; + return TRUE; } -static int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg, +static BOOL update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) { - int status = 0; - if (!proxy || !msg) - return -1; + return FALSE; switch (type) { case SecondaryUpdate_CacheBitmap: - IFCALL(proxy->CacheBitmap, msg->context, (CACHE_BITMAP_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CacheBitmap, msg->context, (CACHE_BITMAP_ORDER*) msg->wParam); case SecondaryUpdate_CacheBitmapV2: - IFCALL(proxy->CacheBitmapV2, msg->context, (CACHE_BITMAP_V2_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CacheBitmapV2, msg->context, + (CACHE_BITMAP_V2_ORDER*) msg->wParam); case SecondaryUpdate_CacheBitmapV3: - IFCALL(proxy->CacheBitmapV3, msg->context, (CACHE_BITMAP_V3_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CacheBitmapV3, msg->context, + (CACHE_BITMAP_V3_ORDER*) msg->wParam); case SecondaryUpdate_CacheColorTable: - IFCALL(proxy->CacheColorTable, msg->context, (CACHE_COLOR_TABLE_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CacheColorTable, msg->context, + (CACHE_COLOR_TABLE_ORDER*) msg->wParam); case SecondaryUpdate_CacheGlyph: - IFCALL(proxy->CacheGlyph, msg->context, (CACHE_GLYPH_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CacheGlyph, msg->context, (CACHE_GLYPH_ORDER*) msg->wParam); case SecondaryUpdate_CacheGlyphV2: - IFCALL(proxy->CacheGlyphV2, msg->context, (CACHE_GLYPH_V2_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CacheGlyphV2, msg->context, (CACHE_GLYPH_V2_ORDER*) msg->wParam); case SecondaryUpdate_CacheBrush: - IFCALL(proxy->CacheBrush, msg->context, (CACHE_BRUSH_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CacheBrush, msg->context, (CACHE_BRUSH_ORDER*) msg->wParam); default: - status = -1; - break; + return FALSE; } - - return status; } -static int update_message_free_altsec_update_class(wMessage* msg, int type) +static BOOL update_message_free_altsec_update_class(wMessage* msg, int type) { - int status = 0; - if (!msg) - return -1; + return FALSE; switch (type) { @@ -2223,86 +2051,78 @@ static int update_message_free_altsec_update_class(wMessage* msg, int type) break; default: - status = -1; - break; + return FALSE; } - return status; + return TRUE; } -static int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg, +static BOOL update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) { int status = 0; if (!proxy || !msg) - return -1; + return FALSE; switch (type) { case AltSecUpdate_CreateOffscreenBitmap: - IFCALL(proxy->CreateOffscreenBitmap, msg->context, (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CreateOffscreenBitmap, msg->context, + (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam); case AltSecUpdate_SwitchSurface: - IFCALL(proxy->SwitchSurface, msg->context, (SWITCH_SURFACE_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->SwitchSurface, msg->context, (SWITCH_SURFACE_ORDER*) msg->wParam); case AltSecUpdate_CreateNineGridBitmap: - IFCALL(proxy->CreateNineGridBitmap, msg->context, (CREATE_NINE_GRID_BITMAP_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->CreateNineGridBitmap, msg->context, + (CREATE_NINE_GRID_BITMAP_ORDER*) msg->wParam); case AltSecUpdate_FrameMarker: - IFCALL(proxy->FrameMarker, msg->context, (FRAME_MARKER_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->FrameMarker, msg->context, (FRAME_MARKER_ORDER*) msg->wParam); case AltSecUpdate_StreamBitmapFirst: - IFCALL(proxy->StreamBitmapFirst, msg->context, (STREAM_BITMAP_FIRST_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->StreamBitmapFirst, msg->context, + (STREAM_BITMAP_FIRST_ORDER*) msg->wParam); case AltSecUpdate_StreamBitmapNext: - IFCALL(proxy->StreamBitmapNext, msg->context, (STREAM_BITMAP_NEXT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->StreamBitmapNext, msg->context, + (STREAM_BITMAP_NEXT_ORDER*) msg->wParam); case AltSecUpdate_DrawGdiPlusFirst: - IFCALL(proxy->DrawGdiPlusFirst, msg->context, (DRAW_GDIPLUS_FIRST_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->DrawGdiPlusFirst, msg->context, + (DRAW_GDIPLUS_FIRST_ORDER*) msg->wParam); case AltSecUpdate_DrawGdiPlusNext: - IFCALL(proxy->DrawGdiPlusNext, msg->context, (DRAW_GDIPLUS_NEXT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->DrawGdiPlusNext, msg->context, + (DRAW_GDIPLUS_NEXT_ORDER*) msg->wParam); case AltSecUpdate_DrawGdiPlusEnd: - IFCALL(proxy->DrawGdiPlusEnd, msg->context, (DRAW_GDIPLUS_END_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->DrawGdiPlusEnd, msg->context, + (DRAW_GDIPLUS_END_ORDER*) msg->wParam); case AltSecUpdate_DrawGdiPlusCacheFirst: - IFCALL(proxy->DrawGdiPlusCacheFirst, msg->context, (DRAW_GDIPLUS_CACHE_FIRST_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->DrawGdiPlusCacheFirst, msg->context, + (DRAW_GDIPLUS_CACHE_FIRST_ORDER*) msg->wParam); case AltSecUpdate_DrawGdiPlusCacheNext: - IFCALL(proxy->DrawGdiPlusCacheNext, msg->context, (DRAW_GDIPLUS_CACHE_NEXT_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->DrawGdiPlusCacheNext, msg->context, + (DRAW_GDIPLUS_CACHE_NEXT_ORDER*) msg->wParam); case AltSecUpdate_DrawGdiPlusCacheEnd: - IFCALL(proxy->DrawGdiPlusCacheEnd, msg->context, (DRAW_GDIPLUS_CACHE_END_ORDER*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->DrawGdiPlusCacheEnd, msg->context, + (DRAW_GDIPLUS_CACHE_END_ORDER*) msg->wParam); default: - status = -1; - break; + return FALSE; } - - return status; } -static int update_message_free_window_update_class(wMessage* msg, int type) +static BOOL update_message_free_window_update_class(wMessage* msg, int type) { - int status = 0; - if (!msg) - return -1; + return FALSE; switch (type) { @@ -2378,164 +2198,154 @@ static int update_message_free_window_update_class(wMessage* msg, int type) break; default: - status = -1; - break; + return FALSE; } - return status; + return TRUE; } -static int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg, +static BOOL update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) { - int status = 0; - if (!proxy || !msg) - return -1; + return FALSE; switch (type) { case WindowUpdate_WindowCreate: - IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_STATE_ORDER*) msg->lParam); - break; + return IFCALLRESULT(FALSE, proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_STATE_ORDER*) msg->lParam); case WindowUpdate_WindowUpdate: - IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_STATE_ORDER*) msg->lParam); - break; + return IFCALLRESULT(FALSE, proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_STATE_ORDER*) msg->lParam); case WindowUpdate_WindowIcon: { WINDOW_ORDER_INFO* orderInfo = (WINDOW_ORDER_INFO*) msg->wParam; WINDOW_ICON_ORDER* windowIcon = (WINDOW_ICON_ORDER*) msg->lParam; - IFCALL(proxy->WindowIcon, msg->context, orderInfo, windowIcon); + return IFCALLRESULT(FALSE, proxy->WindowIcon, msg->context, orderInfo, windowIcon); } - break; case WindowUpdate_WindowCachedIcon: - IFCALL(proxy->WindowCachedIcon, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_CACHED_ICON_ORDER*) msg->lParam); - break; + return IFCALLRESULT(FALSE, proxy->WindowCachedIcon, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_CACHED_ICON_ORDER*) msg->lParam); case WindowUpdate_WindowDelete: - IFCALL(proxy->WindowDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->WindowDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); case WindowUpdate_NotifyIconCreate: - IFCALL(proxy->NotifyIconCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (NOTIFY_ICON_STATE_ORDER*) msg->lParam); - break; + return IFCALLRESULT(FALSE, proxy->NotifyIconCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (NOTIFY_ICON_STATE_ORDER*) msg->lParam); case WindowUpdate_NotifyIconUpdate: - IFCALL(proxy->NotifyIconUpdate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (NOTIFY_ICON_STATE_ORDER*) msg->lParam); - break; + return IFCALLRESULT(FALSE, proxy->NotifyIconUpdate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (NOTIFY_ICON_STATE_ORDER*) msg->lParam); case WindowUpdate_NotifyIconDelete: - IFCALL(proxy->NotifyIconDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->NotifyIconDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); case WindowUpdate_MonitoredDesktop: - IFCALL(proxy->MonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (MONITORED_DESKTOP_ORDER*) msg->lParam); - break; + return IFCALLRESULT(FALSE, proxy->MonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (MONITORED_DESKTOP_ORDER*) msg->lParam); case WindowUpdate_NonMonitoredDesktop: - IFCALL(proxy->NonMonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->NonMonitoredDesktop, msg->context, + (WINDOW_ORDER_INFO*) msg->wParam); default: - status = -1; - break; + return FALSE; } - - return status; } -int update_message_free_pointer_update_class(wMessage* msg, int type) +static BOOL update_message_free_pointer_update_class(wMessage* msg, int type) { - int status = 0; + rdpContext* context; if (!msg) - return -1; + return FALSE; + + context = msg->context; switch (type) { case PointerUpdate_PointerPosition: + { + POINTER_POSITION_UPDATE* wParam = (POINTER_POSITION_UPDATE*)msg->wParam; + free_pointer_position_update(context, wParam); + } + break; + case PointerUpdate_PointerSystem: + { + POINTER_SYSTEM_UPDATE* wParam = (POINTER_SYSTEM_UPDATE*)msg->wParam; + free_pointer_system_update(context, wParam); + } + break; + case PointerUpdate_PointerCached: - free(msg->wParam); + { + POINTER_CACHED_UPDATE* wParam = (POINTER_CACHED_UPDATE*) msg->wParam; + free_pointer_cached_update(context, wParam); + } break; case PointerUpdate_PointerColor: { POINTER_COLOR_UPDATE* wParam = (POINTER_COLOR_UPDATE*) msg->wParam; - free(wParam->andMaskData); - free(wParam->xorMaskData); - free(wParam); + free_pointer_color_update(context, wParam); } break; case PointerUpdate_PointerNew: { POINTER_NEW_UPDATE* wParam = (POINTER_NEW_UPDATE*) msg->wParam; - free(wParam->colorPtrAttr.andMaskData); - free(wParam->colorPtrAttr.xorMaskData); - free(wParam); + free_pointer_new_update(context, wParam); } break; default: - status = -1; - break; + return FALSE; } - return status; + return TRUE; } -static int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg, +static BOOL update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) { - int status = 0; - if (!proxy || !msg) - return -1; + return FALSE; switch (type) { case PointerUpdate_PointerPosition: - IFCALL(proxy->PointerPosition, msg->context, (POINTER_POSITION_UPDATE*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->PointerPosition, msg->context, + (POINTER_POSITION_UPDATE*) msg->wParam); case PointerUpdate_PointerSystem: - IFCALL(proxy->PointerSystem, msg->context, (POINTER_SYSTEM_UPDATE*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->PointerSystem, msg->context, + (POINTER_SYSTEM_UPDATE*) msg->wParam); case PointerUpdate_PointerColor: - IFCALL(proxy->PointerColor, msg->context, (POINTER_COLOR_UPDATE*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->PointerColor, msg->context, (POINTER_COLOR_UPDATE*) msg->wParam); case PointerUpdate_PointerNew: - IFCALL(proxy->PointerNew, msg->context, (POINTER_NEW_UPDATE*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->PointerNew, msg->context, (POINTER_NEW_UPDATE*) msg->wParam); case PointerUpdate_PointerCached: - IFCALL(proxy->PointerCached, msg->context, (POINTER_CACHED_UPDATE*) msg->wParam); - break; + return IFCALLRESULT(FALSE, proxy->PointerCached, msg->context, + (POINTER_CACHED_UPDATE*) msg->wParam); default: - status = -1; - break; + return FALSE; } - - return status; } -static int update_message_free_class(wMessage* msg, int msgClass, int msgType) +static BOOL update_message_free_class(wMessage* msg, int msgClass, int msgType) { - int status = 0; + BOOL status = FALSE; switch (msgClass) { @@ -2564,11 +2374,10 @@ static int update_message_free_class(wMessage* msg, int msgClass, int msgType) break; default: - status = -1; break; } - if (status < 0) + if (!status) WLog_ERR(TAG, "Unknown message: class: %d type: %d", msgClass, msgType); return status; @@ -2577,7 +2386,7 @@ static int update_message_free_class(wMessage* msg, int msgClass, int msgType) static int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, int msgClass, int msgType) { - int status = 0; + BOOL status = FALSE; switch (msgClass) { @@ -2606,14 +2415,17 @@ static int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, in break; default: - status = -1; + status = FALSE; break; } - if (status < 0) - WLog_ERR(TAG, "Unknown message: class: %d type: %d", msgClass, msgType); + if (!status) + { + WLog_ERR(TAG, "message: class: %d type: %d failed", msgClass, msgType); + return -1; + } - return status; + return 0; } int update_message_queue_process_message(rdpUpdate* update, wMessage* message) diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c index b68ac9116..1f1c00d91 100644 --- a/libfreerdp/core/orders.c +++ b/libfreerdp/core/orders.c @@ -35,6 +35,11 @@ #include "orders.h" +#include "../cache/glyph.h" +#include "../cache/bitmap.h" +#include "../cache/brush.h" +#include "../cache/cache.h" + #define TAG FREERDP_TAG("core.orders") static const char* const PRIMARY_DRAWING_ORDER_STRINGS[] = @@ -174,6 +179,14 @@ static const BYTE BPP_BMF[] = 6, 0, 0, 0, 0, 0, 0, 0 }; +static const char* update_secondary_order_to_string(BYTE order) +{ + if (order >= ARRAYSIZE(SECONDARY_DRAWING_ORDER_STRINGS)) + return "UNKNOWN"; + + return SECONDARY_DRAWING_ORDER_STRINGS[order]; +} + static INLINE BOOL update_read_coord(wStream* s, INT32* coord, BOOL delta) { INT8 lsi8; @@ -1672,12 +1685,16 @@ static BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo, return update_read_brush(s, &ellipse_cb->brush, orderInfo->fieldFlags >> 8); } /* Secondary Drawing Orders */ -static BOOL update_read_cache_bitmap_order(wStream* s, - CACHE_BITMAP_ORDER* cache_bitmap, +static CACHE_BITMAP_ORDER* update_read_cache_bitmap_order(rdpUpdate* update, wStream* s, BOOL compressed, UINT16 flags) { + CACHE_BITMAP_ORDER* cache_bitmap = calloc(1, sizeof(CACHE_BITMAP_ORDER)); + + if (!cache_bitmap || !update || !s) + goto fail; + if (Stream_GetRemainingLength(s) < 9) - return FALSE; + goto fail; Stream_Read_UINT8(s, cache_bitmap->cacheId); /* cacheId (1 byte) */ Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */ @@ -1688,7 +1705,7 @@ static BOOL update_read_cache_bitmap_order(wStream* s, if ((cache_bitmap->bitmapBpp < 1) || (cache_bitmap->bitmapBpp > 32)) { WLog_ERR(TAG, "invalid bitmap bpp %"PRIu32"", cache_bitmap->bitmapBpp); - return FALSE; + goto fail; } Stream_Read_UINT16(s, cache_bitmap->bitmapLength); /* bitmapLength (2 bytes) */ @@ -1701,29 +1718,27 @@ static BOOL update_read_cache_bitmap_order(wStream* s, BYTE* bitmapComprHdr = (BYTE*) & (cache_bitmap->bitmapComprHdr); if (Stream_GetRemainingLength(s) < 8) - return FALSE; + goto fail; Stream_Read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */ cache_bitmap->bitmapLength -= 8; } - - if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength) - return FALSE; - - Stream_GetPointer(s, cache_bitmap->bitmapDataStream); - Stream_Seek(s, cache_bitmap->bitmapLength); - } - else - { - if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength) - return FALSE; - - Stream_GetPointer(s, cache_bitmap->bitmapDataStream); - Stream_Seek(s, cache_bitmap->bitmapLength); /* bitmapDataStream */ } + if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength) + goto fail; + + cache_bitmap->bitmapDataStream = malloc(cache_bitmap->bitmapLength); + + if (!cache_bitmap->bitmapDataStream) + goto fail; + + Stream_Read(s, cache_bitmap->bitmapDataStream, cache_bitmap->bitmapLength); cache_bitmap->compressed = compressed; - return TRUE; + return cache_bitmap; +fail: + free_cache_bitmap_order(update->context, cache_bitmap); + return NULL; } int update_approximate_cache_bitmap_order(const CACHE_BITMAP_ORDER* cache_bitmap, @@ -1773,11 +1788,15 @@ BOOL update_write_cache_bitmap_order(wStream* s, return TRUE; } -static BOOL update_read_cache_bitmap_v2_order(wStream* s, - CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, +static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* update, wStream* s, BOOL compressed, UINT16 flags) { BYTE bitsPerPixelId; + CACHE_BITMAP_V2_ORDER* cache_bitmap_v2 = calloc(1, sizeof(CACHE_BITMAP_V2_ORDER)); + + if (!cache_bitmap_v2 || !update || !s) + goto fail; + cache_bitmap_v2->cacheId = flags & 0x0003; cache_bitmap_v2->flags = (flags & 0xFF80) >> 7; bitsPerPixelId = (flags & 0x0078) >> 3; @@ -1786,7 +1805,7 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s, if (cache_bitmap_v2->flags & CBR2_PERSISTENT_KEY_PRESENT) { if (Stream_GetRemainingLength(s) < 8) - return FALSE; + goto fail; Stream_Read_UINT32(s, cache_bitmap_v2->key1); /* key1 (4 bytes) */ Stream_Read_UINT32(s, cache_bitmap_v2->key2); /* key2 (4 bytes) */ @@ -1796,7 +1815,7 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s, { if (!update_read_2byte_unsigned(s, &cache_bitmap_v2->bitmapWidth)) /* bitmapWidth */ - return FALSE; + goto fail; cache_bitmap_v2->bitmapHeight = cache_bitmap_v2->bitmapWidth; } @@ -1806,13 +1825,13 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s, || /* bitmapWidth */ !update_read_2byte_unsigned(s, &cache_bitmap_v2->bitmapHeight)) /* bitmapHeight */ - return FALSE; + goto fail; } if (!update_read_4byte_unsigned(s, &cache_bitmap_v2->bitmapLength) || /* bitmapLength */ !update_read_2byte_unsigned(s, &cache_bitmap_v2->cacheIndex)) /* cacheIndex */ - return FALSE; + goto fail; if (cache_bitmap_v2->flags & CBR2_DO_NOT_CACHE) cache_bitmap_v2->cacheIndex = BITMAP_CACHE_WAITING_LIST_INDEX; @@ -1822,7 +1841,7 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s, if (!(cache_bitmap_v2->flags & CBR2_NO_BITMAP_COMPRESSION_HDR)) { if (Stream_GetRemainingLength(s) < 8) - return FALSE; + goto fail; Stream_Read_UINT16(s, cache_bitmap_v2->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ @@ -1833,24 +1852,22 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s, cache_bitmap_v2->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ cache_bitmap_v2->bitmapLength = cache_bitmap_v2->cbCompMainBodySize; } - - if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength) - return FALSE; - - Stream_GetPointer(s, cache_bitmap_v2->bitmapDataStream); - Stream_Seek(s, cache_bitmap_v2->bitmapLength); - } - else - { - if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength) - return FALSE; - - Stream_GetPointer(s, cache_bitmap_v2->bitmapDataStream); - Stream_Seek(s, cache_bitmap_v2->bitmapLength); } + if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength) + goto fail; + + cache_bitmap_v2->bitmapDataStream = malloc(cache_bitmap_v2->bitmapLength); + + if (!cache_bitmap_v2->bitmapDataStream) + goto fail; + + Stream_Read(s, cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapLength); cache_bitmap_v2->compressed = compressed; - return TRUE; + return cache_bitmap_v2; +fail: + free_cache_bitmap_v2_order(update->context, cache_bitmap_v2); + return NULL; } int update_approximate_cache_bitmap_v2_order(CACHE_BITMAP_V2_ORDER* cache_bitmap_v2, BOOL compressed, UINT16* flags) @@ -1932,21 +1949,25 @@ BOOL update_write_cache_bitmap_v2_order(wStream* s, cache_bitmap_v2->compressed = compressed; return TRUE; } -static BOOL update_read_cache_bitmap_v3_order(wStream* s, - CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, +static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* update, wStream* s, UINT16 flags) { BYTE bitsPerPixelId; BITMAP_DATA_EX* bitmapData; UINT32 new_len; BYTE* new_data; + CACHE_BITMAP_V3_ORDER* cache_bitmap_v3 = calloc(1, sizeof(CACHE_BITMAP_V3_ORDER)); + + if (!cache_bitmap_v3 || !update || !s) + goto fail; + cache_bitmap_v3->cacheId = flags & 0x00000003; cache_bitmap_v3->flags = (flags & 0x0000FF80) >> 7; bitsPerPixelId = (flags & 0x00000078) >> 3; cache_bitmap_v3->bpp = CBR23_BPP[bitsPerPixelId]; if (Stream_GetRemainingLength(s) < 21) - return FALSE; + goto fail; Stream_Read_UINT16(s, cache_bitmap_v3->cacheIndex); /* cacheIndex (2 bytes) */ Stream_Read_UINT32(s, cache_bitmap_v3->key1); /* key1 (4 bytes) */ @@ -1957,7 +1978,7 @@ static BOOL update_read_cache_bitmap_v3_order(wStream* s, if ((bitmapData->bpp < 1) || (bitmapData->bpp > 32)) { WLog_ERR(TAG, "invalid bpp value %"PRIu32"", bitmapData->bpp); - return FALSE; + goto fail; } Stream_Seek_UINT8(s); /* reserved1 (1 byte) */ @@ -1968,18 +1989,22 @@ static BOOL update_read_cache_bitmap_v3_order(wStream* s, Stream_Read_UINT32(s, new_len); /* length (4 bytes) */ if (Stream_GetRemainingLength(s) < new_len) - return FALSE; + goto fail; new_data = (BYTE*) realloc(bitmapData->data, new_len); if (!new_data) - return FALSE; + goto fail; bitmapData->data = new_data; bitmapData->length = new_len; Stream_Read(s, bitmapData->data, bitmapData->length); - return TRUE; + return cache_bitmap_v3; +fail: + free_cache_bitmap_v3_order(update->context, cache_bitmap_v3); + return NULL; } + int update_approximate_cache_bitmap_v3_order(CACHE_BITMAP_V3_ORDER* cache_bitmap_v3, UINT16* flags) { @@ -2014,15 +2039,18 @@ BOOL update_write_cache_bitmap_v3_order(wStream* s, Stream_Write(s, bitmapData->data, bitmapData->length); return TRUE; } -static BOOL update_read_cache_color_table_order(wStream* s, - CACHE_COLOR_TABLE_ORDER* cache_color_table, +static CACHE_COLOR_TABLE_ORDER* update_read_cache_color_table_order(rdpUpdate* update, wStream* s, UINT16 flags) { int i; UINT32* colorTable; + CACHE_COLOR_TABLE_ORDER* cache_color_table = calloc(1, sizeof(CACHE_COLOR_TABLE_ORDER)); + + if (!cache_color_table) + goto fail; if (Stream_GetRemainingLength(s) < 3) - return FALSE; + goto fail; Stream_Read_UINT8(s, cache_color_table->cacheIndex); /* cacheIndex (1 byte) */ Stream_Read_UINT16(s, @@ -2031,19 +2059,23 @@ static BOOL update_read_cache_color_table_order(wStream* s, if (cache_color_table->numberColors != 256) { /* This field MUST be set to 256 */ - return FALSE; + goto fail; } if (Stream_GetRemainingLength(s) < cache_color_table->numberColors * 4) - return FALSE; + goto fail; colorTable = (UINT32*) &cache_color_table->colorTable; for (i = 0; i < (int) cache_color_table->numberColors; i++) update_read_color_quad(s, &colorTable[i]); - return TRUE; + return cache_color_table; +fail: + free_cache_color_table_order(update->context, cache_color_table); + return NULL; } + int update_approximate_cache_color_table_order( const CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags) { @@ -2076,14 +2108,16 @@ BOOL update_write_cache_color_table_order(wStream* s, return TRUE; } -static BOOL update_read_cache_glyph_order(wStream* s, - CACHE_GLYPH_ORDER* cache_glyph_order, - UINT16 flags) +static CACHE_GLYPH_ORDER* update_read_cache_glyph_order(rdpUpdate* update, wStream* s, UINT16 flags) { UINT32 i; + CACHE_GLYPH_ORDER* cache_glyph_order = calloc(1, sizeof(CACHE_GLYPH_ORDER)); + + if (!cache_glyph_order || !update || !s) + goto fail; if (Stream_GetRemainingLength(s) < 2) - return FALSE; + goto fail; Stream_Read_UINT8(s, cache_glyph_order->cacheId); /* cacheId (1 byte) */ Stream_Read_UINT8(s, cache_glyph_order->cGlyphs); /* cGlyphs (1 byte) */ @@ -2093,7 +2127,7 @@ static BOOL update_read_cache_glyph_order(wStream* s, GLYPH_DATA* glyph = &cache_glyph_order->glyphData[i]; if (Stream_GetRemainingLength(s) < 10) - return FALSE; + goto fail; Stream_Read_UINT16(s, glyph->cacheIndex); Stream_Read_INT16(s, glyph->x); @@ -2104,23 +2138,35 @@ static BOOL update_read_cache_glyph_order(wStream* s, glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; if (Stream_GetRemainingLength(s) < glyph->cb) - return FALSE; + goto fail; glyph->aj = (BYTE*) malloc(glyph->cb); if (!glyph->aj) - return FALSE; + goto fail; Stream_Read(s, glyph->aj, glyph->cb); } - if (flags & CG_GLYPH_UNICODE_PRESENT) + if ((flags & CG_GLYPH_UNICODE_PRESENT) && (cache_glyph_order->cGlyphs > 0)) { - return Stream_SafeSeek(s, cache_glyph_order->cGlyphs * 2); + cache_glyph_order->unicodeCharacters = calloc(cache_glyph_order->cGlyphs, sizeof(WCHAR)); + + if (!cache_glyph_order->unicodeCharacters) + goto fail; + + if (Stream_GetRemainingLength(s) < sizeof(WCHAR) * cache_glyph_order->cGlyphs) + goto fail; + + Stream_Read_UTF16_String(s, cache_glyph_order->unicodeCharacters, cache_glyph_order->cGlyphs); } - return TRUE; + return cache_glyph_order; +fail: + free_cache_glyph_order(update->context, cache_glyph_order); + return NULL; } + int update_approximate_cache_glyph_order( const CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags) { @@ -2164,11 +2210,15 @@ BOOL update_write_cache_glyph_order(wStream* s, return TRUE; } -static BOOL update_read_cache_glyph_v2_order(wStream* s, - CACHE_GLYPH_V2_ORDER* cache_glyph_v2, +static CACHE_GLYPH_V2_ORDER* update_read_cache_glyph_v2_order(rdpUpdate* update, wStream* s, UINT16 flags) { UINT32 i; + CACHE_GLYPH_V2_ORDER* cache_glyph_v2 = calloc(1, sizeof(CACHE_GLYPH_V2_ORDER)); + + if (!cache_glyph_v2) + goto fail; + cache_glyph_v2->cacheId = (flags & 0x000F); cache_glyph_v2->flags = (flags & 0x00F0) >> 4; cache_glyph_v2->cGlyphs = (flags & 0xFF00) >> 8; @@ -2178,7 +2228,7 @@ static BOOL update_read_cache_glyph_v2_order(wStream* s, GLYPH_DATA_V2* glyph = &cache_glyph_v2->glyphData[i]; if (Stream_GetRemainingLength(s) < 1) - return FALSE; + goto fail; Stream_Read_UINT8(s, glyph->cacheIndex); @@ -2187,33 +2237,48 @@ static BOOL update_read_cache_glyph_v2_order(wStream* s, !update_read_2byte_unsigned(s, &glyph->cx) || !update_read_2byte_unsigned(s, &glyph->cy)) { - return FALSE; + goto fail; } glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; if (Stream_GetRemainingLength(s) < glyph->cb) - return FALSE; + goto fail; glyph->aj = (BYTE*) malloc(glyph->cb); if (!glyph->aj) - return FALSE; + goto fail; Stream_Read(s, glyph->aj, glyph->cb); } - if (flags & CG_GLYPH_UNICODE_PRESENT) - return Stream_SafeSeek(s, cache_glyph_v2->cGlyphs * 2); + if ((flags & CG_GLYPH_UNICODE_PRESENT) && (cache_glyph_v2->cGlyphs > 0)) + { + cache_glyph_v2->unicodeCharacters = calloc(cache_glyph_v2->cGlyphs, sizeof(WCHAR)); - return TRUE; + if (!cache_glyph_v2->unicodeCharacters) + goto fail; + + if (Stream_GetRemainingLength(s) < sizeof(WCHAR) * cache_glyph_v2->cGlyphs) + goto fail; + + Stream_Read_UTF16_String(s, cache_glyph_v2->unicodeCharacters, cache_glyph_v2->cGlyphs); + } + + return cache_glyph_v2; +fail: + free_cache_glyph_v2_order(update->context, cache_glyph_v2); + return NULL; } + int update_approximate_cache_glyph_v2_order( const CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags) { return 8 + cache_glyph_v2->cGlyphs * 32; } + BOOL update_write_cache_glyph_v2_order(wStream* s, const CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags) @@ -2290,16 +2355,18 @@ static BOOL update_compress_brush(wStream* s, const BYTE* input, BYTE bpp) { return FALSE; } -static BOOL update_read_cache_brush_order(wStream* s, - CACHE_BRUSH_ORDER* cache_brush, - UINT16 flags) +static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStream* s, UINT16 flags) { int i; BYTE iBitmapFormat; BOOL compressed = FALSE; + CACHE_BRUSH_ORDER* cache_brush = calloc(1, sizeof(CACHE_BRUSH_ORDER)); + + if (!cache_brush) + goto fail; if (Stream_GetRemainingLength(s) < 6) - return FALSE; + goto fail; Stream_Read_UINT8(s, cache_brush->index); /* cacheEntry (1 byte) */ Stream_Read_UINT8(s, iBitmapFormat); /* iBitmapFormat (1 byte) */ @@ -2316,12 +2383,12 @@ static BOOL update_read_cache_brush_order(wStream* s, if (cache_brush->length != 8) { WLog_ERR(TAG, "incompatible 1bpp brush of length:%"PRIu32"", cache_brush->length); - return TRUE; // should be FALSE ? + goto fail; } /* rows are encoded in reverse order */ if (Stream_GetRemainingLength(s) < 8) - return FALSE; + goto fail; for (i = 7; i >= 0; i--) { @@ -2341,7 +2408,7 @@ static BOOL update_read_cache_brush_order(wStream* s, { /* compressed brush */ if (!update_decompress_brush(s, cache_brush->data, cache_brush->bpp)) - return FALSE; + goto fail; } else { @@ -2349,7 +2416,7 @@ static BOOL update_read_cache_brush_order(wStream* s, UINT32 scanline = (cache_brush->bpp / 8) * 8; if (Stream_GetRemainingLength(s) < scanline * 8) - return FALSE; + goto fail; for (i = 7; i >= 0; i--) { @@ -2359,7 +2426,10 @@ static BOOL update_read_cache_brush_order(wStream* s, } } - return TRUE; + return cache_brush; +fail: + free_cache_brush_order(update->context, cache_brush); + return NULL; } int update_approximate_cache_brush_order( const CACHE_BRUSH_ORDER* cache_brush, UINT16* flags) @@ -3252,6 +3322,7 @@ static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags) static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags) { + BOOL rc = FALSE; BYTE* next; BYTE orderType; UINT16 extraFlags; @@ -3269,135 +3340,111 @@ static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ Stream_Read_UINT8(s, orderType); /* orderType (1 byte) */ next = Stream_Pointer(s) + ((INT16) orderLength) + 7; - - if (orderType < SECONDARY_DRAWING_ORDER_COUNT) - WLog_Print(update->log, WLOG_DEBUG, "%s Secondary Drawing Order (0x%02"PRIX8")", - SECONDARY_DRAWING_ORDER_STRINGS[orderType], orderType); - else - WLog_Print(update->log, WLOG_DEBUG, "Unknown Secondary Drawing Order (0x%02"PRIX8")", - orderType); + WLog_Print(update->log, WLOG_DEBUG, "%s Secondary Drawing Order (0x%02"PRIX8")", + update_secondary_order_to_string(orderType), orderType); switch (orderType) { case ORDER_TYPE_BITMAP_UNCOMPRESSED: - if (!update_read_cache_bitmap_order(s, &(secondary->cache_bitmap_order), FALSE, - extraFlags)) - { - WLog_ERR(TAG, - "ORDER_TYPE_BITMAP_UNCOMPRESSED - update_read_cache_bitmap_order() failed"); - return FALSE; - } - - IFCALL(secondary->CacheBitmap, context, &(secondary->cache_bitmap_order)); - break; - case ORDER_TYPE_CACHE_BITMAP_COMPRESSED: - if (!update_read_cache_bitmap_order(s, &(secondary->cache_bitmap_order), TRUE, - extraFlags)) { - WLog_ERR(TAG, - "ORDER_TYPE_CACHE_BITMAP_COMPRESSED - update_read_cache_bitmap_order() failed"); - return FALSE; - } + const BOOL compressed = (orderType == ORDER_TYPE_CACHE_BITMAP_COMPRESSED); + CACHE_BITMAP_ORDER* order = update_read_cache_bitmap_order(update, s, compressed, extraFlags); - IFCALL(secondary->CacheBitmap, context, &(secondary->cache_bitmap_order)); + if (order) + { + rc = IFCALLRESULT(FALSE, secondary->CacheBitmap, context, order); + free_cache_bitmap_order(context, order); + } + } break; case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2: - if (!update_read_cache_bitmap_v2_order(s, &(secondary->cache_bitmap_v2_order), - FALSE, extraFlags)) - { - WLog_ERR(TAG, - "ORDER_TYPE_BITMAP_UNCOMPRESSED_V2 - update_read_cache_bitmap_v2_order() failed"); - return FALSE; - } - - IFCALL(secondary->CacheBitmapV2, context, &(secondary->cache_bitmap_v2_order)); - break; - case ORDER_TYPE_BITMAP_COMPRESSED_V2: - if (!update_read_cache_bitmap_v2_order(s, &(secondary->cache_bitmap_v2_order), - TRUE, extraFlags)) { - WLog_ERR(TAG, - "ORDER_TYPE_BITMAP_COMPRESSED_V2 - update_read_cache_bitmap_v2_order() failed"); - return FALSE; - } + const BOOL compressed = (orderType == ORDER_TYPE_BITMAP_COMPRESSED_V2); + CACHE_BITMAP_V2_ORDER* order = update_read_cache_bitmap_v2_order(update, s, compressed, extraFlags); - IFCALL(secondary->CacheBitmapV2, context, &(secondary->cache_bitmap_v2_order)); + if (order) + { + rc = IFCALLRESULT(FALSE, secondary->CacheBitmapV2, context, order); + free_cache_bitmap_v2_order(context, order); + } + } break; case ORDER_TYPE_BITMAP_COMPRESSED_V3: - if (!update_read_cache_bitmap_v3_order(s, &(secondary->cache_bitmap_v3_order), - extraFlags)) { - WLog_ERR(TAG, - "ORDER_TYPE_BITMAP_COMPRESSED_V3 - update_read_cache_bitmap_v3_order() failed"); - return FALSE; - } + CACHE_BITMAP_V3_ORDER* order = update_read_cache_bitmap_v3_order(update, s, extraFlags); - IFCALL(secondary->CacheBitmapV3, context, &(secondary->cache_bitmap_v3_order)); + if (order) + { + rc = IFCALLRESULT(FALSE, secondary->CacheBitmapV3, context, order); + free_cache_bitmap_v3_order(context, order); + } + } break; case ORDER_TYPE_CACHE_COLOR_TABLE: - if (!update_read_cache_color_table_order(s, - &(secondary->cache_color_table_order), extraFlags)) { - WLog_ERR(TAG, - "ORDER_TYPE_CACHE_COLOR_TABLE - update_read_cache_color_table_order() failed"); - return FALSE; - } + CACHE_COLOR_TABLE_ORDER* order = update_read_cache_color_table_order(update, s, extraFlags); - IFCALL(secondary->CacheColorTable, context, - &(secondary->cache_color_table_order)); + if (order) + { + rc = IFCALLRESULT(FALSE, secondary->CacheColorTable, context, order); + free_cache_color_table_order(context, order); + } + } break; case ORDER_TYPE_CACHE_GLYPH: if (secondary->glyph_v2) { - if (!update_read_cache_glyph_v2_order(s, &(secondary->cache_glyph_v2_order), - extraFlags)) - { - WLog_ERR(TAG, - "ORDER_TYPE_CACHE_GLYPH - update_read_cache_glyph_v2_order() failed"); - return FALSE; - } + CACHE_GLYPH_V2_ORDER* order = update_read_cache_glyph_v2_order(update, s, extraFlags); - IFCALL(secondary->CacheGlyphV2, context, &(secondary->cache_glyph_v2_order)); + if (order) + { + rc = IFCALLRESULT(FALSE, secondary->CacheGlyphV2, context, order); + free_cache_glyph_v2_order(context, order); + } } else { - if (!update_read_cache_glyph_order(s, &(secondary->cache_glyph_order), - extraFlags)) - { - WLog_ERR(TAG, - "ORDER_TYPE_CACHE_GLYPH - update_read_cache_glyph_order() failed"); - return FALSE; - } + CACHE_GLYPH_ORDER* order = update_read_cache_glyph_order(update, s, extraFlags); - IFCALL(secondary->CacheGlyph, context, &(secondary->cache_glyph_order)); + if (order) + { + rc = IFCALLRESULT(FALSE, secondary->CacheGlyph, context, order); + free_cache_glyph_order(context, order); + } } break; case ORDER_TYPE_CACHE_BRUSH: - if (!update_read_cache_brush_order(s, &(secondary->cache_brush_order), - extraFlags)) { - WLog_ERR(TAG, - "ORDER_TYPE_CACHE_BRUSH - update_read_cache_brush_order() failed"); - return FALSE; - } + CACHE_BRUSH_ORDER* order = update_read_cache_brush_order(update, s, extraFlags); - IFCALL(secondary->CacheBrush, context, &(secondary->cache_brush_order)); + if (order) + { + rc = IFCALLRESULT(FALSE, secondary->CacheBrush, context, order); + free_cache_brush_order(context, order); + } + } break; default: break; } + if (!rc) + { + WLog_ERR(TAG, "SECONDARY ORDER %s [%"PRIx16"] failed", update_secondary_order_to_string(orderType), + orderType); + } + Stream_SetPointer(s, next); - return TRUE; + return rc; } static BOOL update_recv_altsec_order(rdpUpdate* update, wStream* s, BYTE flags) diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 808879405..cb353f658 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -39,6 +39,9 @@ #include #include +#include "../cache/pointer.h" +#include "../cache/palette.h" +#include "../cache/bitmap.h" #define TAG FREERDP_TAG("core.update") @@ -50,6 +53,14 @@ static const char* const UPDATE_TYPE_STRINGS[] = "Synchronize" }; +static const char* update_type_to_string(UINT16 updateType) +{ + if (updateType >= ARRAYSIZE(UPDATE_TYPE_STRINGS)) + return "UNKNOWN"; + + return UPDATE_TYPE_STRINGS[updateType]; +} + static BOOL update_recv_orders(rdpUpdate* update, wStream* s) { UINT16 numberOrders; @@ -172,13 +183,16 @@ static BOOL update_write_bitmap_data(rdpUpdate* update, wStream* s, return TRUE; } -BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, - BITMAP_UPDATE* bitmapUpdate) +BITMAP_UPDATE* update_read_bitmap_update(rdpUpdate* update, wStream* s) { UINT32 i; + BITMAP_UPDATE* bitmapUpdate = calloc(1, sizeof(BITMAP_UPDATE)); + + if (!bitmapUpdate) + goto fail; if (Stream_GetRemainingLength(s) < 2) - return FALSE; + goto fail; Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */ WLog_Print(update->log, WLOG_TRACE, "BitmapUpdate: %"PRIu32"", bitmapUpdate->number); @@ -192,7 +206,7 @@ BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, sizeof(BITMAP_DATA) * count); if (!newdata) - return FALSE; + goto fail; bitmapUpdate->rectangles = newdata; ZeroMemory(&bitmapUpdate->rectangles[bitmapUpdate->count], @@ -204,10 +218,13 @@ BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, for (i = 0; i < bitmapUpdate->number; i++) { if (!update_read_bitmap_data(update, s, &bitmapUpdate->rectangles[i])) - return FALSE; + goto fail; } - return TRUE; + return bitmapUpdate; +fail: + free_bitmap_update(update->context, bitmapUpdate); + return NULL; } static BOOL update_write_bitmap_update(rdpUpdate* update, wStream* s, @@ -231,14 +248,17 @@ static BOOL update_write_bitmap_update(rdpUpdate* update, wStream* s, return TRUE; } -BOOL update_read_palette(rdpUpdate* update, wStream* s, - PALETTE_UPDATE* palette_update) +PALETTE_UPDATE* update_read_palette(rdpUpdate* update, wStream* s) { int i; PALETTE_ENTRY* entry; + PALETTE_UPDATE* palette_update = calloc(1, sizeof(PALETTE_UPDATE)); + + if (!palette_update) + goto fail; if (Stream_GetRemainingLength(s) < 6) - return FALSE; + goto fail; Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */ Stream_Read_UINT32(s, @@ -248,7 +268,7 @@ BOOL update_read_palette(rdpUpdate* update, wStream* s, palette_update->number = 256; if (Stream_GetRemainingLength(s) < palette_update->number * 3) - return FALSE; + goto fail; /* paletteEntries */ for (i = 0; i < (int) palette_update->number; i++) @@ -259,7 +279,10 @@ BOOL update_read_palette(rdpUpdate* update, wStream* s, Stream_Read_UINT8(s, entry->blue); } - return TRUE; + return palette_update; +fail: + free_palette_update(update->context, palette_update); + return NULL; } static void update_read_synchronize(rdpUpdate* update, wStream* s) @@ -290,35 +313,51 @@ BOOL update_recv_play_sound(rdpUpdate* update, wStream* s) return TRUE; } -BOOL update_read_pointer_position(wStream* s, - POINTER_POSITION_UPDATE* pointer_position) +POINTER_POSITION_UPDATE* update_read_pointer_position(rdpUpdate* update, wStream* s) { + POINTER_POSITION_UPDATE* pointer_position = calloc(1, sizeof(POINTER_POSITION_UPDATE)); + + if (!pointer_position) + goto fail; + if (Stream_GetRemainingLength(s) < 4) - return FALSE; + goto fail; Stream_Read_UINT16(s, pointer_position->xPos); /* xPos (2 bytes) */ Stream_Read_UINT16(s, pointer_position->yPos); /* yPos (2 bytes) */ - return TRUE; + return pointer_position; +fail: + free_pointer_position_update(update->context, pointer_position); + return NULL; } -static BOOL update_read_pointer_system(wStream* s, - POINTER_SYSTEM_UPDATE* pointer_system) +POINTER_SYSTEM_UPDATE* update_read_pointer_system(rdpUpdate* update, wStream* s) { + POINTER_SYSTEM_UPDATE* pointer_system = calloc(1, sizeof(POINTER_SYSTEM_UPDATE)); + + if (!pointer_system) + goto fail; + if (Stream_GetRemainingLength(s) < 4) - return FALSE; + goto fail; Stream_Read_UINT32(s, pointer_system->type); /* systemPointerType (4 bytes) */ - return TRUE; + return pointer_system; +fail: + free_pointer_system_update(update->context, pointer_system); + return NULL; } -BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, - int xorBpp) +static BOOL _update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, BYTE xorBpp) { BYTE* newMask; UINT32 scanlineSize; + if (!pointer_color) + goto fail; + if (Stream_GetRemainingLength(s) < 14) - return FALSE; + goto fail; Stream_Read_UINT16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */ Stream_Read_UINT16(s, pointer_color->xPos); /* xPos (2 bytes) */ @@ -336,7 +375,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, Stream_Read_UINT16(s, pointer_color->height); /* height (2 bytes) */ if ((pointer_color->width > 96) || (pointer_color->height > 96)) - return FALSE; + goto fail; Stream_Read_UINT16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */ @@ -369,7 +408,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, * In fact instead of 24-bpp, the bpp parameter is given by the containing packet. */ if (Stream_GetRemainingLength(s) < pointer_color->lengthXorMask) - return FALSE; + goto fail; scanlineSize = (7 + xorBpp * pointer_color->width) / 8; scanlineSize = ((scanlineSize + 1) / 2) * 2; @@ -380,13 +419,13 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, "invalid lengthXorMask: width=%"PRIu32" height=%"PRIu32", %"PRIu32" instead of %"PRIu32"", pointer_color->width, pointer_color->height, pointer_color->lengthXorMask, scanlineSize * pointer_color->height); - return FALSE; + goto fail; } newMask = realloc(pointer_color->xorMaskData, pointer_color->lengthXorMask); if (!newMask) - return FALSE; + goto fail; pointer_color->xorMaskData = newMask; Stream_Read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask); @@ -402,7 +441,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, * bytes). */ if (Stream_GetRemainingLength(s) < pointer_color->lengthAndMask) - return FALSE; + goto fail; scanlineSize = ((7 + pointer_color->width) / 8); scanlineSize = ((1 + scanlineSize) / 2) * 2; @@ -411,13 +450,13 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, { WLog_ERR(TAG, "invalid lengthAndMask: %"PRIu32" instead of %"PRIu32"", pointer_color->lengthAndMask, scanlineSize * pointer_color->height); - return FALSE; + goto fail; } newMask = realloc(pointer_color->andMaskData, pointer_color->lengthAndMask); if (!newMask) - return FALSE; + goto fail; pointer_color->andMaskData = newMask; Stream_Read(s, pointer_color->andMaskData, pointer_color->lengthAndMask); @@ -427,37 +466,74 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, Stream_Seek_UINT8(s); /* pad (1 byte) */ return TRUE; +fail: + return FALSE; } -BOOL update_read_pointer_new(wStream* s, POINTER_NEW_UPDATE* pointer_new) +POINTER_COLOR_UPDATE* update_read_pointer_color(rdpUpdate* update, wStream* s, BYTE xorBpp) { + POINTER_COLOR_UPDATE* pointer_color = calloc(1, sizeof(POINTER_COLOR_UPDATE)); + + if (!pointer_color) + goto fail; + + if (!_update_read_pointer_color(s, pointer_color, xorBpp)) + goto fail; + + return pointer_color; +fail: + free_pointer_color_update(update->context, pointer_color); + return NULL; +} + +POINTER_NEW_UPDATE* update_read_pointer_new(rdpUpdate* update, wStream* s) +{ + POINTER_NEW_UPDATE* pointer_new = calloc(1, sizeof(POINTER_NEW_UPDATE)); + + if (!pointer_new) + goto fail; + if (Stream_GetRemainingLength(s) < 2) - return FALSE; + goto fail; Stream_Read_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ if ((pointer_new->xorBpp < 1) || (pointer_new->xorBpp > 32)) { WLog_ERR(TAG, "invalid xorBpp %"PRIu32"", pointer_new->xorBpp); - return FALSE; + goto fail; } - return update_read_pointer_color(s, &pointer_new->colorPtrAttr, - pointer_new->xorBpp); /* colorPtrAttr */ + if (!_update_read_pointer_color(s, &pointer_new->colorPtrAttr, + pointer_new->xorBpp)) /* colorPtrAttr */ + goto fail; + + return pointer_new; +fail: + free_pointer_new_update(update->context, pointer_new); + return NULL; } -BOOL update_read_pointer_cached(wStream* s, - POINTER_CACHED_UPDATE* pointer_cached) +POINTER_CACHED_UPDATE* update_read_pointer_cached(rdpUpdate* update, wStream* s) { + POINTER_CACHED_UPDATE* pointer = calloc(1, sizeof(POINTER_CACHED_UPDATE)); + + if (!pointer) + goto fail; + if (Stream_GetRemainingLength(s) < 2) return FALSE; - Stream_Read_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ - return TRUE; + Stream_Read_UINT16(s, pointer->cacheIndex); /* cacheIndex (2 bytes) */ + return pointer; +fail: + free_pointer_cached_update(update->context, pointer); + return NULL; } BOOL update_recv_pointer(rdpUpdate* update, wStream* s) { + BOOL rc = FALSE; UINT16 messageType; rdpContext* context = update->context; rdpPointerUpdate* pointer = update->pointer; @@ -471,49 +547,75 @@ BOOL update_recv_pointer(rdpUpdate* update, wStream* s) switch (messageType) { case PTR_MSG_TYPE_POSITION: - if (!update_read_pointer_position(s, &pointer->pointer_position)) - return FALSE; + { + POINTER_POSITION_UPDATE* pointer_position = update_read_pointer_position(update, s); - IFCALL(pointer->PointerPosition, context, &pointer->pointer_position); + if (pointer_position) + { + rc = IFCALLRESULT(FALSE, pointer->PointerPosition, context, pointer_position); + free_pointer_position_update(context, pointer_position); + } + } break; case PTR_MSG_TYPE_SYSTEM: - if (!update_read_pointer_system(s, &pointer->pointer_system)) - return FALSE; + { + POINTER_SYSTEM_UPDATE* pointer_system = update_read_pointer_system(update, s); - IFCALL(pointer->PointerSystem, context, &pointer->pointer_system); + if (pointer_system) + { + rc = IFCALLRESULT(FALSE, pointer->PointerSystem, context, pointer_system); + free_pointer_system_update(context, pointer_system); + } + } break; case PTR_MSG_TYPE_COLOR: - if (!update_read_pointer_color(s, &pointer->pointer_color, 24)) - return FALSE; + { + POINTER_COLOR_UPDATE* pointer_color = update_read_pointer_color(update, s, 24); - IFCALL(pointer->PointerColor, context, &pointer->pointer_color); + if (pointer_color) + { + rc = IFCALLRESULT(FALSE, pointer->PointerColor, context, pointer_color); + free_pointer_color_update(context, pointer_color); + } + } break; case PTR_MSG_TYPE_POINTER: - if (!update_read_pointer_new(s, &pointer->pointer_new)) - return FALSE; + { + POINTER_NEW_UPDATE* pointer_new = update_read_pointer_new(update, s); - IFCALL(pointer->PointerNew, context, &pointer->pointer_new); + if (pointer_new) + { + rc = IFCALLRESULT(FALSE, pointer->PointerNew, context, pointer_new); + free_pointer_new_update(context, pointer_new); + } + } break; case PTR_MSG_TYPE_CACHED: - if (!update_read_pointer_cached(s, &pointer->pointer_cached)) - return FALSE; + { + POINTER_CACHED_UPDATE* pointer_cached = update_read_pointer_cached(update, s); - IFCALL(pointer->PointerCached, context, &pointer->pointer_cached); + if (pointer_cached) + { + rc = IFCALLRESULT(FALSE, pointer->PointerCached, context, pointer_cached); + free_pointer_cached_update(context, pointer_cached); + } + } break; default: break; } - return TRUE; + return rc; } BOOL update_recv(rdpUpdate* update, wStream* s) { + BOOL rc = FALSE; UINT16 updateType; rdpContext* context = update->context; @@ -524,52 +626,65 @@ BOOL update_recv(rdpUpdate* update, wStream* s) } Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */ + //WLog_DBG(TAG, "%s Update Data PDU", UPDATE_TYPE_STRINGS[updateType]); - IFCALL(update->BeginPaint, context); + if (!IFCALLRESULT(FALSE, update->BeginPaint, context)) + return FALSE; switch (updateType) { case UPDATE_TYPE_ORDERS: - if (!update_recv_orders(update, s)) - { - /* XXX: Do we have to call EndPaint? */ - WLog_ERR(TAG, "UPDATE_TYPE_ORDERS - update_recv_orders() failed"); - return FALSE; - } - + rc = update_recv_orders(update, s); break; case UPDATE_TYPE_BITMAP: - if (!update_read_bitmap_update(update, s, &update->bitmap_update)) { - WLog_ERR(TAG, "UPDATE_TYPE_BITMAP - update_read_bitmap_update() failed"); - return FALSE; - } + BITMAP_UPDATE* bitmap_update = update_read_bitmap_update(update, s); - IFCALL(update->BitmapUpdate, context, &update->bitmap_update); + if (!bitmap_update) + { + WLog_ERR(TAG, "UPDATE_TYPE_BITMAP - update_read_bitmap_update() failed"); + return FALSE; + } + + rc = IFCALLRESULT(FALSE, update->BitmapUpdate, context, &update->bitmap_update); + free_bitmap_update(update->context, bitmap_update); + } break; case UPDATE_TYPE_PALETTE: - if (!update_read_palette(update, s, &update->palette_update)) { - WLog_ERR(TAG, "UPDATE_TYPE_PALETTE - update_read_palette() failed"); - return FALSE; - } + PALETTE_UPDATE* palette_update = update_read_palette(update, s); - IFCALL(update->Palette, context, &update->palette_update); + if (!palette_update) + { + WLog_ERR(TAG, "UPDATE_TYPE_PALETTE - update_read_palette() failed"); + return FALSE; + } + + rc = IFCALLRESULT(FALSE, update->Palette, context, palette_update); + free_palette_update(context, palette_update); + } break; case UPDATE_TYPE_SYNCHRONIZE: update_read_synchronize(update, s); - IFCALL(update->Synchronize, context); + rc = IFCALLRESULT(TRUE, update->Synchronize, context); break; default: - WLog_ERR(TAG, "unknown update type %"PRIu16"", updateType); break; } - IFCALL(update->EndPaint, context); + if (!rc) + { + WLog_ERR(TAG, "UPDATE_TYPE %s [%"PRIu16"] failed", update_type_to_string(updateType), updateType); + return FALSE; + } + + if (!IFCALLRESULT(FALSE, update->EndPaint, context)) + return FALSE; + return TRUE; } @@ -2133,10 +2248,6 @@ void update_free(rdpUpdate* update) deleteList = &(update->altsec->create_offscreen_bitmap.deleteList); free(deleteList->indices); free(update->bitmap_update.rectangles); - free(update->pointer->pointer_color.andMaskData); - free(update->pointer->pointer_color.xorMaskData); - free(update->pointer->pointer_new.colorPtrAttr.andMaskData); - free(update->pointer->pointer_new.colorPtrAttr.xorMaskData); free(update->pointer); free(update->primary->polyline.points); free(update->primary->polygon_sc.points); diff --git a/libfreerdp/core/update.h b/libfreerdp/core/update.h index df0990c08..a8b88b1dd 100644 --- a/libfreerdp/core/update.h +++ b/libfreerdp/core/update.h @@ -43,21 +43,21 @@ FREERDP_LOCAL void update_free(rdpUpdate* update); FREERDP_LOCAL void update_reset_state(rdpUpdate* update); FREERDP_LOCAL BOOL update_post_connect(rdpUpdate* update); FREERDP_LOCAL void update_post_disconnect(rdpUpdate* update); -FREERDP_LOCAL BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, - BITMAP_UPDATE* bitmapUpdate); -FREERDP_LOCAL BOOL update_read_palette(rdpUpdate* update, wStream* s, - PALETTE_UPDATE* palette_update); + FREERDP_LOCAL BOOL update_recv_play_sound(rdpUpdate* update, wStream* s); FREERDP_LOCAL BOOL update_recv_pointer(rdpUpdate* update, wStream* s); FREERDP_LOCAL BOOL update_recv(rdpUpdate* update, wStream* s); -FREERDP_LOCAL BOOL update_read_pointer_position(wStream* s, - POINTER_POSITION_UPDATE* pointer_position); -FREERDP_LOCAL BOOL update_read_pointer_color(wStream* s, - POINTER_COLOR_UPDATE* pointer_color, int xorBpp); -FREERDP_LOCAL BOOL update_read_pointer_new(wStream* s, - POINTER_NEW_UPDATE* pointer_new); -FREERDP_LOCAL BOOL update_read_pointer_cached(wStream* s, - POINTER_CACHED_UPDATE* pointer_cached); + +FREERDP_LOCAL BITMAP_UPDATE* update_read_bitmap_update(rdpUpdate* update, wStream* s); +FREERDP_LOCAL PALETTE_UPDATE* update_read_palette(rdpUpdate* update, wStream* s); + +FREERDP_LOCAL POINTER_SYSTEM_UPDATE* update_read_pointer_system(rdpUpdate* update, wStream* s); +FREERDP_LOCAL POINTER_POSITION_UPDATE* update_read_pointer_position(rdpUpdate* update, wStream* s); +FREERDP_LOCAL POINTER_COLOR_UPDATE* update_read_pointer_color(rdpUpdate* update, wStream* s, + BYTE xorBpp); +FREERDP_LOCAL POINTER_NEW_UPDATE* update_read_pointer_new(rdpUpdate* update, wStream* s); +FREERDP_LOCAL POINTER_CACHED_UPDATE* update_read_pointer_cached(rdpUpdate* update, wStream* s); + FREERDP_LOCAL BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s); FREERDP_LOCAL BOOL update_read_suppress_output(rdpUpdate* update, wStream* s); FREERDP_LOCAL void update_register_server_callbacks(rdpUpdate* update);