Added new client callback LoadChannels and freerdp_client_load_channels

Split channel loading from PreConnect as it might be necessary to
reinitialize channels on redirect
This commit is contained in:
akallabeth 2022-06-22 12:17:44 +02:00 committed by akallabeth
parent 21cfb23e0b
commit 650a275ceb
15 changed files with 75 additions and 46 deletions

View File

@ -177,7 +177,7 @@ static BOOL android_desktop_resize(rdpContext* context)
freerdp_callback("OnGraphicsResize", "(JIII)V", (jlong)context->instance, freerdp_callback("OnGraphicsResize", "(JIII)V", (jlong)context->instance,
context->settings->DesktopWidth, context->settings->DesktopHeight, context->settings->DesktopWidth, context->settings->DesktopHeight,
context->settings->ColorDepth); context->freerdp_settings_get_uint32(settings, FreeRDP_ColorDepth));
return TRUE; return TRUE;
} }
@ -212,12 +212,6 @@ static BOOL android_pre_connect(freerdp* instance)
return FALSE; return FALSE;
} }
if (!freerdp_client_load_addins(instance->context->channels, instance->context->settings))
{
WLog_ERR(TAG, "Failed to load addins [%l08X]", GetLastError());
return FALSE;
}
freerdp_callback("OnPreConnect", "(J)V", (jlong)instance); freerdp_callback("OnPreConnect", "(J)V", (jlong)instance);
return TRUE; return TRUE;
} }
@ -307,7 +301,8 @@ static BOOL android_post_connect(freerdp* instance)
update->EndPaint = android_end_paint; update->EndPaint = android_end_paint;
update->DesktopResize = android_desktop_resize; update->DesktopResize = android_desktop_resize;
freerdp_callback("OnSettingsChanged", "(JIII)V", (jlong)instance, settings->DesktopWidth, freerdp_callback("OnSettingsChanged", "(JIII)V", (jlong)instance, settings->DesktopWidth,
settings->DesktopHeight, settings->ColorDepth); settings->DesktopHeight,
freerdp_settings_get_uint32(settings, FreeRDP_ColorDepth));
freerdp_callback("OnConnectionSuccess", "(J)V", (jlong)instance); freerdp_callback("OnConnectionSuccess", "(J)V", (jlong)instance);
return TRUE; return TRUE;
} }
@ -537,6 +532,7 @@ static BOOL android_client_new(freerdp* instance, rdpContext* context)
if (!android_event_queue_init(instance)) if (!android_event_queue_init(instance))
return FALSE; return FALSE;
instance->LoadChannels = freerdp_client_load_channels;
instance->PreConnect = android_pre_connect; instance->PreConnect = android_pre_connect;
instance->PostConnect = android_post_connect; instance->PostConnect = android_post_connect;
instance->PostDisconnect = android_post_disconnect; instance->PostDisconnect = android_post_disconnect;

View File

@ -860,9 +860,6 @@ BOOL mac_pre_connect(freerdp *instance)
PubSub_SubscribeChannelDisconnected(instance->context->pubSub, PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
mac_OnChannelDisconnectedEventHandler); mac_OnChannelDisconnectedEventHandler);
if (!freerdp_client_load_addins(instance->context->channels, settings))
return FALSE;
return TRUE; return TRUE;
} }

View File

@ -88,6 +88,7 @@ static BOOL mfreerdp_client_new(freerdp *instance, rdpContext *context)
WINPR_ASSERT(mfc); WINPR_ASSERT(mfc);
mfc->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); mfc->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
context->instance->LoadChannels = freerdp_client_load_channels;
context->instance->PreConnect = mac_pre_connect; context->instance->PreConnect = mac_pre_connect;
context->instance->PostConnect = mac_post_connect; context->instance->PostConnect = mac_post_connect;
context->instance->PostDisconnect = mac_post_disconnect; context->instance->PostDisconnect = mac_post_disconnect;

View File

