Merge pull request #4530 from akallabeth/order_refactor

[leak fixes] Refactored order updates
This commit is contained in:
Martin Fleisz 2018-07-04 14:21:36 +02:00 committed by GitHub
commit a0fddd1747
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1670 additions and 945 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -227,13 +227,6 @@ struct rdp_update
rdpPcap* pcap_rfx;
BOOL initialState;
BITMAP_UPDATE bitmap_update;
PALETTE_UPDATE palette_update;
PLAY_SOUND_UPDATE play_sound;
SURFACE_BITS_COMMAND surface_bits_command;
SURFACE_FRAME_MARKER surface_frame_marker;
BOOL asynchronous;
rdpUpdateProxy* proxy;
wMessageQueue* queue;

View File

@ -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)

View File

@ -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);
}

41
libfreerdp/cache/bitmap.h vendored Normal file
View File

@ -0,0 +1,41 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
* 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 <freerdp/api.h>
#include <freerdp/update.h>
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 */

View File

@ -29,19 +29,19 @@
#include <freerdp/freerdp.h>
#include <winpr/stream.h>
#include <freerdp/cache/brush.h>
#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;
}

31
libfreerdp/cache/brush.h vendored Normal file
View File

@ -0,0 +1,31 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
* 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 <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/pointer.h>
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 */

View File

@ -27,6 +27,8 @@
#include <freerdp/cache/cache.h>
#include "cache.h"
rdpCache* cache_new(rdpSettings* settings)
{
rdpCache* cache;
@ -90,3 +92,53 @@ 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);
}
SURFACE_BITS_COMMAND* copy_surface_bits_command(rdpContext* context, const SURFACE_BITS_COMMAND* order)
{
SURFACE_BITS_COMMAND* dst = calloc(1, sizeof(SURFACE_BITS_COMMAND));
if (!dst || !order)
goto fail;
*dst = *order;
dst->bmp.bitmapData = (BYTE*) malloc(order->bmp.bitmapDataLength);
if (!dst->bmp.bitmapData)
goto fail;
CopyMemory(dst->bmp.bitmapData, order->bmp.bitmapData,
order->bmp.bitmapDataLength);
return dst;
fail:
free_surface_bits_command(context, dst);
return NULL;
}
void free_surface_bits_command(rdpContext* context, SURFACE_BITS_COMMAND* order)
{
if (order)
free(order->bmp.bitmapData);
free(order);
}

36
libfreerdp/cache/cache.h vendored Normal file
View File

@ -0,0 +1,36 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
* 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 <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/pointer.h>
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);
FREERDP_LOCAL SURFACE_BITS_COMMAND* copy_surface_bits_command(rdpContext* context,
const SURFACE_BITS_COMMAND* order);
FREERDP_LOCAL void free_surface_bits_command(rdpContext* context, SURFACE_BITS_COMMAND* order);
#endif /* FREERDP_LIB_CACHE_CACHE_H */

View File

@ -31,6 +31,8 @@
#include <freerdp/log.h>
#include <freerdp/cache/glyph.h>
#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);
}

35
libfreerdp/cache/glyph.h vendored Normal file
View File

@ -0,0 +1,35 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
* 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 <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/pointer.h>
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 */

View File

@ -28,6 +28,8 @@
#include <freerdp/log.h>
#include <freerdp/cache/palette.h>
#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;
}

30
libfreerdp/cache/palette.h vendored Normal file
View File

@ -0,0 +1,30 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
* 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 <freerdp/api.h>
#include <freerdp/update.h>
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 */

View File

@ -30,6 +30,7 @@
#include <freerdp/log.h>
#include <freerdp/cache/pointer.h>
#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;
}

49
libfreerdp/cache/pointer.h vendored Normal file
View File

@ -0,0 +1,49 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
*
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
* 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 <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/pointer.h>
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 */

View File

