FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
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
30static MSUSB_PIPE_DESCRIPTOR* msusb_mspipe_new(void)
31{
32 return (MSUSB_PIPE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_PIPE_DESCRIPTOR));
33}
34
35static 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((void*)MsPipes);
43 }
44}
45
46BOOL 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 original 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
60static 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;
94out_error:
95
96 for (UINT32 pnum = 0; pnum < NumberOfPipes; pnum++)
97 free(MsPipes[pnum]);
98
99 free((void*)MsPipes);
100 return NULL;
101}
102
103static MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_new(void)
104{
105 return (MSUSB_INTERFACE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_INTERFACE_DESCRIPTOR));
106}
107
108void 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
118static 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((void*)MsInterfaces);
129 }
130}
131
132BOOL 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
143MSUSB_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;
177out_error:
178 msusb_msinterface_free(MsInterface);
179 return NULL;
180}
181
182BOOL msusb_msinterface_write(const 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
236static 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;
254fail:
255
256 for (UINT32 inum = 0; inum < NumInterfaces; inum++)
257 msusb_msinterface_free(MsInterfaces[inum]);
258
259 free((void*)MsInterfaces);
260 return NULL;
261}
262
263BOOL msusb_msconfig_write(const MSUSB_CONFIG_DESCRIPTOR* MsConfg, wStream* out)
264{
265 if (!MsConfg)
266 return FALSE;
267
268 if (!Stream_EnsureRemainingCapacity(out, 8))
269 return FALSE;
270
271 /* ConfigurationHandle*/
272 Stream_Write_UINT32(out, MsConfg->ConfigurationHandle);
273 /* NumInterfaces*/
274 Stream_Write_UINT32(out, MsConfg->NumInterfaces);
275 /* Interfaces */
276 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfg->MsInterfaces;
277
278 for (UINT32 inum = 0; inum < MsConfg->NumInterfaces; inum++)
279 {
280 const MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum];
281
282 if (!msusb_msinterface_write(MsInterface, out))
283 return FALSE;
284 }
285
286 return TRUE;
287}
288
289MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_new(void)
290{
291 return (MSUSB_CONFIG_DESCRIPTOR*)calloc(1, sizeof(MSUSB_CONFIG_DESCRIPTOR));
292}
293
294void msusb_msconfig_free(MSUSB_CONFIG_DESCRIPTOR* MsConfig)
295{
296 if (MsConfig)
297 {
298 msusb_msinterface_free_list(MsConfig->MsInterfaces, MsConfig->NumInterfaces);
299 MsConfig->MsInterfaces = NULL;
300 free(MsConfig);
301 }
302}
303
304MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_read(wStream* s, UINT32 NumInterfaces)
305{
306 MSUSB_CONFIG_DESCRIPTOR* MsConfig = NULL;
307 BYTE lenConfiguration = 0;
308 BYTE typeConfiguration = 0;
309
310 if (!Stream_CheckAndLogRequiredCapacityOfSize(TAG, (s), 3ULL + NumInterfaces, 2ULL))
311 return NULL;
312
313 MsConfig = msusb_msconfig_new();
314
315 if (!MsConfig)
316 goto fail;
317
318 MsConfig->MsInterfaces = msusb_msinterface_read_list(s, NumInterfaces);
319
320 if (!MsConfig->MsInterfaces)
321 goto fail;
322
323 Stream_Read_UINT8(s, lenConfiguration);
324 Stream_Read_UINT8(s, typeConfiguration);
325
326 if (lenConfiguration != 0x9 || typeConfiguration != 0x2)
327 {
328 WLog_ERR(TAG, "len and type must be 0x9 and 0x2 , but it is 0x%" PRIx8 " and 0x%" PRIx8 "",
329 lenConfiguration, typeConfiguration);
330 goto fail;
331 }
332
333 Stream_Read_UINT16(s, MsConfig->wTotalLength);
334 Stream_Seek(s, 1);
335 Stream_Read_UINT8(s, MsConfig->bConfigurationValue);
336 MsConfig->NumInterfaces = NumInterfaces;
337 return MsConfig;
338fail:
339 msusb_msconfig_free(MsConfig);
340 return NULL;
341}
342
343void msusb_msconfig_dump(const MSUSB_CONFIG_DESCRIPTOR* MsConfig)
344{
345 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL;
346 MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL;
347 MSUSB_PIPE_DESCRIPTOR** MsPipes = NULL;
348 MSUSB_PIPE_DESCRIPTOR* MsPipe = NULL;
349
350 WLog_INFO(TAG, "=================MsConfig:========================");
351 WLog_INFO(TAG, "wTotalLength:%" PRIu16 "", MsConfig->wTotalLength);
352 WLog_INFO(TAG, "bConfigurationValue:%" PRIu8 "", MsConfig->bConfigurationValue);
353 WLog_INFO(TAG, "ConfigurationHandle:0x%08" PRIx32 "", MsConfig->ConfigurationHandle);
354 WLog_INFO(TAG, "InitCompleted:%d", MsConfig->InitCompleted);
355 WLog_INFO(TAG, "MsOutSize:%d", MsConfig->MsOutSize);
356 WLog_INFO(TAG, "NumInterfaces:%" PRIu32 "", MsConfig->NumInterfaces);
357 MsInterfaces = MsConfig->MsInterfaces;
358
359 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
360 {
361 MsInterface = MsInterfaces[inum];
362 WLog_INFO(TAG, " Interface: %" PRIu8 "", MsInterface->InterfaceNumber);
363 WLog_INFO(TAG, " Length: %" PRIu16 "", MsInterface->Length);
364 WLog_INFO(TAG, " NumberOfPipesExpected: %" PRIu16 "",
365 MsInterface->NumberOfPipesExpected);
366 WLog_INFO(TAG, " AlternateSetting: %" PRIu8 "", MsInterface->AlternateSetting);
367 WLog_INFO(TAG, " NumberOfPipes: %" PRIu32 "", MsInterface->NumberOfPipes);
368 WLog_INFO(TAG, " InterfaceHandle: 0x%08" PRIx32 "", MsInterface->InterfaceHandle);
369 WLog_INFO(TAG, " bInterfaceClass: 0x%02" PRIx8 "", MsInterface->bInterfaceClass);
370 WLog_INFO(TAG, " bInterfaceSubClass: 0x%02" PRIx8 "", MsInterface->bInterfaceSubClass);
371 WLog_INFO(TAG, " bInterfaceProtocol: 0x%02" PRIx8 "", MsInterface->bInterfaceProtocol);
372 WLog_INFO(TAG, " InitCompleted: %d", MsInterface->InitCompleted);
373 MsPipes = MsInterface->MsPipes;
374
375 for (UINT32 pnum = 0; pnum < MsInterface->NumberOfPipes; pnum++)
376 {
377 MsPipe = MsPipes[pnum];
378 WLog_INFO(TAG, " Pipe: %" PRIu32, pnum);
379 WLog_INFO(TAG, " MaximumPacketSize: 0x%04" PRIx16 "", MsPipe->MaximumPacketSize);
380 WLog_INFO(TAG, " MaximumTransferSize: 0x%08" PRIx32 "",
381 MsPipe->MaximumTransferSize);
382 WLog_INFO(TAG, " PipeFlags: 0x%08" PRIx32 "", MsPipe->PipeFlags);
383 WLog_INFO(TAG, " PipeHandle: 0x%08" PRIx32 "", MsPipe->PipeHandle);
384 WLog_INFO(TAG, " bEndpointAddress: 0x%02" PRIx8 "", MsPipe->bEndpointAddress);
385 WLog_INFO(TAG, " bInterval: %" PRIu8 "", MsPipe->bInterval);
386 WLog_INFO(TAG, " PipeType: 0x%02" PRIx8 "", MsPipe->PipeType);
387 WLog_INFO(TAG, " InitCompleted: %d", MsPipe->InitCompleted);
388 }
389 }
390
391 WLog_INFO(TAG, "==================================================");
392}