libfreerdp-core: started porting extension plugin interface

This commit is contained in:
Marc-André Moreau 2011-11-09 15:33:58 -05:00
parent c8735d720e
commit 0043b16472
4 changed files with 260 additions and 3 deletions

View File

@ -20,14 +20,14 @@
#ifndef __RDP_EXTENSION_H
#define __RDP_EXTENSION_H
#include <freerdp/freerdp.h>
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/freerdp.h>
/* Extensions ought to check for it to ensure compatibility */
#define RDPEXT_API 1
#define FREERDP_EXT_API 1
#define RDPEXT_EXPORT_FUNC_NAME "FreeRDPExtensionEntry"
#define FREERDP_EXT_EXPORT_FUNC_NAME "FreeRDPExtensionEntry"
typedef struct rdp_ext_plugin rdpExtPlugin;
@ -52,6 +52,7 @@ struct _FREERDP_EXTENSION_ENTRY_POINTS
PREGISTERPOSTCONNECTHOOK pRegisterPostConnectHook;
void* data;
};
typedef struct _FREERDP_EXTENSION_ENTRY_POINTS FREERDP_EXTENSION_ENTRY_POINTS;
typedef FREERDP_EXTENSION_ENTRY_POINTS* PFREERDP_EXTENSION_ENTRY_POINTS;

View File

@ -24,6 +24,8 @@ include_directories(${ZLIB_INCLUDE_DIRS})
set(LIBFREERDP_CORE_SRCS
activation.c
activation.h
extension.c
extension.h
ber.c
ber.h
gcc.c

202
libfreerdp-core/extension.c Normal file
View File

@ -0,0 +1,202 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Extension Plugin Interface
*
* Copyright 2010-2011 Vic Lee
* Copyright 2011 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/memory.h>
#include "rdp.h"
#include "extension.h"
#ifdef _WIN32
#define DLOPEN(f) LoadLibraryA(f)
#define DLSYM(f, n) GetProcAddress(f, n)
#define DLCLOSE(f) FreeLibrary(f)
#define PATH_SEPARATOR '\\'
#define PLUGIN_EXT "dll"
#else
#include <dlfcn.h>
#define DLOPEN(f) dlopen(f, RTLD_LOCAL | RTLD_LAZY)
#define DLSYM(f, n) dlsym(f, n)
#define DLCLOSE(f) dlclose(f)
#define PATH_SEPARATOR '/'
#define PLUGIN_EXT "so"
#endif
static uint32 FREERDP_CC freerdp_ext_register_extension(rdpExtPlugin* plugin)
{
rdpExt* ext = (rdpExt*) plugin->ext;
if (ext->num_plugins >= FREERDP_EXT_MAX_COUNT)
{
printf("freerdp_ext_register_extension: maximum number of plugins reached.\n");
return 1;
}
ext->plugins[ext->num_plugins++] = plugin;
return 0;
}
static uint32 FREERDP_CC freerdp_ext_register_pre_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook)
{
rdpExt* ext = (rdpExt*) plugin->ext;
if (ext->num_pre_connect_hooks >= FREERDP_EXT_MAX_COUNT)
{
printf("freerdp_ext_register_pre_connect_hook: maximum plugin reached.\n");
return 1;
}
ext->pre_connect_hooks[ext->num_pre_connect_hooks] = hook;
ext->pre_connect_hooks_instances[ext->num_pre_connect_hooks] = plugin;
ext->num_pre_connect_hooks++;
return 0;
}
static uint32 FREERDP_CC freerdp_ext_register_post_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook)
{
rdpExt* ext = (rdpExt*) plugin->ext;
if (ext->num_post_connect_hooks >= FREERDP_EXT_MAX_COUNT)
{
printf("freerdp_ext_register_post_connect_hook: maximum plugin reached.\n");
return 1;
}
ext->post_connect_hooks[ext->num_post_connect_hooks] = hook;
ext->post_connect_hooks_instances[ext->num_post_connect_hooks] = plugin;
ext->num_post_connect_hooks++;
return 0;
}
static int freerdp_ext_load_plugins(rdpExt* ext)
{
int i;
void* han;
char path[256];
rdpSettings* settings;
PFREERDP_EXTENSION_ENTRY entry;
FREERDP_EXTENSION_ENTRY_POINTS entryPoints;
settings = ext->instance->settings;
entryPoints.ext = ext;
entryPoints.pRegisterExtension = freerdp_ext_register_extension;
entryPoints.pRegisterPreConnectHook = freerdp_ext_register_pre_connect_hook;
entryPoints.pRegisterPostConnectHook = freerdp_ext_register_post_connect_hook;
for (i = 0; settings->extensions[i].name[0]; i++)
{
if (strchr(settings->extensions[i].name, PATH_SEPARATOR) == NULL)
snprintf(path, sizeof(path), EXT_PATH "/%s." PLUGIN_EXT, settings->extensions[i].name);
else
snprintf(path, sizeof(path), "%s", settings->extensions[i].name);
han = DLOPEN(path);
printf("freerdp_ext_load_plugins: %s\n", path);
if (han == NULL)
{
printf("freerdp_ext_load_plugins: failed to load %s\n", path);
continue;
}
entry = (PFREERDP_EXTENSION_ENTRY) DLSYM(han, FREERDP_EXT_EXPORT_FUNC_NAME);
if (entry == NULL)
{
DLCLOSE(han);
printf("freerdp_ext_load_plugins: failed to find export function in %s\n", path);
continue;
}
entryPoints.data = ext->instance->settings->extensions[i].data;
if (entry(&entryPoints) != 0)
{
DLCLOSE(han);
printf("freerdp_ext_load_plugins: %s entry returns error.\n", path);
continue;
}
}
return 0;
}
static int freerdp_ext_call_init(rdpExt* ext)
{
int i;
for (i = 0; i < ext->num_plugins; i++)
ext->plugins[i]->init(ext->plugins[i], ext->instance);
return 0;
}
static int freerdp_ext_call_uninit(rdpExt* ext)
{
int i;
for (i = 0; i < ext->num_plugins; i++)
ext->plugins[i]->uninit(ext->plugins[i], ext->instance);
return 0;
}
int freerdp_ext_pre_connect(rdpExt* ext)
{
int i;
for (i = 0; i < ext->num_pre_connect_hooks; i++)
ext->pre_connect_hooks[i](ext->pre_connect_hooks_instances[i], ext->instance);
return 0;
}
int freerdp_ext_post_connect(rdpExt* ext)
{
int i;
for (i = 0; i < ext->num_post_connect_hooks; i++)
ext->post_connect_hooks[i](ext->post_connect_hooks_instances[i], ext->instance);
return 0;
}
rdpExt* freerdp_ext_new(rdpRdp* rdp)
{
rdpExt* ext;
ext = xnew(rdpExt);
ext->instance = rdp->instance;
freerdp_ext_load_plugins(ext);
freerdp_ext_call_init(ext);
return ext;
}
void freerdp_ext_free(rdpExt* ext)
{
freerdp_ext_call_uninit(ext);
xfree(ext);
}

