From a57c480b29f117699b3f97b01ab24ef5fbce0447 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 30 Nov 2022 10:19:32 +0100 Subject: [PATCH] [channel,rdpdr] proper queue cleanup for rdpdr --- channels/drive/client/drive_main.c | 19 +++++++++++++++++++ channels/parallel/client/parallel_main.c | 19 +++++++++++++++++++ channels/rdpdr/client/irp.c | 11 +++++++---- channels/serial/client/serial_main.c | 19 +++++++++++++++++++ 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index a376af58e..7c291ad51 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -858,6 +858,21 @@ static void drive_file_objfree(void* obj) drive_file_free((DRIVE_FILE*)obj); } +static void drive_message_free(void* obj) +{ + wMessage* msg = obj; + if (!msg) + return; + if (msg->id != 0) + return; + + IRP* irp = (IRP*)msg->wParam; + if (!irp) + return; + WINPR_ASSERT(irp->Discard); + irp->Discard(irp); +} + /** * Function description * @@ -958,6 +973,10 @@ static UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, goto out_error; } + wObject* obj = MessageQueue_Object(drive->IrpQueue); + WINPR_ASSERT(obj); + obj->fnObjectFree = drive_message_free; + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)drive))) { WLog_ERR(TAG, "RegisterDevice failed with error %" PRIu32 "!", error); diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index dbf49322e..30f04758e 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -398,6 +398,21 @@ static UINT parallel_free(DEVICE* device) return CHANNEL_RC_OK; } +static void parallel_message_free(void* obj) +{ + wMessage* msg = obj; + if (!msg) + return; + if (msg->id != 0) + return; + + IRP* irp = (IRP*)msg->wParam; + if (!irp) + return; + WINPR_ASSERT(irp->Discard); + irp->Discard(irp); +} + /** * Function description * @@ -465,6 +480,10 @@ UINT parallel_DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) goto error_out; } + wObject* obj = MessageQueue_Object(parallel->queue); + WINPR_ASSERT(obj); + obj->fnObjectFree = parallel_message_free; + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)parallel))) { WLog_ERR(TAG, "RegisterDevice failed with error %" PRIu32 "!", error); diff --git a/channels/rdpdr/client/irp.c b/channels/rdpdr/client/irp.c index ad443dca1..420899fad 100644 --- a/channels/rdpdr/client/irp.c +++ b/channels/rdpdr/client/irp.c @@ -65,7 +65,12 @@ static UINT irp_complete(IRP* irp) rdpdrPlugin* rdpdr; UINT error; + WINPR_ASSERT(irp); + WINPR_ASSERT(irp->output); + WINPR_ASSERT(irp->devman); + rdpdr = (rdpdrPlugin*)irp->devman->plugin; + WINPR_ASSERT(rdpdr); pos = Stream_GetPosition(irp->output); Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4); @@ -134,7 +139,7 @@ IRP* irp_new(DEVMAN* devman, wStreamPool* pool, wStream* s, UINT* error) if (!irp->output) { WLog_ERR(TAG, "Stream_New failed!"); - winpr_aligned_free(irp); + irp_free(irp); if (error) *error = CHANNEL_RC_NO_MEMORY; return NULL; @@ -142,9 +147,7 @@ IRP* irp_new(DEVMAN* devman, wStreamPool* pool, wStream* s, UINT* error) if (!rdpdr_write_iocompletion_header(irp->output, DeviceId, irp->CompletionId, 0)) { - if (irp->output) - Stream_Release(irp->output); - winpr_aligned_free(irp); + irp_free(irp); if (error) *error = CHANNEL_RC_NO_MEMORY; return NULL; diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index 52cfa6782..ded7b998d 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -795,6 +795,21 @@ static UINT serial_free(DEVICE* device) #endif /* __linux__ */ +static void serial_message_free(void* obj) +{ + wMessage* msg = obj; + if (!msg) + return; + if (msg->id != 0) + return; + + IRP* irp = (IRP*)msg->wParam; + if (!irp) + return; + WINPR_ASSERT(irp->Discard); + irp->Discard(irp); +} + /** * Function description * @@ -919,6 +934,10 @@ UINT serial_DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) goto error_out; } + wObject* obj = MessageQueue_Object(serial->MainIrpQueue); + WINPR_ASSERT(obj); + obj->fnObjectFree = serial_message_free; + /* IrpThreads content only modified by create_irp_thread() */ serial->IrpThreads = ListDictionary_New(FALSE);