~paulliu/ubuntu/quantal/freerdp/fixext

« back to all changes in this revision

Viewing changes to channels/rdpdr/devman.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2012-01-31 10:02:14 UTC
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: package-import@ubuntu.com-20120131100214-zvig71djj2sqgq22
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- c-basic-offset: 8 -*-
2
 
   FreeRDP: A Remote Desktop Protocol client.
3
 
   Redirected Device Manager
4
 
 
5
 
   Copyright (C) Marc-Andre Moreau <marcandre.moreau@gmail.com> 2010
6
 
 
7
 
   This program is free software; you can redistribute it and/or modify
8
 
   it under the terms of the GNU General Public License as published by
9
 
   the Free Software Foundation; either version 2 of the License, or
10
 
   (at your option) any later version.
11
 
 
12
 
   This program is distributed in the hope that it will be useful,
13
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
   GNU General Public License for more details.
16
 
 
17
 
   You should have received a copy of the GNU General Public License
18
 
   along with this program; if not, write to the Free Software
19
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
 
*/
21
 
 
22
 
#include <dlfcn.h>
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol client.
 
3
 * File System Virtual Channel
 
4
 *
 
5
 * Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
6
 * Copyright 2010-2011 Vic Lee
 
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
#include "config.h"
 
22
#include <stdio.h>
23
23
#include <stdlib.h>
24
 
#include <stdio.h>
25
24
#include <string.h>
 
25
#include <freerdp/types.h>
 
26
#include <freerdp/utils/memory.h>
 
27
#include <freerdp/utils/stream.h>
 
28
#include <freerdp/utils/list.h>
 
29
#include <freerdp/utils/svc_plugin.h>
 
30
#include <freerdp/utils/load_plugin.h>
26
31
 
27
 
#include "config.h"
28
32
#include "rdpdr_types.h"
29
 
#include "rdpdr_constants.h"
30
33
#include "devman.h"
31
34
 
32
 
DEVMAN*
33
 
devman_new(void* data)
 
35
DEVMAN* devman_new(rdpSvcPlugin* plugin)
34
36
{
35
37
        DEVMAN* devman;
36
 
        PDEVMAN_ENTRY_POINTS pDevmanEntryPoints;
37
 
 
38
 
        devman = (PDEVMAN)malloc(sizeof(DEVMAN));
39
 
        pDevmanEntryPoints = (PDEVMAN_ENTRY_POINTS)malloc(sizeof(DEVMAN_ENTRY_POINTS));
40
 
 
41
 
        devman->idev = NULL;
42
 
        devman->head = NULL;
43
 
        devman->tail = NULL;
44
 
        devman->count = 0;
 
38
 
 
39
        devman = xnew(DEVMAN);
 
40
        devman->plugin = plugin;
45
41
        devman->id_sequence = 1;
46
 
 
47
 
        pDevmanEntryPoints->pDevmanRegisterService = devman_register_service;
48
 
        pDevmanEntryPoints->pDevmanUnregisterService = devman_unregister_service;
49
 
        pDevmanEntryPoints->pDevmanRegisterDevice = devman_register_device;
50
 
        pDevmanEntryPoints->pDevmanUnregisterDevice = devman_unregister_device;
51
 
        pDevmanEntryPoints->pExtendedData = data;
52
 
        devman->pDevmanEntryPoints = (void*)pDevmanEntryPoints;
 
42
        devman->devices = list_new();
53
43
 
54
44
        return devman;
55
45
}
56
46
 
57
 
int
58
 
devman_free(DEVMAN* devman)
59
 
{
60
 
        DEVICE* pdev;
61
 
 
62
 
        /* unregister all services, which will in turn unregister all devices */
63
 
 
64
 
        devman_rewind(devman);
65
 
 
66
 
        while (devman_has_next(devman) != 0)
67
 
        {
68
 
                pdev = devman_get_next(devman);
69
 
                devman_unregister_service(devman, pdev->service);
70
 
                devman_rewind(devman);
71
 
        }
72
 
 
73
 
        free(devman->pDevmanEntryPoints);
74
 
 
75
 
        /* free devman */
76
 
        free(devman);
77
 
 
78
 
        return 1;
79
 
}
80
 
 
81
 
SERVICE*
82
 
devman_register_service(DEVMAN* devman)
83
 
{
84
 
        SERVICE* srv;
85
 
 
86
 
        srv = (SERVICE*)malloc(sizeof(SERVICE));
87
 
        memset(srv, 0, sizeof(SERVICE));
88
 
 
89
 
        return srv;
90
 
}
91
 
 
92
 
int
93
 
