diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index ab0cd4e39..e81992764 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -661,7 +661,7 @@ void drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* drive->files = ListDictionary_New(TRUE); ListDictionary_Object(drive->files)->fnObjectFree = (OBJECT_FREE_FN) drive_file_free; - drive->IrpQueue = MessageQueue_New(); + drive->IrpQueue = MessageQueue_New(NULL); drive->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) drive_thread_func, drive, CREATE_SUSPENDED, NULL); pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) drive); diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index ae4c5a4dc..59e201c27 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -327,7 +327,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) parallel->path = path; - parallel->queue = MessageQueue_New(); + parallel->queue = MessageQueue_New(NULL); pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) parallel); diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index b4f208a32..57ea44526 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -208,6 +208,10 @@ BOOL freerdp_check_fds(freerdp* instance) int status; rdpRdp* rdp; + assert(instance); + assert(instance->context); + assert(instance->context->rdp); + rdp = instance->context->rdp; status = rdp_check_fds(rdp); diff --git a/libfreerdp/core/input.c b/libfreerdp/core/input.c index 64011b807..fc5b5f4ee 100644 --- a/libfreerdp/core/input.c +++ b/libfreerdp/core/input.c @@ -486,8 +486,15 @@ int input_process_events(rdpInput* input) return input_message_queue_process_pending_messages(input); } +static void input_free_queued_message(void *obj) +{ + wMessage *msg = (wMessage*)obj; + input_message_queue_free_message(msg); +} + rdpInput* input_new(rdpRdp* rdp) { + const wObject cb = { .fnObjectFree = input_free_queued_message }; rdpInput* input; input = (rdpInput*) malloc(sizeof(rdpInput)); @@ -496,7 +503,7 @@ rdpInput* input_new(rdpRdp* rdp) { ZeroMemory(input, sizeof(rdpInput)); - input->queue = MessageQueue_New(); + input->queue = MessageQueue_New(&cb); } return input; diff --git a/libfreerdp/core/message.c b/libfreerdp/core/message.c index b810fa1ad..5d6083f22 100644 --- a/libfreerdp/core/message.c +++ b/libfreerdp/core/message.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include "rdp.h" #include "message.h" #include "transport.h" @@ -971,37 +973,30 @@ static void update_message_PointerCached(rdpContext* context, POINTER_CACHED_UPD } /* Message Queue */ - -int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_free_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case Update_BeginPaint: - IFCALL(proxy->BeginPaint, msg->context); break; case Update_EndPaint: - IFCALL(proxy->EndPaint, msg->context); break; case Update_SetBounds: - IFCALL(proxy->SetBounds, msg->context, (rdpBounds*) msg->wParam); if (msg->wParam) free(msg->wParam); break; case Update_Synchronize: - IFCALL(proxy->Synchronize, msg->context); break; case Update_DesktopResize: - IFCALL(proxy->DesktopResize, msg->context); break; case Update_BitmapUpdate: - IFCALL(proxy->BitmapUpdate, msg->context, (BITMAP_UPDATE*) msg->wParam); { int index; BITMAP_UPDATE* wParam = (BITMAP_UPDATE*) msg->wParam; @@ -1022,30 +1017,23 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in break; case Update_Palette: - IFCALL(proxy->Palette, msg->context, (PALETTE_UPDATE*) msg->wParam); free(msg->wParam); break; case Update_PlaySound: - IFCALL(proxy->PlaySound, msg->context, (PLAY_SOUND_UPDATE*) msg->wParam); free(msg->wParam); break; case Update_RefreshRect: - IFCALL(proxy->RefreshRect, msg->context, - (BYTE) (size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); free(msg->lParam); break; case Update_SuppressOutput: - IFCALL(proxy->SuppressOutput, msg->context, - (BYTE) (size_t) msg->wParam, (RECTANGLE_16*) msg->lParam); if (msg->lParam) free(msg->lParam); break; case Update_SurfaceCommand: - IFCALL(proxy->SurfaceCommand, msg->context, (wStream*) msg->wParam); { wStream* s = (wStream*) msg->wParam; Stream_Free(s, TRUE); @@ -1053,7 +1041,6 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in break; case Update_SurfaceBits: - IFCALL(proxy->SurfaceBits, msg->context, (SURFACE_BITS_COMMAND*) msg->wParam); { #ifdef WITH_STREAM_POOL rdpContext* context = (rdpContext*) msg->context; @@ -1068,10 +1055,81 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in break; case Update_SurfaceFrameMarker: - IFCALL(proxy->SurfaceFrameMarker, msg->context, (SURFACE_FRAME_MARKER*) msg->wParam); free(msg->wParam); break; + case Update_SurfaceFrameAcknowledge: + break; + + default: + status = -1; + break; + } + + return status; +} + + +static int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case Update_BeginPaint: + IFCALL(proxy->BeginPaint, msg->context); + break; + + case Update_EndPaint: + IFCALL(proxy->EndPaint, msg->context); + break; + + case Update_SetBounds: + IFCALL(proxy->SetBounds, msg->context, (rdpBounds*) msg->wParam); + break; + + case Update_Synchronize: + IFCALL(proxy->Synchronize, msg->context); + break; + + case Update_DesktopResize: + IFCALL(proxy->DesktopResize, msg->context); + break; + + case Update_BitmapUpdate: + IFCALL(proxy->BitmapUpdate, msg->context, (BITMAP_UPDATE*) msg->wParam); + break; + + case Update_Palette: + IFCALL(proxy->Palette, msg->context, (PALETTE_UPDATE*) msg->wParam); + break; + + case Update_PlaySound: + IFCALL(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); + break; + + case Update_SuppressOutput: + IFCALL(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); + break; + + case Update_SurfaceBits: + IFCALL(proxy->SurfaceBits, msg->context, (SURFACE_BITS_COMMAND*) msg->wParam); + break; + + case Update_SurfaceFrameMarker: + IFCALL(proxy->SurfaceFrameMarker, msg->context, (SURFACE_FRAME_MARKER*) msg->wParam); + break; + case Update_SurfaceFrameAcknowledge: IFCALL(proxy->SurfaceFrameAcknowledge, msg->context, (UINT32) (size_t) msg->wParam); break; @@ -1084,69 +1142,57 @@ int update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, in return status; } -int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +static int update_message_free_primary_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case PrimaryUpdate_DstBlt: - IFCALL(proxy->DstBlt, msg->context, (DSTBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_PatBlt: - IFCALL(proxy->PatBlt, msg->context, (PATBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_ScrBlt: - IFCALL(proxy->ScrBlt, msg->context, (SCRBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_OpaqueRect: - IFCALL(proxy->OpaqueRect, msg->context, (OPAQUE_RECT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_DrawNineGrid: - IFCALL(proxy->DrawNineGrid, msg->context, (DRAW_NINE_GRID_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiDstBlt: - IFCALL(proxy->MultiDstBlt, msg->context, (MULTI_DSTBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiPatBlt: - IFCALL(proxy->MultiPatBlt, msg->context, (MULTI_PATBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiScrBlt: - IFCALL(proxy->MultiScrBlt, msg->context, (MULTI_SCRBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiOpaqueRect: - IFCALL(proxy->MultiOpaqueRect, msg->context, (MULTI_OPAQUE_RECT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_MultiDrawNineGrid: - IFCALL(proxy->MultiDrawNineGrid, msg->context, (MULTI_DRAW_NINE_GRID_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_LineTo: - IFCALL(proxy->LineTo, msg->context, (LINE_TO_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_Polyline: - IFCALL(proxy->Polyline, msg->context, (POLYLINE_ORDER*) msg->wParam); { POLYLINE_ORDER* wParam = (POLYLINE_ORDER*) msg->wParam; @@ -1156,32 +1202,26 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* break; case PrimaryUpdate_MemBlt: - IFCALL(proxy->MemBlt, msg->context, (MEMBLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_Mem3Blt: - IFCALL(proxy->Mem3Blt, msg->context, (MEM3BLT_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_SaveBitmap: - IFCALL(proxy->SaveBitmap, msg->context, (SAVE_BITMAP_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_GlyphIndex: - IFCALL(proxy->GlyphIndex, msg->context, (GLYPH_INDEX_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_FastIndex: - IFCALL(proxy->FastIndex, msg->context, (FAST_INDEX_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_FastGlyph: - IFCALL(proxy->FastGlyph, msg->context, (FAST_GLYPH_ORDER*) msg->wParam); { FAST_GLYPH_ORDER* wParam = (FAST_GLYPH_ORDER*) msg->wParam; if (wParam->glyphData.aj) @@ -1191,7 +1231,6 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* break; case PrimaryUpdate_PolygonSC: - IFCALL(proxy->PolygonSC, msg->context, (POLYGON_SC_ORDER*) msg->wParam); { POLYGON_SC_ORDER* wParam = (POLYGON_SC_ORDER*) msg->wParam; @@ -1201,7 +1240,6 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* break; case PrimaryUpdate_PolygonCB: - IFCALL(proxy->PolygonCB, msg->context, (POLYGON_CB_ORDER*) msg->wParam); { POLYGON_CB_ORDER* wParam = (POLYGON_CB_ORDER*) msg->wParam; @@ -1211,12 +1249,10 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* break; case PrimaryUpdate_EllipseSC: - IFCALL(proxy->EllipseSC, msg->context, (ELLIPSE_SC_ORDER*) msg->wParam); free(msg->wParam); break; case PrimaryUpdate_EllipseCB: - IFCALL(proxy->EllipseCB, msg->context, (ELLIPSE_CB_ORDER*) msg->wParam); free(msg->wParam); break; @@ -1228,14 +1264,116 @@ int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* return status; } -int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) + +static int update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case PrimaryUpdate_DstBlt: + IFCALL(proxy->DstBlt, msg->context, (DSTBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_PatBlt: + IFCALL(proxy->PatBlt, msg->context, (PATBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_ScrBlt: + IFCALL(proxy->ScrBlt, msg->context, (SCRBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_OpaqueRect: + IFCALL(proxy->OpaqueRect, msg->context, (OPAQUE_RECT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_DrawNineGrid: + IFCALL(proxy->DrawNineGrid, msg->context, (DRAW_NINE_GRID_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiDstBlt: + IFCALL(proxy->MultiDstBlt, msg->context, (MULTI_DSTBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiPatBlt: + IFCALL(proxy->MultiPatBlt, msg->context, (MULTI_PATBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiScrBlt: + IFCALL(proxy->MultiScrBlt, msg->context, (MULTI_SCRBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiOpaqueRect: + IFCALL(proxy->MultiOpaqueRect, msg->context, (MULTI_OPAQUE_RECT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MultiDrawNineGrid: + IFCALL(proxy->MultiDrawNineGrid, msg->context, (MULTI_DRAW_NINE_GRID_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_LineTo: + IFCALL(proxy->LineTo, msg->context, (LINE_TO_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_Polyline: + IFCALL(proxy->Polyline, msg->context, (POLYLINE_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_MemBlt: + IFCALL(proxy->MemBlt, msg->context, (MEMBLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_Mem3Blt: + IFCALL(proxy->Mem3Blt, msg->context, (MEM3BLT_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_SaveBitmap: + IFCALL(proxy->SaveBitmap, msg->context, (SAVE_BITMAP_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_GlyphIndex: + IFCALL(proxy->GlyphIndex, msg->context, (GLYPH_INDEX_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_FastIndex: + IFCALL(proxy->FastIndex, msg->context, (FAST_INDEX_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_FastGlyph: + IFCALL(proxy->FastGlyph, msg->context, (FAST_GLYPH_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_PolygonSC: + IFCALL(proxy->PolygonSC, msg->context, (POLYGON_SC_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_PolygonCB: + IFCALL(proxy->PolygonCB, msg->context, (POLYGON_CB_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_EllipseSC: + IFCALL(proxy->EllipseSC, msg->context, (ELLIPSE_SC_ORDER*) msg->wParam); + break; + + case PrimaryUpdate_EllipseCB: + IFCALL(proxy->EllipseCB, msg->context, (ELLIPSE_CB_ORDER*) msg->wParam); + break; + + default: + status = -1; + break; + } + + return status; +} + +static int update_message_free_secondary_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case SecondaryUpdate_CacheBitmap: - IFCALL(proxy->CacheBitmap, msg->context, (CACHE_BITMAP_ORDER*) msg->wParam); { CACHE_BITMAP_ORDER* wParam = (CACHE_BITMAP_ORDER*) msg->wParam; @@ -1245,7 +1383,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheBitmapV2: - IFCALL(proxy->CacheBitmapV2, msg->context, (CACHE_BITMAP_V2_ORDER*) msg->wParam); { CACHE_BITMAP_V2_ORDER* wParam = (CACHE_BITMAP_V2_ORDER*) msg->wParam; @@ -1255,7 +1392,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheBitmapV3: - IFCALL(proxy->CacheBitmapV3, msg->context, (CACHE_BITMAP_V3_ORDER*) msg->wParam); { CACHE_BITMAP_V3_ORDER* wParam = (CACHE_BITMAP_V3_ORDER*) msg->wParam; @@ -1265,7 +1401,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheColorTable: - IFCALL(proxy->CacheColorTable, msg->context, (CACHE_COLOR_TABLE_ORDER*) msg->wParam); { CACHE_COLOR_TABLE_ORDER* wParam = (CACHE_COLOR_TABLE_ORDER*) msg->wParam; free(wParam); @@ -1273,7 +1408,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheGlyph: - IFCALL(proxy->CacheGlyph, msg->context, (CACHE_GLYPH_ORDER*) msg->wParam); { CACHE_GLYPH_ORDER* wParam = (CACHE_GLYPH_ORDER*) msg->wParam; free(wParam); @@ -1281,7 +1415,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheGlyphV2: - IFCALL(proxy->CacheGlyphV2, msg->context, (CACHE_GLYPH_V2_ORDER*) msg->wParam); { CACHE_GLYPH_V2_ORDER* wParam = (CACHE_GLYPH_V2_ORDER*) msg->wParam; free(wParam); @@ -1289,7 +1422,6 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag break; case SecondaryUpdate_CacheBrush: - IFCALL(proxy->CacheBrush, msg->context, (CACHE_BRUSH_ORDER*) msg->wParam); { CACHE_BRUSH_ORDER* wParam = (CACHE_BRUSH_ORDER*) msg->wParam; free(wParam); @@ -1304,14 +1436,56 @@ int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessag return status; } -int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) + +static int update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case SecondaryUpdate_CacheBitmap: + IFCALL(proxy->CacheBitmap, msg->context, (CACHE_BITMAP_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheBitmapV2: + IFCALL(proxy->CacheBitmapV2, msg->context, (CACHE_BITMAP_V2_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheBitmapV3: + IFCALL(proxy->CacheBitmapV3, msg->context, (CACHE_BITMAP_V3_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheColorTable: + IFCALL(proxy->CacheColorTable, msg->context, (CACHE_COLOR_TABLE_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheGlyph: + IFCALL(proxy->CacheGlyph, msg->context, (CACHE_GLYPH_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheGlyphV2: + IFCALL(proxy->CacheGlyphV2, msg->context, (CACHE_GLYPH_V2_ORDER*) msg->wParam); + break; + + case SecondaryUpdate_CacheBrush: + IFCALL(proxy->CacheBrush, msg->context, (CACHE_BRUSH_ORDER*) msg->wParam); + break; + + default: + status = -1; + break; + } + + return status; +} + +static int update_message_free_altsec_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case AltSecUpdate_CreateOffscreenBitmap: - IFCALL(proxy->CreateOffscreenBitmap, msg->context, (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam); { CREATE_OFFSCREEN_BITMAP_ORDER* wParam = (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam; @@ -1321,57 +1495,46 @@ int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* break; case AltSecUpdate_SwitchSurface: - IFCALL(proxy->SwitchSurface, msg->context, (SWITCH_SURFACE_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_CreateNineGridBitmap: - IFCALL(proxy->CreateNineGridBitmap, msg->context, (CREATE_NINE_GRID_BITMAP_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_FrameMarker: - IFCALL(proxy->FrameMarker, msg->context, (FRAME_MARKER_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_StreamBitmapFirst: - IFCALL(proxy->StreamBitmapFirst, msg->context, (STREAM_BITMAP_FIRST_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_StreamBitmapNext: - IFCALL(proxy->StreamBitmapNext, msg->context, (STREAM_BITMAP_NEXT_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusFirst: - IFCALL(proxy->DrawGdiPlusFirst, msg->context, (DRAW_GDIPLUS_FIRST_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusNext: - IFCALL(proxy->DrawGdiPlusNext, msg->context, (DRAW_GDIPLUS_NEXT_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusEnd: - IFCALL(proxy->DrawGdiPlusEnd, msg->context, (DRAW_GDIPLUS_END_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusCacheFirst: - IFCALL(proxy->DrawGdiPlusCacheFirst, msg->context, (DRAW_GDIPLUS_CACHE_FIRST_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusCacheNext: - IFCALL(proxy->DrawGdiPlusCacheNext, msg->context, (DRAW_GDIPLUS_CACHE_NEXT_ORDER*) msg->wParam); free(msg->wParam); break; case AltSecUpdate_DrawGdiPlusCacheEnd: - IFCALL(proxy->DrawGdiPlusCacheEnd, msg->context, (DRAW_GDIPLUS_CACHE_END_ORDER*) msg->wParam); free(msg->wParam); break; @@ -1383,22 +1546,81 @@ int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* return status; } -int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) + +static int update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case AltSecUpdate_CreateOffscreenBitmap: + IFCALL(proxy->CreateOffscreenBitmap, msg->context, (CREATE_OFFSCREEN_BITMAP_ORDER*) msg->wParam); + break; + + case AltSecUpdate_SwitchSurface: + IFCALL(proxy->SwitchSurface, msg->context, (SWITCH_SURFACE_ORDER*) msg->wParam); + break; + + case AltSecUpdate_CreateNineGridBitmap: + IFCALL(proxy->CreateNineGridBitmap, msg->context, (CREATE_NINE_GRID_BITMAP_ORDER*) msg->wParam); + break; + + case AltSecUpdate_FrameMarker: + IFCALL(proxy->FrameMarker, msg->context, (FRAME_MARKER_ORDER*) msg->wParam); + break; + + case AltSecUpdate_StreamBitmapFirst: + IFCALL(proxy->StreamBitmapFirst, msg->context, (STREAM_BITMAP_FIRST_ORDER*) msg->wParam); + break; + + case AltSecUpdate_StreamBitmapNext: + IFCALL(proxy->StreamBitmapNext, msg->context, (STREAM_BITMAP_NEXT_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusFirst: + IFCALL(proxy->DrawGdiPlusFirst, msg->context, (DRAW_GDIPLUS_FIRST_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusNext: + IFCALL(proxy->DrawGdiPlusNext, msg->context, (DRAW_GDIPLUS_NEXT_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusEnd: + IFCALL(proxy->DrawGdiPlusEnd, msg->context, (DRAW_GDIPLUS_END_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusCacheFirst: + IFCALL(proxy->DrawGdiPlusCacheFirst, msg->context, (DRAW_GDIPLUS_CACHE_FIRST_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusCacheNext: + IFCALL(proxy->DrawGdiPlusCacheNext, msg->context, (DRAW_GDIPLUS_CACHE_NEXT_ORDER*) msg->wParam); + break; + + case AltSecUpdate_DrawGdiPlusCacheEnd: + IFCALL(proxy->DrawGdiPlusCacheEnd, msg->context, (DRAW_GDIPLUS_CACHE_END_ORDER*) msg->wParam); + break; + + default: + status = -1; + break; + } + + return status; +} + +static int update_message_free_window_update_class(wMessage* msg, int type) { int status = 0; switch (type) { case WindowUpdate_WindowCreate: - IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_STATE_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; case WindowUpdate_WindowUpdate: - IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_STATE_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; @@ -1408,8 +1630,6 @@ int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* 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); - if (windowIcon->iconInfo->cbBitsColor > 0) { free(windowIcon->iconInfo->bitsColor); @@ -1431,39 +1651,29 @@ int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* break; case WindowUpdate_WindowCachedIcon: - IFCALL(proxy->WindowCachedIcon, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (WINDOW_CACHED_ICON_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; case WindowUpdate_WindowDelete: - IFCALL(proxy->WindowDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); free(msg->wParam); break; case WindowUpdate_NotifyIconCreate: - IFCALL(proxy->NotifyIconCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (NOTIFY_ICON_STATE_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; case WindowUpdate_NotifyIconUpdate: - IFCALL(proxy->NotifyIconUpdate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (NOTIFY_ICON_STATE_ORDER*) msg->lParam); free(msg->wParam); free(msg->lParam); break; case WindowUpdate_NotifyIconDelete: - IFCALL(proxy->NotifyIconDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); free(msg->wParam); break; case WindowUpdate_MonitoredDesktop: - IFCALL(proxy->MonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, - (MONITORED_DESKTOP_ORDER*) msg->lParam); { MONITORED_DESKTOP_ORDER* lParam = (MONITORED_DESKTOP_ORDER*) msg->lParam; @@ -1475,7 +1685,6 @@ int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* break; case WindowUpdate_NonMonitoredDesktop: - IFCALL(proxy->NonMonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); free(msg->wParam); break; @@ -1487,24 +1696,85 @@ int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* return status; } -int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) + +static int update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) { int status = 0; switch (type) { - case PointerUpdate_PointerPosition: - IFCALL(proxy->PointerPosition, msg->context, (POINTER_POSITION_UPDATE*) msg->wParam); - free(msg->wParam); + case WindowUpdate_WindowCreate: + IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_STATE_ORDER*) msg->lParam); break; + case WindowUpdate_WindowUpdate: + IFCALL(proxy->WindowCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_STATE_ORDER*) msg->lParam); + break; + + 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); + } + break; + + case WindowUpdate_WindowCachedIcon: + IFCALL(proxy->WindowCachedIcon, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (WINDOW_CACHED_ICON_ORDER*) msg->lParam); + break; + + case WindowUpdate_WindowDelete: + IFCALL(proxy->WindowDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); + break; + + case WindowUpdate_NotifyIconCreate: + IFCALL(proxy->NotifyIconCreate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (NOTIFY_ICON_STATE_ORDER*) msg->lParam); + break; + + case WindowUpdate_NotifyIconUpdate: + IFCALL(proxy->NotifyIconUpdate, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (NOTIFY_ICON_STATE_ORDER*) msg->lParam); + break; + + case WindowUpdate_NotifyIconDelete: + IFCALL(proxy->NotifyIconDelete, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); + break; + + case WindowUpdate_MonitoredDesktop: + IFCALL(proxy->MonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam, + (MONITORED_DESKTOP_ORDER*) msg->lParam); + break; + + case WindowUpdate_NonMonitoredDesktop: + IFCALL(proxy->NonMonitoredDesktop, msg->context, (WINDOW_ORDER_INFO*) msg->wParam); + break; + + default: + status = -1; + break; + } + + return status; +} + +int update_message_free_pointer_update_class(wMessage* msg, int type) +{ + int status = 0; + + switch(type) + { + case PointerUpdate_PointerPosition: case PointerUpdate_PointerSystem: - IFCALL(proxy->PointerSystem, msg->context, (POINTER_SYSTEM_UPDATE*) msg->wParam); + case PointerUpdate_PointerCached: free(msg->wParam); break; case PointerUpdate_PointerColor: - IFCALL(proxy->PointerColor, msg->context, (POINTER_COLOR_UPDATE*) msg->wParam); { POINTER_COLOR_UPDATE* wParam = (POINTER_COLOR_UPDATE*) msg->wParam; @@ -1513,9 +1783,8 @@ int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* free(wParam); } break; - + case PointerUpdate_PointerNew: - IFCALL(proxy->PointerNew, msg->context, (POINTER_NEW_UPDATE*) msg->wParam); { POINTER_NEW_UPDATE* wParam = (POINTER_NEW_UPDATE*) msg->wParam; @@ -1524,10 +1793,38 @@ int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* free(wParam); } break; + default: + status = -1; + break; + } + + return status; +} + +static int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type) +{ + int status = 0; + + switch (type) + { + case PointerUpdate_PointerPosition: + IFCALL(proxy->PointerPosition, msg->context, (POINTER_POSITION_UPDATE*) msg->wParam); + break; + + case PointerUpdate_PointerSystem: + IFCALL(proxy->PointerSystem, msg->context, (POINTER_SYSTEM_UPDATE*) msg->wParam); + break; + + case PointerUpdate_PointerColor: + IFCALL(proxy->PointerColor, msg->context, (POINTER_COLOR_UPDATE*) msg->wParam); + break; + + case PointerUpdate_PointerNew: + IFCALL(proxy->PointerNew, msg->context, (POINTER_NEW_UPDATE*) msg->wParam); + break; case PointerUpdate_PointerCached: IFCALL(proxy->PointerCached, msg->context, (POINTER_CACHED_UPDATE*) msg->wParam); - free(msg->wParam); break; default: @@ -1538,7 +1835,48 @@ int update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* return status; } -int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, int msgClass, int msgType) +static int update_message_free_class(wMessage*msg, int msgClass, int msgType) +{ + int status = 0; + + switch (msgClass) + { + case Update_Class: + status = update_message_free_update_class(msg, msgType); + break; + + case PrimaryUpdate_Class: + status = update_message_free_primary_update_class(msg, msgType); + break; + + case SecondaryUpdate_Class: + status = update_message_free_secondary_update_class(msg, msgType); + break; + + case AltSecUpdate_Class: + status = update_message_free_altsec_update_class(msg, msgType); + break; + + case WindowUpdate_Class: + status = update_message_free_window_update_class(msg, msgType); + break; + + case PointerUpdate_Class: + status = update_message_free_pointer_update_class(msg, msgType); + break; + + default: + status = -1; + break; + } + + if (status < 0) + fprintf(stderr, "Unknown message: class: %d type: %d\n", msgClass, msgType); + + return status; +} + +static int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, int msgClass, int msgType) { int status = 0; @@ -1592,6 +1930,29 @@ int update_message_queue_process_message(rdpUpdate* update, wMessage* message) msgType = GetMessageType(message->id); status = update_message_process_class(update->proxy, message, msgClass, msgType); + update_message_free_class(message, msgClass, msgType); + + if (status < 0) + status = -1; + + return 1; +} + +int update_message_queue_free_message(wMessage *message) +{ + int status; + int msgClass; + int msgType; + + assert(message); + + if (message->id == WMQ_QUIT) + return 0; + + msgClass = GetMessageClass(message->id); + msgType = GetMessageType(message->id); + + status = update_message_free_class(message, msgClass, msgType); if (status < 0) status = -1; @@ -1860,8 +2221,36 @@ static void input_message_ExtendedMouseEvent(rdpInput* input, UINT16 flags, UINT } /* Event Queue */ +static int input_message_free_input_class(wMessage* msg, int type) +{ + int status = 0; -int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg, int type) + switch (type) + { + case Input_SynchronizeEvent: + break; + + case Input_KeyboardEvent: + break; + + case Input_UnicodeKeyboardEvent: + break; + + case Input_MouseEvent: + break; + + case Input_ExtendedMouseEvent: + break; + + default: + status = -1; + break; + } + + return status; +} + +static int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg, int type) { int status = 0; @@ -1913,7 +2302,28 @@ int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg, int t return status; } -int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClass, int msgType) +static int input_message_free_class(wMessage* msg, int msgClass, int msgType) +{ + int status = 0; + + switch (msgClass) + { + case Input_Class: + status = input_message_free_input_class(msg, msgType); + break; + + default: + status = -1; + break; + } + + if (status < 0) + fprintf(stderr, "Unknown event: class: %d type: %d\n", msgClass, msgType); + + return status; +} + +static int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClass, int msgType) { int status = 0; @@ -1934,6 +2344,26 @@ int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClas return status; } +int input_message_queue_free_message(wMessage* message) +{ + int status; + int msgClass; + int msgType; + + if (message->id == WMQ_QUIT) + return 0; + + msgClass = GetMessageClass(message->id); + msgType = GetMessageType(message->id); + + status = input_message_free_class(message, msgClass, msgType); + + if (status < 0) + return -1; + + return 1; +} + int input_message_queue_process_message(rdpInput* input, wMessage* message) { int status; @@ -1947,6 +2377,7 @@ int input_message_queue_process_message(rdpInput* input, wMessage* message) msgType = GetMessageType(message->id); status = input_message_process_class(input->proxy, message, msgClass, msgType); + input_message_free_class(message, msgClass, msgType); if (status < 0) return -1; diff --git a/libfreerdp/core/message.h b/libfreerdp/core/message.h index 99d79b9d5..fad0e15ce 100644 --- a/libfreerdp/core/message.h +++ b/libfreerdp/core/message.h @@ -123,6 +123,8 @@ struct rdp_update_proxy }; int update_message_queue_process_message(rdpUpdate* update, wMessage* message); +int update_message_queue_free_message(wMessage* message); + int update_message_queue_process_pending_messages(rdpUpdate* update); rdpUpdateProxy* update_message_proxy_new(rdpUpdate* update); @@ -148,6 +150,7 @@ struct rdp_input_proxy }; int input_message_queue_process_message(rdpInput* input, wMessage* message); +int input_message_queue_free_message(wMessage* message); int input_message_queue_process_pending_messages(rdpInput* input); rdpInputProxy* input_message_proxy_new(rdpInput* input); diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 70ff6c069..f47cf4b59 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -1051,6 +1051,12 @@ void transport_free(rdpTransport* transport) { if (transport) { + if (transport->async) + { + assert(!transport->thread); + assert(!transport->stopEvent); + } + if (transport->ReceiveBuffer) Stream_Release(transport->ReceiveBuffer); diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 49077aec6..a4cebdf08 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -1544,8 +1544,16 @@ int update_process_messages(rdpUpdate* update) return update_message_queue_process_pending_messages(update); } +static void update_free_queued_message(void *obj) +{ + wMessage *msg = (wMessage*)obj; + + update_message_queue_free_message(msg); +} + rdpUpdate* update_new(rdpRdp* rdp) { + const wObject cb = { .fnObjectFree = update_free_queued_message }; rdpUpdate* update; update = (rdpUpdate*) malloc(sizeof(rdpUpdate)); @@ -1587,7 +1595,7 @@ rdpUpdate* update_new(rdpRdp* rdp) update->initialState = TRUE; - update->queue = MessageQueue_New(); + update->queue = MessageQueue_New(&cb); } return update; diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 91d74e130..f37c4e5da 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -402,6 +402,8 @@ struct _wMessageQueue wMessage* array; CRITICAL_SECTION lock; HANDLE event; + + wObject object; }; typedef struct _wMessageQueue wMessageQueue; @@ -418,7 +420,43 @@ WINPR_API void MessageQueue_PostQuit(wMessageQueue* queue, int nExitCode); WINPR_API int MessageQueue_Get(wMessageQueue* queue, wMessage* message); WINPR_API int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove); -WINPR_API wMessageQueue* MessageQueue_New(void); +/*! \brief Clears all elements in a message queue. + * + * \note If dynamically allocated data is part of the messages, + * a custom cleanup handler must be passed in the 'callback' + * argument for MessageQueue_New. + * + * \param queue The queue to clear. + * + * \return 0 in case of success or a error code otherwise. + */ +WINPR_API int MessageQueue_Clear(wMessageQueue *queue); + +/*! \brief Creates a new message queue. + * If 'callback' is null, no custom cleanup will be done + * on message queue deallocation. + * If the 'callback' argument contains valid uninit or + * free functions those will be called by + * 'MessageQueue_Clear'. + * + * \param callback a pointer to custom initialization / cleanup functions. + * Can be NULL if not used. + * + * \return A pointer to a newly allocated MessageQueue or NULL. + */ +WINPR_API wMessageQueue* MessageQueue_New(const wObject *callback); + +/*! \brief Frees resources allocated by a message queue. + * This function will only free resources allocated + * internally. + * + * \note Empty the queue before calling this function with + * 'MessageQueue_Clear', 'MessageQueue_Get' or + * 'MessageQueue_Peek' to free all resources allocated + * by the message contained. + * + * \param queue A pointer to the queue to be freed. + */ WINPR_API void MessageQueue_Free(wMessageQueue* queue); /* Message Pipe */ diff --git a/winpr/libwinpr/utils/collections/MessagePipe.c b/winpr/libwinpr/utils/collections/MessagePipe.c index 6be37e7ed..a7e0eade9 100644 --- a/winpr/libwinpr/utils/collections/MessagePipe.c +++ b/winpr/libwinpr/utils/collections/MessagePipe.c @@ -54,8 +54,8 @@ wMessagePipe* MessagePipe_New() if (pipe) { - pipe->In = MessageQueue_New(); - pipe->Out = MessageQueue_New(); + pipe->In = MessageQueue_New(NULL); + pipe->Out = MessageQueue_New(NULL); } return pipe; diff --git a/winpr/libwinpr/utils/collections/MessageQueue.c b/winpr/libwinpr/utils/collections/MessageQueue.c index e7b8a5e84..b4dc6c295 100644 --- a/winpr/libwinpr/utils/collections/MessageQueue.c +++ b/winpr/libwinpr/utils/collections/MessageQueue.c @@ -178,7 +178,7 @@ int MessageQueue_Peek(wMessageQueue* queue, wMessage* message, BOOL remove) * Construction, Destruction */ -wMessageQueue* MessageQueue_New() +wMessageQueue* MessageQueue_New(const wObject *callback) { wMessageQueue* queue = NULL; @@ -196,6 +196,11 @@ wMessageQueue* MessageQueue_New() InitializeCriticalSectionAndSpinCount(&queue->lock, 4000); queue->event = CreateEvent(NULL, TRUE, FALSE, NULL); + + if (callback) + queue->object = *callback; + else + ZeroMemory(&queue->object, sizeof(queue->object)); } return queue; @@ -209,3 +214,32 @@ void MessageQueue_Free(wMessageQueue* queue) free(queue->array); free(queue); } + +int MessageQueue_Clear(wMessageQueue *queue) +{ + int status = 0; + + EnterCriticalSection(&queue->lock); + + while(queue->size > 0) + { + wMessage *msg = &(queue->array[queue->head]); + + /* Free resources of message. */ + if (queue->object.fnObjectUninit) + queue->object.fnObjectUninit(msg); + if (queue->object.fnObjectFree) + queue->object.fnObjectFree(msg); + + ZeroMemory(msg, sizeof(wMessage)); + + queue->head = (queue->head + 1) % queue->capacity; + queue->size--; + } + ResetEvent(queue->event); + + LeaveCriticalSection(&queue->lock); + + return status; +} + diff --git a/winpr/libwinpr/utils/test/TestMessageQueue.c b/winpr/libwinpr/utils/test/TestMessageQueue.c index 2185cab14..10a5942e6 100644 --- a/winpr/libwinpr/utils/test/TestMessageQueue.c +++ b/winpr/libwinpr/utils/test/TestMessageQueue.c @@ -29,7 +29,7 @@ int TestMessageQueue(int argc, char* argv[]) HANDLE thread; wMessageQueue* queue; - queue = MessageQueue_New(); + queue = MessageQueue_New(NULL); thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) message_queue_consumer_thread, (void*) queue, 0, NULL);