@ -158,11 +158,6 @@ static BOOL tf_pre_connect(freerdp* instance)
PubSub_SubscribeChannelDisconnected(instance->context->pubSub, PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
tf_OnChannelDisconnectedEventHandler); tf_OnChannelDisconnectedEventHandler);
/* Load all required plugins / channels / libraries specified by current
* settings. */
if (!freerdp_client_load_addins(instance->context->channels, settings))
return FALSE;
/* TODO: Any code your client requires */ /* TODO: Any code your client requires */
return TRUE; return TRUE;
} }
@ -326,6 +321,7 @@ static BOOL tf_client_new(freerdp* instance, rdpContext* context)
if (!instance || !context) if (!instance || !context)
return FALSE; return FALSE;
instance->LoadChannels = freerdp_client_load_channels;
instance->PreConnect = tf_pre_connect; instance->PreConnect = tf_pre_connect;
instance->PostConnect = tf_post_connect; instance->PostConnect = tf_post_connect;
instance->PostDisconnect = tf_post_disconnect; instance->PostDisconnect = tf_post_disconnect;

View File

@ -204,9 +204,6 @@ static BOOL wl_pre_connect(freerdp* instance)
} }
} }
if (!freerdp_client_load_addins(instance->context->channels, settings))
return FALSE;
return TRUE; return TRUE;
} }
@ -621,6 +618,7 @@ static BOOL wlf_client_new(freerdp* instance, rdpContext* context)
if (!instance || !context) if (!instance || !context)
return FALSE; return FALSE;
instance->LoadChannels = freerdp_client_load_channels;
instance->PreConnect = wl_pre_connect; instance->PreConnect = wl_pre_connect;
instance->PostConnect = wl_post_connect; instance->PostConnect = wl_post_connect;
instance->PostDisconnect = wl_post_disconnect; instance->PostDisconnect = wl_post_disconnect;

View File

@ -273,9 +273,6 @@ static BOOL wf_pre_connect(freerdp* instance)
freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, desktopHeight); freerdp_settings_set_uint32(settings, FreeRDP_DesktopHeight, desktopHeight);
} }
if (!freerdp_client_load_addins(context->channels, context->settings))
return -1;
rc = freerdp_keyboard_init(freerdp_settings_get_uint32(settings, FreeRDP_KeyboardLayout)); rc = freerdp_keyboard_init(freerdp_settings_get_uint32(settings, FreeRDP_KeyboardLayout));
freerdp_settings_set_uint32(settings, FreeRDP_KeyboardLayout, rc); freerdp_settings_set_uint32(settings, FreeRDP_KeyboardLayout, rc);
PubSub_SubscribeChannelConnected(instance->context->pubSub, wf_OnChannelConnectedEventHandler); PubSub_SubscribeChannelConnected(instance->context->pubSub, wf_OnChannelConnectedEventHandler);
@ -1308,6 +1305,7 @@ static BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context)
return FALSE; return FALSE;
WINPR_ASSERT(instance); WINPR_ASSERT(instance);
instance->LoadChannels = freerdp_client_load_channels;
instance->PreConnect = wf_pre_connect; instance->PreConnect = wf_pre_connect;
instance->PostConnect = wf_post_connect; instance->PostConnect = wf_post_connect;
instance->PostDisconnect = wf_post_disconnect; instance->PostDisconnect = wf_post_disconnect;

View File

