diff --git a/src/protocols/rdp/channels/common-svc.c b/src/protocols/rdp/channels/common-svc.c index b73dd6e1..8b076341 100644 --- a/src/protocols/rdp/channels/common-svc.c +++ b/src/protocols/rdp/channels/common-svc.c @@ -89,10 +89,9 @@ void guac_rdp_common_svc_write(guac_rdp_common_svc* svc, return; } - /* NOTE: Data sent via pVirtualChannelWriteEx MUST always be dynamically - * allocated, as it will be automatically freed using free(). If provided, - * the last parameter (user data) MUST be a pointer to a wStream, as it - * will automatically be freed by FreeRDP using Stream_Free() */ + /* NOTE: The wStream sent via pVirtualChannelWriteEx will automatically be + * freed later with a call to Stream_Free() when handling the + * corresponding write cancel/completion event. */ svc->_entry_points.pVirtualChannelWriteEx(svc->_init_handle, svc->_open_handle, Stream_Buffer(output_stream), Stream_GetPosition(output_stream), output_stream); diff --git a/src/protocols/rdp/plugins/guac-common-svc/guac-common-svc.c b/src/protocols/rdp/plugins/guac-common-svc/guac-common-svc.c index 91dee29b..d00af95b 100644 --- a/src/protocols/rdp/plugins/guac-common-svc/guac-common-svc.c +++ b/src/protocols/rdp/plugins/guac-common-svc/guac-common-svc.c @@ -28,10 +28,8 @@ #include /** - * Event handler for events which deal with data transmitted over an open SVC. - * This specific implementation of the event handler currently handles only the - * CHANNEL_EVENT_DATA_RECEIVED event, delegating actual handling of that event - * to guac_rdp_common_svc_process_receive(). + * Event handler for events which deal with data transmitted over an open SVC, + * including receipt of inbound data and completion of outbound writes. * * The FreeRDP requirements for this function follow those of the * VirtualChannelOpenEventEx callback defined within Microsoft's RDP API: @@ -83,6 +81,13 @@ static VOID guac_rdp_common_svc_handle_open_event(LPVOID user_param, DWORD open_handle, UINT event, LPVOID data, UINT32 data_length, UINT32 total_length, UINT32 data_flags) { + /* Free stream data after send is complete */ + if ((event == CHANNEL_EVENT_WRITE_CANCELLED + || event == CHANNEL_EVENT_WRITE_COMPLETE) && data != NULL) { + Stream_Free((wStream*) data, TRUE); + return; + } + /* Ignore all events except for received data */ if (event != CHANNEL_EVENT_DATA_RECEIVED) return;