diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt index 09cba743f..eb83700af 100644 --- a/channels/CMakeLists.txt +++ b/channels/CMakeLists.txt @@ -15,6 +15,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +if(WITH_STATIC_PLUGINS) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + set(FILENAME "ChannelOptions.cmake") file(GLOB FILEPATHS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/${FILENAME}") @@ -30,6 +34,11 @@ foreach(FILEPATH ${FILEPATHS}) endif() endforeach(FILEPATH) +if(WITH_CLIENT_CHANNELS) + add_subdirectory(client) +endif() + if(WITH_SERVER_CHANNELS) add_subdirectory(server) endif() + diff --git a/channels/client/.gitignore b/channels/client/.gitignore new file mode 100644 index 000000000..aa03c94be --- /dev/null +++ b/channels/client/.gitignore @@ -0,0 +1,2 @@ +tables.c + diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index f628bd0b1..67e3e4ab9 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -19,8 +19,35 @@ set(MODULE_NAME "freerdp-channels-client") set(MODULE_PREFIX "FREERDP_CHANNELS_CLIENT") set(${MODULE_PREFIX}_SRCS + tables.c + tables.h loader.c) +foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) + + set(STATIC_MODULE_NAME ${${STATIC_MODULE}_CLIENT_NAME}) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${STATIC_MODULE_NAME}) + + if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "VirtualChannelEntry") + set(ENTRY_POINT_NAME "${${STATIC_MODULE}_CLIENT_NAME}_${${STATIC_MODULE}_CLIENT_ENTRY}") + set(ENTRY_POINT_IMPORT "extern int ${ENTRY_POINT_NAME}(PCHANNEL_ENTRY_POINTS pEntryPoints);") + set(VIRTUAL_CHANNEL_ENTRY_IMPORTS "${VIRTUAL_CHANNEL_ENTRY_IMPORTS}\n${VIRTUAL_CHANNEL_ENTRY_IMPORTS}${ENTRY_POINT_IMPORT}") + set(VIRTUAL_CHANNEL_ENTRY_TABLE "${VIRTUAL_CHANNEL_ENTRY_TABLE}\n\t{ \"${STATIC_MODULE_NAME}\", ${ENTRY_POINT_NAME} },") + endif() + + if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL "DeviceServiceEntry") + set(ENTRY_POINT_NAME "${${STATIC_MODULE}_CLIENT_NAME}_${${STATIC_MODULE}_CLIENT_ENTRY}") + set(ENTRY_POINT_IMPORT "extern int ${ENTRY_POINT_NAME}(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints);") + set(DEVICE_SERVICE_ENTRY_IMPORTS "${DEVICE_SERVICE_ENTRY_IMPORTS}\n${DEVICE_SERVICE_ENTRY_IMPORTS}${ENTRY_POINT_IMPORT}") + set(DEVICE_SERVICE_ENTRY_TABLE "${DEVICE_SERVICE_ENTRY_TABLE}\n\t{ \"${STATIC_MODULE_NAME}\", ${ENTRY_POINT_NAME} },") + endif() +endforeach() + +set(VIRTUAL_CHANNEL_ENTRY_TABLE "${VIRTUAL_CHANNEL_ENTRY_TABLE}\n\t{ \"\", NULL }") +set(DEVICE_SERVICE_ENTRY_TABLE "${DEVICE_SERVICE_ENTRY_TABLE}\n\t{ \"\", NULL }") + +configure_file(tables.c.in tables.c) + add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") diff --git a/channels/client/loader.c b/channels/client/loader.c index b3513115f..884864b92 100644 --- a/channels/client/loader.c +++ b/channels/client/loader.c @@ -17,4 +17,49 @@ * limitations under the License. */ +#include "tables.h" +#include +#include +#include + +extern const VIRTUAL_CHANNEL_ENTRY VIRTUAL_CHANNEL_TABLE[]; +extern const DEVICE_SERVICE_ENTRY DEVICE_SERVICE_TABLE[]; + +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; + } + } + 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 NULL; +} diff --git a/channels/client/tables.c.in b/channels/client/tables.c.in new file mode 100644 index 000000000..087dc827e --- /dev/null +++ b/channels/client/tables.c.in @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Static Entry Point Tables + * + * Copyright 2012 Marc-Andre Moreau + * + * 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. + */ + +#include "tables.h" +${VIRTUAL_CHANNEL_ENTRY_IMPORTS} +${DEVICE_SERVICE_ENTRY_IMPORTS} + +const VIRTUAL_CHANNEL_ENTRY VIRTUAL_CHANNEL_TABLE[] = +{${VIRTUAL_CHANNEL_ENTRY_TABLE} +}; + +const DEVICE_SERVICE_ENTRY DEVICE_SERVICE_TABLE[] = +{${DEVICE_SERVICE_ENTRY_TABLE} +}; + diff --git a/channels/client/tables.h b/channels/client/tables.h new file mode 100644 index 000000000..3851748e4 --- /dev/null +++ b/channels/client/tables.h @@ -0,0 +1,42 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Static Entry Point Tables + * + * Copyright 2012 Marc-Andre Moreau + * + * 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. + */ + +#include + +#ifndef PDEVICE_SERVICE_ENTRY_POINTS +#define PDEVICE_SERVICE_ENTRY_POINTS void* +#endif + +typedef int (*VIRTUAL_CHANNEL_ENTRY_FN)(PCHANNEL_ENTRY_POINTS pEntryPoints); +typedef int (*DEVICE_SERVICE_ENTRY_FN)(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints); + +struct _VIRTUAL_CHANNEL_ENTRY +{ + const char* name; + const VIRTUAL_CHANNEL_ENTRY_FN entry; +}; +typedef struct _VIRTUAL_CHANNEL_ENTRY VIRTUAL_CHANNEL_ENTRY; + +struct _DEVICE_SERVICE_ENTRY +{ + const char* name; + const DEVICE_SERVICE_ENTRY_FN entry; +}; +typedef struct _DEVICE_SERVICE_ENTRY DEVICE_SERVICE_ENTRY; + diff --git a/channels/disk/CMakeLists.txt b/channels/disk/CMakeLists.txt index 676de4e85..e9b0c0846 100644 --- a/channels/disk/CMakeLists.txt +++ b/channels/disk/CMakeLists.txt @@ -15,7 +15,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +set(MODULE_NAME "disk") +set(MODULE_PREFIX "CHANNEL_RDPDR_DISK") + 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() diff --git a/channels/disk/client/CMakeLists.txt b/channels/disk/client/CMakeLists.txt index a2c9d6b01..586c89462 100644 --- a/channels/disk/client/CMakeLists.txt +++ b/channels/disk/client/CMakeLists.txt @@ -36,7 +36,16 @@ endif() include_directories(../../rdpdr/client) -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 "DeviceServiceEntry" PARENT_SCOPE) + + add_library(${MODULE_NAME} STATIC ${${MODULE_PREFIX}_SRCS}) +endif() + set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") if(WITH_MONOLITHIC_BUILD) diff --git a/channels/disk/client/disk_main.c b/channels/disk/client/disk_main.c index d79100782..b996c6d6b 100644 --- a/channels/disk/client/disk_main.c +++ b/channels/disk/client/disk_main.c @@ -695,10 +695,10 @@ void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char* na } #ifdef WITH_STATIC_PLUGINS -int disk_entry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) -#else -int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) +#define DeviceServiceEntry disk_DeviceServiceEntry #endif + +const int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { char* name; char* path; diff --git a/channels/rdpdr/CMakeLists.txt b/channels/rdpdr/CMakeLists.txt index 676de4e85..1d8adcfc8 100644 --- a/channels/rdpdr/CMakeLists.txt +++ b/channels/rdpdr/CMakeLists.txt @@ -15,7 +15,15 @@ # See the License for the specific language governing permissions and # limitations under the License. +set(MODULE_NAME "rdpdr") +set(MODULE_PREFIX "CHANNEL_RDPDR") + 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() diff --git a/channels/rdpdr/client/CMakeLists.txt b/channels/rdpdr/client/CMakeLists.txt index 18856aad8..c9969b253 100644 --- a/channels/rdpdr/client/CMakeLists.txt +++ b/channels/rdpdr/client/CMakeLists.txt @@ -19,22 +19,31 @@ set(MODULE_NAME "rdpdr") set(MODULE_PREFIX "CHANNEL_RDPDR_CLIENT") set(${MODULE_PREFIX}_SRCS - rdpdr_constants.h - rdpdr_types.h - rdpdr_capabilities.c - rdpdr_capabilities.h - devman.c - devman.h irp.c irp.h + devman.c + devman.h rdpdr_main.c - rdpdr_main.h) + rdpdr_main.h + rdpdr_types.h + rdpdr_constants.h + rdpdr_capabilities.c + rdpdr_capabilities.h) if(MSVC AND (NOT WITH_STATIC_PLUGINS)) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) endif() -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) diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 188999a0e..eaf92b526 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -26,6 +26,8 @@ #include #include +#include + #include #include #include @@ -313,6 +315,30 @@ static void rdpdr_process_terminate(rdpSvcPlugin* plugin) xfree(plugin); } -DEFINE_SVC_PLUGIN(rdpdr, "rdpdr", - CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | - CHANNEL_OPTION_COMPRESS_RDP) +#ifdef WITH_STATIC_PLUGINS +#define VirtualChannelEntry rdpdr_VirtualChannelEntry +#endif + +const int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) +{ + rdpdrPlugin* _p; + + _p = (rdpdrPlugin*) malloc(sizeof(rdpdrPlugin)); + ZeroMemory(_p, sizeof(rdpdrPlugin)); + + _p->plugin.channel_def.options = + CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP; + + strcpy(_p->plugin.channel_def.name, "rdpdr"); + + _p->plugin.connect_callback = rdpdr_process_connect; + _p->plugin.receive_callback = rdpdr_process_receive; + _p->plugin.event_callback = rdpdr_process_event; + _p->plugin.terminate_callback = rdpdr_process_terminate; + + svc_plugin_init((rdpSvcPlugin*) _p, pEntryPoints); + + return 1; +}