@ -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")
/**
@ -53,8 +57,6 @@
* two less significant bits of the first byte.
*/
#ifdef WITH_DEBUG_RDP
static const char* const FASTPATH_UPDATETYPE_STRINGS[] =
{
"Orders", /* 0x0 */
@ -70,7 +72,14 @@ static const char* const FASTPATH_UPDATETYPE_STRINGS[] =
"Cached Pointer", /* 0xA */
"New Pointer", /* 0xB */
};
#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.
@ -281,6 +290,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 +313,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, 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, 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)
@ -330,6 +353,7 @@ static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s)
static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, wStream* s)
{
BOOL rc = FALSE;
int status = 0;
rdpUpdate* update;
rdpContext* context;
@ -346,103 +370,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 +633,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 +768,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)

File diff suppressed because it is too large Load Diff

View File

@ -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,21 @@ 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;
if (!update || !s)
return NULL;
cache_bitmap = calloc(1, sizeof(CACHE_BITMAP_ORDER));
if (!cache_bitmap)
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 +1710,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 +1723,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 +1793,20 @@ 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;
if (!update || !s)
return NULL;
cache_bitmap_v2 = calloc(1, sizeof(CACHE_BITMAP_V2_ORDER));
if (!cache_bitmap_v2)
goto fail;
cache_bitmap_v2->cacheId = flags & 0x0003;
cache_bitmap_v2->flags = (flags & 0xFF80) >> 7;
bitsPerPixelId = (flags & 0x0078) >> 3;
@ -1786,7 +1815,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 +1825,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 +1835,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 +1851,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 +1862,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 +1959,30 @@ 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;
if (!update || !s)
return NULL;
cache_bitmap_v3 = calloc(1, sizeof(CACHE_BITMAP_V3_ORDER));
if (!cache_bitmap_v3)
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 +1993,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 +2004,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 +2054,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 +2074,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 +2123,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 +2142,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 +2153,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 +2225,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 +2243,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 +2252,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 +2370,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 +2398,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 +2423,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 +2431,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 +2441,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 +3337,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 +3355,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)

View File

@ -85,39 +85,45 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp)
static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s)
{
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
SURFACE_BITS_COMMAND* cmd = calloc(1, sizeof(SURFACE_BITS_COMMAND));
if (!cmd)
return FALSE;
if (Stream_GetRemainingLength(s) < 8)
return FALSE;
goto fail;
Stream_Read_UINT16(s, cmd->destLeft);
Stream_Read_UINT16(s, cmd->destTop);
Stream_Read_UINT16(s, cmd->destRight);
Stream_Read_UINT16(s, cmd->destBottom);
if (!update_recv_surfcmd_bitmap_ex(s, &cmd->bmp))
return FALSE;
goto fail;
if (!update->SurfaceBits)
{
WLog_ERR(TAG, "Missing callback update->SurfaceBits");
return FALSE;
goto fail;
}
return update->SurfaceBits(update->context, cmd);
fail:
free_surface_bits_command(update->context, cmd);
return FALSE;
}
static BOOL update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s)
{
SURFACE_FRAME_MARKER* marker = &update->surface_frame_marker;
SURFACE_FRAME_MARKER marker;
if (Stream_GetRemainingLength(s) < 6)
return FALSE;
Stream_Read_UINT16(s, marker->frameAction);
Stream_Read_UINT32(s, marker->frameId);
Stream_Read_UINT16(s, marker.frameAction);
Stream_Read_UINT32(s, marker.frameId);
WLog_Print(update->log, WLOG_DEBUG, "SurfaceFrameMarker: action: %s (%"PRIu32") id: %"PRIu32"",
(!marker->frameAction) ? "Begin" : "End",
marker->frameAction, marker->frameId);
(!marker.frameAction) ? "Begin" : "End",
marker.frameAction, marker.frameId);
if (!update->SurfaceFrameMarker)
{
@ -125,7 +131,7 @@ static BOOL update_recv_surfcmd_frame_marker(rdpUpdate* update, wStream* s)
return FALSE;
}
return update->SurfaceFrameMarker(update->context, marker);
return update->SurfaceFrameMarker(update->context, &marker);
}
int update_recv_surfcmds(rdpUpdate* update, wStream* s)

View File

