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).
This commit is contained in:
Pascal Nowack 2022-06-07 06:31:48 +02:00 committed by akallabeth
parent 5460bb3133
commit bc111b04d3
3 changed files with 38 additions and 1 deletions

View File

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

View File

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

View File

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