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
46void msusb_mspipes_replace(MSUSB_INTERFACE_DESCRIPTOR* MsInterface,
47 MSUSB_PIPE_DESCRIPTOR** NewMsPipes, UINT32 NewNumberOfPipes)
48{
49 WINPR_ASSERT(MsInterface);
50 WINPR_ASSERT(NewMsPipes || (NewNumberOfPipes == 0));
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}
58
59static MSUSB_PIPE_DESCRIPTOR** msusb_mspipes_read(wStream* s, UINT32 NumberOfPipes)
60{
61 MSUSB_PIPE_DESCRIPTOR** MsPipes = nullptr;
62
63 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, (s), NumberOfPipes, 12ull))
64 return nullptr;
65
66 MsPipes = (MSUSB_PIPE_DESCRIPTOR**)calloc(NumberOfPipes, sizeof(MSUSB_PIPE_DESCRIPTOR*));
67
68 if (!MsPipes)
69 return nullptr;
70
71 for (UINT32 pnum = 0; pnum < NumberOfPipes; pnum++)
72 {
73 MSUSB_PIPE_DESCRIPTOR* MsPipe = msusb_mspipe_new();
74
75 if (!MsPipe)
76 goto out_error;
77
78 Stream_Read_UINT16(s, MsPipe->MaximumPacketSize);
79 Stream_Seek(s, 2);
80 Stream_Read_UINT32(s, MsPipe->MaximumTransferSize);
81 Stream_Read_UINT32(s, MsPipe->PipeFlags);
82 /* Already set to zero by memset
83 MsPipe->PipeHandle = 0;
84 MsPipe->bEndpointAddress = 0;
85 MsPipe->bInterval = 0;
86 MsPipe->PipeType = 0;
87 MsPipe->InitCompleted = 0;
88 */
89 MsPipes[pnum] = MsPipe;
90 }
91
92 return MsPipes;
93out_error:
94
95 for (UINT32 pnum = 0; pnum < NumberOfPipes; pnum++)
96 free(MsPipes[pnum]);
97
98 free((void*)MsPipes);
99 return nullptr;
100}
101
102WINPR_ATTR_MALLOC(msusb_msinterface_free, 1)
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 = nullptr;
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 if (MsConfig->NumInterfaces <= InterfaceNumber)
138 return FALSE;
139
140 msusb_msinterface_free(MsConfig->MsInterfaces[InterfaceNumber]);
141 MsConfig->MsInterfaces[InterfaceNumber] = NewMsInterface;
142 return TRUE;
143}
144
145MSUSB_INTERFACE_DESCRIPTOR* msusb_msinterface_read(wStream* s)
146{
147 if (!Stream_CheckAndLogRequiredLength(TAG, (s), 12))
148 return nullptr;
149
150 MSUSB_INTERFACE_DESCRIPTOR* MsInterface = msusb_msinterface_new();
151
152 if (!MsInterface)
153 return nullptr;
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 = nullptr;
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 nullptr;
180}
181
182BOOL msusb_msinterface_write(const MSUSB_INTERFACE_DESCRIPTOR* MsInterface, wStream* out)
183{
184 MSUSB_PIPE_DESCRIPTOR** MsPipes = nullptr;
185 MSUSB_PIPE_DESCRIPTOR* MsPipe = nullptr;
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 = nullptr;
239 MsInterfaces =
240 (MSUSB_INTERFACE_DESCRIPTOR**)calloc(NumInterfaces, sizeof(MSUSB_INTERFACE_DESCRIPTOR*));
241
242 if (!MsInterfaces)
243 return nullptr;
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 nullptr;
261}
262
263BOOL msusb_msconfig_write(const MSUSB_CONFIG_DESCRIPTOR* MsConfig, wStream* out)
264{
265 if (!MsConfig)
266 return FALSE;
267
268 if (!Stream_EnsureRemainingCapacity(out, 8))
269 return FALSE;
270
271 /* ConfigurationHandle*/
272 Stream_Write_UINT32(out, MsConfig->ConfigurationHandle);
273 /* NumInterfaces*/
274 Stream_Write_UINT32(out, MsConfig->NumInterfaces);
275 /* Interfaces */
276 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = MsConfig->MsInterfaces;
277
278 for (UINT32 inum = 0; inum < MsConfig->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 = nullptr;
300 free(MsConfig);
301 }
302}
303
304MSUSB_CONFIG_DESCRIPTOR* msusb_msconfig_read(wStream* s, UINT32 NumInterfaces)
305{
306 MSUSB_CONFIG_DESCRIPTOR* MsConfig = nullptr;
307 BYTE lenConfiguration = 0;
308 BYTE typeConfiguration = 0;
309
310 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, (s), 3ULL + NumInterfaces, 2ULL))
311 return nullptr;
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 /* Record the count now so the cleanup path frees every interface descriptor. */
324 MsConfig->NumInterfaces = NumInterfaces;
325
326 if (!Stream_CheckAndLogRequiredLength(TAG, (s), 6))
327 goto fail;
328
329 Stream_Read_UINT8(s, lenConfiguration);
330 Stream_Read_UINT8(s, typeConfiguration);
331
332 if (lenConfiguration != 0x9 || typeConfiguration != 0x2)
333 {
334 WLog_ERR(TAG, "len and type must be 0x9 and 0x2 , but it is 0x%" PRIx8 " and 0x%" PRIx8 "",
335 lenConfiguration, typeConfiguration);
336 goto fail;
337 }
338
339 Stream_Read_UINT16(s, MsConfig->wTotalLength);
340 Stream_Seek(s, 1);
341 Stream_Read_UINT8(s, MsConfig->bConfigurationValue);
342 return MsConfig;
343fail:
344 msusb_msconfig_free(MsConfig);
345 return nullptr;
346}
347
348void msusb_msconfig_dump(const MSUSB_CONFIG_DESCRIPTOR* MsConfig)
349{
350 MSUSB_INTERFACE_DESCRIPTOR** MsInterfaces = nullptr;
351 MSUSB_INTERFACE_DESCRIPTOR* MsInterface = nullptr;
352 MSUSB_PIPE_DESCRIPTOR** MsPipes = nullptr;
353 MSUSB_PIPE_DESCRIPTOR* MsPipe = nullptr;
354
355 WLog_INFO(TAG, "=================MsConfig:========================");
356 WLog_INFO(TAG, "wTotalLength:%" PRIu16 "", MsConfig->wTotalLength);
357 WLog_INFO(TAG, "bConfigurationValue:%" PRIu8 "", MsConfig->bConfigurationValue);
358 WLog_INFO(TAG, "ConfigurationHandle:0x%08" PRIx32 "", MsConfig->ConfigurationHandle);
359 WLog_INFO(TAG, "InitCompleted:%d", MsConfig->InitCompleted);
360 WLog_INFO(TAG, "MsOutSize:%d", MsConfig->MsOutSize);
361 WLog_INFO(TAG, "NumInterfaces:%" PRIu32 "", MsConfig->NumInterfaces);
362 MsInterfaces = MsConfig->MsInterfaces;
363
364 for (UINT32 inum = 0; inum < MsConfig->NumInterfaces; inum++)
365 {
366 MsInterface = MsInterfaces[inum];
367 WLog_INFO(TAG, " Interface: %" PRIu8 "", MsInterface->InterfaceNumber);
368 WLog_INFO(TAG, " Length: %" PRIu16 "", MsInterface->Length);
369 WLog_INFO(TAG, " NumberOfPipesExpected: %" PRIu16 "",
370 MsInterface->NumberOfPipesExpected);
371 WLog_INFO(TAG, " AlternateSetting: %" PRIu8 "", MsInterface->AlternateSetting);
372 WLog_INFO(TAG, " NumberOfPipes: %" PRIu32 "", MsInterface->NumberOfPipes);
373 WLog_INFO(TAG, " InterfaceHandle: 0x%08" PRIx32 "", MsInterface->InterfaceHandle);
374 WLog_INFO(TAG, " bInterfaceClass: 0x%02" PRIx8 "", MsInterface->bInterfaceClass);
375 WLog_INFO(TAG, " bInterfaceSubClass: 0x%02" PRIx8 "", MsInterface->bInterfaceSubClass);
376 WLog_INFO(TAG, " bInterfaceProtocol: 0x%02" PRIx8 "", MsInterface->bInterfaceProtocol);
377 WLog_INFO(TAG, " InitCompleted: %d", MsInterface->InitCompleted);
378 MsPipes = MsInterface->MsPipes;
379
380 for (UINT32 pnum = 0; pnum < MsInterface->NumberOfPipes; pnum++)
381 {
382 MsPipe = MsPipes[pnum];
383 WLog_INFO(TAG, " Pipe: %" PRIu32, pnum);
384 WLog_INFO(TAG, " MaximumPacketSize: 0x%04" PRIx16 "", MsPipe->MaximumPacketSize);
385 WLog_INFO(TAG, " MaximumTransferSize: 0x%08" PRIx32 "",
386 MsPipe->MaximumTransferSize);
387 WLog_INFO(TAG, " PipeFlags: 0x%08" PRIx32 "", MsPipe->PipeFlags);
388 WLog_INFO(TAG, " PipeHandle: 0x%08" PRIx32 "", MsPipe->PipeHandle);
389 WLog_INFO(TAG, " bEndpointAddress: 0x%02" PRIx8 "", MsPipe->bEndpointAddress);
390 WLog_INFO(TAG, " bInterval: %" PRIu8 "", MsPipe->bInterval);
391 WLog_INFO(TAG, " PipeType: 0x%02" PRIx8 "", MsPipe->PipeType);
392 WLog_INFO(TAG, " InitCompleted: %d", MsPipe->InitCompleted);
393 }
394 }
395
396 WLog_INFO(TAG, "==================================================");
397}