2 * PROJECT: ReactOS Universal Serial Bus Driver/Helper Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbd/usbd.c
5 * PURPOSE: Helper Library for USB
7 * Filip Navara <xnavara@volny.cz>
8 * Michael Martin <michael.martin@reactos.org>
13 * Universal Serial Bus Driver/Helper Library
15 * Written by Filip Navara <xnavara@volny.cz>
18 * This driver was obsoleted in Windows XP and most functions
19 * became pure stubs. But some of them were retained for backward
20 * compatibilty with existing drivers.
22 * Preserved functions:
24 * USBD_Debug_GetHeap (implemented)
25 * USBD_Debug_RetHeap (implemented)
26 * USBD_CalculateUsbBandwidth (implemented, tested)
27 * USBD_CreateConfigurationRequestEx (implemented)
28 * USBD_CreateConfigurationRequest
29 * USBD_GetInterfaceLength (implemented)
30 * USBD_ParseConfigurationDescriptorEx (implemented)
31 * USBD_ParseDescriptors (implemented)
32 * USBD_GetPdoRegistryParameters (implemented)
38 #ifndef PLUGPLAY_REGKEY_DRIVER
39 #define PLUGPLAY_REGKEY_DRIVER 2
41 typedef struct _USBD_INTERFACE_LIST_ENTRY
{
42 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
43 PUSBD_INTERFACE_INFORMATION Interface
;
44 } USBD_INTERFACE_LIST_ENTRY
, *PUSBD_INTERFACE_LIST_ENTRY
;
47 DriverEntry(PDRIVER_OBJECT DriverObject
,
48 PUNICODE_STRING RegistryPath
)
50 return STATUS_SUCCESS
;
57 DllInitialize(ULONG Unknown
)
75 USBD_Debug_GetHeap(ULONG Unknown1
, POOL_TYPE PoolType
, ULONG NumberOfBytes
,
78 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
85 USBD_Debug_RetHeap(PVOID Heap
, ULONG Unknown2
, ULONG Unknown3
)
94 USBD_Debug_LogEntry(PCHAR Name
, ULONG_PTR Info1
, ULONG_PTR Info2
,
103 USBD_AllocateDeviceName(ULONG Unknown
)
112 USBD_CalculateUsbBandwidth(
118 ULONG OverheadTable
[] = {
119 0x00, /* UsbdPipeTypeControl */
120 0x09, /* UsbdPipeTypeIsochronous */
121 0x00, /* UsbdPipeTypeBulk */
122 0x0d /* UsbdPipeTypeInterrupt */
126 if (OverheadTable
[EndpointType
] != 0)
128 Result
= ((MaxPacketSize
+ OverheadTable
[EndpointType
]) * 8 * 7) / 6;
140 USBD_Dispatch(ULONG Unknown1
, ULONG Unknown2
, ULONG Unknown3
, ULONG Unknown4
)
149 USBD_FreeDeviceMutex(PVOID Unknown
)
157 USBD_FreeDeviceName(PVOID Unknown
)
165 USBD_WaitDeviceMutex(PVOID Unknown
)
173 USBD_GetSuspendPowerState(ULONG Unknown1
)
182 USBD_InitializeDevice(ULONG Unknown1
, ULONG Unknown2
, ULONG Unknown3
,
183 ULONG Unknown4
, ULONG Unknown5
, ULONG Unknown6
)
185 return STATUS_NOT_SUPPORTED
;
192 USBD_RegisterHostController(ULONG Unknown1
, ULONG Unknown2
, ULONG Unknown3
,
193 ULONG Unknown4
, ULONG Unknown5
, ULONG Unknown6
, ULONG Unknown7
,
194 ULONG Unknown8
, ULONG Unknown9
, ULONG Unknown10
)
196 return STATUS_NOT_SUPPORTED
;
203 USBD_GetDeviceInformation(ULONG Unknown1
, ULONG Unknown2
, ULONG Unknown3
)
205 return STATUS_NOT_SUPPORTED
;
212 USBD_CreateDevice(ULONG Unknown1
, ULONG Unknown2
, ULONG Unknown3
,
213 ULONG Unknown4
, ULONG Unknown5
)
215 return STATUS_NOT_SUPPORTED
;
222 USBD_RemoveDevice(ULONG Unknown1
, ULONG Unknown2
, ULONG Unknown3
)
224 return STATUS_NOT_SUPPORTED
;
231 USBD_CompleteRequest(ULONG Unknown1
, ULONG Unknown2
)
239 USBD_RegisterHcFilter(
240 PDEVICE_OBJECT DeviceObject
,
241 PDEVICE_OBJECT FilterDeviceObject
250 USBD_SetSuspendPowerState(ULONG Unknown1
, ULONG Unknown2
)
258 USBD_MakePdoName(ULONG Unknown1
, ULONG Unknown2
)
260 return STATUS_NOT_SUPPORTED
;
268 PDEVICE_OBJECT RootHubPdo
,
272 return STATUS_NOT_SUPPORTED
;
279 USBD_GetUSBDIVersion(
280 PUSBD_VERSION_INFORMATION Version
285 Version
->USBDI_Version
= USBDI_VERSION
;
286 Version
->Supported_USB_Version
= 0x100;
294 USBD_RestoreDevice(ULONG Unknown1
, ULONG Unknown2
, ULONG Unknown3
)
296 return STATUS_NOT_SUPPORTED
;
303 USBD_RegisterHcDeviceCapabilities(ULONG Unknown1
, ULONG Unknown2
,
312 USBD_CreateConfigurationRequestEx(
313 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
314 PUSBD_INTERFACE_LIST_ENTRY InterfaceList
319 ULONG InterfaceCount
;
320 ULONG InterfaceNumber
, EndPointNumber
;
321 PUSBD_INTERFACE_INFORMATION InterfaceInfo
;
323 for (InterfaceCount
= 0;
324 InterfaceList
[InterfaceCount
].InterfaceDescriptor
!= NULL
;
327 UrbSize
+= sizeof(USBD_INTERFACE_INFORMATION
);
328 UrbSize
+= (InterfaceList
[InterfaceCount
].InterfaceDescriptor
->bNumEndpoints
- 1) * sizeof(USBD_PIPE_INFORMATION
);
331 UrbSize
+= sizeof(URB
) + sizeof(USBD_INTERFACE_INFORMATION
);
333 Urb
= ExAllocatePool(NonPagedPool
, UrbSize
);
334 RtlZeroMemory(Urb
, UrbSize
);
335 Urb
->UrbSelectConfiguration
.Hdr
.Function
= URB_FUNCTION_SELECT_CONFIGURATION
;
336 Urb
->UrbSelectConfiguration
.Hdr
.Length
= sizeof(Urb
->UrbSelectConfiguration
);
337 Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
= ConfigurationDescriptor
;
339 InterfaceInfo
= &Urb
->UrbSelectConfiguration
.Interface
;
340 for (InterfaceNumber
= 0; InterfaceNumber
< InterfaceCount
; InterfaceNumber
++)
342 InterfaceList
[InterfaceNumber
].Interface
= InterfaceInfo
;
343 InterfaceInfo
->Length
= sizeof(USBD_INTERFACE_INFORMATION
) +
344 ((InterfaceList
[InterfaceNumber
].InterfaceDescriptor
->bNumEndpoints
- 1) * sizeof(USBD_PIPE_INFORMATION
));
345 InterfaceInfo
->InterfaceNumber
= InterfaceList
[InterfaceNumber
].InterfaceDescriptor
->bInterfaceNumber
;
346 InterfaceInfo
->AlternateSetting
= InterfaceList
[InterfaceNumber
].InterfaceDescriptor
->bAlternateSetting
;
347 InterfaceInfo
->NumberOfPipes
= InterfaceList
[InterfaceNumber
].InterfaceDescriptor
->bNumEndpoints
;
348 for (EndPointNumber
= 0; EndPointNumber
< InterfaceInfo
->NumberOfPipes
; EndPointNumber
++)
350 InterfaceInfo
->Pipes
[EndPointNumber
].MaximumTransferSize
= PAGE_SIZE
;
352 InterfaceInfo
= (PUSBD_INTERFACE_INFORMATION
) ((ULONG_PTR
)InterfaceInfo
+ InterfaceInfo
->Length
);
362 USBD_CreateConfigurationRequest(
363 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
367 /* WindowsXP returns NULL */
375 USBD_GetInterfaceLength(
376 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
,
381 PUSB_INTERFACE_DESCRIPTOR CurrentDescriptor
= InterfaceDescriptor
;
383 BOOLEAN InterfaceFound
= FALSE
;
385 for (Current
= (ULONG_PTR
)CurrentDescriptor
;
386 Current
< (ULONG_PTR
)BufferEnd
;
387 Current
+= CurrentDescriptor
->bLength
)
389 CurrentDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)Current
;
391 if ((CurrentDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
) && (InterfaceFound
))
393 else if (CurrentDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
394 InterfaceFound
= TRUE
;
396 Length
+= CurrentDescriptor
->bLength
;
405 PUSB_COMMON_DESCRIPTOR NTAPI
406 USBD_ParseDescriptors(
407 PVOID DescriptorBuffer
,
413 PUSB_COMMON_DESCRIPTOR PComDes
= StartPosition
;
417 if (PComDes
>= (PUSB_COMMON_DESCRIPTOR
)
418 ((PLONG
)DescriptorBuffer
+ TotalLength
) ) break;
419 if (PComDes
->bDescriptorType
== DescriptorType
) return PComDes
;
420 if (PComDes
->bLength
== 0) break;
421 PComDes
= (PUSB_COMMON_DESCRIPTOR
)((ULONG_PTR
)PComDes
+ PComDes
->bLength
);
430 PUSB_INTERFACE_DESCRIPTOR NTAPI
431 USBD_ParseConfigurationDescriptorEx(
432 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
434 LONG InterfaceNumber
,
435 LONG AlternateSetting
,
437 LONG InterfaceSubClass
,
438 LONG InterfaceProtocol
442 PUSB_INTERFACE_DESCRIPTOR UsbInterfaceDesc
= StartPosition
;
444 while(UsbInterfaceDesc
)
446 UsbInterfaceDesc
= (PUSB_INTERFACE_DESCRIPTOR
)
447 USBD_ParseDescriptors(ConfigurationDescriptor
,
448 ConfigurationDescriptor
->wTotalLength
,
450 USB_INTERFACE_DESCRIPTOR_TYPE
);
452 if (!UsbInterfaceDesc
) break;
454 if(InterfaceNumber
!= -1)
456 if(InterfaceNumber
!= UsbInterfaceDesc
->bInterfaceNumber
) x
= 1;
458 if(AlternateSetting
!= -1)
460 if(AlternateSetting
!= UsbInterfaceDesc
->bAlternateSetting
) x
= 1;
462 if(InterfaceClass
!= -1)
464 if(InterfaceClass
!= UsbInterfaceDesc
->bInterfaceClass
) x
= 1;
466 if(InterfaceSubClass
!= -1)
468 if(InterfaceSubClass
!= UsbInterfaceDesc
->bInterfaceSubClass
) x
= 1;
470 if(InterfaceProtocol
!= -1)
472 if(InterfaceProtocol
!= UsbInterfaceDesc
->bInterfaceProtocol
) x
= 1;
475 if (!x
) return UsbInterfaceDesc
;
477 if (UsbInterfaceDesc
->bLength
== 0) break;
478 UsbInterfaceDesc
= UsbInterfaceDesc
+ UsbInterfaceDesc
->bLength
;
486 PUSB_INTERFACE_DESCRIPTOR NTAPI
487 USBD_ParseConfigurationDescriptor(
488 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
489 UCHAR InterfaceNumber
,
490 UCHAR AlternateSetting
493 return USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
,
494 (PVOID
)ConfigurationDescriptor
, InterfaceNumber
, AlternateSetting
,
503 USBD_GetPdoRegistryParameter(
504 PDEVICE_OBJECT PhysicalDeviceObject
,
506 ULONG ParameterLength
,
512 HANDLE DevInstRegKey
;
514 Status
= IoOpenDeviceRegistryKey(PhysicalDeviceObject
,
515 PLUGPLAY_REGKEY_DRIVER
, STANDARD_RIGHTS_ALL
, &DevInstRegKey
);
516 if (NT_SUCCESS(Status
))
518 PKEY_VALUE_FULL_INFORMATION FullInfo
;
519 UNICODE_STRING ValueName
;
522 RtlInitUnicodeString(&ValueName
, KeyName
);
523 Length
= ParameterLength
+ KeyNameLength
+ sizeof(KEY_VALUE_FULL_INFORMATION
);
524 FullInfo
= ExAllocatePool(PagedPool
, Length
);
527 Status
= ZwQueryValueKey(DevInstRegKey
, &ValueName
,
528 KeyValueFullInformation
, FullInfo
, Length
, &Length
);
529 if (NT_SUCCESS(Status
))
531 RtlCopyMemory(Parameter
,
532 ((PUCHAR
)FullInfo
) + FullInfo
->DataOffset
,
533 ParameterLength
/*FullInfo->DataLength*/);
535 ExFreePool(FullInfo
);
537 Status
= STATUS_NO_MEMORY
;
538 ZwClose(DevInstRegKey
);