2 * FreeRDP: A Remote Desktop Protocol Client
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.
24 #include <freerdp/freerdp.h>
25 #include <freerdp/utils/print.h>
26 #include <freerdp/utils/memory.h>
28 #include "extension.h"
31 #define DLOPEN(f) LoadLibraryA(f)
32 #define DLSYM(f, n) GetProcAddress(f, n)
33 #define DLCLOSE(f) FreeLibrary(f)
34 #define PATH_SEPARATOR '\\'
35 #define PLUGIN_EXT "dll"
38 #define DLOPEN(f) dlopen(f, RTLD_LOCAL | RTLD_LAZY)
39 #define DLSYM(f, n) dlsym(f, n)
40 #define DLCLOSE(f) dlclose(f)
41 #define PATH_SEPARATOR '/'
44 #define PLUGIN_EXT "dylib"
46 #define PLUGIN_EXT "so"
51 static uint32 FREERDP_CC extension_register_plugin(rdpExtPlugin* plugin)
53 rdpExtension* ext = (rdpExtension*) plugin->ext;
55 if (ext->num_plugins >= FREERDP_EXT_MAX_COUNT)
57 printf("extension_register_extension: maximum number of plugins reached.\n");
61 ext->plugins[ext->num_plugins++] = plugin;
65 static uint32 FREERDP_CC extension_register_pre_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook)
67 rdpExtension* ext = (rdpExtension*) plugin->ext;
69 if (ext->num_pre_connect_hooks >= FREERDP_EXT_MAX_COUNT)
71 printf("extension_register_pre_connect_hook: maximum plugin reached.\n");
75 ext->pre_connect_hooks[ext->num_pre_connect_hooks] = hook;
76 ext->pre_connect_hooks_instances[ext->num_pre_connect_hooks] = plugin;
77 ext->num_pre_connect_hooks++;
81 static uint32 FREERDP_CC extension_register_post_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook)
83 rdpExtension* ext = (rdpExtension*) plugin->ext;
85 if (ext->num_post_connect_hooks >= FREERDP_EXT_MAX_COUNT)
87 printf("extension_register_post_connect_hook: maximum plugin reached.\n");
91 ext->post_connect_hooks[ext->num_post_connect_hooks] = hook;
92 ext->post_connect_hooks_instances[ext->num_post_connect_hooks] = plugin;
93 ext->num_post_connect_hooks++;
98 static int extension_load_plugins(rdpExtension* extension)
103 rdpSettings* settings;
104 PFREERDP_EXTENSION_ENTRY entry;
105 FREERDP_EXTENSION_ENTRY_POINTS entryPoints;
107 settings = extension->instance->settings;
109 entryPoints.ext = extension;
110 entryPoints.pRegisterExtension = extension_register_plugin;
111 entryPoints.pRegisterPreConnectHook = extension_register_pre_connect_hook;
112 entryPoints.pRegisterPostConnectHook = extension_register_post_connect_hook;
114 for (i = 0; settings->extensions[i].name[0]; i++)
116 if (strchr(settings->extensions[i].name, PATH_SEPARATOR) == NULL)
117 snprintf(path, sizeof(path), EXT_PATH "/%s." PLUGIN_EXT, settings->extensions[i].name);
119 snprintf(path, sizeof(path), "%s", settings->extensions[i].name);
122 printf("extension_load_plugins: %s\n", path);
125 printf("extension_load_plugins: failed to load %s\n", path);
129 entry = (PFREERDP_EXTENSION_ENTRY) DLSYM(han, FREERDP_EXT_EXPORT_FUNC_NAME);
133 printf("extension_load_plugins: failed to find export function in %s\n", path);
137 entryPoints.data = extension->instance->settings->extensions[i].data;
138 if (entry(&entryPoints) != 0)
141 printf("extension_load_plugins: %s entry returns error.\n", path);
149 static int extension_init_plugins(rdpExtension* extension)
153 for (i = 0; i < extension->num_plugins; i++)
154 extension->plugins[i]->init(extension->plugins[i], extension->instance);
159 static int extension_uninit_plugins(rdpExtension* extension)
163 for (i = 0; i < extension->num_plugins; i++)
164 extension->plugins[i]->uninit(extension->plugins[i], extension->instance);
170 int extension_pre_connect(rdpExtension* extension)
174 for (i = 0; i < extension->num_pre_connect_hooks; i++)
175 extension->pre_connect_hooks[i](extension->pre_connect_hooks_instances[i], extension->instance);
180 int extension_post_connect(rdpExtension* ext)
184 for (i = 0; i < ext->num_post_connect_hooks; i++)
185 ext->post_connect_hooks[i](ext->post_connect_hooks_instances[i], ext->instance);
190 rdpExtension* extension_new(freerdp* instance)
192 rdpExtension* extension = NULL;
194 if (instance != NULL)
196 extension = xnew(rdpExtension);
198 extension->instance = instance;
200 extension_load_plugins(extension);
201 extension_init_plugins(extension);
207 void extension_free(rdpExtension* extension)
209 if (extension != NULL)
211 extension_uninit_plugins(extension);