FreeRDP
msusb.c
1 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <freerdp/log.h>
26 #include <msusb.h>
27 
28 #define TAG FREERDP_TAG("utils")
29 
30 static MSUSB_PIPE_DESCRIPTOR* msusb_mspipe_new(void)
31 {
32  return (MSUSB_PIPE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_PIPE_DESCRIPTOR));
33 }
34 
35 static void msusb_mspipes_free(MSUSB_PIPE_DESCRIPTOR** MsPipes, UINT32 NumberOfPipes)
36 {
37  if (MsPipes)
38  {
39  for (UINT32 pnum = 0; pnum < NumberOfPipes && MsPipes[pnum]; pnum++)
40  free(MsPipes[pnum]);
41 
42  free(MsPipes);
43  }
44 }
45 
46 BOOL msusb_mspipes_replace(MSUSB_INTERFACE_DESCRIPTOR* MsInterface,
47  MSUSB_PIPE_DESCRIPTOR** NewMsPipes, UINT32 NewNumberOfPipes)
48 {
49  if (!MsInterface || !NewMsPipes)
50  return FALSE;
51 
52  /* free orignal MsPipes */
53  msusb_mspipes_free(MsInterface->MsPipes, MsInterface->NumberOfPipes);
54  /* And replace it */
55  MsInterface->MsPipes = NewMsPipes;
56  MsInterface->NumberOfPipes = NewNumberOfPipes;
57  return TRUE;
58 }
59 
60 static MSUSB_PIPE_DESCRIPTOR** msusb_mspipes_read(wStream* s, UINT32 NumberOfPipes)
61 {
62  MSUSB_PIPE_DESCRIPTOR** MsPipes = NULL;
63 
64  if (!Stream_CheckAndLogRequiredCapacityOfSize(TAG, (s), NumberOfPipes, 12ull))
65  return NULL;
66 
67  MsPipes = (MSUSB_PIPE_DESCRIPTOR**)calloc(NumberOfPipes, sizeof(MSUSB_PIPE_DESCRIPTOR*));
68 
69  if (!MsPipes)
70  return NULL;
71 
72  for (UINT32 pnum = 0; pnum < NumberOfPipes; pnum++)
73  {
74  MSUSB_PIPE_DESCRIPTOR* MsPipe = msusb_mspipe_new();
75 
76  if (!MsPipe)
77  goto out_error;
78 
79  Stream_Read_UINT16(s, MsPipe->MaximumPacketSize);
80  Stream_Seek(s, 2);
81  Stream_Read_UINT32(s, MsPipe->MaximumTransferSize);
82  Stream_Read_UINT32(s, MsPipe->PipeFlags);
83  /* Already set to zero by memset
84  MsPipe->PipeHandle = 0;
85  MsPipe->bEndpointAddress = 0;
86  MsPipe->bInterval = 0;
87  MsPipe->PipeType = 0;
88  MsPipe->InitCompleted = 0;
89  */
90  MsPipes[pnum] = MsPipe;
91  }
92 
93  return MsPipes;
94 out_error:
95 
96  for (UINT32 pnum = 0; pnum < NumberOfPipes; pnum++)
97  free(MsPipes[pnum]);
98 
99  free(MsPipes);
100  return NULL;
101 }
102 
103 static MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_new(void)
104 {
105  return (MSUSB_INTERFACE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_INTERFACE_DESCRIPTOR));
106 }
107 
108 void msusb_msinterface_free(MSUSB_INTERFACE_DESCRIPTOR* MsInterface)
109 {
110  if (MsInterface)
111  {
112  msusb_mspipes_free(MsInterface->MsPipes, MsInterface->NumberOfPipes);
113  MsInterface->MsPipes = NULL;
114  free(MsInterface);
115  }
116 }
117 
118 static void msusb_msinterface_free_list(MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces,
119  UINT32 NumInterfaces)
120 {
121  if (MsInterfaces)
122  {
123  for (UINT32 inum = 0; inum < NumInterfaces; inum++)
124  {
125  msusb_msinterface_free(MsInterfaces[inum]);
126  }
127 
128  free(MsInterfaces);
129  }
130 }
131 
132 BOOL msusb_msinterface_replace(MSUSB_CONFIG_DESCRIPTOR* MsConfig, BYTE InterfaceNumber,
133  MSUSB_INTERFACE_DESCRIPTOR* NewMsInterface)
134 {
135  if (!MsConfig || !MsConfig->MsInterfaces)
136  return FALSE;
137 
138  msusb_msinterface_free(MsConfig->MsInterfaces[InterfaceNumber]);
139  MsConfig->MsInterfaces[InterfaceNumber] = NewMsInterface;
140  return TRUE;
141 }
142 
143 MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_read(wStream* s)
144 {
145  MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL;
146 
147  if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 12))
148  return NULL;
149 
150  MsInterface = msusb_msinterface_new();
151 
152  if (!MsInterface)
153  return NULL;
154 
155  Stream_Read_UINT16(s, MsInterface->Length);
156  Stream_Read_UINT16(s, MsInterface->NumberOfPipesExpected);
157  Stream_Read_UINT8(s, MsInterface->InterfaceNumber);
158  Stream_Read_UINT8(s, MsInterface->AlternateSetting);
159  Stream_Seek(s, 2);
160  Stream_Read_UINT32(s, MsInterface->NumberOfPipes);
161  MsInterface->InterfaceHandle = 0;
162  MsInterface->bInterfaceClass = 0;
163  MsInterface->bInterfaceSubClass = 0;
164  MsInterface->bInterfaceProtocol = 0;
165  MsInterface->InitCompleted = 0;
166  MsInterface->MsPipes = NULL;
167 
168  if (MsInterface->NumberOfPipes > 0)
169  {
170  MsInterface->MsPipes = msusb_mspipes_read(s, MsInterface->NumberOfPipes);
171 
172  if (!MsInterface->MsPipes)
173  goto out_error;
174  }
175 
176  return MsInterface;
177 out_error:
178  msusb_msinterface_free(MsInterface);
179  return NULL;
180 }
181 
182 BOOL msusb_msinterface_write(MSUSB_INTERFACE_DESCRIPTOR* MsInterface, wStream* out)
183 {
184  MSUSB_PIPE_DESCRIPTOR** MsPipes = NULL;
185  MSUSB_PIPE_DESCRIPTOR* MsPipe = NULL;
186 
187  if (!MsInterface)
188  return FALSE;
189 
190  if (!Stream_EnsureRemainingCapacity(out, 16 + MsInterface->NumberOfPipes * 20))
191  return FALSE;
192 
193  /* Length */
194  Stream_Write_UINT16(out, MsInterface->Length);
195  /* InterfaceNumber */
196  Stream_Write_UINT8(out, MsInterface->InterfaceNumber);
197  /* AlternateSetting */
198  Stream_Write_UINT8(out, MsInterface->AlternateSetting);
199  /* bInterfaceClass */
200  Stream_Write_UINT8(out, MsInterface->bInterfaceClass);
201  /* bInterfaceSubClass */
202  Stream_Write_UINT8(out, MsInterface->bInterfaceSubClass);
203  /* bInterfaceProtocol */
204  Stream_Write_UINT8(out, MsInterface->bInterfaceProtocol);
205  /* Padding */
206  Stream_Write_UINT8(out, 0);
207  /* InterfaceHandle */
208  Stream_Write_UINT32(out, MsInterface->InterfaceHandle);
209  /* NumberOfPipes */
210  Stream_Write_UINT32(out, MsInterface->NumberOfPipes);
211  /* Pipes */
212  MsPipes = MsInterface->MsPipes;
213 
214  for (UINT32 pnum = 0; pnum < MsInterface->NumberOfPipes; pnum++)
215  {
216  MsPipe = MsPipes[pnum];
217  /* MaximumPacketSize */
218  Stream_Write_UINT16(out, MsPipe->MaximumPacketSize);
219  /* EndpointAddress */
220  Stream_Write_UINT8(out, MsPipe->bEndpointAddress);
221  /* Interval */
222  Stream_Write_UINT8(out, MsPipe->bInterval);
223  /* PipeType */
224  Stream_Write_UINT32(out, MsPipe->PipeType);
225  /* PipeHandle */
226  Stream_Write_UINT32(out, MsPipe->PipeHandle);
227  /* MaximumTransferSize */
228  Stream_Write_UINT32(out, MsPipe->MaximumTransferSize);
229  /* PipeFlags */
230  Stream_Write_UINT32(out, MsPipe->PipeFlags);
231  }
232 
233  return TRUE;
234 }
235 
236 static MSUSB_INTERFACE_DESCRIPTOR** msusb_msinterface_read_list(wStream* s, UINT32 NumInterfaces)
237 {
238  MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL;
239  MsInterfaces =
240  (MSUSB_INTERFACE_DESCRIPTOR**)calloc(NumInterfaces, sizeof(MSUSB_INTERFACE_DESCRIPTOR*));
241 
242  if (!MsInterfaces)
243  return NULL;
244 
245  for (UINT32 inum = 0; inum < NumInterfaces; inum++)
246  {
247  MsInterfaces[inum] = msusb_msinterface_read(s);
248 
249  if (!MsInterfaces[inum])
250  goto fail;
251  }
252 
253  return MsInterfaces;
254 fail:
255 
256  for (UINT32 inum = 0; inum < NumInterfaces; inum++)
257  msusb_msinterface_free(MsInterfaces[inum]);
258 
259  free(MsInterfaces);
260  return NULL;
261 }
262 
263 BOOL msusb_msconfig_write(MSUSB_CONFIG_DESCRIPTOR* MsConfg, wStream* out)
264 {
265  MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL;
266  MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL;
267 
268  if (!MsConfg)
269  return FALSE;
270 
271  if (!Stream_EnsureRemainingCapacity(out, 8))
272  return FALSE;
273 
274  /* ConfigurationHandle*/
275  Stream_Write_UINT32(out, MsConfg->ConfigurationHandle);
276  /* NumInterfaces*/
277  Stream_Write_UINT32(out, MsConfg->NumInterfaces);
278  /* Interfaces */
279  MsInterfaces = MsConfg->MsInterfaces;
280 
281  for (UINT32 inum = 0; inum < MsConfg->NumInterfaces; inum++)
282  {
283  MsInterface = MsInterfaces[inum];
284 
285  if (!msusb_msinterface_write(MsInterface, out))
286  return FALSE;
287  }
288 
289  return TRUE;
290 }
291 
292 MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_new(void)
293 {
294  return (MSUSB_CONFIG_DESCRIPTOR*)calloc(1, sizeof(MSUSB_CONFIG_DESCRIPTOR));
295 }
296 
297 void msusb_msconfig_free(MSUSB_CONFIG_DESCRIPTOR* MsConfig)
298 {
299  if (MsConfig)
300  {
301  msusb_msinterface_free_list(MsConfig->MsInterfaces, MsConfig->NumInterfaces);
302  MsConfig->MsInterfaces = NULL;
303  free(MsConfig);
304  }
305 }
306 
307 MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_read(wStream* s, UINT32 NumInterfaces)
308 {
309  MSUSB_CONFIG_DESCRIPTOR* MsConfig = NULL;
310  BYTE lenConfiguration = 0;
311  BYTE typeConfiguration = 0;
312 
313  if (!Stream_CheckAndLogRequiredCapacityOfSize(TAG, (s), 3ULL + NumInterfaces, 2ULL))
314  return NULL;
315 
316  MsConfig = msusb_msconfig_new();
317 
318  if (!MsConfig)
319  goto fail;
320 
321  MsConfig->MsInterfaces = msusb_msinterface_read_list(s, NumInterfaces);
322 
323  if (!MsConfig->MsInterfaces)
324  goto fail;
325 
326  Stream_Read_UINT8(s, lenConfiguration);
327  Stream_Read_UINT8(s, typeConfiguration);
328 
329  if (lenConfiguration != 0x9 || typeConfiguration != 0x2)
330  {
331  WLog_ERR(TAG, "len and type must be 0x9 and 0x2 , but it is 0x%" PRIx8 " and 0x%" PRIx8 "",
332  lenConfiguration, typeConfiguration);
333  goto fail;
334  }
335 
336  Stream_Read_UINT16(s, MsConfig->wTotalLength);
337  Stream_Seek(s, 1);
338  Stream_Read_UINT8(s, MsConfig->bConfigurationValue);
339  MsConfig->NumInterfaces = NumInterfaces;
340  return MsConfig;
341 fail:
342  msusb_msconfig_free(MsConfig);
343  return NULL;
344 }
345 
346 void msusb_msconfig_dump(MSUSB_CONFIG_DESCRIPTOR* MsConfig)
347 {
348  MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL;
349  MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL;
350  MSUSB_PIPE_DESCRIPTOR** MsPipes = NULL;
351  MSUSB_PIPE_DESCRIPTOR* MsPipe = NULL;
352 
353  WLog_INFO(TAG, "=================MsConfig:========================");
354  WLog_INFO(TAG, "wTotalLength:%" PRIu16 "", MsConfig->wTotalLength);
355  WLog_INFO(TAG, "bConfigurationValue:%" PRIu8 "", MsConfig->bConfigurationValue);
356  WLog_INFO(TAG, "ConfigurationHandle:0x%08" PRIx32 "", MsConfig->ConfigurationHandle);
357  WLog_INFO(TAG, "InitCompleted:%d", MsConfig->InitCompleted);
358  WLog_INFO(TAG, "MsOutSize:%d", MsConfig->MsOutSize);
359  WLog_INFO(TAG, "NumInterfaces:%" PRIu32 "", MsConfig->NumInterfaces);
360  MsInterfaces = MsConfig->MsInterfaces;
361 
362  for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
363  {
364  MsInterface = MsInterfaces[inum];
365  WLog_INFO(TAG, " Interface: %" PRIu8 "", MsInterface->InterfaceNumber);
366  WLog_INFO(TAG, " Length: %" PRIu16 "", MsInterface->Length);
367  WLog_INFO(TAG, " NumberOfPipesExpected: %" PRIu16 "",
368  MsInterface->NumberOfPipesExpected);
369  WLog_INFO(TAG, " AlternateSetting: %" PRIu8 "", MsInterface->AlternateSetting);
370  WLog_INFO(TAG, " NumberOfPipes: %" PRIu32 "", MsInterface->NumberOfPipes);
371  WLog_INFO(TAG, " InterfaceHandle: 0x%08" PRIx32 "", MsInterface->InterfaceHandle);
372  WLog_INFO(TAG, " bInterfaceClass: 0x%02" PRIx8 "", MsInterface->bInterfaceClass);
373  WLog_INFO(TAG, " bInterfaceSubClass: 0x%02" PRIx8 "", MsInterface->bInterfaceSubClass);
374  WLog_INFO(TAG, " bInterfaceProtocol: 0x%02" PRIx8 "", MsInterface->bInterfaceProtocol);
375  WLog_INFO(TAG, " InitCompleted: %d", MsInterface->InitCompleted);
376  MsPipes = MsInterface->MsPipes;
377 
378  for (UINT32 pnum = 0; pnum < MsInterface->NumberOfPipes; pnum++)
379  {
380  MsPipe = MsPipes[pnum];
381  WLog_INFO(TAG, " Pipe: %" PRIu32, pnum);
382  WLog_INFO(TAG, " MaximumPacketSize: 0x%04" PRIx16 "", MsPipe->MaximumPacketSize);
383  WLog_INFO(TAG, " MaximumTransferSize: 0x%08" PRIx32 "",
384  MsPipe->MaximumTransferSize);
385  WLog_INFO(TAG, " PipeFlags: 0x%08" PRIx32 "", MsPipe->PipeFlags);
386  WLog_INFO(TAG, " PipeHandle: 0x%08" PRIx32 "", MsPipe->PipeHandle);
387  WLog_INFO(TAG, " bEndpointAddress: 0x%02" PRIx8 "", MsPipe->bEndpointAddress);
388  WLog_INFO(TAG, " bInterval: %" PRIu8 "", MsPipe->bInterval);
389  WLog_INFO(TAG, " PipeType: 0x%02" PRIx8 "", MsPipe->PipeType);
390  WLog_INFO(TAG, " InitCompleted: %d", MsPipe->InitCompleted);
391  }
392  }
393 
394  WLog_INFO(TAG, "==================================================");
395 }