channels: added support for loading plugins from a static entry table
This commit is contained in:
parent
84f88883e9
commit
93f88d1c48
@ -21,7 +21,7 @@ set(MODULE_PREFIX "FREERDP_CHANNELS_CLIENT")
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
tables.c
|
||||
tables.h
|
||||
loader.c)
|
||||
channels.c)
|
||||
|
||||
foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channel Loader
|
||||
* Client Channels
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
@ -23,43 +23,62 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
extern const VIRTUAL_CHANNEL_ENTRY VIRTUAL_CHANNEL_TABLE[];
|
||||
extern const DEVICE_SERVICE_ENTRY DEVICE_SERVICE_TABLE[];
|
||||
|
||||
void* freerdp_channels_find_static_virtual_channel_entry(const char* name)
|
||||
{
|
||||
int index = 0;
|
||||
VIRTUAL_CHANNEL_ENTRY* pEntry;
|
||||
|
||||
pEntry = (VIRTUAL_CHANNEL_ENTRY*) &VIRTUAL_CHANNEL_TABLE[index++];
|
||||
|
||||
while (pEntry->entry != NULL)
|
||||
{
|
||||
if (strcmp(pEntry->name, name) == 0)
|
||||
{
|
||||
return (void*) pEntry->entry;
|
||||
}
|
||||
|
||||
pEntry = (VIRTUAL_CHANNEL_ENTRY*) &VIRTUAL_CHANNEL_TABLE[index++];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* freerdp_channels_find_static_device_service_entry(const char* name)
|
||||
{
|
||||
int index = 0;
|
||||
DEVICE_SERVICE_ENTRY* pEntry;
|
||||
|
||||
pEntry = (DEVICE_SERVICE_ENTRY*) &DEVICE_SERVICE_TABLE[index++];
|
||||
|
||||
while (pEntry->entry != NULL)
|
||||
{
|
||||
if (strcmp(pEntry->name, name) == 0)
|
||||
{
|
||||
return (void*) pEntry->entry;
|
||||
}
|
||||
|
||||
pEntry = (DEVICE_SERVICE_ENTRY*) &DEVICE_SERVICE_TABLE[index++];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* freerdp_channels_find_static_entry(const char* name, const char* entry)
|
||||
{
|
||||
if (strcmp(entry, "VirtualChannelEntry") == 0)
|
||||
{
|
||||
VIRTUAL_CHANNEL_ENTRY* pEntry;
|
||||
|
||||
pEntry = (VIRTUAL_CHANNEL_ENTRY*) &VIRTUAL_CHANNEL_TABLE[0];
|
||||
|
||||
while (pEntry != NULL)
|
||||
{
|
||||
if (strcmp(pEntry->name, name) == 0)
|
||||
{
|
||||
return (void*) pEntry->entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return freerdp_channels_find_static_virtual_channel_entry(name);
|
||||
}
|
||||
else if (strcmp(entry, "DeviceServiceEntry") == 0)
|
||||
{
|
||||
DEVICE_SERVICE_ENTRY* pEntry;
|
||||
|
||||
pEntry = (DEVICE_SERVICE_ENTRY*) &DEVICE_SERVICE_TABLE[0];
|
||||
|
||||
while (pEntry != NULL)
|
||||
{
|
||||
if (strcmp(pEntry->name, name) == 0)
|
||||
{
|
||||
return (void*) pEntry->entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return freerdp_channels_find_static_device_service_entry(name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -20,6 +20,11 @@ set(MODULE_PREFIX "CHANNEL_RDPSND")
|
||||
|
||||
if(WITH_CLIENT_CHANNELS)
|
||||
add_subdirectory(client)
|
||||
if(${MODULE_PREFIX}_CLIENT_STATIC)
|
||||
set(CHANNEL_STATIC_CLIENT_MODULES ${CHANNEL_STATIC_CLIENT_MODULES} ${MODULE_PREFIX} PARENT_SCOPE)
|
||||
set(${MODULE_PREFIX}_CLIENT_NAME ${${MODULE_PREFIX}_CLIENT_NAME} PARENT_SCOPE)
|
||||
set(${MODULE_PREFIX}_CLIENT_ENTRY ${${MODULE_PREFIX}_CLIENT_ENTRY} PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_SERVER_CHANNELS)
|
||||
|
@ -1,9 +1,7 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Client
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# Copyright 2011 O.S. Systems Software Ltda.
|
||||
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
|
||||
# Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -24,7 +22,16 @@ set(${MODULE_PREFIX}_SRCS
|
||||
rdpsnd_main.c
|
||||
rdpsnd_main.h)
|
||||
|
||||
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
if(NOT WITH_STATIC_PLUGINS)
|
||||
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
else()
|
||||
set(${MODULE_PREFIX}_STATIC ON PARENT_SCOPE)
|
||||
set(${MODULE_PREFIX}_NAME ${MODULE_NAME} PARENT_SCOPE)
|
||||
set(${MODULE_PREFIX}_ENTRY "VirtualChannelEntry" PARENT_SCOPE)
|
||||
|
||||
add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS})
|
||||
endif()
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
|
||||
|
||||
if(WITH_MONOLITHIC_BUILD)
|
||||
@ -35,6 +42,8 @@ endif()
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${MODULE_NAME}/Client")
|
||||
|
||||
if(WITH_ALSA)
|
||||
add_subdirectory(alsa)
|
||||
endif()
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
@ -563,6 +565,30 @@ static void rdpsnd_process_terminate(rdpSvcPlugin* plugin)
|
||||
xfree(plugin);
|
||||
}
|
||||
|
||||
DEFINE_SVC_PLUGIN(rdpsnd, "rdpsnd",
|
||||
CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP)
|
||||
#ifdef WITH_STATIC_PLUGINS
|
||||
#define VirtualChannelEntry rdpsnd_VirtualChannelEntry
|
||||
#endif
|
||||
|
||||
const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
{
|
||||
rdpsndPlugin* _p;
|
||||
|
||||
_p = (rdpsndPlugin*) malloc(sizeof(rdpsndPlugin));
|
||||
ZeroMemory(_p, sizeof(rdpsndPlugin));
|
||||
|
||||
_p->plugin.channel_def.options =
|
||||
CHANNEL_OPTION_INITIALIZED |
|
||||
CHANNEL_OPTION_ENCRYPT_RDP;
|
||||
|
||||
strcpy(_p->plugin.channel_def.name, "rdpsnd");
|
||||
|
||||
_p->plugin.connect_callback = rdpsnd_process_connect;
|
||||
_p->plugin.receive_callback = rdpsnd_process_receive;
|
||||
_p->plugin.event_callback = rdpsnd_process_event;
|
||||
_p->plugin.terminate_callback = rdpsnd_process_terminate;
|
||||
|
||||
svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,10 @@ endif()
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/resources)
|
||||
|
||||
if(WITH_STATIC_PLUGINS)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-channels-client)
|
||||
endif()
|
||||
|
||||
if(WITH_MONOLITHIC_BUILD)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp)
|
||||
else()
|
||||
|
@ -58,6 +58,10 @@
|
||||
#include <freerdp/plugins/cliprdr.h>
|
||||
#include <freerdp/rail.h>
|
||||
|
||||
#ifdef WITH_STATIC_PLUGINS
|
||||
#include <freerdp/client/channels.h>
|
||||
#endif
|
||||
|
||||
#include <winpr/synch.h>
|
||||
|
||||
#include "xf_gdi.h"
|
||||
@ -944,14 +948,27 @@ int xf_process_client_args(rdpSettings* settings, const char* opt, const char* v
|
||||
*/
|
||||
int xf_process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data)
|
||||
{
|
||||
void* entry;
|
||||
rdpChannels* channels = (rdpChannels*) user_data;
|
||||
|
||||
printf("loading plugin %s\n", name);
|
||||
entry = NULL;
|
||||
|
||||
#ifdef WITH_STATIC_PLUGINS
|
||||
entry = freerdp_channels_find_static_virtual_channel_entry(name);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
if (freerdp_channels_client_load(channels, settings, entry, plugin_data) == 0)
|
||||
{
|
||||
printf("loading channel %s (static)\n", name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("loading channel %s (plugin)\n", name);
|
||||
freerdp_channels_load_plugin(channels, settings, name, plugin_data);
|
||||
// FIXME we should check the return code for freerdp_channels_load_plugin()
|
||||
// and report any error to the caller. freerdp_parse_args() actually expect to get
|
||||
// an error code when there is a loading error.
|
||||
// Is it as easy as "return freerdp_channels_load_plugin()" ?
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -21,14 +21,15 @@ file(GLOB FREERDP_HEADERS "freerdp/*.h")
|
||||
install(FILES ${FREERDP_HEADERS} DESTINATION include/freerdp)
|
||||
|
||||
install(DIRECTORY freerdp/cache DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/channels DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/codec DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/crypto DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/gdi DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/locale DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/plugins DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/rail DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/server DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/utils DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/client DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/server DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY freerdp/channels DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h")
|
||||
|
||||
|
||||
|
@ -33,6 +33,8 @@ FREERDP_API int freerdp_channels_global_init(void);
|
||||
FREERDP_API int freerdp_channels_global_uninit(void);
|
||||
FREERDP_API rdpChannels* freerdp_channels_new(void);
|
||||
FREERDP_API void freerdp_channels_free(rdpChannels* channels);
|
||||
FREERDP_API int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings,
|
||||
void* entry, void* data);
|
||||
FREERDP_API int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings,
|
||||
const char* name, void* data);
|
||||
FREERDP_API int freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance);
|
||||
|
30
include/freerdp/client/channels.h
Normal file
30
include/freerdp/client/channels.h
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Channels
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_CHANNELS_CLIENT
|
||||
#define FREERDP_CHANNELS_CLIENT
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
void* freerdp_channels_find_static_virtual_channel_entry(const char* name);
|
||||
void* freerdp_channels_find_static_device_service_entry(const char* name);
|
||||
void* freerdp_channels_find_static_entry(const char* name, const char* entry);
|
||||
|
||||
#endif /* FREERDP_CHANNELS_CLIENT */
|
||||
|
@ -32,6 +32,10 @@ endif()
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
|
||||
|
||||
if(WITH_STATIC_PLUGINS)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-channels-client)
|
||||
endif()
|
||||
|
||||
if(WITH_MONOLITHIC_BUILD)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr)
|
||||
set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
|
||||
|
@ -671,18 +671,12 @@ void freerdp_channels_free(rdpChannels* channels)
|
||||
xfree(channels);
|
||||
}
|
||||
|
||||
/**
|
||||
* this is called when processing the command line parameters
|
||||
* called only from main thread
|
||||
*/
|
||||
int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, const char* name, void* data)
|
||||
int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, void* entry, void* data)
|
||||
{
|
||||
int ok;
|
||||
int status;
|
||||
struct lib_data* lib;
|
||||
CHANNEL_ENTRY_POINTS_EX ep;
|
||||
|
||||
DEBUG_CHANNELS("%s", name);
|
||||
|
||||
if (channels->num_libs_data + 1 >= CHANNEL_MAX_COUNT)
|
||||
{
|
||||
DEBUG_CHANNELS("too many channels");
|
||||
@ -690,13 +684,7 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c
|
||||
}
|
||||
|
||||
lib = channels->libs_data + channels->num_libs_data;
|
||||
lib->entry = (PVIRTUALCHANNELENTRY) freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME);
|
||||
|
||||
if (lib->entry == NULL)
|
||||
{
|
||||
DEBUG_CHANNELS("failed to find export function");
|
||||
return 1;
|
||||
}
|
||||
lib->entry = (PVIRTUALCHANNELENTRY) entry;
|
||||
|
||||
ep.cbSize = sizeof(ep);
|
||||
ep.protocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000;
|
||||
@ -714,7 +702,7 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c
|
||||
WaitForSingleObject(g_mutex_init, INFINITE);
|
||||
|
||||
g_init_channels = channels;
|
||||
ok = lib->entry((PCHANNEL_ENTRY_POINTS) &ep);
|
||||
status = lib->entry((PCHANNEL_ENTRY_POINTS) &ep);
|
||||
g_init_channels = NULL;
|
||||
|
||||
ReleaseMutex(g_mutex_init);
|
||||
@ -723,7 +711,7 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c
|
||||
channels->settings = 0;
|
||||
channels->can_call_init = 0;
|
||||
|
||||
if (!ok)
|
||||
if (!status)
|
||||
{
|
||||
DEBUG_CHANNELS("export function call failed");
|
||||
return 1;
|
||||
@ -732,6 +720,27 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* this is called when processing the command line parameters
|
||||
* called only from main thread
|
||||
*/
|
||||
int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, const char* name, void* data)
|
||||
{
|
||||
void* entry;
|
||||
|
||||
DEBUG_CHANNELS("%s", name);
|
||||
|
||||
entry = (PVIRTUALCHANNELENTRY) freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME);
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
DEBUG_CHANNELS("failed to find export function");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return freerdp_channels_client_load(channels, settings, entry, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* go through and inform all the libraries that we are initialized
|
||||
* called only from main thread
|
||||
|
Loading…
Reference in New Issue
Block a user