ReactOS 0.4.15-dev-7942-gd23573b
descriptor.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbccgp/descriptor.c
5 * PURPOSE: USB device driver.
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
9 * Cameron Gutman
10 */
11
12#include "usbccgp.h"
13
14#define NDEBUG
15#include <debug.h>
16
22 IN ULONG DescriptorLength,
23 IN UCHAR DescriptorIndex,
24 IN LANGID LanguageId,
25 OUT PVOID *OutDescriptor)
26{
27 PURB Urb;
30
31 //
32 // sanity checks
33 //
35 ASSERT(OutDescriptor);
36 ASSERT(DescriptorLength);
37
38 //
39 // first allocate descriptor buffer
40 //
41 Descriptor = AllocateItem(NonPagedPool, DescriptorLength);
42 if (!Descriptor)
43 {
44 //
45 // no memory
46 //
48 }
49
50 //
51 // allocate urb
52 //
53 Urb = (PURB) AllocateItem(NonPagedPool, sizeof(URB));
54 if (!Urb)
55 {
56 //
57 // no memory
58 //
61 }
62
63 //
64 // initialize urb
65 //
67 sizeof(Urb->UrbControlDescriptorRequest),
69 DescriptorIndex,
70 LanguageId,
72 NULL,
73 DescriptorLength,
74 NULL);
75
76 //
77 // submit urb
78 //
80
81 //
82 // free urb
83 //
84 FreeItem(Urb);
85
86 if (NT_SUCCESS(Status))
87 {
88 //
89 // store result
90 //
91 *OutDescriptor = Descriptor;
92 }
93
94 //
95 // done
96 //
97 return Status;
98}
99
101NTAPI
104 IN ULONG DescriptorLength,
105 IN UCHAR DescriptorIndex,
106 IN LANGID LanguageId,
107 OUT PVOID *OutDescriptor)
108{
110 PUSB_STRING_DESCRIPTOR StringDescriptor;
111 ULONG Size;
113
114 // retrieve descriptor
115 Status = USBCCGP_GetDescriptor(DeviceObject, USB_STRING_DESCRIPTOR_TYPE, DescriptorLength, DescriptorIndex, LanguageId, OutDescriptor);
116 if (!NT_SUCCESS(Status))
117 {
118 // failed
119 return Status;
120 }
121
122 // get descriptor structure
123 StringDescriptor = (PUSB_STRING_DESCRIPTOR)*OutDescriptor;
124
125 // sanity check
126 ASSERT(StringDescriptor->bLength < DescriptorLength - 2);
127
128 if (StringDescriptor->bLength == 2)
129 {
130 // invalid descriptor
131 FreeItem(StringDescriptor);
133 }
134
135 // calculate size
136 Size = StringDescriptor->bLength + sizeof(WCHAR);
137
138 // allocate buffer
140 if (!Buffer)
141 {
142 // no memory
143 FreeItem(StringDescriptor);
145 }
146
147 // copy result
148 RtlCopyMemory(Buffer, StringDescriptor->bString, Size - FIELD_OFFSET(USB_STRING_DESCRIPTOR, bString));
149
150 // free buffer
151 FreeItem(StringDescriptor);
152
153 // store result
154 *OutDescriptor = (PVOID)Buffer;
155 return STATUS_SUCCESS;
156}
157
158
162{
164 PFDO_DEVICE_EXTENSION DeviceExtension;
165 USHORT DescriptorLength;
166
167 //
168 // get device extension
169 //
170 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
171
172 //
173 // first get device descriptor
174 //
175 Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(USB_DEVICE_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->DeviceDescriptor);
176 if (!NT_SUCCESS(Status))
177 {
178 //
179 // failed to get device descriptor
180 //
181 DeviceExtension->DeviceDescriptor = NULL;
182 return Status;
183 }
184
185 //
186 // now get basic configuration descriptor
187 //
188 Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(USB_CONFIGURATION_DESCRIPTOR), 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
189 if (!NT_SUCCESS(Status))
190 {
191 //
192 // failed to get configuration descriptor
193 //
194 FreeItem(DeviceExtension->DeviceDescriptor);
195 DeviceExtension->DeviceDescriptor = NULL;
196 return Status;
197 }
198
199 //
200 // backup length
201 //
202 DescriptorLength = DeviceExtension->ConfigurationDescriptor->wTotalLength;
203
204 //
205 // release basic descriptor
206 //
207 FreeItem(DeviceExtension->ConfigurationDescriptor);
208 DeviceExtension->ConfigurationDescriptor = NULL;
209
210 //
211 // allocate full descriptor
212 //
213 Status = USBCCGP_GetDescriptor(DeviceExtension->NextDeviceObject, USB_CONFIGURATION_DESCRIPTOR_TYPE, DescriptorLength, 0, 0, (PVOID*)&DeviceExtension->ConfigurationDescriptor);
214 if (!NT_SUCCESS(Status))
215 {
216 //
217 // failed to get configuration descriptor
218 //
219 FreeItem(DeviceExtension->DeviceDescriptor);
220 DeviceExtension->DeviceDescriptor = NULL;
221 return Status;
222 }
223 return Status;
224}
225
228 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
230{
232 ULONG Count = 0;
234
235 //
236 // allocate array
237 //
238 Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * ConfigurationDescriptor->bNumInterfaces);
239 if (!Array)
241
242 //
243 // enumerate all interfaces
244 //
245 Count = 0;
246 do
247 {
248 //
249 // find next descriptor
250 //
251 InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, Count, 0, -1, -1, -1);
253 break;
254
255 //
256 // store descriptor
257 //
258 Array[Count] = InterfaceDescriptor;
259 Count++;
260
261 }while(TRUE);
262
263 //
264 // store result
265 //
266 *OutArray = Array;
267
268 //
269 // done
270 //
271 return STATUS_SUCCESS;
272}
273
274VOID
276 IN PFDO_DEVICE_EXTENSION FDODeviceExtension,
277 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
278{
280
281 Descriptor = (PUSB_COMMON_DESCRIPTOR)ConfigurationDescriptor;
282
283 DbgPrint("Bogus ConfigurationDescriptor Found\n");
284 DbgPrint("InterfaceCount %x\n", ConfigurationDescriptor->bNumInterfaces);
285
286 do
287 {
288 if (((ULONG_PTR)Descriptor) >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
289 break;
290
291 DbgPrint("Descriptor Type %x Length %lu Offset %lu\n", Descriptor->bDescriptorType, Descriptor->bLength, ((ULONG_PTR)Descriptor - (ULONG_PTR)ConfigurationDescriptor));
292
293 // check for invalid descriptors
294 if (!Descriptor->bLength)
295 {
296 DbgPrint("Bogus Descriptor!!!\n");
297 break;
298 }
299
300 // advance to next descriptor
302
303 }while(TRUE);
304
305
306}
307
308
310NTAPI
312 IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension,
313 IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
314{
317 ULONG DescriptorCount;
318
319 //
320 // sanity checks
321 //
322 ASSERT(ConfigurationDescriptor);
323 ASSERT(ConfigurationDescriptor->bNumInterfaces);
324
325 //
326 // count all interface descriptors
327 //
328 DescriptorCount = ConfigurationDescriptor->bNumInterfaces;
329 if (DescriptorCount == 0)
330 {
331 DPRINT1("[USBCCGP] DescriptorCount is zero\n");
333 }
334
335 //
336 // allocate array holding the interface descriptors
337 //
338 FDODeviceExtension->InterfaceList = AllocateItem(NonPagedPool, sizeof(USBD_INTERFACE_LIST_ENTRY) * (DescriptorCount + 1));
339 if (!FDODeviceExtension->InterfaceList)
340 {
341 //
342 // no memory
343 //
345 }
346
347 //
348 // reset interface list count
349 //
350 FDODeviceExtension->InterfaceListCount = 0;
351
352 do
353 {
354 //
355 // parse configuration descriptor
356 //
357 InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, InterfaceIndex, -1, -1, -1, -1);
359 {
360 //
361 // store in interface list
362 //
363 ASSERT(FDODeviceExtension->InterfaceListCount < DescriptorCount);
364 FDODeviceExtension->InterfaceList[FDODeviceExtension->InterfaceListCount].InterfaceDescriptor = InterfaceDescriptor;
365 FDODeviceExtension->InterfaceListCount++;
366 }
367 else
368 {
369 DumpConfigurationDescriptor(ConfigurationDescriptor);
370 DumpFullConfigurationDescriptor(FDODeviceExtension, ConfigurationDescriptor);
371
372 //
373 // see issue
374 // CORE-6574 Test 3 (USB Web Cam)
375 //
376 if (FDODeviceExtension->DeviceDescriptor && FDODeviceExtension->DeviceDescriptor->idVendor == 0x0458 && FDODeviceExtension->DeviceDescriptor->idProduct == 0x705f)
377 ASSERT(FALSE);
378 }
379
380 //
381 // move to next interface
382 //
384
385 }while(InterfaceIndex < DescriptorCount);
386
387 //
388 // sanity check
389 //
390 ASSERT(FDODeviceExtension->InterfaceListCount);
391
392 //
393 // done
394 //
395 return STATUS_SUCCESS;
396}
397
398VOID
400{
401 DbgPrint("Dumping ConfigurationDescriptor %x\n", ConfigurationDescriptor);
402 DbgPrint("bLength %x\n", ConfigurationDescriptor->bLength);
403 DbgPrint("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
404 DbgPrint("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
405 DbgPrint("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
406 DbgPrint("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
407 DbgPrint("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
408 DbgPrint("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
409 DbgPrint("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
410}
411
415 IN PFDO_DEVICE_EXTENSION DeviceExtension,
417{
419 PURB Urb;
420
421 //
422 // allocate urb
423 //
424 Urb = AllocateItem(NonPagedPool, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bNumEndpoints));
425 if (!Urb)
426 {
427 //
428 // no memory
429 //
431 }
432
433 //
434 // now prepare interface urb
435 //
436 UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bInterfaceNumber, DeviceExtension->InterfaceList[InterfaceIndex].InterfaceDescriptor->bAlternateSetting);
437
438 //
439 // now select the interface
440 //
441 Status = USBCCGP_SyncUrbRequest(DeviceExtension->NextDeviceObject, Urb);
442
443 //
444 // did it succeed
445 //
446 if (NT_SUCCESS(Status))
447 {
448 //
449 // update configuration info
450 //
451 ASSERT(Urb->UrbSelectInterface.Interface.Length == DeviceExtension->InterfaceList[InterfaceIndex].Interface->Length);
452 RtlCopyMemory(DeviceExtension->InterfaceList[InterfaceIndex].Interface, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
453 }
454
455 //
456 // free urb
457 //
458 FreeItem(Urb);
459
460 //
461 // done
462 //
463 return Status;
464}
465
469 IN PFDO_DEVICE_EXTENSION DeviceExtension)
470{
471 PUSBD_INTERFACE_INFORMATION InterfaceInformation;
473 PURB Urb;
474 ULONG Index;
475
476 //
477 // now scan configuration descriptors
478 //
479 Status = USBCCGP_ScanConfigurationDescriptor(DeviceExtension, DeviceExtension->ConfigurationDescriptor);
480 if (!NT_SUCCESS(Status))
481 {
482 //
483 // failed to scan
484 //
485 return Status;
486 }
487
488 //
489 // now allocate the urb
490 //
491 Urb = USBD_CreateConfigurationRequestEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->InterfaceList);
492 if (!Urb)
493 {
494 //
495 // no memory
496 //
498 }
499
500 //
501 // submit urb
502 //
503 Status = USBCCGP_SyncUrbRequest(DeviceExtension->NextDeviceObject, Urb);
504 if (!NT_SUCCESS(Status))
505 {
506 //
507 // failed to set configuration
508 //
509 DPRINT1("USBCCGP_SyncUrbRequest failed to set interface %x\n", Status);
510 ExFreePool(Urb);
511 return Status;
512 }
513
514 //
515 // get interface information
516 //
517 InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
518 for(Index = 0; Index < DeviceExtension->InterfaceListCount; Index++)
519 {
520 //
521 // allocate buffer to store interface information
522 //
523 DeviceExtension->InterfaceList[Index].Interface = AllocateItem(NonPagedPool, InterfaceInformation->Length);
524 if (!DeviceExtension->InterfaceList[Index].Interface)
525 {
526 //
527 // no memory
528 //
530 }
531
532 //
533 // copy interface information
534 //
535 RtlCopyMemory(DeviceExtension->InterfaceList[Index].Interface, InterfaceInformation, InterfaceInformation->Length);
536
537 //
538 // move to next interface
539 //
540 InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + InterfaceInformation->Length);
541 }
542
543
544 //
545 // store pipe handle
546 //
547 DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
548
549 //
550 // free interface list & urb
551 //
552 ExFreePool(Urb);
553
554 //
555 // done
556 //
557 return Status;
558}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
VOID DumpFullConfigurationDescriptor(IN PFDO_DEVICE_EXTENSION FDODeviceExtension, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
Definition: descriptor.c:275
NTSTATUS USBCCGP_SelectConfiguration(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: descriptor.c:467
VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
Definition: descriptor.c:399
NTSTATUS NTAPI USBCCGP_GetStringDescriptor(IN PDEVICE_OBJECT DeviceObject, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: descriptor.c:102
NTSTATUS NTAPI USBCCGP_GetDescriptor(IN PDEVICE_OBJECT DeviceObject, IN UCHAR DescriptorType, IN ULONG DescriptorLength, IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor)
Definition: descriptor.c:19
NTSTATUS AllocateInterfaceDescriptorsArray(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, OUT PUSB_INTERFACE_DESCRIPTOR **OutArray)
Definition: descriptor.c:227
NTSTATUS USBCCGP_SelectInterface(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension, IN ULONG InterfaceIndex)
Definition: descriptor.c:413
NTSTATUS USBCCGP_GetDescriptors(IN PDEVICE_OBJECT DeviceObject)
Definition: descriptor.c:160
NTSTATUS NTAPI USBCCGP_ScanConfigurationDescriptor(IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
Definition: descriptor.c:311
NTSTATUS USBCCGP_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:35
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
#define DbgPrint
Definition: hal.h:12
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
USHORT LANGID
Definition: mui.h:9
#define ASSERT(a)
Definition: mode.c:44
int Count
Definition: noreturn.cpp:7
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: usb.h:529
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:533
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:532
Definition: usbdlib.h:7
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
struct _USB_STRING_DESCRIPTOR * PUSB_STRING_DESCRIPTOR
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
#define USB_STRING_DESCRIPTOR_TYPE
Definition: usb100.h:51
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
struct _USBD_INTERFACE_INFORMATION * PUSBD_INTERFACE_INFORMATION
struct _URB * PURB
PURB NTAPI USBD_CreateConfigurationRequestEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSBD_INTERFACE_LIST_ENTRY InterfaceList)
Definition: usbd.c:329
PUSB_INTERFACE_DESCRIPTOR NTAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PVOID StartPosition, LONG InterfaceNumber, LONG AlternateSetting, LONG InterfaceClass, LONG InterfaceSubClass, LONG InterfaceProtocol)
Definition: usbd.c:496
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:160
#define UsbBuildSelectInterfaceRequest(urb, length, configurationHandle, interfaceNumber, alternateSetting)
Definition: usbdlib.h:59
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:117
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: wdfusb.h:2334
_In_ WDFUSBDEVICE _In_ UCHAR InterfaceIndex
Definition: wdfusb.h:2462
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180