@ -39,6 +39,9 @@
#include <freerdp/peer.h>
#include <freerdp/codec/bitmap.h>
#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)
@ -283,42 +306,59 @@ static BOOL update_read_play_sound(wStream* s, PLAY_SOUND_UPDATE* play_sound)
BOOL update_recv_play_sound(rdpUpdate* update, wStream* s)
{
if (!update_read_play_sound(s, &update->play_sound))
PLAY_SOUND_UPDATE play_sound;
if (!update_read_play_sound(s, &play_sound))
return FALSE;
IFCALL(update->PlaySound, update->context, &update->play_sound);
return TRUE;
return IFCALLRESULT(FALSE, update->PlaySound, update->context, &play_sound);
}
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 +376,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 +409,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 +420,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 +442,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 +451,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 +467,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)
{
if (Stream_GetRemainingLength(s) < 2)
return FALSE;
POINTER_CACHED_UPDATE* pointer = calloc(1, sizeof(POINTER_CACHED_UPDATE));
Stream_Read_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
return TRUE;
if (!pointer)
goto fail;
if (Stream_GetRemainingLength(s) < 2)
goto fail;
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 +548,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 +627,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, 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;
}
@ -2058,44 +2174,37 @@ rdpUpdate* update_new(rdpRdp* rdp)
return NULL;
update->log = WLog_Get("com.freerdp.core.update");
update->bitmap_update.count = 64;
update->bitmap_update.rectangles = (BITMAP_DATA*) calloc(
update->bitmap_update.count, sizeof(BITMAP_DATA));
if (!update->bitmap_update.rectangles)
goto error_rectangles;
update->pointer = (rdpPointerUpdate*) calloc(1, sizeof(rdpPointerUpdate));
if (!update->pointer)
goto error_pointer;
goto fail;
update->primary = (rdpPrimaryUpdate*) calloc(1, sizeof(rdpPrimaryUpdate));
if (!update->primary)
goto error_primary;
goto fail;
update->secondary = (rdpSecondaryUpdate*) calloc(1, sizeof(rdpSecondaryUpdate));
if (!update->secondary)
goto error_secondary;
goto fail;
update->altsec = (rdpAltSecUpdate*) calloc(1, sizeof(rdpAltSecUpdate));
if (!update->altsec)
goto error_altsec;
goto fail;
update->window = (rdpWindowUpdate*) calloc(1, sizeof(rdpWindowUpdate));
if (!update->window)
goto error_window;
goto fail;
deleteList = &(update->altsec->create_offscreen_bitmap.deleteList);
deleteList->sIndices = 64;
deleteList->indices = calloc(deleteList->sIndices, 2);
if (!deleteList->indices)
goto error_indices;
goto fail;
deleteList->cIndices = 0;
update->SuppressOutput = update_send_suppress_output;
@ -2103,25 +2212,11 @@ rdpUpdate* update_new(rdpRdp* rdp)
update->queue = MessageQueue_New(&cb);
if (!update->queue)
goto error_queue;
goto fail;
return update;
error_queue:
free(deleteList->indices);
error_indices:
free(update->window);
error_window:
free(update->altsec);
error_altsec:
free(update->secondary);
error_secondary:
free(update->primary);
error_primary:
free(update->pointer);
error_pointer:
free(update->bitmap_update.rectangles);
error_rectangles:
free(update);
fail:
update_free(update);
return NULL;
}
@ -2129,25 +2224,32 @@ void update_free(rdpUpdate* update)
{
if (update != NULL)
{
OFFSCREEN_DELETE_LIST* deleteList;
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);
OFFSCREEN_DELETE_LIST* deleteList = &(update->altsec->create_offscreen_bitmap.deleteList);
if (deleteList)
free(deleteList->indices);
free(update->pointer);
free(update->primary->polyline.points);
free(update->primary->polygon_sc.points);
free(update->primary->fast_glyph.glyphData.aj);
free(update->primary);
if (update->primary)
{
free(update->primary->polyline.points);
free(update->primary->polygon_sc.points);
free(update->primary->fast_glyph.glyphData.aj);
free(update->primary);
}
free(update->secondary);
free(update->altsec);
free(update->window->monitored_desktop.windowIds);
update_free_window_state(&update->window->window_state);
update_free_window_icon_info(update->window->window_icon.iconInfo);
free(update->window);
if (update->window)
{
free(update->window->monitored_desktop.windowIds);
update_free_window_state(&update->window->window_state);
update_free_window_icon_info(update->window->window_icon.iconInfo);
free(update->window);
}
MessageQueue_Free(update->queue);
free(update);
}

