diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e8b28226..0e8827b45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,7 @@ if(NOT DEFINED BUILD_SHARED_LIBS) endif() if(NOT DEFINED EXPORT_ALL_SYMBOLS) - set(EXPORT_ALL_SYMBOLS FALSE) + set(EXPORT_ALL_SYMBOLS TRUE) endif() # Configure MSVC Runtime @@ -291,6 +291,8 @@ set(FREERDP_KEYMAP_PATH "${FREERDP_DATA_PATH}/keymaps") # Path to put plugins +set(FREERDP_LIBRARY_PATH "${CMAKE_INSTALL_LIBDIR}") + set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_LIBDIR}/freerdp") set(FREERDP_ADDIN_PATH "${FREERDP_PLUGIN_PATH}") diff --git a/channels/audin/client/CMakeLists.txt b/channels/audin/client/CMakeLists.txt index 54d874164..303640640 100644 --- a/channels/audin/client/CMakeLists.txt +++ b/channels/audin/client/CMakeLists.txt @@ -30,7 +30,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "") set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} MODULE freerdp - MODULES freerdp-utils) + MODULES freerdp-common freerdp-utils) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 9815a8c64..f395d9d91 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -27,7 +27,8 @@ #include #include -#include + +#include #include "audin_main.h" @@ -444,14 +445,14 @@ static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_ if (strrchr(name, '.') != NULL) { - entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_plugin(name, AUDIN_DEVICE_EXPORT_FUNC_NAME); + entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_dynamic_addin(name, NULL, AUDIN_DEVICE_EXPORT_FUNC_NAME); } else { fullname = xzalloc(strlen(name) + 8); strcpy(fullname, "audin_"); strcat(fullname, name); - entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_plugin(fullname, AUDIN_DEVICE_EXPORT_FUNC_NAME); + entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_dynamic_addin(fullname, NULL, AUDIN_DEVICE_EXPORT_FUNC_NAME); free(fullname); } diff --git a/channels/client/channels.c b/channels/client/channels.c index c43e5fd9c..c4a75b778 100644 --- a/channels/client/channels.c +++ b/channels/client/channels.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -112,40 +113,9 @@ void* freerdp_channels_client_find_static_entry(const char* name, const char* id return NULL; } -void* freerdp_channels_client_find_dynamic_entry(const char* name, const char* identifier) -{ - char* path; - void* entry; - char* module; - - module = freerdp_append_shared_library_suffix((char*) identifier); - path = freerdp_construct_path(FREERDP_PLUGIN_PATH, module); - - entry = freerdp_load_library_symbol(path, module); - - free(module); - free(path); - - return entry; -} - -void* freerdp_channels_client_find_entry(const char* name, const char* identifier) -{ - void* pChannelEntry = NULL; - - pChannelEntry = freerdp_channels_client_find_static_entry(name, identifier); - - if (!pChannelEntry) - { - pChannelEntry = freerdp_channels_client_find_dynamic_entry(name, identifier); - } - - 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) +FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags) { int i, j; DWORD nAddins; @@ -197,16 +167,16 @@ FREERDP_ADDIN** freerdp_channels_list_client_static_addins(LPSTR lpName, LPSTR l LPCSTR gAddinPath = FREERDP_ADDIN_PATH; LPCSTR gInstallPrefix = FREERDP_INSTALL_PREFIX; -FREERDP_ADDIN** freerdp_channels_list_client_dynamic_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags) { int index; int nDashes; HANDLE hFind; DWORD nAddins; - LPSTR lpPattern; + LPSTR pszPattern; size_t cchPattern; - LPCSTR lpExtension; - LPSTR lpSearchPath; + LPCSTR pszExtension; + LPSTR pszSearchPath; size_t cchSearchPath; size_t cchAddinPath; size_t cchInstallPrefix; @@ -216,42 +186,42 @@ FREERDP_ADDIN** freerdp_channels_list_client_dynamic_addins(LPSTR lpName, LPSTR cchAddinPath = strlen(gAddinPath); cchInstallPrefix = strlen(gInstallPrefix); - lpExtension = PathGetSharedLibraryExtensionA(0); + pszExtension = PathGetSharedLibraryExtensionA(0); - cchPattern = 128 + strlen(lpExtension) + 2; - lpPattern = (LPSTR) malloc(cchPattern + 1); + cchPattern = 128 + strlen(pszExtension) + 2; + pszPattern = (LPSTR) malloc(cchPattern + 1); - if (lpName && lpSubsystem && lpType) + if (pszName && pszSubsystem && pszType) { - sprintf_s(lpPattern, cchPattern, "%s-client-%s-%s.%s", lpName, lpSubsystem, lpType, lpExtension); + sprintf_s(pszPattern, cchPattern, "%s-client-%s-%s.%s", pszName, pszSubsystem, pszType, pszExtension); } - else if (lpName && lpType) + else if (pszName && pszType) { - sprintf_s(lpPattern, cchPattern, "%s-client-?-%s.%s", lpName, lpType, lpExtension); + sprintf_s(pszPattern, cchPattern, "%s-client-?-%s.%s", pszName, pszType, pszExtension); } - else if (lpName) + else if (pszName) { - sprintf_s(lpPattern, cchPattern, "%s-client*.%s", lpName, lpExtension); + sprintf_s(pszPattern, cchPattern, "%s-client*.%s", pszName, pszExtension); } else { - sprintf_s(lpPattern, cchPattern, "?-client*.%s", lpExtension); + sprintf_s(pszPattern, cchPattern, "?-client*.%s", pszExtension); } - cchPattern = strlen(lpPattern); + cchPattern = strlen(pszPattern); cchSearchPath = cchInstallPrefix + cchAddinPath + cchPattern + 3; - lpSearchPath = (LPSTR) malloc(cchSearchPath + 1); + pszSearchPath = (LPSTR) malloc(cchSearchPath + 1); - CopyMemory(lpSearchPath, gInstallPrefix, cchInstallPrefix); - lpSearchPath[cchInstallPrefix] = '\0'; + CopyMemory(pszSearchPath, gInstallPrefix, cchInstallPrefix); + pszSearchPath[cchInstallPrefix] = '\0'; - NativePathCchAppendA(lpSearchPath, cchSearchPath + 1, gAddinPath); - NativePathCchAppendA(lpSearchPath, cchSearchPath + 1, lpPattern); + NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, gAddinPath); + NativePathCchAppendA(pszSearchPath, cchSearchPath + 1, pszPattern); - cchSearchPath = strlen(lpSearchPath); + cchSearchPath = strlen(pszSearchPath); - hFind = FindFirstFileA(lpSearchPath, &FindData); + hFind = FindFirstFileA(pszSearchPath, &FindData); nAddins = 0; ppAddins = (FREERDP_ADDIN**) malloc(sizeof(FREERDP_ADDIN*) * 128); @@ -342,12 +312,12 @@ FREERDP_ADDIN** freerdp_channels_list_client_dynamic_addins(LPSTR lpName, LPSTR return ppAddins; } -FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +FREERDP_ADDIN** freerdp_channels_list_addins(LPSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags) { if (dwFlags & FREERDP_ADDIN_STATIC) - return freerdp_channels_list_client_static_addins(lpName, lpSubsystem, lpType, dwFlags); + return freerdp_channels_list_client_static_addins(pszName, pszSubsystem, pszType, dwFlags); else if (dwFlags & FREERDP_ADDIN_DYNAMIC) - return freerdp_channels_list_client_dynamic_addins(lpName, lpSubsystem, lpType, dwFlags); + return freerdp_channels_list_dynamic_addins(pszName, pszSubsystem, pszType, dwFlags); return NULL; } @@ -362,139 +332,42 @@ void freerdp_channels_addin_list_free(FREERDP_ADDIN** ppAddins) free(ppAddins); } -void* freerdp_channels_load_static_addin_entry(LPCSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) +void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, 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)) + if (pszSubsystem != NULL) { - return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry; - } + subsystems = (STATIC_SUBSYSTEM_ENTRY*) CLIENT_STATIC_ADDIN_TABLE[i].table; - 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) + for (j = 0; subsystems[j].name != NULL; j++) { - if (lpType) + if (strcmp(subsystems[j].name, pszSubsystem) == 0) { - if (strcmp(subsystems[j].type, lpType) == 0) + if (pszType) + { + if (strcmp(subsystems[j].type, pszType) == 0) + return (void*) subsystems[j].entry; + } + else + { return (void*) subsystems[j].entry; - } - else - { - return (void*) subsystems[j].entry; + } } } } + else + { + return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry; + } } return NULL; } -void* freerdp_channels_load_dynamic_addin_entry(LPCSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags) -{ - void* entry; - 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); - - library = LoadLibraryA(lpFilePath); - - if (!library) - return NULL; - - if (lpSubsystem) - { - LPSTR lpEntryName; - size_t cchEntryName; - - /* subsystem add-in */ - - cchEntryName = 64 + strlen(lpName); - lpEntryName = (LPSTR) malloc(cchEntryName + 1); - sprintf_s(lpEntryName, cchEntryName + 1, "freerdp_%s_client_subsystem_entry", lpName); - - entry = GetProcAddress(library, lpEntryName); - - if (entry) - return entry; - } - else - { - /* channel add-in */ - - entry = GetProcAddress(library, lpType); - - if (entry) - return entry; - } - - return NULL; -} - -void* freerdp_channels_load_addin_entry(LPCSTR 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 */ @@ -1168,7 +1041,7 @@ int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, c DEBUG_CHANNELS("%s", name); - entry = (PVIRTUALCHANNELENTRY) freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME); + entry = (PVIRTUALCHANNELENTRY) freerdp_load_channel_addin_entry(name, NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); if (entry == NULL) { diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index 6db0744fa..780433bb8 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -28,6 +28,8 @@ #include #include +#include + #include #include #include @@ -229,7 +231,8 @@ int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* while (data && data->size > 0) { - pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_plugin((char*) data->data[0], "DVCPluginEntry"); + pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry((char*) data->data[0], + NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); if (pDVCPluginEntry != NULL) { diff --git a/channels/rdpdr/client/devman.c b/channels/rdpdr/client/devman.c index 0f5ab9680..bd80a571f 100644 --- a/channels/rdpdr/client/devman.c +++ b/channels/rdpdr/client/devman.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -99,7 +100,8 @@ BOOL devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device) if (!ServiceName) return FALSE; - entry = (PDEVICE_SERVICE_ENTRY) freerdp_channels_client_find_static_entry("DeviceServiceEntry", ServiceName); + entry = (PDEVICE_SERVICE_ENTRY) freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0); + //entry = (PDEVICE_SERVICE_ENTRY) freerdp_channels_client_find_static_entry("DeviceServiceEntry", ServiceName); if (!entry) { diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index 3bd9b48bb..3128c0cc2 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -32,8 +32,9 @@ #include -#include #include +#include +#include #include #include #include @@ -446,26 +447,13 @@ static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlug static BOOL rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, RDP_PLUGIN_DATA* data) { - FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints; PFREERDP_RDPSND_DEVICE_ENTRY entry; - char* fullname; + FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints; + + entry = (PFREERDP_RDPSND_DEVICE_ENTRY) freerdp_load_channel_addin_entry("rdpsnd", (LPSTR) name, NULL, 0); - if (strrchr(name, '.') != NULL) - { - entry = (PFREERDP_RDPSND_DEVICE_ENTRY) freerdp_load_plugin(name, RDPSND_DEVICE_EXPORT_FUNC_NAME); - } - else - { - fullname = xzalloc(strlen(name) + 8); - strcpy(fullname, "rdpsnd-client-"); - strcat(fullname, name); - entry = (PFREERDP_RDPSND_DEVICE_ENTRY) freerdp_load_plugin(fullname, RDPSND_DEVICE_EXPORT_FUNC_NAME); - free(fullname); - } if (entry == NULL) - { return FALSE; - } entryPoints.rdpsnd = rdpsnd; entryPoints.pRegisterRdpsndDevice = rdpsnd_register_device_plugin; diff --git a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c index d085a32e7..c45989cf7 100644 --- a/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c +++ b/channels/tsmf/client/ffmpeg/tsmf_ffmpeg.c @@ -507,10 +507,9 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder) static BOOL initialized = FALSE; -ITSMFDecoder* -TSMFDecoderEntry(void) +ITSMFDecoder* TSMFDecoderEntry(void) { - TSMFFFmpegDecoder * decoder; + TSMFFFmpegDecoder* decoder; if (!initialized) { diff --git a/channels/tsmf/client/tsmf_decoder.c b/channels/tsmf/client/tsmf_decoder.c index 778420349..b9b850198 100644 --- a/channels/tsmf/client/tsmf_decoder.c +++ b/channels/tsmf/client/tsmf_decoder.c @@ -28,15 +28,17 @@ #include #include +#include + #include "tsmf_types.h" #include "tsmf_constants.h" #include "tsmf_decoder.h" static ITSMFDecoder* tsmf_load_decoder_by_name(const char* name, TS_AM_MEDIA_TYPE* media_type) { + char* fullname; ITSMFDecoder* decoder; TSMF_DECODER_ENTRY entry; - char* fullname; if (strrchr(name, '.') != NULL) entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(name, TSMF_DECODER_EXPORT_FUNC_NAME); @@ -48,22 +50,24 @@ static ITSMFDecoder* tsmf_load_decoder_by_name(const char* name, TS_AM_MEDIA_TYP entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(fullname, TSMF_DECODER_EXPORT_FUNC_NAME); free(fullname); } + if (entry == NULL) - { return NULL; - } decoder = entry(); + if (decoder == NULL) { DEBUG_WARN("failed to call export function in %s", name); return NULL; } + if (!decoder->SetFormat(decoder, media_type)) { decoder->Free(decoder); decoder = NULL; } + return decoder; } diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index 9588318ad..879a0b6d6 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -792,6 +792,8 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine data = (thread_data*) xzalloc(sizeof(thread_data)); data->instance = instance; + freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); + if (freerdp_detect_new_command_line_syntax(__argc, __argv)) { printf("Using new command-line syntax\n"); diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 44e65063f..bfe53a562 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -402,6 +403,8 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; + freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); + flags = COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_SIGIL_PLUS_MINUS; status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings, @@ -763,7 +766,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) if (settings->DeviceRedirection) { - entry = freerdp_channels_client_find_entry("VirtualChannelEntry", "rdpdr"); + entry = freerdp_load_channel_addin_entry("rdpdr", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); if (entry) { diff --git a/client/common/test/TestClientChannels.c b/client/common/test/TestClientChannels.c index 3793879fe..e0a13688c 100644 --- a/client/common/test/TestClientChannels.c +++ b/client/common/test/TestClientChannels.c @@ -8,7 +8,6 @@ int TestClientChannels(int argc, char* argv[]) { int index; - void* entry; DWORD dwFlags; FREERDP_ADDIN* pAddin; FREERDP_ADDIN** ppAddins; @@ -16,7 +15,7 @@ int TestClientChannels(int argc, char* argv[]) dwFlags = FREERDP_ADDIN_DYNAMIC; printf("Enumerate all\n"); - ppAddins = freerdp_channels_list_client_addins(NULL, NULL, NULL, dwFlags); + ppAddins = freerdp_channels_list_addins(NULL, NULL, NULL, dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -29,7 +28,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, dwFlags); + ppAddins = freerdp_channels_list_addins("rdpsnd", NULL, NULL, dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -42,7 +41,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", dwFlags); + ppAddins = freerdp_channels_list_addins("tsmf", NULL, "video", dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -54,7 +53,7 @@ int TestClientChannels(int argc, char* argv[]) freerdp_channels_addin_list_free(ppAddins); - ppAddins = freerdp_channels_list_client_addins("unknown", NULL, NULL, dwFlags); + ppAddins = freerdp_channels_list_addins("unknown", NULL, NULL, dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -69,7 +68,7 @@ int TestClientChannels(int argc, char* argv[]) printf("Enumerate static addins\n"); dwFlags = FREERDP_ADDIN_STATIC; - ppAddins = freerdp_channels_list_client_addins(NULL, NULL, NULL, dwFlags); + ppAddins = freerdp_channels_list_addins(NULL, NULL, NULL, dwFlags); for (index = 0; ppAddins[index] != NULL; index++) { @@ -81,15 +80,5 @@ int TestClientChannels(int argc, char* argv[]) freerdp_channels_addin_list_free(ppAddins); - dwFlags = FREERDP_ADDIN_DYNAMIC; - - entry = freerdp_channels_load_addin_entry("drive", NULL, "DeviceServiceEntry", 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/config.h.in b/config.h.in index abd5ffba8..c5c3f2ea7 100644 --- a/config.h.in +++ b/config.h.in @@ -15,6 +15,8 @@ #define FREERDP_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" +#define FREERDP_LIBRARY_PATH "${FREERDP_LIBRARY_PATH}" + #define FREERDP_ADDIN_PATH "${FREERDP_ADDIN_PATH}" /* Include files */ diff --git a/include/freerdp/addin.h b/include/freerdp/addin.h new file mode 100644 index 000000000..8a3dcdc63 --- /dev/null +++ b/include/freerdp/addin.h @@ -0,0 +1,61 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Addin Loader + * + * 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. + */ + +#ifndef FREERDP_COMMON_ADDIN_H +#define FREERDP_COMMON_ADDIN_H + +#include +#include + +#define FREERDP_ADDIN_CLIENT 0x00000001 +#define FREERDP_ADDIN_SERVER 0x00000002 + +#define FREERDP_ADDIN_STATIC 0x00000010 +#define FREERDP_ADDIN_DYNAMIC 0x00000020 + +#define FREERDP_ADDIN_NAME 0x00000100 +#define FREERDP_ADDIN_SUBSYSTEM 0x00000200 +#define FREERDP_ADDIN_TYPE 0x00000400 + +#define FREERDP_ADDIN_CHANNEL_STATIC 0x00001000 +#define FREERDP_ADDIN_CHANNEL_DYNAMIC 0x00002000 +#define FREERDP_ADDIN_CHANNEL_DEVICE 0x00004000 + +struct _FREERDP_ADDIN +{ + DWORD dwFlags; + CHAR cName[16]; + CHAR cType[16]; + CHAR cSubsystem[16]; +}; +typedef struct _FREERDP_ADDIN FREERDP_ADDIN; + +typedef void* (*FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN)(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags); + +FREERDP_API LPSTR freerdp_get_library_install_path(); +FREERDP_API LPSTR freerdp_get_dynamic_addin_install_path(); + +FREERDP_API int freerdp_register_addin_provider(FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN provider, DWORD dwFlags); + +FREERDP_API void* freerdp_load_dynamic_addin(LPCSTR pszFileName, LPCSTR pszPath, LPCSTR pszEntryName); +FREERDP_API void* freerdp_load_dynamic_channel_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags); +FREERDP_API void* freerdp_load_channel_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags); + +#endif /* FREERDP_COMMON_ADDIN_H */ + diff --git a/include/freerdp/client/channels.h b/include/freerdp/client/channels.h index 6be6160db..27a051308 100644 --- a/include/freerdp/client/channels.h +++ b/include/freerdp/client/channels.h @@ -21,35 +21,14 @@ #define FREERDP_CHANNELS_CLIENT #include +#include #include -#define FREERDP_ADDIN_CLIENT 0x00000001 -#define FREERDP_ADDIN_SERVER 0x00000002 - -#define FREERDP_ADDIN_STATIC 0x00000010 -#define FREERDP_ADDIN_DYNAMIC 0x00000020 - -#define FREERDP_ADDIN_NAME 0x00000100 -#define FREERDP_ADDIN_SUBSYSTEM 0x00000200 -#define FREERDP_ADDIN_TYPE 0x00000400 - -struct _FREERDP_ADDIN -{ - DWORD dwFlags; - CHAR cName[16]; - CHAR cType[16]; - CHAR cSubsystem[16]; -}; -typedef struct _FREERDP_ADDIN FREERDP_ADDIN; - FREERDP_API void* freerdp_channels_client_find_static_entry(const char* name, const char* identifier); -FREERDP_API void* freerdp_channels_client_find_dynamic_entry(const char* name, const char* identifier); -FREERDP_API void* freerdp_channels_client_find_entry(const char* name, const char* identifier); +FREERDP_API void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags); -FREERDP_API FREERDP_ADDIN** freerdp_channels_list_client_addins(LPSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags); +FREERDP_API FREERDP_ADDIN** freerdp_channels_list_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(LPCSTR lpName, LPSTR lpSubsystem, LPSTR lpType, DWORD dwFlags); - #endif /* FREERDP_CHANNELS_CLIENT */ diff --git a/include/freerdp/utils/load_plugin.h b/include/freerdp/utils/load_plugin.h index 0cd24a149..d74f016e8 100644 --- a/include/freerdp/utils/load_plugin.h +++ b/include/freerdp/utils/load_plugin.h @@ -23,13 +23,8 @@ #include #include -FREERDP_API void* freerdp_open_library(const char* file); -FREERDP_API void* freerdp_get_library_symbol(void* library, const char* name); -FREERDP_API BOOL freerdp_close_library(void* library); FREERDP_API void* freerdp_load_library_symbol(const char* file, const char* name); FREERDP_API void* freerdp_load_plugin(const char* name, const char* entry_name); FREERDP_API void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const char* entry_name); -FREERDP_API BOOL freerdp_register_static_plugin(const char* name, const char* entry_name, void* entry_addr); -FREERDP_API void* freerdp_load_static_plugin(const char* name, const char* entry_name); #endif /* __LOAD_PLUGIN_UTILS_H */ diff --git a/libfreerdp/CMakeLists.txt b/libfreerdp/CMakeLists.txt index 05af04e49..0f8cde408 100644 --- a/libfreerdp/CMakeLists.txt +++ b/libfreerdp/CMakeLists.txt @@ -24,6 +24,7 @@ endif() set(${MODULE_PREFIX}_SUBMODULES utils + common gdi rail cache @@ -54,3 +55,4 @@ if(MONOLITHIC_BUILD) set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp") endif() + diff --git a/libfreerdp/common/CMakeLists.txt b/libfreerdp/common/CMakeLists.txt new file mode 100644 index 000000000..d98282920 --- /dev/null +++ b/libfreerdp/common/CMakeLists.txt @@ -0,0 +1,41 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# libfreerdp-common cmake build script +# +# 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. + +set(MODULE_NAME "freerdp-common") +set(MODULE_PREFIX "FREERDP_COMMON") + +set(${MODULE_PREFIX}_SRCS + addin.c) + +add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" + MONOLITHIC ${MONOLITHIC_BUILD} + SOURCES ${${MODULE_PREFIX}_SRCS}) + +set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-crt winpr-path winpr-file winpr-utils) + +if(MONOLITHIC_BUILD) + set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) +else() + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp") diff --git a/libfreerdp/common/addin.c b/libfreerdp/common/addin.c new file mode 100644 index 000000000..3b4a771fc --- /dev/null +++ b/libfreerdp/common/addin.c @@ -0,0 +1,237 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Addin Loader + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include + +#include + +LPCSTR gAddinPath = FREERDP_ADDIN_PATH; +LPCSTR gLibraryPath = FREERDP_LIBRARY_PATH; +LPCSTR gInstallPrefix = FREERDP_INSTALL_PREFIX; + +LPSTR freerdp_get_library_install_path() +{ + LPSTR pszPath; + size_t cchPath; + size_t cchLibraryPath; + size_t cchInstallPrefix; + + cchLibraryPath = strlen(gLibraryPath); + cchInstallPrefix = strlen(gInstallPrefix); + + cchPath = cchInstallPrefix + cchLibraryPath + 2; + pszPath = (LPSTR) malloc(cchPath + 1); + + CopyMemory(pszPath, gInstallPrefix, cchInstallPrefix); + pszPath[cchInstallPrefix] = '\0'; + + NativePathCchAppendA(pszPath, cchPath + 1, gLibraryPath); + + return pszPath; +} + +LPSTR freerdp_get_dynamic_addin_install_path() +{ + LPSTR pszPath; + size_t cchPath; + size_t cchAddinPath; + size_t cchInstallPrefix; + + cchAddinPath = strlen(gAddinPath); + cchInstallPrefix = strlen(gInstallPrefix); + + cchPath = cchInstallPrefix + cchAddinPath + 2; + pszPath = (LPSTR) malloc(cchPath + 1); + + CopyMemory(pszPath, gInstallPrefix, cchInstallPrefix); + pszPath[cchInstallPrefix] = '\0'; + + NativePathCchAppendA(pszPath, cchPath + 1, gAddinPath); + + return pszPath; +} + +void* freerdp_load_dynamic_addin(LPCSTR pszFileName, LPCSTR pszPath, LPCSTR pszEntryName) +{ + void* entry; + BOOL bHasExt; + PCSTR pszExt; + size_t cchExt; + HINSTANCE library; + size_t cchFileName; + LPSTR pszFilePath; + size_t cchFilePath; + LPSTR pszAddinFile; + size_t cchAddinFile; + LPSTR pszAddinInstallPath; + size_t cchAddinInstallPath; + + entry = NULL; + cchExt = 0; + bHasExt = TRUE; + cchFileName = strlen(pszFileName); + + if (PathCchFindExtensionA(pszFileName, cchFileName + 1, &pszExt) != S_OK) + { + pszExt = PathGetSharedLibraryExtensionA(PATH_SHARED_LIB_EXT_WITH_DOT); + cchExt = strlen(pszExt); + bHasExt = FALSE; + } + + pszAddinInstallPath = freerdp_get_dynamic_addin_install_path(); + cchAddinInstallPath = strlen(pszAddinInstallPath); + + cchFilePath = cchAddinInstallPath + cchFileName + 32; + pszFilePath = (LPSTR) malloc(cchFilePath + 1); + + if (bHasExt) + { + pszAddinFile = _strdup(pszFileName); + cchAddinFile = strlen(pszAddinFile); + } + else + { + cchAddinFile = cchFileName + cchExt + 2; + pszAddinFile = (LPSTR) malloc(cchAddinFile + 1); + sprintf_s(pszAddinFile, cchAddinFile, "%s%s", pszFileName, pszExt); + cchAddinFile = strlen(pszAddinFile); + } + + CopyMemory(pszFilePath, pszAddinInstallPath, cchAddinInstallPath); + pszFilePath[cchAddinInstallPath] = '\0'; + + NativePathCchAppendA((LPSTR) pszFilePath, cchFilePath + 1, pszAddinFile); + + library = LoadLibraryA(pszFilePath); + + if (!library) + return NULL; + + entry = GetProcAddress(library, pszEntryName); + + if (entry) + return entry; + + free(pszAddinInstallPath); + free(pszAddinFile); + + return entry; +} + +void* freerdp_load_dynamic_channel_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags) +{ + void* entry; + LPSTR pszFileName; + size_t cchFileName; + LPCSTR pszExtension; + + pszExtension = PathGetSharedLibraryExtensionA(0); + + if (pszName && pszSubsystem && pszType) + { + cchFileName = strlen(pszName) + strlen(pszSubsystem) + strlen(pszType) + strlen(pszExtension) + 32; + pszFileName = (LPSTR) malloc(cchFileName); + sprintf_s(pszFileName, cchFileName, "%s-client-%s-%s.%s", pszName, pszSubsystem, pszType, pszExtension); + cchFileName = strlen(pszFileName); + } + else if (pszName && pszSubsystem) + { + cchFileName = strlen(pszName) + strlen(pszSubsystem) + strlen(pszExtension) + 32; + pszFileName = (LPSTR) malloc(cchFileName); + sprintf_s(pszFileName, cchFileName, "%s-client-%s.%s", pszName, pszSubsystem, pszExtension); + cchFileName = strlen(pszFileName); + } + else if (pszName) + { + cchFileName = strlen(pszName) + strlen(pszExtension) + 32; + pszFileName = (LPSTR) malloc(cchFileName); + sprintf_s(pszFileName, cchFileName, "%s-client.%s", pszName, pszExtension); + cchFileName = strlen(pszFileName); + } + else + { + return NULL; + } + + if (pszSubsystem) + { + LPSTR pszEntryName; + size_t cchEntryName; + + /* subsystem add-in */ + + cchEntryName = 64 + strlen(pszName); + pszEntryName = (LPSTR) malloc(cchEntryName + 1); + sprintf_s(pszEntryName, cchEntryName + 1, "freerdp_%s_client_subsystem_entry", pszName); + + entry = freerdp_load_dynamic_addin(pszFileName, NULL, pszEntryName); + + if (entry) + return entry; + } + else + { + /* channel add-in */ + + if (dwFlags & FREERDP_ADDIN_CHANNEL_STATIC) + entry = freerdp_load_dynamic_addin(pszFileName, NULL, "VirtualChannelEntry"); + else if (dwFlags & FREERDP_ADDIN_CHANNEL_DYNAMIC) + entry = freerdp_load_dynamic_addin(pszFileName, NULL, "DVCPluginEntry"); + else if (dwFlags & FREERDP_ADDIN_CHANNEL_DEVICE) + entry = freerdp_load_dynamic_addin(pszFileName, NULL, "DeviceServiceEntry"); + else + entry = freerdp_load_dynamic_addin(pszFileName, NULL, pszType); + + if (entry) + return entry; + } + + return NULL; +} + +static FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN freerdp_load_static_channel_addin_entry = NULL; + +int freerdp_register_addin_provider(FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN provider, DWORD dwFlags) +{ + freerdp_load_static_channel_addin_entry = provider; + return 0; +} + +void* freerdp_load_channel_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags) +{ + void* entry = NULL; + + if (freerdp_load_static_channel_addin_entry) + entry = freerdp_load_static_channel_addin_entry(pszName, pszSubsystem, pszType, dwFlags); + + if (!entry) + entry = freerdp_load_dynamic_channel_addin_entry(pszName, pszSubsystem, pszType, dwFlags); + + return entry; +} diff --git a/libfreerdp/utils/load_plugin.c b/libfreerdp/utils/load_plugin.c index be5b958e5..a986faa68 100644 --- a/libfreerdp/utils/load_plugin.c +++ b/libfreerdp/utils/load_plugin.c @@ -28,6 +28,8 @@ #include #include +#include + #include #include #include @@ -61,9 +63,6 @@ struct static_plugin }; typedef struct static_plugin staticPlugin; -static staticPlugin g_static_plugins[MAX_STATIC_PLUGINS]; -static int g_static_plugins_count; - /** * This function will load the specified library, retrieve the specified symbol in it, and return a pointer to it. * It is used in freerdp_load_plugin() and freerdp_load_channel_plugin(). @@ -112,16 +111,11 @@ void* freerdp_load_library_symbol(const char* file, const char* name) */ void* freerdp_load_plugin(const char* name, const char* entry_name) { +#if 0 char* path; void* entry; char* suffixed_name; - /* first attempt to load a static plugin */ - entry = freerdp_load_static_plugin(name, entry_name); - - if (entry != NULL) - return entry; - suffixed_name = freerdp_append_shared_library_suffix((char*) name); if (!freerdp_path_contains_separator(suffixed_name)) @@ -147,59 +141,7 @@ void* freerdp_load_plugin(const char* name, const char* entry_name) } return entry; +#endif + return freerdp_load_dynamic_addin(name, NULL, entry_name); } -/** - * This function is used to register a static plugin so that it can be loaded later on using freerdp_load_plugin. - * - * @param name [IN] - name of the library to load - * @param entry_name [IN] - name of the symbol to register for later loading - * @param entry [IN] - function pointer to the entry function - * - * @return TRUE on success, otherwise FALSE. - */ -BOOL freerdp_register_static_plugin(const char* name, const char* entry_name, void* entry_addr) -{ - staticPlugin* plugin; - - if (g_static_plugins_count >= MAX_STATIC_PLUGINS) - { - printf("freerdp_register_static_plugin: cannot register %s/%s", name, entry_name); - return FALSE; - } - - /* add the static plugin to the vector */ - plugin = &g_static_plugins[g_static_plugins_count++]; - plugin->name = name; - plugin->entry_name = entry_name; - plugin->entry_addr = entry_addr; - - return TRUE; -} - -/** - * This is a helper function, used by freerdp_load_plugin to return a function pointer from the static plugin table - * - * @param name [IN] - name of the library to load - * @param entry_name [IN] - name of the symbol to register for later loading - * - * @return Pointer to the entry function, NULL if no matching plugin could be found - */ - -void* freerdp_load_static_plugin(const char* name, const char* entry_name) -{ - int i; - staticPlugin* plugin; - - for (i = 0; i < g_static_plugins_count; i++) - { - plugin = &g_static_plugins[i]; - - if (!strcmp(plugin->name, name) && !strcmp(plugin->entry_name, entry_name)) - { - return plugin->entry_addr; - } - } - - return NULL; -} diff --git a/winpr/libwinpr/library/library.c b/winpr/libwinpr/library/library.c index 424e6d2cc..0706367e8 100644 --- a/winpr/libwinpr/library/library.c +++ b/winpr/libwinpr/library/library.c @@ -87,7 +87,7 @@ HMODULE LoadLibraryA(LPCSTR lpLibFileName) if (library == NULL) { - printf("LoadLibraryA: failed to open %s: %s\n", lpLibFileName, dlerror()); + printf("LoadLibraryA: %s\n", dlerror()); return NULL; } diff --git a/winpr/libwinpr/path/path.c b/winpr/libwinpr/path/path.c index e86cf4eaa..3da6cdcda 100644 --- a/winpr/libwinpr/path/path.c +++ b/winpr/libwinpr/path/path.c @@ -491,7 +491,33 @@ HRESULT PathCchCombineExW(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, HRESULT PathCchFindExtensionA(PCSTR pszPath, size_t cchPath, PCSTR* ppszExt) { - return 0; + char* p = (char*) pszPath; + + /* find end of string */ + + while (*p && cchPath) + { + cchPath--; + p++; + } + + /* search backwards for '.' */ + + while (p > pszPath) + { + if (*p == '.') + { + *ppszExt = (PCSTR) p; + return S_OK; + } + + if ((*p == '\\') || (*p == '/') || (*p == ':')) + return S_FALSE; + + p--; + } + + return S_FALSE; } HRESULT PathCchFindExtensionW(PCWSTR pszPath, size_t cchPath, PCWSTR* ppszExt) diff --git a/winpr/libwinpr/path/test/TestPathCchFindExtension.c b/winpr/libwinpr/path/test/TestPathCchFindExtension.c index 35ce6b576..7a6ddbe84 100644 --- a/winpr/libwinpr/path/test/TestPathCchFindExtension.c +++ b/winpr/libwinpr/path/test/TestPathCchFindExtension.c @@ -5,8 +5,20 @@ #include #include +static const char testPathExtension[] = "C:\\Windows\\System32\\cmd.exe"; + int TestPathCchFindExtension(int argc, char* argv[]) { + PCSTR pszExt; + + if (PathCchFindExtensionA(testPathExtension, sizeof(testPathExtension), &pszExt) != S_OK) + { + printf("PathCchFindExtensionA failure: expected S_OK\n"); + return -1; + } + + printf("Extension: %s\n", pszExt); + return 0; }