~ubuntu-branches/ubuntu/vivid/freerdp/vivid

« back to all changes in this revision

Viewing changes to libfreerdp/core/extension.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-11-11 12:20:50 UTC
  • mfrom: (1.1.9) (9.1.17 sid)
  • Revision ID: package-import@ubuntu.com-20141111122050-wyr8hrnwco9fcmum
Tags: 1.1.0~git20140921.1.440916e+dfsg1-2ubuntu1
* Merge with Debian unstable, remaining changes
  - Disable ffmpeg support
* Disable gstreamer support, this relies on gstreamer 0.10 and we don't want
  to add any more deps on that.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol Implementation
 
3
 * FreeRDP Extension Plugin Interface
 
4
 *
 
5
 * Copyright 2010-2011 Vic Lee
 
6
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
7
 *
 
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
 
11
 *
 
12
 *     http://www.apache.org/licenses/LICENSE-2.0
 
13
 *
 
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.
 
19
 */
 
20
 
 
21
#ifdef HAVE_CONFIG_H
 
22
#include "config.h"
 
23
#endif
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
 
 
29
#include <winpr/crt.h>
 
30
 
 
31
#include <freerdp/freerdp.h>
 
32
 
 
33
#include "extension.h"
 
34
 
 
35
#ifdef _WIN32
 
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"
 
41
#else
 
42
#include <dlfcn.h>
 
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 '/'
 
47
 
 
48
#ifdef __APPLE__
 
49
#define PLUGIN_EXT "dylib"
 
50
#else
 
51
#define PLUGIN_EXT "so"
 
52
#endif 
 
53
 
 
54
#endif
 
55
 
 
56
static UINT32 FREERDP_CC extension_register_plugin(rdpExtPlugin* plugin)
 
57
{
 
58
        rdpExtension* ext = (rdpExtension*) plugin->ext;
 
59
 
 
60
        if (ext->num_plugins >= FREERDP_EXT_MAX_COUNT)
 
61
        {
 
62
                fprintf(stderr, "extension_register_extension: maximum number of plugins reached.\n");
 
63
                return 1;
 
64
        }
 
65
 
 
66
        ext->plugins[ext->num_plugins++] = plugin;
 
67
        return 0;
 
68
}
 
69
 
 
70
static UINT32 FREERDP_CC extension_register_pre_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook)
 
71
{
 
72
        rdpExtension* ext = (rdpExtension*) plugin->ext;
 
73
 
 
74
        if (ext->num_pre_connect_hooks >= FREERDP_EXT_MAX_COUNT)
 
75
        {
 
76
                fprintf(stderr, "extension_register_pre_connect_hook: maximum plugin reached.\n");
 
77
                return 1;
 
78
        }
 
79
 
 
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++;
 
83
        return 0;
 
84
}
 
85
 
 
86
static UINT32 FREERDP_CC extension_register_post_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook)
 
87
{
 
88
        rdpExtension* ext = (rdpExtension*) plugin->ext;
 
89
 
 
90
        if (ext->num_post_connect_hooks >= FREERDP_EXT_MAX_COUNT)
 
91
        {
 
92
                fprintf(stderr, "extension_register_post_connect_hook: maximum plugin reached.\n");
 
93
                return 1;
 
94
        }
 
95
 
 
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++;
 
99
 
 
100
        return 0;
 
101
}
 
102
 
 
103
static int extension_load_plugins(rdpExtension* extension)
 
104
{
 
105
        int i;
 
106
        void* han;
 
107
        char path[256];
 
108
        rdpSettings* settings;
 
109
        PFREERDP_EXTENSION_ENTRY entry;
 
110
        FREERDP_EXTENSION_ENTRY_POINTS entryPoints;
 
111
 
 
112
        settings = extension->instance->settings;
 
113
 
 
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;
 
118
 
 
119
        for (i = 0; settings->extensions[i].name[0]; i++)
 
120
        {
 
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);
 
123
                else
 
124
                        sprintf_s(path, sizeof(path), "%s", settings->extensions[i].name);
 
125
 
 
126
                han = DLOPEN(path);
 
127
                fprintf(stderr, "extension_load_plugins: %s\n", path);
 
128
 
 
129
                if (han == NULL)
 
130
                {
 
131
                        fprintf(stderr, "extension_load_plugins: failed to load %s\n", path);
 
132
                        continue;
 
133
                }
 
134
 
 
135
                entry = (PFREERDP_EXTENSION_ENTRY) DLSYM(han, FREERDP_EXT_EXPORT_FUNC_NAME);
 
136
                if (entry == NULL)
 
137
                {
 
138
                        DLCLOSE(han);
 
139
                        fprintf(stderr, "extension_load_plugins: failed to find export function in %s\n", path);
 
140
                        continue;
 
141
                }
 
142
 
 
143
                entryPoints.data = extension->instance->settings->extensions[i].data;
 
144
                if (entry(&entryPoints) != 0)
 
145
                {
 
146
                        DLCLOSE(han);
 
147
                        fprintf(stderr, "extension_load_plugins: %s entry returns error.\n", path);
 
148
                        continue;
 
149
                }
 
150
        }
 
151
 
 
152
        return 0;
 
153
}
 
154
 
 
155
static int extension_init_plugins(rdpExtension* extension)
 
156
{
 
157
        int i;
 
158
 
 
159
        for (i = 0; i < extension->num_plugins; i++)
 
160
                extension->plugins[i]->init(extension->plugins[i], extension->instance);
 
161
 
 
162
        return 0;
 
163
}
 
164
 
 
165
static int extension_uninit_plugins(rdpExtension* extension)
 
166
{
 
167
        int i;
 
168
 
 
169
        for (i = 0; i < extension->num_plugins; i++)
 
170
                extension->plugins[i]->uninit(extension->plugins[i], extension->instance);
 
171
 
 
172
        return 0;
 
173
}
 
174
 
 
175
/** Gets through all registered pre-connect hooks and executes them.
 
176
 *  @param extension - pointer to a rdpExtension structure
 
177
 *  @return 0 always
 
178
 */
 
179
int extension_pre_connect(rdpExtension* extension)
 
180
{
 
181
        int i;
 
182
 
 
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);
 
185
 
 
186
        return 0;
 
187
}
 
188
 
 
189
/** Gets through all registered post-connect hooks and executes them.
 
190
 *  @param extension - pointer to a rdpExtension structure
 
191
 *  @return 0 always
 
192
 */
 
193
int extension_post_connect(rdpExtension* ext)
 
194
{
 
195
        int i;
 
196
 
 
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);
 
199
 
 
200
        return 0;
 
201
}
 
202
 
 
203
void extension_load_and_init_plugins(rdpExtension* extension)
 
204
{
 
205
        extension_load_plugins(extension);
 
206
        extension_init_plugins(extension);
 
207
}
 
208
 
 
209
rdpExtension* extension_new(freerdp* instance)
 
210
{
 
211
        rdpExtension* extension = NULL;
 
212
 
 
213
        if (instance != NULL)
 
214
        {
 
215
                extension = (rdpExtension*) malloc(sizeof(rdpExtension));
 
216
                ZeroMemory(extension, sizeof(rdpExtension));
 
217
 
 
218
                extension->instance = instance;
 
219
        }
 
220
 
 
221
        return extension;
 
222
}
 
223
 
 
224
void extension_free(rdpExtension* extension)
 
225
{
 
226
        if (extension != NULL)
 
227
        {
 
228
                extension_uninit_plugins(extension);
 
229
                free(extension);
 
230
        }
 
231
}