libfreerdp-common: refactoring of addin loader

This commit is contained in:
Marc-André Moreau 2012-11-17 22:03:04 -05:00
parent d478950abd
commit 925eb59bf1
23 changed files with 476 additions and 313 deletions

View File

@ -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}")

View File

@ -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})

View File

@ -27,7 +27,8 @@
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/addin.h>
#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);
}

View File

@ -34,6 +34,7 @@
#include <freerdp/client/channels.h>
#include <freerdp/channels/channels.h>
#include <freerdp/svc.h>
#include <freerdp/addin.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/wait_obj.h>
#include <freerdp/utils/load_plugin.h>
@ -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)
{

View File

@ -28,6 +28,8 @@
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <freerdp/addin.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
@ -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)
{

View File

@ -29,6 +29,7 @@
#include <winpr/crt.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/svc_plugin.h>
@ -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)
{

View File

@ -32,8 +32,9 @@
#include <winpr/crt.h>
#include <freerdp/constants.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/list.h>
@ -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;

View File

@ -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)
{

View File

@ -28,15 +28,17 @@
#include <freerdp/utils/memory.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/client/channels.h>
#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;
}

View File

@ -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");

View File

@ -24,6 +24,7 @@
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <freerdp/addin.h>
#include <freerdp/settings.h>
#include <freerdp/client/channels.h>
@ -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)
{

View File

@ -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;
}

View File

@ -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 */

61
include/freerdp/addin.h Normal file
View File

@ -0,0 +1,61 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Addin Loader
*
* 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_COMMON_ADDIN_H
#define FREERDP_COMMON_ADDIN_H
#include <freerdp/api.h>
#include <freerdp/types.h>
#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 */

View File

@ -21,35 +21,14 @@
#define FREERDP_CHANNELS_CLIENT
#include <freerdp/api.h>
#include <freerdp/addin.h>
#include <freerdp/channels/channels.h>
#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 */

View File

@ -23,13 +23,8 @@
#include <freerdp/api.h>
#include <freerdp/settings.h>
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 */

View File

@ -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()

View File

@ -0,0 +1,41 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# libfreerdp-common cmake build script
#
# 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.
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")

237
libfreerdp/common/addin.c Normal file
View File

@ -0,0 +1,237 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Addin Loader
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <winpr/path.h>
#include <winpr/library.h>
#include <freerdp/addin.h>
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;
}

View File

@ -28,6 +28,8 @@
#include <winpr/crt.h>
#include <winpr/windows.h>
#include <freerdp/addin.h>
#include <freerdp/utils/file.h>
#include <freerdp/utils/print.h>
#include <freerdp/utils/memory.h>
@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -5,8 +5,20 @@
#include <winpr/tchar.h>
#include <winpr/winpr.h>
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;
}