@ -1,4 +1,4 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Implementation * FreeRDP: A Remote Desktop Protocol Implementation
* X11 Client Interface * X11 Client Interface
* *
@ -1223,9 +1223,6 @@ static BOOL xf_pre_connect(freerdp* instance)
PubSub_SubscribeChannelConnected(context->pubSub, xf_OnChannelConnectedEventHandler); PubSub_SubscribeChannelConnected(context->pubSub, xf_OnChannelConnectedEventHandler);
PubSub_SubscribeChannelDisconnected(context->pubSub, xf_OnChannelDisconnectedEventHandler); PubSub_SubscribeChannelDisconnected(context->pubSub, xf_OnChannelDisconnectedEventHandler);
if (!freerdp_client_load_addins(channels, settings))
return FALSE;
if (!settings->Username && !settings->CredentialsFromStdin && !settings->SmartcardLogon) if (!settings->Username && !settings->CredentialsFromStdin && !settings->SmartcardLogon)
{ {
char login_name[MAX_PATH] = { 0 }; char login_name[MAX_PATH] = { 0 };
@ -1851,6 +1848,7 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
WINPR_ASSERT(!xfc->display); WINPR_ASSERT(!xfc->display);
WINPR_ASSERT(!xfc->mutex); WINPR_ASSERT(!xfc->mutex);
WINPR_ASSERT(!xfc->x11event); WINPR_ASSERT(!xfc->x11event);
instance->LoadChannels = freerdp_client_load_channels;
instance->PreConnect = xf_pre_connect; instance->PreConnect = xf_pre_connect;
instance->PostConnect = xf_post_connect; instance->PostConnect = xf_post_connect;
instance->PostDisconnect = xf_post_disconnect; instance->PostDisconnect = xf_post_disconnect;

View File

@ -1207,3 +1207,15 @@ BOOL freerdp_client_send_extended_button_event(rdpClientContext* cctx, BOOL rela
return TRUE; return TRUE;
} }
BOOL freerdp_client_load_channels(freerdp* instance)
{
WINPR_ASSERT(instance);
WINPR_ASSERT(instance->context);
if (!freerdp_client_load_addins(instance->context->channels, instance->context->settings))
{
WLog_ERR(TAG, "Failed to load addins [%l08X]", GetLastError());
return FALSE;
}
return TRUE;
}

View File

@ -193,6 +193,8 @@ extern "C"
FREERDP_API int freerdp_client_common_stop(rdpContext* context); FREERDP_API int freerdp_client_common_stop(rdpContext* context);
FREERDP_API BOOL freerdp_client_load_channels(freerdp* instance);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -111,9 +111,7 @@ extern "C"
typedef BOOL (*pContextNew)(freerdp* instance, rdpContext* context); typedef BOOL (*pContextNew)(freerdp* instance, rdpContext* context);
typedef void (*pContextFree)(freerdp* instance, rdpContext* context); typedef void (*pContextFree)(freerdp* instance, rdpContext* context);
typedef BOOL (*pPreConnect)(freerdp* instance); typedef BOOL (*pConnectCallback)(freerdp* instance);
typedef BOOL (*pPostConnect)(freerdp* instance);
typedef BOOL (*pRedirect)(freerdp* instance);
typedef void (*pPostDisconnect)(freerdp* instance); typedef void (*pPostDisconnect)(freerdp* instance);
typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** password, typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** password,
char** domain); char** domain);
@ -405,13 +403,13 @@ owned by rdpRdp */
ALIGN64 UINT ConnectionCallbackState; /* 47 */ ALIGN64 UINT ConnectionCallbackState; /* 47 */
ALIGN64 pPreConnect ALIGN64 pConnectCallback
PreConnect; /**< (offset 48) PreConnect; /**< (offset 48)
Callback for pre-connect operations. Callback for pre-connect operations.
Can be set before calling freerdp_connect() to have it executed before the Can be set before calling freerdp_connect() to have it executed before the
actual connection happens. Must be set to NULL if not needed. */ actual connection happens. Must be set to NULL if not needed. */
ALIGN64 pPostConnect ALIGN64 pConnectCallback
PostConnect; /**< (offset 49) PostConnect; /**< (offset 49)
Callback for post-connect operations. Callback for post-connect operations.
Can be set before calling freerdp_connect() to have it executed after the Can be set before calling freerdp_connect() to have it executed after the
@ -452,13 +450,18 @@ owned by rdpRdp */
Callback for gateway consent messages. Callback for gateway consent messages.
It is used to present consent messages to the user. */ It is used to present consent messages to the user. */
ALIGN64 pRedirect ALIGN64 pConnectCallback Redirect; /**< (offset 58)
Redirect; /**< (offset 59) Callback for redirect operations.
Callback for redirect operations. Can be set after
Can be set after rdp_client_disconnect_and_clear and applying redirection rdp_client_disconnect_and_clear and applying redirection settings but before
settings but before rdp_client_connect() to have it executed after the rdp_client_connect() to have it executed after the actual connection has
actual connection has succeeded. Must be set to NULL if not needed. */ succeeded. Must be set to NULL if not needed. */
UINT64 paddingD[64 - 59]; /* 59 */ ALIGN64 pConnectCallback
LoadChannels; /**< (offset 59)
* callback for loading channel configuration. Might be called multiple
* times when redirection occurs. */
UINT64 paddingD[64 - 60]; /* 60 */
ALIGN64 pSendChannelData ALIGN64 pSendChannelData
SendChannelData; /* (offset 64) SendChannelData; /* (offset 64)

View File

@ -69,7 +69,8 @@ struct proxy_plugin
proxyHookFn ClientLoginFailure; /* 72 custom=rdpContext* */ proxyHookFn ClientLoginFailure; /* 72 custom=rdpContext* */
proxyHookFn ClientEndPaint; /* 73 custom=rdpContext* */ proxyHookFn ClientEndPaint; /* 73 custom=rdpContext* */
proxyHookFn ClientRedirect; /* 74 custom=rdpContext* */ proxyHookFn ClientRedirect; /* 74 custom=rdpContext* */
UINT64 reserved3[96 - 75]; /* 75-95 */ proxyHookFn ClientLoadChannels; /* 75 custom=rdpContext* */
UINT64 reserved3[96 - 76]; /* 76-95 */
proxyHookFn ServerPostConnect; /* 96 custom=freerdp_peer* */ proxyHookFn ServerPostConnect; /* 96 custom=freerdp_peer* */
proxyHookFn ServerPeerActivate; /* 97 custom=freerdp_peer* */ proxyHookFn ServerPeerActivate; /* 97 custom=freerdp_peer* */

