FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
devman.c
1
24#include <freerdp/config.h>
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include <winpr/crt.h>
31#include <winpr/stream.h>
32
33#include <freerdp/types.h>
34#include <freerdp/addin.h>
35#include <freerdp/client/channels.h>
36#include <freerdp/channels/log.h>
37
38#include "rdpdr_main.h"
39
40#include "devman.h"
41
42#define TAG CHANNELS_TAG("rdpdr.client")
43
44static void devman_device_free(void* obj)
45{
46 DEVICE* device = (DEVICE*)obj;
47
48 if (!device)
49 return;
50
51 IFCALL(device->Free, device);
52}
53
54DEVMAN* devman_new(rdpdrPlugin* rdpdr)
55{
56 DEVMAN* devman = NULL;
57
58 if (!rdpdr)
59 return NULL;
60
61 devman = (DEVMAN*)calloc(1, sizeof(DEVMAN));
62
63 if (!devman)
64 {
65 WLog_Print(rdpdr->log, WLOG_INFO, "calloc failed!");
66 return NULL;
67 }
68
69 devman->plugin = (void*)rdpdr;
70 devman->id_sequence = 1;
71 devman->devices = ListDictionary_New(TRUE);
72
73 if (!devman->devices)
74 {
75 WLog_Print(rdpdr->log, WLOG_INFO, "ListDictionary_New failed!");
76 free(devman);
77 return NULL;
78 }
79
80 ListDictionary_ValueObject(devman->devices)->fnObjectFree = devman_device_free;
81 return devman;
82}
83
84void devman_free(DEVMAN* devman)
85{
86 ListDictionary_Free(devman->devices);
87 free(devman);
88}
89
90void devman_unregister_device(DEVMAN* devman, void* key)
91{
92 DEVICE* device = NULL;
93
94 if (!devman || !key)
95 return;
96
97 device = (DEVICE*)ListDictionary_Take(devman->devices, key);
98
99 if (device)
100 devman_device_free(device);
101}
102
108static UINT devman_register_device(DEVMAN* devman, DEVICE* device)
109{
110 void* key = NULL;
111
112 if (!devman || !device)
113 return ERROR_INVALID_PARAMETER;
114
115 device->id = devman->id_sequence++;
116 key = (void*)(size_t)device->id;
117
118 if (!ListDictionary_Add(devman->devices, key, device))
119 {
120 WLog_INFO(TAG, "ListDictionary_Add failed!");
121 return ERROR_INTERNAL_ERROR;
122 }
123
124 return CHANNEL_RC_OK;
125}
126
127DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
128{
129 DEVICE* device = NULL;
130 void* key = (void*)(size_t)id;
131
132 if (!devman)
133 {
134 WLog_ERR(TAG, "device manager=%p", devman);
135 return NULL;
136 }
137
138 device = (DEVICE*)ListDictionary_GetItemValue(devman->devices, key);
139 if (!device)
140 WLog_WARN(TAG, "could not find device ID 0x%08" PRIx32, id);
141 return device;
142}
143
144DEVICE* devman_get_device_by_type(DEVMAN* devman, UINT32 type)
145{
146 DEVICE* device = NULL;
147 ULONG_PTR* keys = NULL;
148
149 if (!devman)
150 return NULL;
151
152 ListDictionary_Lock(devman->devices);
153 const size_t count = ListDictionary_GetKeys(devman->devices, &keys);
154
155 for (size_t x = 0; x < count; x++)
156 {
157 DEVICE* cur = (DEVICE*)ListDictionary_GetItemValue(devman->devices, (void*)keys[x]);
158
159 if (!cur)
160 continue;
161
162 if (cur->type != type)
163 continue;
164
165 device = cur;
166 break;
167 }
168
169 free(keys);
170 ListDictionary_Unlock(devman->devices);
171 return device;
172}
173
174static const char DRIVE_SERVICE_NAME[] = "drive";
175static const char PRINTER_SERVICE_NAME[] = "printer";
176static const char SMARTCARD_SERVICE_NAME[] = "smartcard";
177static const char SERIAL_SERVICE_NAME[] = "serial";
178static const char PARALLEL_SERVICE_NAME[] = "parallel";
179
185UINT devman_load_device_service(DEVMAN* devman, const RDPDR_DEVICE* device, rdpContext* rdpcontext)
186{
187 const char* ServiceName = NULL;
189 union
190 {
191 const RDPDR_DEVICE* cdp;
192 RDPDR_DEVICE* dp;
193 } devconv;
194
195 devconv.cdp = device;
196 if (!devman || !device || !rdpcontext)
197 return ERROR_INVALID_PARAMETER;
198
199 if (device->Type == RDPDR_DTYP_FILESYSTEM)
200 ServiceName = DRIVE_SERVICE_NAME;
201 else if (device->Type == RDPDR_DTYP_PRINT)
202 ServiceName = PRINTER_SERVICE_NAME;
203 else if (device->Type == RDPDR_DTYP_SMARTCARD)
204 ServiceName = SMARTCARD_SERVICE_NAME;
205 else if (device->Type == RDPDR_DTYP_SERIAL)
206 ServiceName = SERIAL_SERVICE_NAME;
207 else if (device->Type == RDPDR_DTYP_PARALLEL)
208 ServiceName = PARALLEL_SERVICE_NAME;
209
210 if (!ServiceName)
211 {
212 WLog_INFO(TAG, "ServiceName %s did not match!", ServiceName);
213 return ERROR_INVALID_NAME;
214 }
215
216 if (device->Name)
217 WLog_INFO(TAG, "Loading device service %s [%s] (static)", ServiceName, device->Name);
218 else
219 WLog_INFO(TAG, "Loading device service %s (static)", ServiceName);
220
221 PVIRTUALCHANNELENTRY pvce =
222 freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0);
223 PDEVICE_SERVICE_ENTRY entry = WINPR_FUNC_PTR_CAST(pvce, PDEVICE_SERVICE_ENTRY);
224
225 if (!entry)
226 {
227 WLog_INFO(TAG, "freerdp_load_channel_addin_entry failed!");
228 return ERROR_INTERNAL_ERROR;
229 }
230
231 ep.devman = devman;
232 ep.RegisterDevice = devman_register_device;
233 ep.device = devconv.dp;
234 ep.rdpcontext = rdpcontext;
235 return entry(&ep);
236}