FreeRDP
Loading...
Searching...
No Matches
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
103WINPR_ATTR_MALLOC(msusb_msinterface_free, 1)
104static MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_new(void)
105{
106 return (MSUSB_INTERFACE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_INTERFACE_DESCRIPTOR));
107}
108
109void msusb_msinterface_free(MSUSB_INTERFACE_DESCRIPTOR* MsInterface)
110{
111 if (MsInterface)
112 {
113 msusb_mspipes_free(MsInterface->MsPipes, MsInterface->NumberOfPipes);
114 MsInterface->MsPipes = NULL;
115 free(MsInterface);
116 }
117}
118
119static void msusb_msinterface_free_list(MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces,
120 UINT32 NumInterfaces)
121{
122 if (MsInterfaces)
123 {
124 for (UINT32 inum = 0; inum < NumInterfaces; inum++)
125 {
126 msusb_msinterface_free(MsInterfaces[inum]);
127 }
128
129 free((void*)MsInterfaces);
130 }
131}
132
133BOOL msusb_msinterface_replace(MSUSB_CONFIG_DESCRIPTOR* MsConfig, BYTE InterfaceNumber,
134 MSUSB_INTERFACE_DESCRIPTOR* NewMsInterface)
135{
136 if (!MsConfig || !MsConfig->MsInterfaces)
137 return FALSE;
138 if (MsConfig->NumInterfaces <= InterfaceNumber)
139 return FALSE;
140
141 msusb_msinterface_free(MsConfig->MsInterfaces[InterfaceNumber]);
142 MsConfig->MsInterfaces[InterfaceNumber] = NewMsInterface;
143 return TRUE;
144}
145
146MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_read(wStream* s)
147{
148 if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 12))
149 return NULL;
150
151 MSUSB_INTERFACE_DESCRIPTOR* MsInterface = msusb_msinterface_new();
152
153 if (!MsInterface)
154 return NULL;
155
156 Stream_Read_UINT16(s, MsInterface->Length);
157 Stream_Read_UINT16(s, MsInterface->NumberOfPipesExpected);
158 Stream_Read_UINT8(s, MsInterface->InterfaceNumber);
159 Stream_Read_UINT8(s, MsInterface->AlternateSetting);
160 Stream_Seek(s, 2);
161 Stream_Read_UINT32(s, MsInterface->NumberOfPipes);
162 MsInterface->InterfaceHandle = 0;
163 MsInterface->bInterfaceClass = 0;
164 MsInterface->bInterfaceSubClass = 0;
165 MsInterface->bInterfaceProtocol = 0;
166 MsInterface->InitCompleted = 0;
167 MsInterface->MsPipes = NULL;
168
169 if (MsInterface->NumberOfPipes > 0)
170 {
171 MsInterface->MsPipes = msusb_mspipes_read(s, MsInterface->NumberOfPipes);
172
173 if (!MsInterface->MsPipes)
174 goto out_error;
175 }
176
177 return MsInterface;
178out_error:
179 msusb_msinterface_free(MsInterface);
180 return NULL;
181}
182
183BOOL msusb_msinterface_write(const MSUSB_INTERFACE_DESCRIPTOR* MsInterface, wStream* out)
184{
185 MSUSB_PIPE_DESCRIPTOR** MsPipes = NULL;
186 MSUSB_PIPE_DESCRIPTOR* MsPipe = NULL;
187
188 if (!MsInterface)
189 return FALSE;
190
191 if (!Stream_EnsureRemainingCapacity(out, 16 + MsInterface->NumberOfPipes * 20))
192 return FALSE;
193
194 /* Length */
195 Stream_Write_UINT16(out, MsInterface->Length);
196 /* InterfaceNumber */
197 Stream_Write_UINT8(out, MsInterface->InterfaceNumber);
198 /* AlternateSetting */
199 Stream_Write_UINT8(out, MsInterface->AlternateSetting);
200 /* bInterfaceClass */
201 Stream_Write_UINT8(out, MsInterface->bInterfaceClass);
202 /* bInterfaceSubClass */
203 Stream_Write_UINT8(out, MsInterface->bInterfaceSubClass);
204 /* bInterfaceProtocol */
205 Stream_Write_UINT8(out, MsInterface->bInterfaceProtocol);
206 /* Padding */
207 Stream_Write_UINT8(out, 0);
208 /* InterfaceHandle */
209 Stream_Write_UINT32(out, MsInterface->InterfaceHandle);
210 /* NumberOfPipes */
211 Stream_Write_UINT32(out, MsInterface->NumberOfPipes);
212 /* Pipes */
213 MsPipes = MsInterface->MsPipes;
214
215 for (UINT32 pnum = 0; pnum < MsInterface->NumberOfPipes; pnum++)
216 {
217 MsPipe = MsPipes[pnum];
218 /* MaximumPacketSize */
219 Stream_Write_UINT16(out, MsPipe->MaximumPacketSize);
220 /* EndpointAddress */
221 Stream_Write_UINT8(out, MsPipe->bEndpointAddress);
222 /* Interval */
223 Stream_Write_UINT8(out, MsPipe->bInterval);
224 /* PipeType */
225 Stream_Write_UINT32(out, MsPipe->PipeType);
226 /* PipeHandle */
227 Stream_Write_UINT32(out, MsPipe->PipeHandle);
228 /* MaximumTransferSize */
229 Stream_Write_UINT32(out, MsPipe->MaximumTransferSize);
230 /* PipeFlags */
231 Stream_Write_UINT32(out, MsPipe->PipeFlags);
232 }
233
234 return TRUE;
235}
236
237static MSUSB_INTERFACE_DESCRIPTOR** msusb_msinterface_read_list(wStream* s, UINT32 NumInterfaces)
238{
239 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL;
240 MsInterfaces =
241 (MSUSB_INTERFACE_DESCRIPTOR**)calloc(NumInterfaces, sizeof(MSUSB_INTERFACE_DESCRIPTOR*));
242
243 if (!MsInterfaces)
244 return NULL;
245
246 for (UINT32 inum = 0; inum < NumInterfaces; inum++)
247 {
248 MsInterfaces[inum] = msusb_msinterface_read(s);
249
250 if (!MsInterfaces[inum])
251 goto fail;
252 }
253
254 return MsInterfaces;
255fail:
256
257 for (UINT32 inum = 0; inum < NumInterfaces; inum++)
258 msusb_msinterface_free(MsInterfaces[inum]);
259
260 free((void*)MsInterfaces);
261 return NULL;
262}
263
264BOOL msusb_msconfig_write(const MSUSB_CONFIG_DESCRIPTOR* MsConfg, wStream* out)
265{
266 if (!MsConfg)
267 return FALSE;
268
269 if (!Stream_EnsureRemainingCapacity(out, 8))
270 return FALSE;
271
272 /* ConfigurationHandle*/
273 Stream_Write_UINT32(out, MsConfg->ConfigurationHandle);
274 /* NumInterfaces*/
275 Stream_Write_UINT32(out, MsConfg->NumInterfaces);
276 /* Interfaces */
277 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfg->MsInterfaces;
278
279 for (UINT32 inum = 0; inum < MsConfg->NumInterfaces; inum++)
280 {
281 const MSUSB_INTERFACE_DESCRIPTOR* MsInterface = MsInterfaces[inum];
282
283 if (!msusb_msinterface_write(MsInterface, out))
284 return FALSE;
285 }
286
287 return TRUE;
288}
289
290MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_new(void)
291{
292 return (MSUSB_CONFIG_DESCRIPTOR*)calloc(1, sizeof(MSUSB_CONFIG_DESCRIPTOR));
293}
294
295void msusb_msconfig_free(MSUSB_CONFIG_DESCRIPTOR* MsConfig)
296{
297 if (MsConfig)
298 {
299 msusb_msinterface_free_list(MsConfig->MsInterfaces, MsConfig->NumInterfaces);
300 MsConfig->MsInterfaces = NULL;
301 free(MsConfig);
302 }
303}
304
305MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_read(wStream* s, UINT32 NumInterfaces)
306{
307 MSUSB_CONFIG_DESCRIPTOR* MsConfig = NULL;
308 BYTE lenConfiguration = 0;
309 BYTE typeConfiguration = 0;
310
311 if (!Stream_CheckAndLogRequiredCapacityOfSize(TAG, (s), 3ULL + NumInterfaces, 2ULL))
312 return NULL;
313
314 MsConfig = msusb_msconfig_new();
315
316 if (!MsConfig)
317 goto fail;
318
319 MsConfig->MsInterfaces = msusb_msinterface_read_list(s, NumInterfaces);
320
321 if (!MsConfig->MsInterfaces)
322 goto fail;
323
324 Stream_Read_UINT8(s, lenConfiguration);
325 Stream_Read_UINT8(s, typeConfiguration);
326
327 if (lenConfiguration != 0x9 || typeConfiguration != 0x2)
328 {
329 WLog_ERR(TAG, "len and type must be 0x9 and 0x2 , but it is 0x%" PRIx8 " and 0x%" PRIx8 "",
330 lenConfiguration, typeConfiguration);
331 goto fail;
332 }
333
334 Stream_Read_UINT16(s, MsConfig->wTotalLength);
335 Stream_Seek(s, 1);
336 Stream_Read_UINT8(s, MsConfig->bConfigurationValue);
337 MsConfig->NumInterfaces = NumInterfaces;
338 return MsConfig;
339fail:
340 msusb_msconfig_free(MsConfig);
341 return NULL;
342}
343
344void msusb_msconfig_dump(const MSUSB_CONFIG_DESCRIPTOR* MsConfig)
345{
346 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = NULL;
347 MSUSB_INTERFACE_DESCRIPTOR* MsInterface = NULL;
348 MSUSB_PIPE_DESCRIPTOR** MsPipes = NULL;
349 MSUSB_PIPE_DESCRIPTOR* MsPipe = NULL;
350
351 WLog_INFO(TAG, "=================MsConfig:========================");
352 WLog_INFO(TAG, "wTotalLength:%" PRIu16 "", MsConfig->wTotalLength);
353 WLog_INFO(TAG, "bConfigurationValue:%" PRIu8 "", MsConfig->bConfigurationValue);
354 WLog_INFO(TAG, "ConfigurationHandle:0x%08" PRIx32 "", MsConfig->ConfigurationHandle);
355 WLog_INFO(TAG, "InitCompleted:%d", MsConfig->InitCompleted);
356 WLog_INFO(TAG, "MsOutSize:%d", MsConfig->MsOutSize);
357 WLog_INFO(TAG, "NumInterfaces:%" PRIu32 "", MsConfig->NumInterfaces);
358 MsInterfaces = MsConfig->MsInterfaces;
359
360 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
361 {
362 MsInterface = MsInterfaces[inum];
363 WLog_INFO(TAG, " Interface: %" PRIu8 "", MsInterface->InterfaceNumber);
364 WLog_INFO(TAG, " Length: %" PRIu16 "", MsInterface->Length);
365 WLog_INFO(TAG, " NumberOfPipesExpected: %" PRIu16 "",
366 MsInterface->NumberOfPipesExpected);
367 WLog_INFO(TAG, " AlternateSetting: %" PRIu8 "", MsInterface->AlternateSetting);
368 WLog_INFO(TAG, " NumberOfPipes: %" PRIu32 "", MsInterface->NumberOfPipes);
369 WLog_INFO(TAG, " InterfaceHandle: 0x%08" PRIx32 "", MsInterface->InterfaceHandle);
370 WLog_INFO(TAG, " bInterfaceClass: 0x%02" PRIx8 "", MsInterface->bInterfaceClass);
371 WLog_INFO(TAG, " bInterfaceSubClass: 0x%02" PRIx8 "", MsInterface->bInterfaceSubClass);
372 WLog_INFO(TAG, " bInterfaceProtocol: 0x%02" PRIx8 "", MsInterface->bInterfaceProtocol);
373 WLog_INFO(TAG, " InitCompleted: %d", MsInterface->InitCompleted);
374 MsPipes = MsInterface->MsPipes;
375
376 for (UINT32 pnum = 0; pnum < MsInterface->NumberOfPipes; pnum++)
377 {
378 MsPipe = MsPipes[pnum];
379 WLog_INFO(TAG, " Pipe: %" PRIu32, pnum);
380 WLog_INFO(TAG, " MaximumPacketSize: 0x%04" PRIx16 "", MsPipe->MaximumPacketSize);
381 WLog_INFO(TAG, " MaximumTransferSize: 0x%08" PRIx32 "",
382 MsPipe->MaximumTransferSize);
383 WLog_INFO(TAG, " PipeFlags: 0x%08" PRIx32 "", MsPipe->PipeFlags);
384 WLog_INFO(TAG, " PipeHandle: 0x%08" PRIx32 "", MsPipe->PipeHandle);
385 WLog_INFO(TAG, " bEndpointAddress: 0x%02" PRIx8 "", MsPipe->bEndpointAddress);
386 WLog_INFO(TAG, " bInterval: %" PRIu8 "", MsPipe->bInterval);
387 WLog_INFO(TAG, " PipeType: 0x%02" PRIx8 "", MsPipe->PipeType);
388 WLog_INFO(TAG, " InitCompleted: %d", MsPipe->InitCompleted);
389 }
390 }
391
392 WLog_INFO(TAG, "==================================================");
393}