From bc111b04d3c45fcc5e7b80d05ff80594a4b19ff7 Mon Sep 17 00:00:00 2001 From: Pascal Nowack Date: Tue, 7 Jun 2022 06:31:48 +0200 Subject: [PATCH] core/server: Add APIs to get notified of DVC creation statuses This allows server implementations to add handling for situations, where the client side does not support them. Particularly useful for the audio output channels (static channel as fallback, when dynamic channel is not supported). --- include/freerdp/channels/wtsvc.h | 8 ++++++++ libfreerdp/core/server.c | 28 +++++++++++++++++++++++++++- libfreerdp/core/server.h | 3 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/freerdp/channels/wtsvc.h b/include/freerdp/channels/wtsvc.h index 28ecd87f7..f2c2e25ec 100644 --- a/include/freerdp/channels/wtsvc.h +++ b/include/freerdp/channels/wtsvc.h @@ -52,6 +52,9 @@ extern "C" DRDYNVC_STATE_FAILED = 3 }; + typedef BOOL (*psDVCCreationStatusCallback)(void* userdata, UINT32 channelId, + INT32 creationStatus); + /** * WTSVirtualChannelManager functions are FreeRDP extensions to the API. */ @@ -65,6 +68,9 @@ extern "C" FREERDP_API HANDLE WTSVirtualChannelManagerGetEventHandle(HANDLE hServer); FREERDP_API BOOL WTSVirtualChannelManagerIsChannelJoined(HANDLE hServer, const char* name); FREERDP_API BYTE WTSVirtualChannelManagerGetDrdynvcState(HANDLE hServer); + FREERDP_API void WTSVirtualChannelManagerSetDVCCreationCallback(HANDLE hServer, + psDVCCreationStatusCallback cb, + void* userdata); /** * Extended FreeRDP WTS functions for channel handling @@ -82,6 +88,8 @@ extern "C" FREERDP_API char** WTSGetAcceptedChannelNames(freerdp_peer* client, size_t* count); FREERDP_API INT64 WTSChannelGetOptions(freerdp_peer* client, UINT16 channel_id); + FREERDP_API UINT32 WTSChannelGetIdByHandle(HANDLE hChannelHandle); + #ifdef __cplusplus } #endif diff --git a/libfreerdp/core/server.c b/libfreerdp/core/server.c index 9c4f0c4c8..410a936cb 100644 --- a/libfreerdp/core/server.c +++ b/libfreerdp/core/server.c @@ -171,6 +171,7 @@ static BOOL wts_read_drdynvc_capabilities_response(rdpPeerChannel* channel, UINT static BOOL wts_read_drdynvc_create_response(rdpPeerChannel* channel, wStream* s, UINT32 length) { UINT32 CreationStatus; + BOOL status = TRUE; WINPR_ASSERT(channel); WINPR_ASSERT(s); @@ -191,7 +192,12 @@ static BOOL wts_read_drdynvc_create_response(rdpPeerChannel* channel, wStream* s channel->dvc_open_state = DVC_OPEN_STATE_SUCCEEDED; } - return TRUE; + IFCALLRET(channel->vcm->dvc_creation_status, status, channel->vcm->dvc_creation_status_userdata, + channel->channelId, (INT32)CreationStatus); + if (!status) + WLog_ERR(TAG, "vcm->dvc_creation_status failed!"); + + return status; } static BOOL wts_read_drdynvc_data_first(rdpPeerChannel* channel, wStream* s, int cbLen, @@ -683,6 +689,17 @@ BYTE WTSVirtualChannelManagerGetDrdynvcState(HANDLE hServer) return vcm->drdynvc_state; } +void WTSVirtualChannelManagerSetDVCCreationCallback(HANDLE hServer, psDVCCreationStatusCallback cb, + void* userdata) +{ + WTSVirtualChannelManager* vcm = hServer; + + WINPR_ASSERT(vcm); + + vcm->dvc_creation_status = cb; + vcm->dvc_creation_status_userdata = userdata; +} + UINT16 WTSChannelGetId(freerdp_peer* client, const char* channel_name) { rdpMcsChannel* channel; @@ -699,6 +716,15 @@ UINT16 WTSChannelGetId(freerdp_peer* client, const char* channel_name) return channel->ChannelId; } +UINT32 WTSChannelGetIdByHandle(HANDLE hChannelHandle) +{ + rdpPeerChannel* channel = hChannelHandle; + + WINPR_ASSERT(channel); + + return channel->channelId; +} + BOOL WTSChannelSetHandleByName(freerdp_peer* client, const char* channel_name, void* handle) { rdpMcsChannel* channel; diff --git a/libfreerdp/core/server.h b/libfreerdp/core/server.h index e49783d0d..821baed62 100644 --- a/libfreerdp/core/server.h +++ b/libfreerdp/core/server.h @@ -80,6 +80,9 @@ struct WTSVirtualChannelManager BYTE drdynvc_state; LONG dvc_channel_id_seq; + psDVCCreationStatusCallback dvc_creation_status; + void* dvc_creation_status_userdata; + wArrayList* dynamicVirtualChannels; };