View File

@ -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);

View File

@ -148,21 +148,21 @@ static wStream* test_peer_stream_init(testPeerContext* context)
static void test_peer_begin_frame(freerdp_peer* client)
{
rdpUpdate* update = client->update;
SURFACE_FRAME_MARKER* fm = &update->surface_frame_marker;
SURFACE_FRAME_MARKER fm;
testPeerContext* context = (testPeerContext*) client->context;
fm->frameAction = SURFACECMD_FRAMEACTION_BEGIN;
fm->frameId = context->frame_id;
update->SurfaceFrameMarker(update->context, fm);
fm.frameAction = SURFACECMD_FRAMEACTION_BEGIN;
fm.frameId = context->frame_id;
update->SurfaceFrameMarker(update->context, &fm);
}
static void test_peer_end_frame(freerdp_peer* client)
{
rdpUpdate* update = client->update;
SURFACE_FRAME_MARKER* fm = &update->surface_frame_marker;
SURFACE_FRAME_MARKER fm;
testPeerContext* context = (testPeerContext*) client->context;
fm->frameAction = SURFACECMD_FRAMEACTION_END;
fm->frameId = context->frame_id;
update->SurfaceFrameMarker(update->context, fm);
fm.frameAction = SURFACECMD_FRAMEACTION_END;
fm.frameId = context->frame_id;
update->SurfaceFrameMarker(update->context, &fm);
context->frame_id++;
}
@ -173,7 +173,7 @@ static BOOL test_peer_draw_background(freerdp_peer* client)
RFX_RECT rect;
BYTE* rgb_data;
rdpUpdate* update = client->update;
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
SURFACE_BITS_COMMAND cmd = { 0 };
testPeerContext* context = (testPeerContext*) client->context;
BOOL ret = FALSE;
@ -194,7 +194,6 @@ static BOOL test_peer_draw_background(freerdp_peer* client)
}
memset(rgb_data, 0xA0, size);
memset(cmd, 0, sizeof(SURFACE_BITS_COMMAND));
if (client->settings->RemoteFxCodec)
{
@ -204,27 +203,27 @@ static BOOL test_peer_draw_background(freerdp_peer* client)
goto out;
}
cmd->bmp.codecID = client->settings->RemoteFxCodecId;
cmd.bmp.codecID = client->settings->RemoteFxCodecId;
}
else
{
nsc_compose_message(context->nsc_context, s,
rgb_data, rect.width, rect.height, rect.width * 3);
cmd->bmp.codecID = client->settings->NSCodecId;
cmd.bmp.codecID = client->settings->NSCodecId;
}
cmd->destLeft = 0;
cmd->destTop = 0;
cmd->destRight = rect.width;
cmd->destBottom = rect.height;
cmd->bmp.bpp = 32;
cmd->bmp.flags = 0;
cmd->bmp.width = rect.width;
cmd->bmp.height = rect.height;
cmd->bmp.bitmapDataLength = Stream_GetPosition(s);
cmd->bmp.bitmapData = Stream_Buffer(s);
cmd.destLeft = 0;
cmd.destTop = 0;
cmd.destRight = rect.width;
cmd.destBottom = rect.height;
cmd.bmp.bpp = 32;
cmd.bmp.flags = 0;
cmd.bmp.width = rect.width;
cmd.bmp.height = rect.height;
cmd.bmp.bitmapDataLength = Stream_GetPosition(s);
cmd.bmp.bitmapData = Stream_Buffer(s);
test_peer_begin_frame(client);
update->SurfaceBits(update->context, cmd);
update->SurfaceBits(update->context, &cmd);
test_peer_end_frame(client);
ret = TRUE;
out:
@ -300,7 +299,7 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
wStream* s;
RFX_RECT rect;
rdpUpdate* update = client->update;
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
SURFACE_BITS_COMMAND cmd = { 0 };
testPeerContext* context = (testPeerContext*) client->context;
if (client->update->dump_rfx)
@ -317,7 +316,6 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
rect.y = 0;
rect.width = context->icon_width;
rect.height = context->icon_height;
memset(cmd, 0, sizeof(SURFACE_BITS_COMMAND));
if (context->icon_x >= 0)
{
@ -327,26 +325,26 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
{
rfx_compose_message(context->rfx_context, s,
&rect, 1, context->bg_data, rect.width, rect.height, rect.width * 3);
cmd->bmp.codecID = client->settings->RemoteFxCodecId;
cmd.bmp.codecID = client->settings->RemoteFxCodecId;
}
else
{
nsc_compose_message(context->nsc_context, s,
context->bg_data, rect.width, rect.height, rect.width * 3);
cmd->bmp.codecID = client->settings->NSCodecId;
cmd.bmp.codecID = client->settings->NSCodecId;
}
cmd->destLeft = context->icon_x;
cmd->destTop = context->icon_y;
cmd->destRight = context->icon_x + context->icon_width;
cmd->destBottom = context->icon_y + context->icon_height;
cmd->bmp.bpp = 32;
cmd->bmp.flags = 0;
cmd->bmp.width = context->icon_width;
cmd->bmp.height = context->icon_height;
cmd->bmp.bitmapDataLength = Stream_GetPosition(s);
cmd->bmp.bitmapData = Stream_Buffer(s);
update->SurfaceBits(update->context, cmd);
cmd.destLeft = context->icon_x;
cmd.destTop = context->icon_y;
cmd.destRight = context->icon_x + context->icon_width;
cmd.destBottom = context->icon_y + context->icon_height;
cmd.bmp.bpp = 32;
cmd.bmp.flags = 0;
cmd.bmp.width = context->icon_width;
cmd.bmp.height = context->icon_height;
cmd.bmp.bitmapDataLength = Stream_GetPosition(s);
cmd.bmp.bitmapData = Stream_Buffer(s);
update->SurfaceBits(update->context, &cmd);
}
s = test_peer_stream_init(context);
@ -355,25 +353,25 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
{
rfx_compose_message(context->rfx_context, s,
&rect, 1, context->icon_data, rect.width, rect.height, rect.width * 3);
cmd->bmp.codecID = client->settings->RemoteFxCodecId;
cmd.bmp.codecID = client->settings->RemoteFxCodecId;
}
else
{
nsc_compose_message(context->nsc_context, s,
context->icon_data, rect.width, rect.height, rect.width * 3);
cmd->bmp.codecID = client->settings->NSCodecId;
cmd.bmp.codecID = client->settings->NSCodecId;
}
cmd->destLeft = x;
cmd->destTop = y;
cmd->destRight = x + context->icon_width;
cmd->destBottom = y + context->icon_height;
cmd->bmp.bpp = 32;
cmd->bmp.width = context->icon_width;
cmd->bmp.height = context->icon_height;
cmd->bmp.bitmapDataLength = Stream_GetPosition(s);
cmd->bmp.bitmapData = Stream_Buffer(s);
update->SurfaceBits(update->context, cmd);
cmd.destLeft = x;
cmd.destTop = y;
cmd.destRight = x + context->icon_width;
cmd.destBottom = y + context->icon_height;
cmd.bmp.bpp = 32;
cmd.bmp.width = context->icon_width;
cmd.bmp.height = context->icon_height;
cmd.bmp.bitmapDataLength = Stream_GetPosition(s);
cmd.bmp.bitmapData = Stream_Buffer(s);
update->SurfaceBits(update->context, &cmd);
context->icon_x = x;
context->icon_y = y;
test_peer_end_frame(client);