devman_unregister_service(DEVMAN* devman, SERVICE* srv)
94
 
{
95
 
        DEVICE* pdev;
96
 
 
97
 
        /* unregister all devices depending on the service */
98
 
 
99
 
        devman_rewind(devman);
100
 
 
101
 
        while (devman_has_next(devman) != 0)
102
 
        {
103
 
                pdev = devman_get_next(devman);
104
 
 
105
 
                if (pdev->service == srv)
106
 
                {
107
 
                        devman_unregister_device(devman, pdev);
108
 
                        devman_rewind(devman);
109
 
                }
110
 
        }
111
 
 
112
 
        /* unregister service */
113
 
        free(srv);
114
 
 
115
 
        return 1;
116
 
}
117
 
 
118
 
DEVICE*
119
 
devman_register_device(DEVMAN* devman, SERVICE* srv, char* name)
120
 
{
121
 
        DEVICE* pdev;
122
 
 
123
 
        pdev = (DEVICE*)malloc(sizeof(DEVICE));
124
 
        pdev->id = devman->id_sequence++;
125
 
        pdev->prev = NULL;
126
 
        pdev->next = NULL;
127
 
        pdev->service = srv;
128
 
        pdev->data_len = 0;
129
 
        pdev->data = NULL;
130
 
 
131
 
        pdev->name = malloc(strlen(name) + 1);
132
 
        strcpy(pdev->name, name);
133
 
 
134
 
        if (devman->head == NULL)
135
 
        {
136
 
                /* linked list is empty */
137
 
                devman->head = pdev;
138
 
                devman->tail = pdev;
139
 
        }
140
 
        else
141
 
        {
142
 
                /* append device to the end of the linked list */
143
 
                devman->tail->next = (void*)pdev;
144
 
                pdev->prev = (void*)devman->tail;
145
 
                devman->tail = pdev;
146
 
        }
147
 
 
148
 
        devman->count++;
149
 
        return pdev;
150
 
}
151
 
 
152
 
int
153
 
devman_unregister_device(DEVMAN* devman, DEVICE* dev)
154
 
{
155
 
        DEVICE* pdev;
156
 
 
157
 
        devman_rewind(devman);
158
 
 
159
 
        while (devman_has_next(devman) != 0)
160
 
        {
161
 
                pdev = devman_get_next(devman);
162
 
 
163
 
                if (pdev == dev) /* device exists */
164
 
                {
165
 
                        /* set previous device to point to next device */
166
 
 
167
 
                        if (dev->prev != NULL)
168
 
                        {
169
 
                                /* unregistered device is not the head */
170
 
                                pdev = (DEVICE*)dev->prev;
171
 
                                pdev->next = dev->next;
172
 
                        }
173
 
                        else
174
 
                        {
175
 
                                /* unregistered device is the head, update head */
176
 
                                devman->head = (DEVICE*)dev->next;
177
 
                        }
178
 
 
179
 
                        /* set next device to point to previous device */
180
 
 
181
 
                        if (dev->next != NULL)
182
 
                        {
183
 
                                /* unregistered device is not the tail */
184
 
                                pdev = (DEVICE*)dev->next;
185
 
                                pdev->prev = dev->prev;
186
 
                        }
187
 
                        else
188
 
                        {
189
 
                                /* unregistered device is the tail, update tail */
190
 
                                devman->tail = (DEVICE*)dev->prev;
191
 
                        }
192
 
 
193
 
                        devman->count--;
194
 
 
195
 
                        if (dev->service->free)
196
 
                                dev->service->free(dev);
197
 
                        free(dev->name);
198
 
                        free(dev); /* free memory for unregistered device */
199
 
                        return 1; /* unregistration successful */
200
 
                }
201
 
        }
202
 
 
203
 
        /* if we reach this point, the device wasn't found */
204
 
        return 0;
205
 
}
206
 
 
207
 
void
208
 
devman_rewind(DEVMAN* devman)
209
 
{
210
 
        devman->idev = devman->head;
211
 
}
212
 
 
213
 
int
214
 
devman_has_next(DEVMAN* devman)
215
 
{
216
 
        if (devman->idev == NULL)
217
 
                return 0;
218
 
        else
219
 
                return 1;
220
 
}
221
 
 
222
 
DEVICE*
223
 
devman_get_next(DEVMAN* devman)
224
 
{
225
 
        DEVICE* pdev;
226
 
 
227
 
        pdev = devman->idev;
228
 
        devman->idev = (DEVICE*)devman->idev->next;
229
 
 
230
 
        return pdev;
231
 
}
232
 
 
233
 
DEVICE*
234
 
