FreeRDP
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 
44 static 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 
54 DEVMAN* 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 
84 void devman_free(DEVMAN* devman)
85 {
86  ListDictionary_Free(devman->devices);
87  free(devman);
88 }
89 
90 void 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 
108 static 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 
127 DEVICE* 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 
144 DEVICE* 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 
174 static const char DRIVE_SERVICE_NAME[] = "drive";
175 static const char PRINTER_SERVICE_NAME[] = "printer";
176 static const char SMARTCARD_SERVICE_NAME[] = "smartcard";
177 static const char SERIAL_SERVICE_NAME[] = "serial";
178 static const char PARALLEL_SERVICE_NAME[] = "parallel";
179 
185 UINT devman_load_device_service(DEVMAN* devman, const RDPDR_DEVICE* device, rdpContext* rdpcontext)
186 {
187  const char* ServiceName = NULL;
188  DEVICE_SERVICE_ENTRY_POINTS ep = { 0 };
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 }