set svn:eol-style to native
[reactos.git] / reactos / drivers / usb / usbd / usbd.c
index d33d67f..6aae920 100644 (file)
-/*\r
- * Universal Serial Bus Driver/Helper Library\r
- *\r
- * Written by Filip Navara <xnavara@volny.cz>\r
- *\r
- * Notes:\r
- *    This driver was obsoleted in Windows XP and most functions\r
- *    became pure stubs. But some of them were retained for backward\r
- *    compatibilty with existing drivers.\r
- *\r
- *    Preserved functions:\r
- *\r
- *    USBD_Debug_GetHeap (implemented)\r
- *    USBD_Debug_RetHeap (implemented)\r
- *    USBD_CalculateUsbBandwidth (implemented, tested)\r
- *    USBD_CreateConfigurationRequestEx (implemented)\r
- *    USBD_CreateConfigurationRequest\r
- *    USBD_GetInterfaceLength (implemented)\r
- *    USBD_ParseConfigurationDescriptorEx\r
- *    USBD_ParseDescriptors\r
- *    USBD_GetPdoRegistryParameters (implemented)\r
- */\r
-\r
-#include <windows.h>\r
-#include <ddk/usbdi.h>\r
-#ifndef PLUGPLAY_REGKEY_DRIVER\r
-#define PLUGPLAY_REGKEY_DRIVER              2\r
-#endif\r
-typedef struct _USBD_INTERFACE_LIST_ENTRY {\r
-    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;\r
-    PUSBD_INTERFACE_INFORMATION Interface;\r
-} USBD_INTERFACE_LIST_ENTRY, *PUSBD_INTERFACE_LIST_ENTRY;\r
-\r
-NTSTATUS STDCALL\r
-DriverEntry(PDRIVER_OBJECT DriverObject,\r
-            PUNICODE_STRING RegistryPath)\r
-{\r
-    return STATUS_SUCCESS;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-DWORD STDCALL\r
-DllInitialize(DWORD Unknown)\r
-{\r
-    return 0;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-DWORD STDCALL\r
-DllUnload(VOID)\r
-{\r
-    return 0;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-PVOID STDCALL\r
-USBD_Debug_GetHeap(DWORD Unknown1, POOL_TYPE PoolType, ULONG NumberOfBytes,\r
-       ULONG Tag)\r
-{\r
-    return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_Debug_RetHeap(PVOID Heap, DWORD Unknown2, DWORD Unknown3)\r
-{\r
-    ExFreePool(Heap);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_Debug_LogEntry(PCHAR Name, ULONG_PTR Info1, ULONG_PTR Info2,\r
-    ULONG_PTR Info3)\r
-{\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-PVOID STDCALL\r
-USBD_AllocateDeviceName(DWORD Unknown)\r
-{\r
-    return NULL;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-DWORD STDCALL\r
-USBD_CalculateUsbBandwidth(\r
-    ULONG MaxPacketSize,\r
-    UCHAR EndpointType,\r
-    BOOLEAN LowSpeed\r
-    )\r
-{\r
-    DWORD OverheadTable[] = {\r
-            0x00, /* UsbdPipeTypeControl */\r
-            0x09, /* UsbdPipeTypeIsochronous */\r
-            0x00, /* UsbdPipeTypeBulk */\r
-            0x0d  /* UsbdPipeTypeInterrupt */\r
-        };\r
-    DWORD Result;\r
-    \r
-    if (OverheadTable[EndpointType] != 0)\r
-    {\r
-        Result = ((MaxPacketSize + OverheadTable[EndpointType]) * 8 * 7) / 6;\r
-        if (LowSpeed)\r
-           return Result << 3;\r
-        return Result;\r
-    }\r
-    return 0;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-DWORD STDCALL\r
-USBD_Dispatch(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)\r
-{\r
-    return 1;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_FreeDeviceMutex(PVOID Unknown)\r
-{\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_FreeDeviceName(PVOID Unknown)\r
-{\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_WaitDeviceMutex(PVOID Unknown)\r
-{\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-DWORD STDCALL\r
-USBD_GetSuspendPowerState(DWORD Unknown1)\r
-{\r
-    return 0;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-USBD_InitializeDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,\r
-    DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)\r
-{\r
-    return STATUS_NOT_SUPPORTED;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-USBD_RegisterHostController(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,\r
-    DWORD Unknown4, DWORD Unknown5, DWORD Unknown6, DWORD Unknown7,\r
-    DWORD Unknown8, DWORD Unknown9, DWORD Unknown10)\r
-{\r
-    return STATUS_NOT_SUPPORTED;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-USBD_GetDeviceInformation(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)\r
-{\r
-    return STATUS_NOT_SUPPORTED;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-USBD_CreateDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,\r
-    DWORD Unknown4, DWORD Unknown5)\r
-{\r
-    return STATUS_NOT_SUPPORTED;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-USBD_RemoveDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)\r
-{\r
-    return STATUS_NOT_SUPPORTED;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_CompleteRequest(DWORD Unknown1, DWORD Unknown2)\r
-{\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_RegisterHcFilter(\r
-    PDEVICE_OBJECT DeviceObject, \r
-    PDEVICE_OBJECT FilterDeviceObject\r
-    )\r
-{\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_SetSuspendPowerState(DWORD Unknown1, DWORD Unknown2)\r
-{\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-USBD_MakePdoName(DWORD Unknown1, DWORD Unknown2)\r
-{\r
-    return STATUS_NOT_SUPPORTED;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-USBD_QueryBusTime(\r
-    PDEVICE_OBJECT RootHubPdo,\r
-    PULONG CurrentFrame\r
-    )\r
-{\r
-    return STATUS_NOT_SUPPORTED;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_GetUSBDIVersion(\r
-    PUSBD_VERSION_INFORMATION Version\r
-    )\r
-{\r
-    if (Version != NULL)\r
-    {\r
-        Version->USBDI_Version = USBDI_VERSION;\r
-        Version->Supported_USB_Version = 0x100;\r
-    }\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS STDCALL\r
-USBD_RestoreDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)\r
-{\r
-    return STATUS_NOT_SUPPORTED;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-VOID STDCALL\r
-USBD_RegisterHcDeviceCapabilities(DWORD Unknown1, DWORD Unknown2,\r
-    DWORD Unknown3)\r
-{\r
-}\r
-\r
-/*\r
- * @implemented\r
- * FIXME: Test\r
- */\r
-PURB\r
-STDCALL\r
-USBD_CreateConfigurationRequestEx(\r
-    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,\r
-    PUSBD_INTERFACE_LIST_ENTRY InterfaceList\r
-    )\r
-{\r
-    PURB Urb;\r
-    DWORD UrbSize;\r
-    DWORD InterfaceCount;\r
-\r
-    for (InterfaceCount = 0;\r
-         InterfaceList[InterfaceCount].InterfaceDescriptor != NULL;\r
-         ++InterfaceCount)\r
-       ;\r
-    /* Include the NULL entry */\r
-    ++InterfaceCount;\r
-\r
-    UrbSize = sizeof(Urb->UrbSelectConfiguration) + \r
-       (InterfaceCount * sizeof(PUSBD_INTERFACE_LIST_ENTRY));\r
-    Urb = ExAllocatePool(NonPagedPool, UrbSize);\r
-    Urb->UrbSelectConfiguration.Hdr.Function =\r
-        URB_FUNCTION_SELECT_CONFIGURATION;        \r
-    Urb->UrbSelectConfiguration.Hdr.Length =\r
-        sizeof(Urb->UrbSelectConfiguration);\r
-    Urb->UrbSelectConfiguration.ConfigurationDescriptor = \r
-       ConfigurationDescriptor;\r
-    memcpy((PVOID)&Urb->UrbSelectConfiguration.Interface, (PVOID)InterfaceList,\r
-       InterfaceCount * sizeof(PUSBD_INTERFACE_LIST_ENTRY));\r
-\r
-    return Urb;\r
-}\r
-\r
-/*\r
- * @unimplemented\r
- */\r
-PURB STDCALL\r
-USBD_CreateConfigurationRequest(\r
-    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,\r
-    PUSHORT Size\r
-    )\r
-{\r
-    return NULL;\r
-}\r
-\r
-/*\r
- * @unimplemented\r
- */\r
-ULONG STDCALL\r
-USBD_GetInterfaceLength(\r
-    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,\r
-    PUCHAR BufferEnd\r
-    )\r
-{\r
-    ULONG_PTR Current;\r
-    PUSB_INTERFACE_DESCRIPTOR CurrentDescriptor = InterfaceDescriptor;\r
-    DWORD Length = CurrentDescriptor->bLength;\r
-\r
-    // USB_ENDPOINT_DESCRIPTOR_TYPE\r
-    if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)\r
-    {\r
-        for (Current = (ULONG_PTR)CurrentDescriptor;\r
-             Current < (ULONG_PTR)BufferEnd;\r
-             Current += CurrentDescriptor->bLength)\r
-            CurrentDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Current;\r
-            Length += CurrentDescriptor->bLength;\r
-\r
-    }\r
-    return Length;\r
-}\r
-\r
-/*\r
- * @unimplemented\r
- */\r
-PUSB_INTERFACE_DESCRIPTOR STDCALL\r
-USBD_ParseConfigurationDescriptorEx(\r
-    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,\r
-    PVOID StartPosition,\r
-    LONG InterfaceNumber,\r
-    LONG AlternateSetting,\r
-    LONG InterfaceClass,\r
-    LONG InterfaceSubClass,\r
-    LONG InterfaceProtocol\r
-    )\r
-{\r
-    return NULL;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-PUSB_INTERFACE_DESCRIPTOR STDCALL\r
-USBD_ParseConfigurationDescriptor(\r
-    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,\r
-    UCHAR InterfaceNumber,\r
-    UCHAR AlternateSetting\r
-    )\r
-{\r
-    return USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,\r
-        (PVOID)ConfigurationDescriptor, InterfaceNumber, AlternateSetting,\r
-        -1, -1, -1);\r
-}\r
-\r
-/*\r
- * @unimplemented\r
- */\r
-PUSB_COMMON_DESCRIPTOR STDCALL\r
-USBD_ParseDescriptors(\r
-    PVOID  DescriptorBuffer,\r
-    ULONG  TotalLength,\r
-    PVOID  StartPosition,\r
-    LONG  DescriptorType\r
-    )\r
-{\r
-    return NULL; \r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-DWORD STDCALL\r
-USBD_GetPdoRegistryParameter(\r
-    PDEVICE_OBJECT PhysicalDeviceObject,\r
-    PVOID Parameter,\r
-    ULONG ParameterLength,\r
-    PWCHAR KeyName,\r
-    ULONG KeyNameLength\r
-    )\r
-{\r
-    NTSTATUS Status;\r
-    HANDLE DevInstRegKey;\r
-\r
-    Status = IoOpenDeviceRegistryKey(PhysicalDeviceObject,\r
-        PLUGPLAY_REGKEY_DRIVER, STANDARD_RIGHTS_ALL, &DevInstRegKey);\r
-    if (NT_SUCCESS(Status))\r
-    {\r
-        PKEY_VALUE_FULL_INFORMATION FullInfo;\r
-        UNICODE_STRING ValueName;\r
-        ULONG Length;\r
-\r
-        RtlInitUnicodeString(&ValueName, KeyName);\r
-        Length = ParameterLength + KeyNameLength + sizeof(KEY_VALUE_FULL_INFORMATION);\r
-        FullInfo = ExAllocatePool(PagedPool, Length);\r
-        if (FullInfo)\r
-        {\r
-            Status = ZwQueryValueKey(DevInstRegKey, &ValueName,\r
-                KeyValueFullInformation, FullInfo, Length, &Length);\r
-            if (NT_SUCCESS(Status))\r
-            {\r
-                RtlCopyMemory(Parameter,\r
-                    ((PUCHAR)FullInfo) + FullInfo->DataOffset,\r
-                    ParameterLength /*FullInfo->DataLength*/);\r
-            }\r
-            ExFreePool(FullInfo);\r
-        } else\r
-            Status = STATUS_NO_MEMORY;\r
-        ZwClose(DevInstRegKey);\r
-    }\r
-    return Status;\r
-}\r
+/*
+ * Universal Serial Bus Driver/Helper Library
+ *
+ * Written by Filip Navara <xnavara@volny.cz>
+ *
+ * Notes:
+ *    This driver was obsoleted in Windows XP and most functions
+ *    became pure stubs. But some of them were retained for backward
+ *    compatibilty with existing drivers.
+ *
+ *    Preserved functions:
+ *
+ *    USBD_Debug_GetHeap (implemented)
+ *    USBD_Debug_RetHeap (implemented)
+ *    USBD_CalculateUsbBandwidth (implemented, tested)
+ *    USBD_CreateConfigurationRequestEx (implemented)
+ *    USBD_CreateConfigurationRequest
+ *    USBD_GetInterfaceLength (implemented)
+ *    USBD_ParseConfigurationDescriptorEx
+ *    USBD_ParseDescriptors
+ *    USBD_GetPdoRegistryParameters (implemented)
+ */
+
+#include <windows.h>
+#include <ddk/usbdi.h>
+#ifndef PLUGPLAY_REGKEY_DRIVER
+#define PLUGPLAY_REGKEY_DRIVER              2
+#endif
+typedef struct _USBD_INTERFACE_LIST_ENTRY {
+    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+    PUSBD_INTERFACE_INFORMATION Interface;
+} USBD_INTERFACE_LIST_ENTRY, *PUSBD_INTERFACE_LIST_ENTRY;
+
+NTSTATUS STDCALL
+DriverEntry(PDRIVER_OBJECT DriverObject,
+            PUNICODE_STRING RegistryPath)
+{
+    return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+DllInitialize(DWORD Unknown)
+{
+    return 0;
+}
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+DllUnload(VOID)
+{
+    return 0;
+}
+
+/*
+ * @implemented
+ */
+PVOID STDCALL
+USBD_Debug_GetHeap(DWORD Unknown1, POOL_TYPE PoolType, ULONG NumberOfBytes,
+       ULONG Tag)
+{
+    return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_Debug_RetHeap(PVOID Heap, DWORD Unknown2, DWORD Unknown3)
+{
+    ExFreePool(Heap);
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_Debug_LogEntry(PCHAR Name, ULONG_PTR Info1, ULONG_PTR Info2,
+    ULONG_PTR Info3)
+{
+}
+
+/*
+ * @implemented
+ */
+PVOID STDCALL
+USBD_AllocateDeviceName(DWORD Unknown)
+{
+    return NULL;
+}
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+USBD_CalculateUsbBandwidth(
+    ULONG MaxPacketSize,
+    UCHAR EndpointType,
+    BOOLEAN LowSpeed
+    )
+{
+    DWORD OverheadTable[] = {
+            0x00, /* UsbdPipeTypeControl */
+            0x09, /* UsbdPipeTypeIsochronous */
+            0x00, /* UsbdPipeTypeBulk */
+            0x0d  /* UsbdPipeTypeInterrupt */
+        };
+    DWORD Result;
+    
+    if (OverheadTable[EndpointType] != 0)
+    {
+        Result = ((MaxPacketSize + OverheadTable[EndpointType]) * 8 * 7) / 6;
+        if (LowSpeed)
+           return Result << 3;
+        return Result;
+    }
+    return 0;
+}
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+USBD_Dispatch(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
+{
+    return 1;
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_FreeDeviceMutex(PVOID Unknown)
+{
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_FreeDeviceName(PVOID Unknown)
+{
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_WaitDeviceMutex(PVOID Unknown)
+{
+}
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+USBD_GetSuspendPowerState(DWORD Unknown1)
+{
+    return 0;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+USBD_InitializeDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,
+    DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+USBD_RegisterHostController(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,
+    DWORD Unknown4, DWORD Unknown5, DWORD Unknown6, DWORD Unknown7,
+    DWORD Unknown8, DWORD Unknown9, DWORD Unknown10)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+USBD_GetDeviceInformation(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+USBD_CreateDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3,
+    DWORD Unknown4, DWORD Unknown5)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+USBD_RemoveDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_CompleteRequest(DWORD Unknown1, DWORD Unknown2)
+{
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_RegisterHcFilter(
+    PDEVICE_OBJECT DeviceObject, 
+    PDEVICE_OBJECT FilterDeviceObject
+    )
+{
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_SetSuspendPowerState(DWORD Unknown1, DWORD Unknown2)
+{
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+USBD_MakePdoName(DWORD Unknown1, DWORD Unknown2)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+USBD_QueryBusTime(
+    PDEVICE_OBJECT RootHubPdo,
+    PULONG CurrentFrame
+    )
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_GetUSBDIVersion(
+    PUSBD_VERSION_INFORMATION Version
+    )
+{
+    if (Version != NULL)
+    {
+        Version->USBDI_Version = USBDI_VERSION;
+        Version->Supported_USB_Version = 0x100;
+    }
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS STDCALL
+USBD_RestoreDevice(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)
+{
+    return STATUS_NOT_SUPPORTED;
+}
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+USBD_RegisterHcDeviceCapabilities(DWORD Unknown1, DWORD Unknown2,
+    DWORD Unknown3)
+{
+}
+
+/*
+ * @implemented
+ * FIXME: Test
+ */
+PURB
+STDCALL
+USBD_CreateConfigurationRequestEx(
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+    PUSBD_INTERFACE_LIST_ENTRY InterfaceList
+    )
+{
+    PURB Urb;
+    DWORD UrbSize;
+    DWORD InterfaceCount;
+
+    for (InterfaceCount = 0;
+         InterfaceList[InterfaceCount].InterfaceDescriptor != NULL;
+         ++InterfaceCount)
+       ;
+    /* Include the NULL entry */
+    ++InterfaceCount;
+
+    UrbSize = sizeof(Urb->UrbSelectConfiguration) + 
+       (InterfaceCount * sizeof(PUSBD_INTERFACE_LIST_ENTRY));
+    Urb = ExAllocatePool(NonPagedPool, UrbSize);
+    Urb->UrbSelectConfiguration.Hdr.Function =
+        URB_FUNCTION_SELECT_CONFIGURATION;        
+    Urb->UrbSelectConfiguration.Hdr.Length =
+        sizeof(Urb->UrbSelectConfiguration);
+    Urb->UrbSelectConfiguration.ConfigurationDescriptor = 
+       ConfigurationDescriptor;
+    memcpy((PVOID)&Urb->UrbSelectConfiguration.Interface, (PVOID)InterfaceList,
+       InterfaceCount * sizeof(PUSBD_INTERFACE_LIST_ENTRY));
+
+    return Urb;
+}
+
+/*
+ * @unimplemented
+ */
+PURB STDCALL
+USBD_CreateConfigurationRequest(
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+    PUSHORT Size
+    )
+{
+    return NULL;
+}
+
+/*
+ * @unimplemented
+ */
+ULONG STDCALL
+USBD_GetInterfaceLength(
+    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
+    PUCHAR BufferEnd
+    )
+{
+    ULONG_PTR Current;
+    PUSB_INTERFACE_DESCRIPTOR CurrentDescriptor = InterfaceDescriptor;
+    DWORD Length = CurrentDescriptor->bLength;
+
+    // USB_ENDPOINT_DESCRIPTOR_TYPE
+    if (CurrentDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
+    {
+        for (Current = (ULONG_PTR)CurrentDescriptor;
+             Current < (ULONG_PTR)BufferEnd;
+             Current += CurrentDescriptor->bLength)
+            CurrentDescriptor = (PUSB_INTERFACE_DESCRIPTOR)Current;
+            Length += CurrentDescriptor->bLength;
+
+    }
+    return Length;
+}
+
+/*
+ * @unimplemented
+ */
+PUSB_INTERFACE_DESCRIPTOR STDCALL
+USBD_ParseConfigurationDescriptorEx(
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+    PVOID StartPosition,
+    LONG InterfaceNumber,
+    LONG AlternateSetting,
+    LONG InterfaceClass,
+    LONG InterfaceSubClass,
+    LONG InterfaceProtocol
+    )
+{
+    return NULL;
+}
+
+/*
+ * @implemented
+ */
+PUSB_INTERFACE_DESCRIPTOR STDCALL
+USBD_ParseConfigurationDescriptor(
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+    UCHAR InterfaceNumber,
+    UCHAR AlternateSetting
+    )
+{
+    return USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
+        (PVOID)ConfigurationDescriptor, InterfaceNumber, AlternateSetting,
+        -1, -1, -1);
+}
+
+/*
+ * @unimplemented
+ */
+PUSB_COMMON_DESCRIPTOR STDCALL
+USBD_ParseDescriptors(
+    PVOID  DescriptorBuffer,
+    ULONG  TotalLength,
+    PVOID  StartPosition,
+    LONG  DescriptorType
+    )
+{
+    return NULL; 
+}
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+USBD_GetPdoRegistryParameter(
+    PDEVICE_OBJECT PhysicalDeviceObject,
+    PVOID Parameter,
+    ULONG ParameterLength,
+    PWCHAR KeyName,
+    ULONG KeyNameLength
+    )
+{
+    NTSTATUS Status;
+    HANDLE DevInstRegKey;
+
+    Status = IoOpenDeviceRegistryKey(PhysicalDeviceObject,
+        PLUGPLAY_REGKEY_DRIVER, STANDARD_RIGHTS_ALL, &DevInstRegKey);
+    if (NT_SUCCESS(Status))
+    {
+        PKEY_VALUE_FULL_INFORMATION FullInfo;
+        UNICODE_STRING ValueName;
+        ULONG Length;
+
+        RtlInitUnicodeString(&ValueName, KeyName);
+        Length = ParameterLength + KeyNameLength + sizeof(KEY_VALUE_FULL_INFORMATION);
+        FullInfo = ExAllocatePool(PagedPool, Length);
+        if (FullInfo)
+        {
+            Status = ZwQueryValueKey(DevInstRegKey, &ValueName,
+                KeyValueFullInformation, FullInfo, Length, &Length);
+            if (NT_SUCCESS(Status))
+            {
+                RtlCopyMemory(Parameter,
+                    ((PUCHAR)FullInfo) + FullInfo->DataOffset,
+                    ParameterLength /*FullInfo->DataLength*/);
+            }
+            ExFreePool(FullInfo);
+        } else
+            Status = STATUS_NO_MEMORY;
+        ZwClose(DevInstRegKey);
+    }
+    return Status;
+}