View File

@ -0,0 +1,52 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Extension Plugin Interface
*
* Copyright 2010-2011 Vic Lee
* Copyright 2011 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 __EXTENSION_H
#define __EXTENSION_H
#include <freerdp/freerdp.h>
#include <freerdp/extension.h>
#include "rdp.h"
#define FREERDP_EXT_MAX_COUNT 16
struct rdp_ext
{
freerdp* instance;
rdpExtPlugin* plugins[FREERDP_EXT_MAX_COUNT];
int num_plugins;
PFREERDP_EXTENSION_HOOK pre_connect_hooks[FREERDP_EXT_MAX_COUNT];
rdpExtPlugin* pre_connect_hooks_instances[FREERDP_EXT_MAX_COUNT];
int num_pre_connect_hooks;
PFREERDP_EXTENSION_HOOK post_connect_hooks[FREERDP_EXT_MAX_COUNT];
rdpExtPlugin* post_connect_hooks_instances[FREERDP_EXT_MAX_COUNT];
int num_post_connect_hooks;
};
typedef struct rdp_ext rdpExt;
int freerdp_ext_pre_connect(rdpExt* ext);
int freerdp_ext_post_connect(rdpExt* ext);
rdpExt* freerdp_ext_new(rdpRdp* rdp);
void freerdp_ext_free(rdpExt* ext);
#endif /* __EXTENSION_H */