diff --git a/CMakeLists.txt b/CMakeLists.txt index 777bbfeff..4cc615962 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,7 +311,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_SOURCE_DI set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) -set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") +set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:\$ORIGIN/..") # Unit Tests diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt index 6eebd5436..e13727640 100644 --- a/channels/CMakeLists.txt +++ b/channels/CMakeLists.txt @@ -73,6 +73,7 @@ macro(define_channel_client_subsystem _channel_name _subsystem _type) set(CHANNEL_NAME ${_channel_name}) set(CHANNEL_SUBSYSTEM ${_subsystem}) string(LENGTH "${_type}" _type_length) + string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT" CHANNEL_PREFIX) if(_type_length GREATER 0) set(SUBSYSTEM_TYPE ${_type}) set(MODULE_NAME "${CHANNEL_NAME}-client-${CHANNEL_SUBSYSTEM}-${SUBSYSTEM_TYPE}") @@ -112,13 +113,23 @@ macro(add_channel_server _channel_prefix _channel_name) endif() endmacro(add_channel_server) -macro(add_channel_client_library _module_prefix _module_name _channel_name _plugin _entry) +macro(add_channel_client_subsystem _channel_prefix _channel_name _subsystem _type) + add_subdirectory(${_subsystem}) + set(_channel_module_name "${_channel_name}-client") + string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}" _subsystem_prefix) + if(${${_subsystem_prefix}_STATIC}) + message(STATUS "Static Subsystem: ${_subsystem_prefix} / ${_subsystem}") + get_target_property(CHANNEL_SUBSYSTEMS ${_channel_module_name} SUBSYSTEMS) + set(SUBSYSTEMS ${SUBSYSTEMS} ${_subsystem}) + set_target_properties(${_channel_module_name} PROPERTIES SUBSYSTEMS "${SUBSYSTEMS}") + endif() +endmacro(add_channel_client_subsystem) - if(${_plugin} AND MSVC AND (NOT STATIC_CHANNELS)) +macro(add_channel_client_library _module_prefix _module_name _channel_name _dynamic _entry) + if(${_dynamic} AND MSVC AND (NOT STATIC_CHANNELS)) set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def) endif() - - if(${_plugin} AND (NOT STATIC_CHANNELS)) + if(${_dynamic} AND (NOT STATIC_CHANNELS)) add_library(${_module_name} ${${_module_prefix}_SRCS}) else() set(${_module_prefix}_STATIC ON PARENT_SCOPE) @@ -127,16 +138,26 @@ macro(add_channel_client_library _module_prefix _module_name _channel_name _plug set(${_module_prefix}_ENTRY ${_entry} PARENT_SCOPE) add_library(${_module_name} STATIC ${${_module_prefix}_SRCS}) endif() - endmacro(add_channel_client_library) -macro(add_channel_server_library _module_prefix _module_name _channel_name _plugin _entry) - - if(${_plugin} AND MSVC AND (NOT STATIC_CHANNELS)) +macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _dynamic _entry) + if(${_dynamic} AND MSVC AND (NOT STATIC_CHANNELS)) set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def) endif() - - if(${_plugin} AND (NOT STATIC_CHANNELS)) + if(${_dynamic} AND (NOT STATIC_CHANNELS)) + add_library(${_module_name} ${${_module_prefix}_SRCS}) + else() + set(${_module_prefix}_STATIC ON PARENT_SCOPE) + set(${_module_prefix}_NAME ${_module_name} PARENT_SCOPE) + add_library(${_module_name} STATIC ${${_module_prefix}_SRCS}) + endif() +endmacro(add_channel_client_subsystem_library) + +macro(add_channel_server_library _module_prefix _module_name _channel_name _dynamic _entry) + if(${_dynamic} AND MSVC AND (NOT STATIC_CHANNELS)) + set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def) + endif() + if(${_dynamic} AND (NOT STATIC_CHANNELS)) add_library(${_module_name} ${${_module_prefix}_SRCS}) else() set(${_module_prefix}_STATIC ON PARENT_SCOPE) @@ -145,7 +166,6 @@ macro(add_channel_server_library _module_prefix _module_name _channel_name _plug set(${_module_prefix}_ENTRY ${_entry} PARENT_SCOPE) add_library(${_module_name} STATIC ${${_module_prefix}_SRCS}) endif() - endmacro(add_channel_server_library) set(FILENAME "ChannelOptions.cmake") diff --git a/channels/audin/client/CMakeLists.txt b/channels/audin/client/CMakeLists.txt index 072092888..54d874164 100644 --- a/channels/audin/client/CMakeLists.txt +++ b/channels/audin/client/CMakeLists.txt @@ -41,9 +41,9 @@ endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client") if(WITH_ALSA) - add_subdirectory(alsa) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "") endif() if(WITH_PULSE) - add_subdirectory(pulse) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "pulse" "") endif() diff --git a/channels/audin/client/alsa/CMakeLists.txt b/channels/audin/client/alsa/CMakeLists.txt index d90e3f8d1..f49bd6131 100644 --- a/channels/audin/client/alsa/CMakeLists.txt +++ b/channels/audin/client/alsa/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${ALSA_INCLUDE_DIRS}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -36,4 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${ALSA_LIBRARIES}) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() diff --git a/channels/audin/client/alsa/audin_alsa.c b/channels/audin/client/alsa/audin_alsa.c index bb2e04dd3..80c6b70e1 100644 --- a/channels/audin/client/alsa/audin_alsa.c +++ b/channels/audin/client/alsa/audin_alsa.c @@ -328,7 +328,11 @@ static void audin_alsa_close(IAudinDevice* device) alsa->user_data = NULL; } -int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) +#ifdef STATIC_CHANNELS +#define freerdp_audin_client_subsystem_entry alsa_freerdp_audin_client_subsystem_entry +#endif + +int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) { AudinALSADevice* alsa; RDP_PLUGIN_DATA* data; diff --git a/channels/audin/client/audin_main.h b/channels/audin/client/audin_main.h index 761cf572c..4eb30564f 100644 --- a/channels/audin/client/audin_main.h +++ b/channels/audin/client/audin_main.h @@ -58,7 +58,7 @@ struct _IAudinDevice void (*Free) (IAudinDevice* devplugin); }; -#define AUDIN_DEVICE_EXPORT_FUNC_NAME "FreeRDPAudinDeviceEntry" +#define AUDIN_DEVICE_EXPORT_FUNC_NAME "freerdp_audin_client_subsystem_entry" typedef void (*PREGISTERAUDINDEVICE)(IWTSPlugin* plugin, IAudinDevice* device); diff --git a/channels/audin/client/pulse/CMakeLists.txt b/channels/audin/client/pulse/CMakeLists.txt index 21bdd6732..d0d773636 100644 --- a/channels/audin/client/pulse/CMakeLists.txt +++ b/channels/audin/client/pulse/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${PULSE_INCLUDE_DIR}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -36,4 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PULSE_LIBRARY}) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() diff --git a/channels/audin/client/pulse/audin_pulse.c b/channels/audin/client/pulse/audin_pulse.c index 73f98925f..244eb81b5 100644 --- a/channels/audin/client/pulse/audin_pulse.c +++ b/channels/audin/client/pulse/audin_pulse.c @@ -430,7 +430,11 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u } } -int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) +#ifdef STATIC_CHANNELS +#define freerdp_audin_client_subsystem_entry pulse_freerdp_audin_client_subsystem_entry +#endif + +int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) { AudinPulseDevice* pulse; RDP_PLUGIN_DATA * data; diff --git a/channels/client/CMakeLists.txt b/channels/client/CMakeLists.txt index 111022928..a5ccabba7 100644 --- a/channels/client/CMakeLists.txt +++ b/channels/client/CMakeLists.txt @@ -26,9 +26,7 @@ set(${MODULE_PREFIX}_SRCS list(REMOVE_DUPLICATES CHANNEL_STATIC_CLIENT_ENTRIES) foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES}) - foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) - if(${${STATIC_MODULE}_CLIENT_ENTRY} STREQUAL ${STATIC_ENTRY}) set(STATIC_MODULE_NAME ${${STATIC_MODULE}_CLIENT_NAME}) set(STATIC_MODULE_CHANNEL ${${STATIC_MODULE}_CLIENT_CHANNEL}) @@ -39,26 +37,48 @@ foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES}) set(${STATIC_ENTRY}_IMPORTS "${${STATIC_ENTRY}_IMPORTS}\n${ENTRY_POINT_IMPORT}") set(${STATIC_ENTRY}_TABLE "${${STATIC_ENTRY}_TABLE}\n\t{ \"${STATIC_MODULE_CHANNEL}\", ${ENTRY_POINT_NAME} },") endif() - endforeach() - endforeach() set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\nconst STATIC_ENTRY_TABLE CLIENT_STATIC_ENTRY_TABLES[] =\n{") foreach(STATIC_ENTRY ${CHANNEL_STATIC_CLIENT_ENTRIES}) - set(CLIENT_STATIC_ENTRY_IMPORTS "${CLIENT_STATIC_ENTRY_IMPORTS}\n${${STATIC_ENTRY}_IMPORTS}") - set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\nconst STATIC_ENTRY CLIENT_${STATIC_ENTRY}_TABLE[] =\n{") set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\n${${STATIC_ENTRY}_TABLE}") set(CLIENT_STATIC_ENTRY_TABLES "${CLIENT_STATIC_ENTRY_TABLES}\n\t{ \"\", NULL }\n};") - set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\n\t{ \"${STATIC_ENTRY}\", CLIENT_${STATIC_ENTRY}_TABLE },") endforeach() set(CLIENT_STATIC_ENTRY_TABLES_LIST "${CLIENT_STATIC_ENTRY_TABLES_LIST}\n\t{ \"\", NULL }\n};") +set(CLIENT_STATIC_ADDIN_TABLE "const STATIC_ADDIN_TABLE CLIENT_STATIC_ADDIN_TABLE[] =\n{") +foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES}) + set(STATIC_MODULE_NAME ${${STATIC_MODULE}_CLIENT_NAME}) + set(STATIC_MODULE_CHANNEL ${${STATIC_MODULE}_CLIENT_CHANNEL}) + string(TOUPPER "CLIENT_${STATIC_MODULE_CHANNEL}_SUBSYSTEM_TABLE" SUBSYSTEM_TABLE_NAME) + set(SUBSYSTEM_TABLE "const STATIC_SUBSYSTEM_ENTRY ${SUBSYSTEM_TABLE_NAME}[] =\n{") + get_target_property(CHANNEL_SUBSYSTEMS ${STATIC_MODULE_NAME} SUBSYSTEMS) + if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND") + set(CHANNEL_SUBSYSTEMS "") + endif() + foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS}) + message(STATUS "STATIC_SUBSYSTEM: ${STATIC_SUBSYSTEM}") + string(TOUPPER "${STATIC_MODULE}_CLIENT_${STATIC_SUBSYSTEM}" SUBSYSTEM_PREFIX) + set(SUBSYSTEM_MODULE_NAME "${STATIC_MODULE_NAME}-${STATIC_SUBSYSTEM}") + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${SUBSYSTEM_MODULE_NAME}) + set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM}_freerdp_${STATIC_MODULE_CHANNEL}_client_subsystem_entry") + set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"${STATIC_SUBSYSTEM}\", \"\", ${STATIC_SUBSYSTEM_ENTRY} },") + set(SUBSYSTEM_IMPORT "extern void ${STATIC_SUBSYSTEM_ENTRY}();") + set(CLIENT_STATIC_SUBSYSTEM_IMPORTS "${CLIENT_STATIC_SUBSYSTEM_IMPORTS}\n${SUBSYSTEM_IMPORT}") + endforeach() + set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"\", \"\", NULL }\n};") + set(CLIENT_STATIC_SUBSYSTEM_TABLES "${CLIENT_STATIC_SUBSYSTEM_TABLES}\n${SUBSYSTEM_TABLE}") + set(ENTRY_POINT_NAME "${STATIC_MODULE_CHANNEL}_${${STATIC_MODULE}_CLIENT_ENTRY}") + set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ \"${STATIC_MODULE_CHANNEL}\", ${ENTRY_POINT_NAME}, ${SUBSYSTEM_TABLE_NAME} },") +endforeach() +set(CLIENT_STATIC_ADDIN_TABLE "${CLIENT_STATIC_ADDIN_TABLE}\n\t{ NULL, NULL, NULL }\n};") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tables.c.in ${CMAKE_CURRENT_SOURCE_DIR}/tables.c) set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS @@ -69,7 +89,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE winpr - MODULES winpr-crt winpr-path winpr-file winpr-synch winpr-interlocked) + MODULES winpr-crt winpr-path winpr-file winpr-synch winpr-library winpr-interlocked) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} PARENT_SCOPE) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) diff --git a/channels/client/channels.c b/channels/client/channels.c index b7fc8a860..c52dd5ab6 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #ifdef WITH_DEBUG_CHANNELS @@ -142,10 +143,59 @@ void* freerdp_channels_client_find_entry(const char* name, const char* identifie return pChannelEntry; } +extern const STATIC_ADDIN_TABLE CLIENT_STATIC_ADDIN_TABLE[]; + +FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +{ + int i, j; + DWORD nAddins; + FREERDP_ADDIN* pAddin; + FREERDP_ADDIN** ppAddins = NULL; + STATIC_SUBSYSTEM_ENTRY* subsystems; + + nAddins = 0; + ppAddins = (FREERDP_ADDIN**) malloc(sizeof(FREERDP_ADDIN*) * 128); + ppAddins[nAddins] = NULL; + + for (i = 0; CLIENT_STATIC_ADDIN_TABLE[i].name != NULL; i++) + { + pAddin = (FREERDP_ADDIN*) malloc(sizeof(FREERDP_ADDIN)); + ZeroMemory(pAddin, sizeof(FREERDP_ADDIN)); + + strcpy(pAddin->cName, CLIENT_STATIC_ADDIN_TABLE[i].name); + + pAddin->dwFlags = FREERDP_ADDIN_CLIENT; + pAddin->dwFlags |= FREERDP_ADDIN_STATIC; + pAddin->dwFlags |= FREERDP_ADDIN_NAME; + + ppAddins[nAddins++] = pAddin; + + subsystems = (STATIC_SUBSYSTEM_ENTRY*) CLIENT_STATIC_ADDIN_TABLE[i].table; + + for (j = 0; subsystems[j].name != NULL; j++) + { + pAddin = (FREERDP_ADDIN*) malloc(sizeof(FREERDP_ADDIN)); + ZeroMemory(pAddin, sizeof(FREERDP_ADDIN)); + + strcpy(pAddin->cName, CLIENT_STATIC_ADDIN_TABLE[i].name); + strcpy(pAddin->cSubsystem, subsystems[j].name); + + pAddin->dwFlags = FREERDP_ADDIN_CLIENT; + pAddin->dwFlags |= FREERDP_ADDIN_STATIC; + pAddin->dwFlags |= FREERDP_ADDIN_NAME; + pAddin->dwFlags |= FREERDP_ADDIN_SUBSYSTEM; + + ppAddins[nAddins++] = pAddin; + } + } + + return ppAddins; +} + LPCSTR gAddinPath = FREERDP_ADDIN_PATH; LPCSTR gInstallPrefix = FREERDP_INSTALL_PREFIX; -FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +FREERDP_ADDIN** freerdp_channels_list_client_dynamic_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) { int index; int nDashes; @@ -290,6 +340,16 @@ FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsys return ppAddins; } +FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +{ + if (dwFlags & FREERDP_ADDIN_STATIC) + return freerdp_channels_list_client_static_addins(lpName, lpSubsystem, lpType, dwFlags); + else if (dwFlags & FREERDP_ADDIN_DYNAMIC) + return freerdp_channels_list_client_dynamic_addins(lpName, lpSubsystem, lpType, dwFlags); + + return NULL; +} + void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins) { int index; @@ -300,6 +360,114 @@ void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins) free(ppAddins); } +void* freerdp_channels_load_dynamic_addin_entry(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +{ + LPSTR lpFileName; + LPSTR lpFilePath; + size_t cchFileName; + size_t cchFilePath; + size_t cchAddinPath; + size_t cchInstallPrefix; + LPCSTR lpExtension; + HINSTANCE library; + + cchAddinPath = strlen(gAddinPath); + cchInstallPrefix = strlen(gInstallPrefix); + + lpExtension = PathGetSharedLibraryExtensionA(0); + + if (lpName && lpSubsystem && lpType) + { + cchFileName = strlen(lpName) + strlen(lpSubsystem) + strlen(lpType) + strlen(lpExtension) + 32; + lpFileName = (LPSTR) malloc(cchFileName); + sprintf_s(lpFileName, cchFileName, "%s-client-%s-%s.%s", lpName, lpSubsystem, lpType, lpExtension); + cchFileName = strlen(lpFileName); + } + else if (lpName && lpSubsystem) + { + cchFileName = strlen(lpName) + strlen(lpSubsystem) + strlen(lpExtension) + 32; + lpFileName = (LPSTR) malloc(cchFileName); + sprintf_s(lpFileName, cchFileName, "%s-client-%s.%s", lpName, lpSubsystem, lpExtension); + cchFileName = strlen(lpFileName); + } + else if (lpName) + { + cchFileName = strlen(lpName) + strlen(lpExtension) + 32; + lpFileName = (LPSTR) malloc(cchFileName); + sprintf_s(lpFileName, cchFileName, "%s-client.%s", lpName, lpExtension); + cchFileName = strlen(lpFileName); + } + else + { + return NULL; + } + + cchFilePath = cchInstallPrefix + cchAddinPath + cchFileName + 32; + lpFilePath = (LPSTR) malloc(cchFilePath + 1); + + CopyMemory(lpFilePath, gInstallPrefix, cchInstallPrefix); + lpFilePath[cchInstallPrefix] = '\0'; + + NativePathCchAppendA(lpFilePath, cchFilePath + 1, gAddinPath); + NativePathCchAppendA(lpFilePath, cchFilePath + 1, lpFileName); + cchFilePath = strlen(lpFilePath); + + printf("lpFilePath: %s\n", lpFilePath); + + library = LoadLibraryA(lpFilePath); + + if (!library) + printf("failed to load library\n"); + + return NULL; +} + +void* freerdp_channels_load_static_addin_entry(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +{ + int i, j; + STATIC_SUBSYSTEM_ENTRY* subsystems; + + for (i = 0; CLIENT_STATIC_ADDIN_TABLE[i].name != NULL; i++) + { + if ((lpSubsystem == NULL) && (lpType == NULL)) + { + return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry; + } + + subsystems = (STATIC_SUBSYSTEM_ENTRY*) CLIENT_STATIC_ADDIN_TABLE[i].table; + + for (j = 0; subsystems[j].name != NULL; j++) + { + if (strcmp(subsystems[j].name, lpSubsystem) == 0) + { + if (lpType) + { + if (strcmp(subsystems[j].type, lpType) == 0) + return (void*) subsystems[j].entry; + } + else + { + return (void*) subsystems[j].entry; + } + } + } + } + + return NULL; +} + +void* freerdp_channels_load_addin_entry(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +{ + void* entry = NULL; + + entry = freerdp_channels_load_static_addin_entry(lpName, lpSubsystem, lpType, dwFlags); + + if (entry) + entry = freerdp_channels_load_dynamic_addin_entry(lpName, lpSubsystem, lpType, dwFlags); + + return entry; +} + struct lib_data { PVIRTUALCHANNELENTRY entry; /* the one and only exported function */ diff --git a/channels/client/tables.c.in b/channels/client/tables.c.in index 7711752b1..b656dbb9b 100644 --- a/channels/client/tables.c.in +++ b/channels/client/tables.c.in @@ -25,4 +25,9 @@ ${CLIENT_STATIC_ENTRY_TABLES} ${CLIENT_STATIC_ENTRY_TABLES_LIST} +${CLIENT_STATIC_SUBSYSTEM_IMPORTS} + +${CLIENT_STATIC_SUBSYSTEM_TABLES} + +${CLIENT_STATIC_ADDIN_TABLE} diff --git a/channels/client/tables.h b/channels/client/tables.h index ad247c61e..361aa943c 100644 --- a/channels/client/tables.h +++ b/channels/client/tables.h @@ -32,3 +32,19 @@ struct _STATIC_ENTRY_TABLE const STATIC_ENTRY* table; }; typedef struct _STATIC_ENTRY_TABLE STATIC_ENTRY_TABLE; + +struct _STATIC_SUBSYSTEM_ENTRY +{ + const char* name; + const char* type; + const void* entry; +}; +typedef struct _STATIC_SUBSYSTEM_ENTRY STATIC_SUBSYSTEM_ENTRY; + +struct _STATIC_ADDIN_TABLE +{ + const char* name; + const void* entry; + const STATIC_SUBSYSTEM_ENTRY* table; +}; +typedef struct _STATIC_ADDIN_TABLE STATIC_ADDIN_TABLE; diff --git a/channels/drive/client/CMakeLists.txt b/channels/drive/client/CMakeLists.txt index d2e41598d..3e78d10fd 100644 --- a/channels/drive/client/CMakeLists.txt +++ b/channels/drive/client/CMakeLists.txt @@ -46,7 +46,7 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) if(NOT STATIC_CHANNELS) - install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client") diff --git a/channels/rdpsnd/client/CMakeLists.txt b/channels/rdpsnd/client/CMakeLists.txt index c189c0c41..a3d888f76 100644 --- a/channels/rdpsnd/client/CMakeLists.txt +++ b/channels/rdpsnd/client/CMakeLists.txt @@ -35,14 +35,13 @@ target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client") if(WITH_ALSA) - add_subdirectory(alsa) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "") endif() if(WITH_PULSE) - add_subdirectory(pulse) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "pulse" "") endif() if(WITH_MACAUDIO) - add_subdirectory(mac) + add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "mac" "") endif() - diff --git a/channels/rdpsnd/client/alsa/CMakeLists.txt b/channels/rdpsnd/client/alsa/CMakeLists.txt index cf3575d61..e65d1dd90 100644 --- a/channels/rdpsnd/client/alsa/CMakeLists.txt +++ b/channels/rdpsnd/client/alsa/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${ALSA_INCLUDE_DIRS}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -36,4 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${ALSA_LIBRARIES}) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() diff --git a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c index 5af67ab27..9d076163d 100644 --- a/channels/rdpsnd/client/alsa/rdpsnd_alsa.c +++ b/channels/rdpsnd/client/alsa/rdpsnd_alsa.c @@ -416,7 +416,11 @@ static void rdpsnd_alsa_start(rdpsndDevicePlugin* device) snd_pcm_start(alsa->out_handle); } -int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) +#ifdef STATIC_CHANNELS +#define freerdp_rdpsnd_client_subsystem_entry alsa_freerdp_rdpsnd_client_subsystem_entry +#endif + +int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { rdpsndAlsaPlugin* alsa; RDP_PLUGIN_DATA* data; diff --git a/channels/rdpsnd/client/mac/CMakeLists.txt b/channels/rdpsnd/client/mac/CMakeLists.txt index 5791399c7..0074888f0 100644 --- a/channels/rdpsnd/client/mac/CMakeLists.txt +++ b/channels/rdpsnd/client/mac/CMakeLists.txt @@ -24,7 +24,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${MACAUDIO_INCLUDE_DIRS}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -38,5 +38,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${MAC_COREFOUNDATION_LIBRARY_ target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) - +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() diff --git a/channels/rdpsnd/client/mac/rdpsnd_mac.c b/channels/rdpsnd/client/mac/rdpsnd_mac.c index 477c90256..23f29567c 100644 --- a/channels/rdpsnd/client/mac/rdpsnd_mac.c +++ b/channels/rdpsnd/client/mac/rdpsnd_mac.c @@ -192,14 +192,16 @@ static void rdpsnd_audio_start(rdpsndDevicePlugin* device) * our job here is to fill aq_buf_ref with audio data and enqueue it */ -static void aq_playback_cb(void *user_data, - AudioQueueRef aq_ref, - AudioQueueBufferRef aq_buf_ref - ) +static void aq_playback_cb(void* user_data, AudioQueueRef aq_ref, AudioQueueBufferRef aq_buf_ref) { + } -int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) +#ifdef STATIC_CHANNELS +#define freerdp_rdpsnd_client_subsystem_entry mac_freerdp_rdpsnd_client_subsystem_entry +#endif + +int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { rdpsndAudioQPlugin* aqPlugin; RDP_PLUGIN_DATA* data; @@ -217,13 +219,15 @@ int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) data = pEntryPoints->plugin_data; - if (data && strcmp((char *)data->data[0], "macaudio") == 0) { + if (data && strcmp((char *)data->data[0], "macaudio") == 0) + { if(strlen((char *)data->data[1]) > 0) aqPlugin->device_name = strdup((char *)data->data[1]); else aqPlugin->device_name = NULL; } - pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)aqPlugin); + + pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*) aqPlugin); + return 0; } - diff --git a/channels/rdpsnd/client/pulse/CMakeLists.txt b/channels/rdpsnd/client/pulse/CMakeLists.txt index 34bcf4254..40568d6f3 100644 --- a/channels/rdpsnd/client/pulse/CMakeLists.txt +++ b/channels/rdpsnd/client/pulse/CMakeLists.txt @@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS include_directories(..) include_directories(${PULSE_INCLUDE_DIR}) -add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) +add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") @@ -36,4 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PULSE_LIBRARY}) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) -install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH}) +if(NOT STATIC_CHANNELS) + install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH}) +endif() diff --git a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c index 38461e47e..f8edb5d1e 100644 --- a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c +++ b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c @@ -523,7 +523,11 @@ static void rdpsnd_pulse_start(rdpsndDevicePlugin* device) pa_stream_trigger(pulse->stream, NULL, NULL); } -int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) +#ifdef STATIC_CHANNELS +#define freerdp_rdpsnd_client_subsystem_entry pulse_freerdp_rdpsnd_client_subsystem_entry +#endif + +int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { rdpsndPulsePlugin* pulse; RDP_PLUGIN_DATA* data; diff --git a/channels/rdpsnd/client/rdpsnd_main.h b/channels/rdpsnd/client/rdpsnd_main.h index d92bdafe3..808e322f8 100644 --- a/channels/rdpsnd/client/rdpsnd_main.h +++ b/channels/rdpsnd/client/rdpsnd_main.h @@ -47,7 +47,7 @@ struct rdpsnd_device_plugin pcFree Free; }; -#define RDPSND_DEVICE_EXPORT_FUNC_NAME "FreeRDPRdpsndDeviceEntry" +#define RDPSND_DEVICE_EXPORT_FUNC_NAME "freerdp_rdpsnd_client_subsystem_entry" typedef void (*PREGISTERRDPSNDDEVICE)(rdpsndPlugin* rdpsnd, rdpsndDevicePlugin* device); @@ -63,4 +63,3 @@ typedef FREERDP_RDPSND_DEVICE_ENTRY_POINTS* PFREERDP_RDPSND_DEVICE_ENTRY_POINTS; typedef int (*PFREERDP_RDPSND_DEVICE_ENTRY)(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints); #endif /* __RDPSND_MAIN_H */ - diff --git a/client/common/test/TestClientChannels.c b/client/common/test/TestClientChannels.c index aeddd70ce..a95de68e5 100644 --- a/client/common/test/TestClientChannels.c +++ b/client/common/test/TestClientChannels.c @@ -8,11 +8,15 @@ int TestClientChannels(int argc, char* argv[]) { int index; + void* entry; + DWORD dwFlags; FREERDP_ADDIN* pAddin; FREERDP_ADDIN** ppAddins; + dwFlags = FREERDP_ADDIN_DYNAMIC; + printf("Enumerate all\n"); - ppAddins = freerdp_channels_list_client_addins(NULL, NULL, NULL, 0); + ppAddins = freerdp_channels_list_client_addins(NULL, NULL, NULL, dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -25,7 +29,7 @@ int TestClientChannels(int argc, char* argv[]) freerdp_channels_addin_list_free(ppAddins); printf("Enumerate rdpsnd\n"); - ppAddins = freerdp_channels_list_client_addins("rdpsnd", NULL, NULL, 0); + ppAddins = freerdp_channels_list_client_addins("rdpsnd", NULL, NULL, dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -38,7 +42,7 @@ int TestClientChannels(int argc, char* argv[]) freerdp_channels_addin_list_free(ppAddins); printf("Enumerate tsmf video\n"); - ppAddins = freerdp_channels_list_client_addins("tsmf", NULL, "video", 0); + ppAddins = freerdp_channels_list_client_addins("tsmf", NULL, "video", dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -51,7 +55,7 @@ int TestClientChannels(int argc, char* argv[]) freerdp_channels_addin_list_free(ppAddins); printf("Enumerate unknown\n"); - ppAddins = freerdp_channels_list_client_addins("unknown", NULL, NULL, 0); + ppAddins = freerdp_channels_list_client_addins("unknown", NULL, NULL, dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -63,5 +67,28 @@ int TestClientChannels(int argc, char* argv[]) freerdp_channels_addin_list_free(ppAddins); + dwFlags = FREERDP_ADDIN_STATIC; + freerdp_channels_list_client_addins(NULL, NULL, NULL, dwFlags); + + for (index = 0; ppAddins[index] != NULL; index++) + { + pAddin = ppAddins[index]; + + printf("Addin: Name: %s Subsystem: %s Type: %s\n", + pAddin->cName, pAddin->cSubsystem, pAddin->cType); + } + + freerdp_channels_addin_list_free(ppAddins); + + dwFlags = FREERDP_ADDIN_STATIC; + + entry = freerdp_channels_load_addin_entry("drive", NULL, NULL, dwFlags); + + printf("drive entry: %s\n", entry ? "non-null" : "null"); + + entry = freerdp_channels_load_addin_entry("rdpsnd", "alsa", NULL, dwFlags); + + printf("rdpsnd-alsa entry: %s\n", entry ? "non-null" : "null"); + return 0; } diff --git a/include/freerdp/client/channels.h b/include/freerdp/client/channels.h index f5de353c7..d5dcaff81 100644 --- a/include/freerdp/client/channels.h +++ b/include/freerdp/client/channels.h @@ -49,5 +49,7 @@ FREERDP_API void* freerdp_channels_client_find_entry(const char* name, const cha FREERDP_API FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags); FREERDP_API void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins); +FREERDP_API void* freerdp_channels_load_addin_entry(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags); + #endif /* FREERDP_CHANNELS_CLIENT */