2
* FreeRDP: A Remote Desktop Protocol Implementation
3
* FreeRDP Extension Plugin Interface
5
* Copyright 2010-2011 Vic Lee
6
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
8
* Licensed under the Apache License, Version 2.0 (the "License");
9
* you may not use this file except in compliance with the License.
10
* You may obtain a copy of the License at
12
* http://www.apache.org/licenses/LICENSE-2.0
14
* Unless required by applicable law or agreed to in writing, software
15
* distributed under the License is distributed on an "AS IS" BASIS,
16
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
* See the License for the specific language governing permissions and
18
* limitations under the License.
29
#include <winpr/crt.h>
31
#include <freerdp/freerdp.h>
33
#include "extension.h"
36
#define DLOPEN(f) LoadLibraryA(f)
37
#define DLSYM(f, n) GetProcAddress(f, n)
38
#define DLCLOSE(f) FreeLibrary(f)
39
#define PATH_SEPARATOR '\\'
40
#define PLUGIN_EXT "dll"
43
#define DLOPEN(f) dlopen(f, RTLD_LOCAL | RTLD_LAZY)
44
#define DLSYM(f, n) dlsym(f, n)
45
#define DLCLOSE(f) dlclose(f)
46
#define PATH_SEPARATOR '/'
49
#define PLUGIN_EXT "dylib"
51
#define PLUGIN_EXT "so"
56
static UINT32 FREERDP_CC extension_register_plugin(rdpExtPlugin* plugin)
58
rdpExtension* ext = (rdpExtension*) plugin->ext;
60
if (ext->num_plugins >= FREERDP_EXT_MAX_COUNT)
62
fprintf(stderr, "extension_register_extension: maximum number of plugins reached.\n");
66
ext->plugins[ext->num_plugins++] = plugin;
70
static UINT32 FREERDP_CC extension_register_pre_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook)
72
rdpExtension* ext = (rdpExtension*) plugin->ext;
74
if (ext->num_pre_connect_hooks >= FREERDP_EXT_MAX_COUNT)
76
fprintf(stderr, "extension_register_pre_connect_hook: maximum plugin reached.\n");
80
ext->pre_connect_hooks[ext->num_pre_connect_hooks] = hook;
81
ext->pre_connect_hooks_instances[ext->num_pre_connect_hooks] = plugin;
82
ext->num_pre_connect_hooks++;
86
static UINT32 FREERDP_CC extension_register_post_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook)
88
rdpExtension* ext = (rdpExtension*) plugin->ext;
90
if (ext->num_post_connect_hooks >= FREERDP_EXT_MAX_COUNT)
92
fprintf(stderr, "extension_register_post_connect_hook: maximum plugin reached.\n");
96
ext->post_connect_hooks[ext->num_post_connect_hooks] = hook;
97
ext->post_connect_hooks_instances[ext->num_post_connect_hooks] = plugin;
98
ext->num_post_connect_hooks++;
103
static int extension_load_plugins(rdpExtension* extension)
108
rdpSettings* settings;
109
PFREERDP_EXTENSION_ENTRY entry;
110
FREERDP_EXTENSION_ENTRY_POINTS entryPoints;
112
settings = extension->instance->settings;
114
entryPoints.ext = extension;
115
entryPoints.pRegisterExtension = extension_register_plugin;
116
entryPoints.pRegisterPreConnectHook = extension_register_pre_connect_hook;
117
entryPoints.pRegisterPostConnectHook = extension_register_post_connect_hook;
119
for (i = 0; settings->extensions[i].name[0]; i++)
121
if (strchr(settings->extensions[i].name, PATH_SEPARATOR) == NULL)
122
sprintf_s(path, sizeof(path), EXT_PATH "/%s." PLUGIN_EXT, settings->extensions[i].name);
124
sprintf_s(path, sizeof(path), "%s", settings->extensions[i].name);
127
fprintf(stderr, "extension_load_plugins: %s\n", path);
131
fprintf(stderr, "extension_load_plugins: failed to load %s\n", path);
135
entry = (PFREERDP_EXTENSION_ENTRY) DLSYM(han, FREERDP_EXT_EXPORT_FUNC_NAME);
139
fprintf(stderr, "extension_load_plugins: failed to find export function in %s\n", path);
143
entryPoints.data = extension->instance->settings->extensions[i].data;
144
if (entry(&entryPoints) != 0)
147
fprintf(stderr, "extension_load_plugins: %s entry returns error.\n", path);
155
static int extension_init_plugins(rdpExtension* extension)
159
for (i = 0; i < extension->num_plugins; i++)
160
extension->plugins[i]->init(extension->plugins[i], extension->instance);
165
static int extension_uninit_plugins(rdpExtension* extension)
169
for (i = 0; i < extension->num_plugins; i++)
170
extension->plugins[i]->uninit(extension->plugins[i], extension->instance);
175
/** Gets through all registered pre-connect hooks and executes them.
176
* @param extension - pointer to a rdpExtension structure
179
int extension_pre_connect(rdpExtension* extension)
183
for (i = 0; i < extension->num_pre_connect_hooks; i++)
184
extension->pre_connect_hooks[i](extension->pre_connect_hooks_instances[i], extension->instance);
189
/** Gets through all registered post-connect hooks and executes them.
190
* @param extension - pointer to a rdpExtension structure
193
int extension_post_connect(rdpExtension* ext)
197
for (i = 0; i < ext->num_post_connect_hooks; i++)
198
ext->post_connect_hooks[i](ext->post_connect_hooks_instances[i], ext->instance);
203
void extension_load_and_init_plugins(rdpExtension* extension)
205
extension_load_plugins(extension);
206
extension_init_plugins(extension);
209
rdpExtension* extension_new(freerdp* instance)
211
rdpExtension* extension = NULL;
213
if (instance != NULL)
215
extension = (rdpExtension*) malloc(sizeof(rdpExtension));
216
ZeroMemory(extension, sizeof(rdpExtension));
218
extension->instance = instance;
224
void extension_free(rdpExtension* extension)
226
if (extension != NULL)
228
extension_uninit_plugins(extension);