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>
12 * Universal Serial Bus Driver/Helper Library
14 * Written by Filip Navara <xnavara@volny.cz>
17 * This driver was obsoleted in Windows XP and most functions
18 * became pure stubs. But some of them were retained for backward
19 * compatibilty with existing drivers.
21 * Preserved functions:
23 * USBD_Debug_GetHeap (implemented)
24 * USBD_Debug_RetHeap (implemented)
25 * USBD_CalculateUsbBandwidth (implemented, tested)
26 * USBD_CreateConfigurationRequestEx (implemented)
27 * USBD_CreateConfigurationRequest
28 * USBD_GetInterfaceLength (implemented)
29 * USBD_ParseConfigurationDescriptorEx (implemented)
30 * USBD_ParseDescriptors (implemented)
31 * USBD_GetPdoRegistryParameters (implemented)
36 #ifndef PLUGPLAY_REGKEY_DRIVER
37 #define PLUGPLAY_REGKEY_DRIVER 2
39 typedef struct _USBD_INTERFACE_LIST_ENTRY
{
40 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
41 PUSBD_INTERFACE_INFORMATION Interface
;
42 } USBD_INTERFACE_LIST_ENTRY
, *PUSBD_INTERFACE_LIST_ENTRY
;
45 DriverEntry(PDRIVER_OBJECT DriverObject
,
46 PUNICODE_STRING RegistryPath
)
48 return STATUS_SUCCESS
;
55 DllInitialize(DWORD Unknown
)
73 USBD_Debug_GetHeap(DWORD Unknown1
, POOL_TYPE PoolType
, ULONG NumberOfBytes
,
76 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
83 USBD_Debug_RetHeap(PVOID Heap
, DWORD Unknown2
, DWORD Unknown3
)
92 USBD_Debug_LogEntry(PCHAR Name
, ULONG_PTR Info1
, ULONG_PTR Info2
,
101 USBD_AllocateDeviceName(DWORD Unknown
)
110 USBD_CalculateUsbBandwidth(
116 DWORD OverheadTable
[] = {
117 0x00, /* UsbdPipeTypeControl */
118 0x09, /* UsbdPipeTypeIsochronous */
119 0x00, /* UsbdPipeTypeBulk */
120 0x0d /* UsbdPipeTypeInterrupt */
124 if (OverheadTable
[EndpointType
] != 0)
126 Result
= ((MaxPacketSize
+ OverheadTable
[EndpointType
]) * 8 * 7) / 6;
138 USBD_Dispatch(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
, DWORD Unknown4
)
147 USBD_FreeDeviceMutex(PVOID Unknown
)
155 USBD_FreeDeviceName(PVOID Unknown
)
163 USBD_WaitDeviceMutex(PVOID Unknown
)
171 USBD_GetSuspendPowerState(DWORD Unknown1
)
180 USBD_InitializeDevice(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
,
181 DWORD Unknown4
, DWORD Unknown5
, DWORD Unknown6
)
183 return STATUS_NOT_SUPPORTED
;
190 USBD_RegisterHostController(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
,
191 DWORD Unknown4
, DWORD Unknown5
, DWORD Unknown6
, DWORD Unknown7
,
192 DWORD Unknown8
, DWORD Unknown9
, DWORD Unknown10
)
194 return STATUS_NOT_SUPPORTED
;
201 USBD_GetDeviceInformation(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
)
203 return STATUS_NOT_SUPPORTED
;
210 USBD_CreateDevice(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
,
211 DWORD Unknown4
, DWORD Unknown5
)
213 return STATUS_NOT_SUPPORTED
;
220 USBD_RemoveDevice(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
)
222 return STATUS_NOT_SUPPORTED
;
229 USBD_CompleteRequest(DWORD Unknown1
, DWORD Unknown2
)
237 USBD_RegisterHcFilter(
238 PDEVICE_OBJECT DeviceObject
,
239 PDEVICE_OBJECT FilterDeviceObject
248 USBD_SetSuspendPowerState(DWORD Unknown1
, DWORD Unknown2
)
256 USBD_MakePdoName(DWORD Unknown1
, DWORD Unknown2
)
258 return STATUS_NOT_SUPPORTED
;
266 PDEVICE_OBJECT RootHubPdo
,
270 return STATUS_NOT_SUPPORTED
;
277 USBD_GetUSBDIVersion(
278 PUSBD_VERSION_INFORMATION Version
283 Version
->USBDI_Version
= USBDI_VERSION
;
284 Version
->Supported_USB_Version
= 0x100;
292 USBD_RestoreDevice(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
)
294 return STATUS_NOT_SUPPORTED
;
301 USBD_RegisterHcDeviceCapabilities(DWORD Unknown1
, DWORD Unknown2
,
312 USBD_CreateConfigurationRequestEx(
313 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
314 PUSBD_INTERFACE_LIST_ENTRY InterfaceList
319 DWORD InterfaceCount
;
321 for (InterfaceCount
= 0;
322 InterfaceList
[InterfaceCount
].InterfaceDescriptor
!= NULL
;
325 /* Include the NULL entry */
328 UrbSize
= sizeof(Urb
->UrbSelectConfiguration
) +
329 (InterfaceCount
* sizeof(PUSBD_INTERFACE_LIST_ENTRY
));
330 Urb
= ExAllocatePool(NonPagedPool
, UrbSize
);
331 Urb
->UrbSelectConfiguration
.Hdr
.Function
=
332 URB_FUNCTION_SELECT_CONFIGURATION
;
333 Urb
->UrbSelectConfiguration
.Hdr
.Length
=
334 sizeof(Urb
->UrbSelectConfiguration
);
335 Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
=
336 ConfigurationDescriptor
;
337 memcpy((PVOID
)&Urb
->UrbSelectConfiguration
.Interface
, (PVOID
)InterfaceList
,
338 InterfaceCount
* sizeof(PUSBD_INTERFACE_LIST_ENTRY
));
347 USBD_CreateConfigurationRequest(
348 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
359 USBD_GetInterfaceLength(
360 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
,
365 PUSB_INTERFACE_DESCRIPTOR CurrentDescriptor
= InterfaceDescriptor
;
366 DWORD Length
= CurrentDescriptor
->bLength
;
368 // USB_ENDPOINT_DESCRIPTOR_TYPE
369 if (CurrentDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
371 for (Current
= (ULONG_PTR
)CurrentDescriptor
;
372 Current
< (ULONG_PTR
)BufferEnd
;
373 Current
+= CurrentDescriptor
->bLength
)
374 CurrentDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)Current
;
375 Length
+= CurrentDescriptor
->bLength
;
384 PUSB_COMMON_DESCRIPTOR NTAPI
385 USBD_ParseDescriptors(
386 PVOID DescriptorBuffer
,
392 PUSB_COMMON_DESCRIPTOR PComDes
= StartPosition
;
396 if (PComDes
>= (PUSB_COMMON_DESCRIPTOR
)
397 ((PLONG
)DescriptorBuffer
+ TotalLength
) ) break;
398 if (PComDes
->bDescriptorType
== DescriptorType
) return PComDes
;
399 if (PComDes
->bLength
== 0) break;
400 PComDes
= PComDes
+ PComDes
->bLength
;
409 PUSB_INTERFACE_DESCRIPTOR NTAPI
410 USBD_ParseConfigurationDescriptorEx(
411 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
413 LONG InterfaceNumber
,
414 LONG AlternateSetting
,
416 LONG InterfaceSubClass
,
417 LONG InterfaceProtocol
421 PUSB_INTERFACE_DESCRIPTOR UsbInterfaceDesc
= StartPosition
;
423 while(UsbInterfaceDesc
)
425 UsbInterfaceDesc
= (PUSB_INTERFACE_DESCRIPTOR
)
426 USBD_ParseDescriptors(ConfigurationDescriptor
,
427 ConfigurationDescriptor
->wTotalLength
,
429 USB_INTERFACE_DESCRIPTOR_TYPE
);
431 if (!UsbInterfaceDesc
) break;
433 if(InterfaceNumber
!= -1)
435 if(InterfaceNumber
!= UsbInterfaceDesc
->bInterfaceNumber
) x
= 1;
437 if(AlternateSetting
!= -1)
439 if(AlternateSetting
!= UsbInterfaceDesc
->bAlternateSetting
) x
= 1;
441 if(InterfaceClass
!= -1)
443 if(InterfaceClass
!= UsbInterfaceDesc
->bInterfaceClass
) x
= 1;
445 if(InterfaceSubClass
!= -1)
447 if(InterfaceSubClass
!= UsbInterfaceDesc
->bInterfaceSubClass
) x
= 1;
449 if(InterfaceProtocol
!= -1)
451 if(InterfaceProtocol
!= UsbInterfaceDesc
->bInterfaceProtocol
) x
= 1;
454 if (!x
) return UsbInterfaceDesc
;
456 if (UsbInterfaceDesc
->bLength
== 0) break;
457 UsbInterfaceDesc
= UsbInterfaceDesc
+ UsbInterfaceDesc
->bLength
;
465 PUSB_INTERFACE_DESCRIPTOR NTAPI
466 USBD_ParseConfigurationDescriptor(
467 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
468 UCHAR InterfaceNumber
,
469 UCHAR AlternateSetting
472 return USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
,
473 (PVOID
)ConfigurationDescriptor
, InterfaceNumber
, AlternateSetting
,
482 USBD_GetPdoRegistryParameter(
483 PDEVICE_OBJECT PhysicalDeviceObject
,
485 ULONG ParameterLength
,
491 HANDLE DevInstRegKey
;
493 Status
= IoOpenDeviceRegistryKey(PhysicalDeviceObject
,
494 PLUGPLAY_REGKEY_DRIVER
, STANDARD_RIGHTS_ALL
, &DevInstRegKey
);
495 if (NT_SUCCESS(Status
))
497 PKEY_VALUE_FULL_INFORMATION FullInfo
;
498 UNICODE_STRING ValueName
;
501 RtlInitUnicodeString(&ValueName
, KeyName
);
502 Length
= ParameterLength
+ KeyNameLength
+ sizeof(KEY_VALUE_FULL_INFORMATION
);
503 FullInfo
= ExAllocatePool(PagedPool
, Length
);
506 Status
= ZwQueryValueKey(DevInstRegKey
, &ValueName
,
507 KeyValueFullInformation
, FullInfo
, Length
, &Length
);
508 if (NT_SUCCESS(Status
))
510 RtlCopyMemory(Parameter
,
511 ((PUCHAR
)FullInfo
) + FullInfo
->DataOffset
,
512 ParameterLength
/*FullInfo->DataLength*/);
514 ExFreePool(FullInfo
);
516 Status
= STATUS_NO_MEMORY
;
517 ZwClose(DevInstRegKey
);