View File

@ -303,15 +303,36 @@ static BOOL pf_client_pre_connect(freerdp* instance)
PubSub_SubscribeErrorInfo(instance->context->pubSub, pf_client_on_error_info); PubSub_SubscribeErrorInfo(instance->context->pubSub, pf_client_on_error_info);
PubSub_SubscribeActivated(instance->context->pubSub, pf_client_on_activated); PubSub_SubscribeActivated(instance->context->pubSub, pf_client_on_activated);
if (!pf_client_use_peer_load_balance_info(pc))
return FALSE;
return pf_modules_run_hook(pc->pdata->module, HOOK_TYPE_CLIENT_PRE_CONNECT, pc->pdata, pc);
}
static BOOL pf_client_load_channels(freerdp* instance)
{
pClientContext* pc;
pServerContext* ps;
const proxyConfig* config;
rdpSettings* settings;
WINPR_ASSERT(instance);
pc = (pClientContext*)instance->context;
WINPR_ASSERT(pc);
WINPR_ASSERT(pc->pdata);
ps = pc->pdata->ps;
WINPR_ASSERT(ps);
WINPR_ASSERT(ps->pdata);
config = ps->pdata->config;
WINPR_ASSERT(config);
settings = instance->context->settings;
WINPR_ASSERT(settings);
/** /**
* Load all required plugins / channels / libraries specified by current * Load all required plugins / channels / libraries specified by current
* settings. * settings.
*/ */
PROXY_LOG_INFO(TAG, pc, "Loading addins"); PROXY_LOG_INFO(TAG, pc, "Loading addins");
if (!pf_client_use_peer_load_balance_info(pc))
return FALSE;
if (!pf_client_load_rdpsnd(pc)) if (!pf_client_load_rdpsnd(pc))
{ {
PROXY_LOG_ERR(TAG, pc, "Failed to load rdpsnd client"); PROXY_LOG_ERR(TAG, pc, "Failed to load rdpsnd client");
@ -371,7 +392,7 @@ static BOOL pf_client_pre_connect(freerdp* instance)
return FALSE; return FALSE;
} }
} }
return pf_modules_run_hook(pc->pdata->module, HOOK_TYPE_CLIENT_PRE_CONNECT, pc->pdata, pc); return pf_modules_run_hook(pc->pdata->module, HOOK_TYPE_CLIENT_LOAD_CHANNELS, pc->pdata, pc);
} }
static BOOL pf_client_receive_channel_data_hook(freerdp* instance, UINT16 channelId, static BOOL pf_client_receive_channel_data_hook(freerdp* instance, UINT16 channelId,
@ -942,6 +963,7 @@ static BOOL pf_client_client_new(freerdp* instance, rdpContext* context)
if (!instance || !context) if (!instance || !context)
return FALSE; return FALSE;
instance->LoadChannels = pf_client_load_channels;
instance->PreConnect = pf_client_pre_connect; instance->PreConnect = pf_client_pre_connect;
instance->PostConnect = pf_client_post_connect; instance->PostConnect = pf_client_post_connect;
instance->PostDisconnect = pf_client_post_disconnect; instance->PostDisconnect = pf_client_post_disconnect;

View File

@ -105,6 +105,8 @@ static const char* pf_modules_get_hook_type_string(PF_HOOK_TYPE result)
return "HOOK_TYPE_SERVER_CHANNELS_FREE"; return "HOOK_TYPE_SERVER_CHANNELS_FREE";
case HOOK_TYPE_SERVER_SESSION_END: case HOOK_TYPE_SERVER_SESSION_END:
return "HOOK_TYPE_SERVER_SESSION_END"; return "HOOK_TYPE_SERVER_SESSION_END";
case HOOK_TYPE_CLIENT_LOAD_CHANNELS:
return "HOOK_TYPE_CLIENT_LOAD_CHANNELS";
case HOOK_TYPE_SERVER_SESSION_INITIALIZE: case HOOK_TYPE_SERVER_SESSION_INITIALIZE:
return "HOOK_TYPE_SERVER_SESSION_INITIALIZE"; return "HOOK_TYPE_SERVER_SESSION_INITIALIZE";
case HOOK_TYPE_SERVER_SESSION_STARTED: case HOOK_TYPE_SERVER_SESSION_STARTED:
@ -168,6 +170,10 @@ static BOOL pf_modules_proxy_ArrayList_ForEachFkt(void* data, size_t index, va_l
ok = IFCALLRESULT(TRUE, plugin->ClientEndPaint, plugin, pdata, custom); ok = IFCALLRESULT(TRUE, plugin->ClientEndPaint, plugin, pdata, custom);
break; break;
case HOOK_TYPE_CLIENT_LOAD_CHANNELS:
ok = IFCALLRESULT(TRUE, plugin->ClientLoadChannels, plugin, pdata, custom);
break;
case HOOK_TYPE_SERVER_POST_CONNECT: case HOOK_TYPE_SERVER_POST_CONNECT:
ok = IFCALLRESULT(TRUE, plugin->ServerPostConnect, plugin, pdata, custom); ok = IFCALLRESULT(TRUE, plugin->ServerPostConnect, plugin, pdata, custom);
break; break;

View File

@ -51,6 +51,7 @@ typedef enum
HOOK_TYPE_CLIENT_VERIFY_X509, HOOK_TYPE_CLIENT_VERIFY_X509,
HOOK_TYPE_CLIENT_LOGIN_FAILURE, HOOK_TYPE_CLIENT_LOGIN_FAILURE,
HOOK_TYPE_CLIENT_END_PAINT, HOOK_TYPE_CLIENT_END_PAINT,
HOOK_TYPE_CLIENT_LOAD_CHANNELS,
HOOK_TYPE_SERVER_POST_CONNECT, HOOK_TYPE_SERVER_POST_CONNECT,
HOOK_TYPE_SERVER_ACTIVATE, HOOK_TYPE_SERVER_ACTIVATE,

View File

@ -128,9 +128,6 @@ static BOOL shw_pre_connect(freerdp* instance)
PubSub_SubscribeChannelConnected(context->pubSub, shw_OnChannelConnectedEventHandler); PubSub_SubscribeChannelConnected(context->pubSub, shw_OnChannelConnectedEventHandler);
PubSub_SubscribeChannelDisconnected(context->pubSub, shw_OnChannelDisconnectedEventHandler); PubSub_SubscribeChannelDisconnected(context->pubSub, shw_OnChannelDisconnectedEventHandler);
if (!freerdp_client_load_addins(context->channels, context->settings))
return FALSE;
return TRUE; return TRUE;
} }
@ -283,6 +280,7 @@ static BOOL shw_freerdp_client_new(freerdp* instance, rdpContext* context)
if (!(shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) if (!(shw->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
return FALSE; return FALSE;
instance->LoadChannels = freerdp_client_load_channels;
instance->PreConnect = shw_pre_connect; instance->PreConnect = shw_pre_connect;
instance->PostConnect = shw_post_connect; instance->PostConnect = shw_post_connect;
instance->Authenticate = shw_authenticate; instance->Authenticate = shw_authenticate;