2 * Universal Serial Bus Driver/Helper Library
4 * Written by Filip Navara <xnavara@volny.cz>
7 * This driver was obsoleted in Windows XP and most functions
8 * became pure stubs. But some of them were retained for backward
9 * compatibilty with existing drivers.
11 * Preserved functions:
13 * USBD_Debug_GetHeap (implemented)
14 * USBD_Debug_RetHeap (implemented)
15 * USBD_CalculateUsbBandwidth (implemented, tested)
16 * USBD_CreateConfigurationRequestEx (implemented)
17 * USBD_CreateConfigurationRequest
18 * USBD_GetInterfaceLength (implemented)
19 * USBD_ParseConfigurationDescriptorEx (implemented)
20 * USBD_ParseDescriptors (implemented)
21 * USBD_GetPdoRegistryParameters (implemented)
24 #include <ddk/ntddk.h>
25 #include <ddk/usbdi.h>
26 #ifndef PLUGPLAY_REGKEY_DRIVER
27 #define PLUGPLAY_REGKEY_DRIVER 2
29 typedef struct _USBD_INTERFACE_LIST_ENTRY
{
30 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
31 PUSBD_INTERFACE_INFORMATION Interface
;
32 } USBD_INTERFACE_LIST_ENTRY
, *PUSBD_INTERFACE_LIST_ENTRY
;
35 DriverEntry(PDRIVER_OBJECT DriverObject
,
36 PUNICODE_STRING RegistryPath
)
38 return STATUS_SUCCESS
;
45 DllInitialize(DWORD Unknown
)
63 USBD_Debug_GetHeap(DWORD Unknown1
, POOL_TYPE PoolType
, ULONG NumberOfBytes
,
66 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
73 USBD_Debug_RetHeap(PVOID Heap
, DWORD Unknown2
, DWORD Unknown3
)
82 USBD_Debug_LogEntry(PCHAR Name
, ULONG_PTR Info1
, ULONG_PTR Info2
,
91 USBD_AllocateDeviceName(DWORD Unknown
)
100 USBD_CalculateUsbBandwidth(
106 DWORD OverheadTable
[] = {
107 0x00, /* UsbdPipeTypeControl */
108 0x09, /* UsbdPipeTypeIsochronous */
109 0x00, /* UsbdPipeTypeBulk */
110 0x0d /* UsbdPipeTypeInterrupt */
114 if (OverheadTable
[EndpointType
] != 0)
116 Result
= ((MaxPacketSize
+ OverheadTable
[EndpointType
]) * 8 * 7) / 6;
128 USBD_Dispatch(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
, DWORD Unknown4
)
137 USBD_FreeDeviceMutex(PVOID Unknown
)
145 USBD_FreeDeviceName(PVOID Unknown
)
153 USBD_WaitDeviceMutex(PVOID Unknown
)
161 USBD_GetSuspendPowerState(DWORD Unknown1
)
170 USBD_InitializeDevice(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
,
171 DWORD Unknown4
, DWORD Unknown5
, DWORD Unknown6
)
173 return STATUS_NOT_SUPPORTED
;
180 USBD_RegisterHostController(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
,
181 DWORD Unknown4
, DWORD Unknown5
, DWORD Unknown6
, DWORD Unknown7
,
182 DWORD Unknown8
, DWORD Unknown9
, DWORD Unknown10
)
184 return STATUS_NOT_SUPPORTED
;
191 USBD_GetDeviceInformation(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
)
193 return STATUS_NOT_SUPPORTED
;
200 USBD_CreateDevice(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
,
201 DWORD Unknown4
, DWORD Unknown5
)
203 return STATUS_NOT_SUPPORTED
;
210 USBD_RemoveDevice(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
)
212 return STATUS_NOT_SUPPORTED
;
219 USBD_CompleteRequest(DWORD Unknown1
, DWORD Unknown2
)
227 USBD_RegisterHcFilter(
228 PDEVICE_OBJECT DeviceObject
,
229 PDEVICE_OBJECT FilterDeviceObject
238 USBD_SetSuspendPowerState(DWORD Unknown1
, DWORD Unknown2
)
246 USBD_MakePdoName(DWORD Unknown1
, DWORD Unknown2
)
248 return STATUS_NOT_SUPPORTED
;
256 PDEVICE_OBJECT RootHubPdo
,
260 return STATUS_NOT_SUPPORTED
;
267 USBD_GetUSBDIVersion(
268 PUSBD_VERSION_INFORMATION Version
273 Version
->USBDI_Version
= USBDI_VERSION
;
274 Version
->Supported_USB_Version
= 0x100;
282 USBD_RestoreDevice(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
)
284 return STATUS_NOT_SUPPORTED
;
291 USBD_RegisterHcDeviceCapabilities(DWORD Unknown1
, DWORD Unknown2
,
302 USBD_CreateConfigurationRequestEx(
303 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
304 PUSBD_INTERFACE_LIST_ENTRY InterfaceList
309 DWORD InterfaceCount
;
311 for (InterfaceCount
= 0;
312 InterfaceList
[InterfaceCount
].InterfaceDescriptor
!= NULL
;
315 /* Include the NULL entry */
318 UrbSize
= sizeof(Urb
->UrbSelectConfiguration
) +
319 (InterfaceCount
* sizeof(PUSBD_INTERFACE_LIST_ENTRY
));
320 Urb
= ExAllocatePool(NonPagedPool
, UrbSize
);
321 Urb
->UrbSelectConfiguration
.Hdr
.Function
=
322 URB_FUNCTION_SELECT_CONFIGURATION
;
323 Urb
->UrbSelectConfiguration
.Hdr
.Length
=
324 sizeof(Urb
->UrbSelectConfiguration
);
325 Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
=
326 ConfigurationDescriptor
;
327 memcpy((PVOID
)&Urb
->UrbSelectConfiguration
.Interface
, (PVOID
)InterfaceList
,
328 InterfaceCount
* sizeof(PUSBD_INTERFACE_LIST_ENTRY
));
337 USBD_CreateConfigurationRequest(
338 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
349 USBD_GetInterfaceLength(
350 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
,
355 PUSB_INTERFACE_DESCRIPTOR CurrentDescriptor
= InterfaceDescriptor
;
356 DWORD Length
= CurrentDescriptor
->bLength
;
358 // USB_ENDPOINT_DESCRIPTOR_TYPE
359 if (CurrentDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
)
361 for (Current
= (ULONG_PTR
)CurrentDescriptor
;
362 Current
< (ULONG_PTR
)BufferEnd
;
363 Current
+= CurrentDescriptor
->bLength
)
364 CurrentDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)Current
;
365 Length
+= CurrentDescriptor
->bLength
;
374 PUSB_COMMON_DESCRIPTOR STDCALL
375 USBD_ParseDescriptors(
376 PVOID DescriptorBuffer
,
382 PUSB_COMMON_DESCRIPTOR PComDes
= StartPosition
;
386 if (PComDes
>= (PUSB_COMMON_DESCRIPTOR
)
387 ((PLONG
)DescriptorBuffer
+ TotalLength
) ) break;
388 if (PComDes
->bDescriptorType
== DescriptorType
) return PComDes
;
389 if (PComDes
->bLength
== 0) break;
390 PComDes
= PComDes
+ PComDes
->bLength
;
399 PUSB_INTERFACE_DESCRIPTOR STDCALL
400 USBD_ParseConfigurationDescriptorEx(
401 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
403 LONG InterfaceNumber
,
404 LONG AlternateSetting
,
406 LONG InterfaceSubClass
,
407 LONG InterfaceProtocol
411 PUSB_INTERFACE_DESCRIPTOR UsbInterfaceDesc
= StartPosition
;
413 while(UsbInterfaceDesc
)
415 UsbInterfaceDesc
= (PUSB_INTERFACE_DESCRIPTOR
)
416 USBD_ParseDescriptors(ConfigurationDescriptor
,
417 ConfigurationDescriptor
->wTotalLength
,
419 USB_INTERFACE_DESCRIPTOR_TYPE
);
421 if (!UsbInterfaceDesc
) break;
423 if(InterfaceNumber
!= -1)
425 if(InterfaceNumber
!= UsbInterfaceDesc
->bInterfaceNumber
) x
= 1;
427 if(AlternateSetting
!= -1)
429 if(AlternateSetting
!= UsbInterfaceDesc
->bAlternateSetting
) x
= 1;
431 if(InterfaceClass
!= -1)
433 if(InterfaceClass
!= UsbInterfaceDesc
->bInterfaceClass
) x
= 1;
435 if(InterfaceSubClass
!= -1)
437 if(InterfaceSubClass
!= UsbInterfaceDesc
->bInterfaceSubClass
) x
= 1;
439 if(InterfaceProtocol
!= -1)
441 if(InterfaceProtocol
!= UsbInterfaceDesc
->bInterfaceProtocol
) x
= 1;
444 if (!x
) return UsbInterfaceDesc
;
446 if (UsbInterfaceDesc
->bLength
== 0) break;
447 UsbInterfaceDesc
= UsbInterfaceDesc
+ UsbInterfaceDesc
->bLength
;
455 PUSB_INTERFACE_DESCRIPTOR STDCALL
456 USBD_ParseConfigurationDescriptor(
457 PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
,
458 UCHAR InterfaceNumber
,
459 UCHAR AlternateSetting
462 return USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor
,
463 (PVOID
)ConfigurationDescriptor
, InterfaceNumber
, AlternateSetting
,
472 USBD_GetPdoRegistryParameter(
473 PDEVICE_OBJECT PhysicalDeviceObject
,
475 ULONG ParameterLength
,
481 HANDLE DevInstRegKey
;
483 Status
= IoOpenDeviceRegistryKey(PhysicalDeviceObject
,
484 PLUGPLAY_REGKEY_DRIVER
, STANDARD_RIGHTS_ALL
, &DevInstRegKey
);
485 if (NT_SUCCESS(Status
))
487 PKEY_VALUE_FULL_INFORMATION FullInfo
;
488 UNICODE_STRING ValueName
;
491 RtlInitUnicodeString(&ValueName
, KeyName
);
492 Length
= ParameterLength
+ KeyNameLength
+ sizeof(KEY_VALUE_FULL_INFORMATION
);
493 FullInfo
= ExAllocatePool(PagedPool
, Length
);
496 Status
= ZwQueryValueKey(DevInstRegKey
, &ValueName
,
497 KeyValueFullInformation
, FullInfo
, Length
, &Length
);
498 if (NT_SUCCESS(Status
))
500 RtlCopyMemory(Parameter
,
501 ((PUCHAR
)FullInfo
) + FullInfo
->DataOffset
,
502 ParameterLength
/*FullInfo->DataLength*/);
504 ExFreePool(FullInfo
);
506 Status
= STATUS_NO_MEMORY
;
507 ZwClose(DevInstRegKey
);