1
/* -*- c-basic-offset: 8 -*-
2
FreeRDP: A Remote Desktop Protocol client.
3
Redirected Device Manager
5
Copyright (C) Marc-Andre Moreau <marcandre.moreau@gmail.com> 2010
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.
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.
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.
2
* FreeRDP: A Remote Desktop Protocol client.
3
* File System Virtual Channel
5
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
* Copyright 2010-2011 Vic Lee
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.
23
23
#include <stdlib.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>
28
32
#include "rdpdr_types.h"
29
#include "rdpdr_constants.h"
30
33
#include "devman.h"
33
devman_new(void* data)
35
DEVMAN* devman_new(rdpSvcPlugin* plugin)
36
PDEVMAN_ENTRY_POINTS pDevmanEntryPoints;
38
devman = (PDEVMAN)malloc(sizeof(DEVMAN));
39
pDevmanEntryPoints = (PDEVMAN_ENTRY_POINTS)malloc(sizeof(DEVMAN_ENTRY_POINTS));
39
devman = xnew(DEVMAN);
40
devman->plugin = plugin;
45
41
devman->id_sequence = 1;
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();
58
devman_free(DEVMAN* devman)
62
/* unregister all services, which will in turn unregister all devices */
64
devman_rewind(devman);
66
while (devman_has_next(devman) != 0)
68
pdev = devman_get_next(devman);
69
devman_unregister_service(devman, pdev->service);
70
devman_rewind(devman);
73
free(devman->pDevmanEntryPoints);
82
devman_register_service(DEVMAN* devman)
86
srv = (SERVICE*)malloc(sizeof(SERVICE));
87
memset(srv, 0, sizeof(SERVICE));
93
devman_unregister_service(DEVMAN* devman, SERVICE* srv)
97
/* unregister all devices depending on the service */
99
devman_rewind(devman);
101
while (devman_has_next(devman) != 0)
103
pdev = devman_get_next(devman);
105
if (pdev->service == srv)
107
devman_unregister_device(devman, pdev);
108
devman_rewind(devman);
112
/* unregister service */
119
devman_register_device(DEVMAN* devman, SERVICE* srv, char* name)
123
pdev = (DEVICE*)malloc(sizeof(DEVICE));
124
pdev->id = devman->id_sequence++;
131
pdev->name = malloc(strlen(name) + 1);
132
strcpy(pdev->name, name);
134
if (devman->head == NULL)
136
/* linked list is empty */
142
/* append device to the end of the linked list */
143
devman->tail->next = (void*)pdev;
144
pdev->prev = (void*)devman->tail;
153
devman_unregister_device(DEVMAN* devman, DEVICE* dev)
157
devman_rewind(devman);
159
while (devman_has_next(devman) != 0)
161
pdev = devman_get_next(devman);
163
if (pdev == dev) /* device exists */
165
/* set previous device to point to next device */
167
if (dev->prev != NULL)
169
/* unregistered device is not the head */
170
pdev = (DEVICE*)dev->prev;
171
pdev->next = dev->next;
175
/* unregistered device is the head, update head */
176
devman->head = (DEVICE*)dev->next;
179
/* set next device to point to previous device */
181
if (dev->next != NULL)
183
/* unregistered device is not the tail */
184
pdev = (DEVICE*)dev->next;
185
pdev->prev = dev->prev;
189
/* unregistered device is the tail, update tail */
190
devman->tail = (DEVICE*)dev->prev;
195
if (dev->service->free)
196
dev->service->free(dev);
198
free(dev); /* free memory for unregistered device */
199
return 1; /* unregistration successful */
203
/* if we reach this point, the device wasn't found */
208
devman_rewind(DEVMAN* devman)
210
devman->idev = devman->head;
214
devman_has_next(DEVMAN* devman)
216
if (devman->idev == NULL)
223
devman_get_next(DEVMAN* devman)
228
devman->idev = (DEVICE*)devman->idev->next;
234
devman_get_device_by_id(DEVMAN* devman, uint32 id)
238
devman_rewind(devman);
240
while (devman_has_next(devman) != 0)
242
pdev = devman_get_next(devman);
244
/* device with given ID was found */
249
/* no device with the given ID was found */
254
devman_get_service_by_type(DEVMAN* devman, int type)
258
devman_rewind(devman);
260
while (devman_has_next(devman) != 0)
262
pdev = devman_get_next(devman);
264
/* service with given type was found */
265
if (pdev->service->type == type)
266
return pdev->service;
269
/* no service with the given type was found */
274
devman_load_device_service(DEVMAN* devman, char* filename)
278
PDEVICE_SERVICE_ENTRY pDeviceServiceEntry = NULL;
280
if (strchr(filename, '/'))
282
fn = strdup(filename);
286
fn = malloc(strlen(PLUGIN_PATH) + strlen(filename) + 10);
287
sprintf(fn, PLUGIN_PATH "/%s.so", filename);
289
dl = dlopen(fn, RTLD_LOCAL | RTLD_LAZY);
291
pDeviceServiceEntry = (PDEVICE_SERVICE_ENTRY)dlsym(dl, "DeviceServiceEntry");
293
if(pDeviceServiceEntry != NULL)
295
pDeviceServiceEntry(devman, devman->pDevmanEntryPoints);
296
LLOGLN(0, ("loaded device service: %s", fn));
47
void devman_free(DEVMAN* devman)
51
while ((device = (DEVICE*)list_dequeue(devman->devices)) != NULL)
52
IFCALL(device->Free, device);
53
list_free(devman->devices);
57
static void devman_register_device(DEVMAN* devman, DEVICE* device)
59
device->id = devman->id_sequence++;
60
list_add(devman->devices, device);
62
DEBUG_SVC("device %d.%s registered", device->id, device->name);
65
static void devman_unregister_device(DEVMAN* devman, DEVICE* device)
67
list_remove(devman->devices, device);
69
DEBUG_SVC("device %d.%s unregistered", device->id, device->name);
72
boolean devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data)
74
DEVICE_SERVICE_ENTRY_POINTS ep;
75
PDEVICE_SERVICE_ENTRY entry;
77
entry = freerdp_load_plugin((char*)plugin_data->data[0], "DeviceServiceEntry");
82
ep.RegisterDevice = devman_register_device;
83
ep.UnregisterDevice = devman_unregister_device;
84
ep.plugin_data = plugin_data;
91
DEVICE* devman_get_device_by_id(DEVMAN* devman, uint32 id)
96
for (item = devman->devices->head; item; item = item->next)
98
device = (DEVICE*)item->data;