FreeRDP
Loading...
Searching...
No Matches
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 if (device->Free)
52 device->Free(device);
53}
54
55DEVMAN* devman_new(rdpdrPlugin* rdpdr)
56{
57 DEVMAN* devman = NULL;
58
59 if (!rdpdr)
60 return NULL;
61
62 devman = (DEVMAN*)calloc(1, sizeof(DEVMAN));
63
64 if (!devman)
65 {
66 WLog_Print(rdpdr->log, WLOG_INFO, "calloc failed!");
67 return NULL;
68 }
69
70 devman->plugin = (void*)rdpdr;
71 devman->id_sequence = 1;
72 devman->devices = ListDictionary_New(TRUE);
73
74 if (!devman->devices)
75 {
76 WLog_Print(rdpdr->log, WLOG_INFO, "ListDictionary_New failed!");
77 free(devman);
78 return NULL;
79 }
80
81 ListDictionary_ValueObject(devman->devices)->fnObjectFree = devman_device_free;
82 return devman;
83}
84
85void devman_free(DEVMAN* devman)
86{
87 ListDictionary_Free(devman->devices);
88 free(devman);
89}
90
91void devman_unregister_device(DEVMAN* devman, void* key)
92{
93 DEVICE* device = NULL;
94
95 if (!devman || !key)
96 return;
97
98 device = (DEVICE*)ListDictionary_Take(devman->devices, key);
99
100 if (device)
101 devman_device_free(device);
102}
103
109static UINT devman_register_device(DEVMAN* devman, DEVICE* device)
110{
111 void* key = NULL;
112
113 if (!devman || !device)
114 return ERROR_INVALID_PARAMETER;
115
116 device->id = devman->id_sequence++;
117 key = (void*)(size_t)device->id;
118
119 if (!ListDictionary_Add(devman->devices, key, device))
120 {
121 WLog_INFO(TAG, "ListDictionary_Add failed!");
122 return ERROR_INTERNAL_ERROR;
123 }
124
125 return CHANNEL_RC_OK;
126}
127
128DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
129{
130 DEVICE* device = NULL;
131 void* key = (void*)(size_t)id;
132
133 if (!devman)
134 {
135 WLog_ERR(TAG, "device manager=NULL");
136 return NULL;
137 }
138
139 device = (DEVICE*)ListDictionary_GetItemValue(devman->devices, key);
140 if (!device)
141 WLog_WARN(TAG, "could not find device ID 0x%08" PRIx32, id);
142 return device;
143}
144
145DEVICE* devman_get_device_by_type(DEVMAN* devman, UINT32 type)
146{
147 DEVICE* device = NULL;
148 ULONG_PTR* keys = NULL;
149
150 if (!devman)
151 return NULL;
152
153 ListDictionary_Lock(devman->devices);
154 const size_t count = ListDictionary_GetKeys(devman->devices, &keys);
155
156 for (size_t x = 0; x < count; x++)
157 {
158 DEVICE* cur = (DEVICE*)ListDictionary_GetItemValue(devman->devices, (void*)keys[x]);
159
160 if (!cur)
161 continue;
162
163 if (cur->type != type)
164 continue;
165
166 device = cur;
167 break;
168 }
169
170 free(keys);
171 ListDictionary_Unlock(devman->devices);
172 return device;
173}
174
175static const char DRIVE_SERVICE_NAME[] = "drive";
176static const char PRINTER_SERVICE_NAME[] = "printer";
177static const char SMARTCARD_SERVICE_NAME[] = "smartcard";
178static const char SERIAL_SERVICE_NAME[] = "serial";
179static const char PARALLEL_SERVICE_NAME[] = "parallel";
180
186UINT devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device, rdpContext* rdpcontext)
187{
188 const char* ServiceName = NULL;
190 union
191 {
192 const RDPDR_DEVICE* cdp;
193 RDPDR_DEVICE* dp;
194 } devconv;
195
196 devconv.cdp = device;
197 if (!devman || !device || !rdpcontext)
198 return ERROR_INVALID_PARAMETER;
199
200 if (device->Type == RDPDR_DTYP_FILESYSTEM)
201 ServiceName = DRIVE_SERVICE_NAME;
202 else if (device->Type == RDPDR_DTYP_PRINT)
203 ServiceName = PRINTER_SERVICE_NAME;
204 else if (device->Type == RDPDR_DTYP_SMARTCARD)
205 ServiceName = SMARTCARD_SERVICE_NAME;
206 else if (device->Type == RDPDR_DTYP_SERIAL)
207 ServiceName = SERIAL_SERVICE_NAME;
208 else if (device->Type == RDPDR_DTYP_PARALLEL)
209 ServiceName = PARALLEL_SERVICE_NAME;
210
211 if (!ServiceName)
212 {
213 WLog_INFO(TAG, "ServiceName %s did not match!", ServiceName);
214 return ERROR_INVALID_NAME;
215 }
216
217 if (device->Name)
218 WLog_INFO(TAG, "Loading device service %s [%s] (static)", ServiceName, device->Name);
219 else
220 WLog_INFO(TAG, "Loading device service %s (static)", ServiceName);
221
222 PVIRTUALCHANNELENTRY pvce =
223 freerdp_load_channel_addin_entry(ServiceName, NULL, "DeviceServiceEntry", 0);
224 PDEVICE_SERVICE_ENTRY entry = WINPR_FUNC_PTR_CAST(pvce, PDEVICE_SERVICE_ENTRY);
225
226 if (!entry)
227 {
228 WLog_INFO(TAG, "freerdp_load_channel_addin_entry failed!");
229 return ERROR_INTERNAL_ERROR;
230 }
231
232 ep.devman = devman;
233 ep.RegisterDevice = devman_register_device;
234 ep.device = devconv.dp;
235 ep.rdpcontext = rdpcontext;
236 return entry(&ep);
237}
OBJECT_FREE_FN fnObjectFree
Definition collections.h:58