devman_get_device_by_id(DEVMAN* devman, uint32 id)
235
 
{
236
 
        DEVICE* pdev;
237
 
 
238
 
        devman_rewind(devman);
239
 
 
240
 
        while (devman_has_next(devman) != 0)
241
 
        {
242
 
                pdev = devman_get_next(devman);
243
 
 
244
 
                /* device with given ID was found */
245
 
                if (pdev->id == id)
246
 
                        return pdev;
247
 
        }
248
 
 
249
 
        /* no device with the given ID was found */
250
 
        return NULL;
251
 
}
252
 
 
253
 
SERVICE*
254
 
devman_get_service_by_type(DEVMAN* devman, int type)
255
 
{
256
 
        DEVICE* pdev;
257
 
 
258
 
        devman_rewind(devman);
259
 
 
260
 
        while (devman_has_next(devman) != 0)
261
 
        {
262
 
                pdev = devman_get_next(devman);
263
 
 
264
 
                /* service with given type was found */
265
 
                if (pdev->service->type == type)
266
 
                        return pdev->service;
267
 
        }
268
 
 
269
 
        /* no service with the given type was found */
270
 
        return NULL;
271
 
}
272
 
 
273
 
int
274
 
devman_load_device_service(DEVMAN* devman, char* filename)
275
 
{
276
 
        void* dl;
277
 
        char* fn;
278
 
        PDEVICE_SERVICE_ENTRY pDeviceServiceEntry = NULL;
279
 
 
280
 
        if (strchr(filename, '/'))
281
 
        {
282
 
                fn = strdup(filename);
283
 
        }
284
 
        else
285
 
        {
286
 
                fn = malloc(strlen(PLUGIN_PATH) + strlen(filename) + 10);
287
 
                sprintf(fn, PLUGIN_PATH "/%s.so", filename);
288
 
        }
289
 
        dl = dlopen(fn, RTLD_LOCAL | RTLD_LAZY);
290
 
 
291
 
        pDeviceServiceEntry = (PDEVICE_SERVICE_ENTRY)dlsym(dl, "DeviceServiceEntry");
292
 
 
293
 
        if(pDeviceServiceEntry != NULL)
294
 
        {
295
 
                pDeviceServiceEntry(devman, devman->pDevmanEntryPoints);
296
 
                LLOGLN(0, ("loaded device service: %s", fn));
297
 
        }
298
 
        free(fn);
299
 
 
300
 
        return 0;
 
47
void devman_free(DEVMAN* devman)
 
48
{
 
49
        DEVICE* device;
 
50
 
 
51
        while ((device = (DEVICE*)list_dequeue(devman->devices)) != NULL)
 
52
                IFCALL(device->Free, device);
 
53
        list_free(devman->devices);
 
54
        xfree(devman);
 
55
}
 
56
 
 
57
static void devman_register_device(DEVMAN* devman, DEVICE* device)
 
58
{
 
59
        device->id = devman->id_sequence++;
 
60
        list_add(devman->devices, device);
 
61
 
 
62
        DEBUG_SVC("device %d.%s registered", device->id, device->name);
 
63
}
 
64
 
 
65
static void devman_unregister_device(DEVMAN* devman, DEVICE* device)
 
66
{
 
67
        list_remove(devman->devices, device);
 
68
 
 
69
        DEBUG_SVC("device %d.%s unregistered", device->id, device->name);
 
70
}
 
71
 
 
72
boolean devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data)
 
73
{
 
74
        DEVICE_SERVICE_ENTRY_POINTS ep;
 
75
        PDEVICE_SERVICE_ENTRY entry;
 
76
 
 
77
        entry = freerdp_load_plugin((char*)plugin_data->data[0], "DeviceServiceEntry");
 
78
        if (entry == NULL)
 
79
                return false;
 
80
 
 
81
        ep.devman = devman;
 
82
        ep.RegisterDevice = devman_register_device;
 
83
        ep.UnregisterDevice = devman_unregister_device;
 
84
        ep.plugin_data = plugin_data;
 
85
 
 
86
        entry(&ep);
 
87
 
 
88
        return true;
 
89
}
 
90
 
 
91
DEVICE* devman_get_device_by_id(DEVMAN* devman, uint32 id)
 
92
{
 
93
        LIST_ITEM* item;
 
94
        DEVICE* device;
 
95
 
 
96
        for (item = devman->devices->head; item; item = item->next)
 
97
        {
 
98
                device = (DEVICE*)item->data;
 
99
                if (device->id == id)
 
100
                        return device;
 
101
        }
 
102
        return NULL;
301
103
}