[2/2] usbd.sys: add USB descriptor parsing functions

Damjan Jovanovic damjan.jov at gmail.com
Thu Mar 18 14:29:01 CDT 2010


Changelog:
* usbd.sys: add USB descriptor parsing functions

Damjan Jovanovic
-------------- next part --------------
diff --git a/dlls/usbd.sys/usbd.c b/dlls/usbd.sys/usbd.c
index e734acd..daeb5c0 100644
--- a/dlls/usbd.sys/usbd.c
+++ b/dlls/usbd.sys/usbd.c
@@ -27,10 +27,87 @@
 #include "winbase.h"
 #include "winternl.h"
 #include "ddk/wdm.h"
+#include "ddk/usb.h"
+#include "ddk/usbdlib.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(usbd);
 
+PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(
+        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+        PVOID StartPosition, LONG InterfaceNumber,
+        LONG AlternateSetting, LONG InterfaceClass,
+        LONG InterfaceSubClass, LONG InterfaceProtocol )
+{
+    /* http://blogs.msdn.com/usbcoreblog/archive/2009/12/12/
+     *        what-is-the-right-way-to-validate-and-parse-configuration-descriptors.aspx
+     */
+
+    PUSB_INTERFACE_DESCRIPTOR interface;
+
+    TRACE( "(%p, %p, %d, %d, %d, %d, %d)\n", ConfigurationDescriptor,
+            StartPosition, InterfaceNumber, AlternateSetting,
+            InterfaceClass, InterfaceSubClass, InterfaceProtocol );
+
+    interface = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
+        ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
+        StartPosition, USB_INTERFACE_DESCRIPTOR_TYPE );
+    while (interface != NULL)
+    {
+        if ((InterfaceNumber == -1 || interface->bInterfaceNumber == InterfaceNumber) &&
+            (AlternateSetting == -1 || interface->bAlternateSetting == AlternateSetting) &&
+            (InterfaceClass == -1 || interface->bInterfaceClass == InterfaceClass) &&
+            (InterfaceSubClass == -1 || interface->bInterfaceSubClass == InterfaceSubClass) &&
+            (InterfaceProtocol == -1 || interface->bInterfaceProtocol == InterfaceProtocol))
+        {
+            return interface;
+        }
+        interface = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
+            ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
+            interface + 1, USB_INTERFACE_DESCRIPTOR_TYPE );
+    }
+    return NULL;
+}
+
+PUSB_COMMON_DESCRIPTOR WINAPI USBD_ParseDescriptors(
+        PVOID DescriptorBuffer,
+        ULONG TotalLength,
+        PVOID StartPosition,
+        LONG DescriptorType )
+{
+    PUSB_COMMON_DESCRIPTOR common;
+
+    TRACE( "(%p, %u, %p, %d)\n", DescriptorBuffer, TotalLength, StartPosition, DescriptorType );
+
+    for (common = (PUSB_COMMON_DESCRIPTOR)DescriptorBuffer;
+         ((char*)common) + sizeof(USB_COMMON_DESCRIPTOR) <= ((char*)DescriptorBuffer) + TotalLength;
+         common = (PUSB_COMMON_DESCRIPTOR)(((char*)common) + common->bLength))
+    {
+        if (StartPosition <= (PVOID)common && common->bDescriptorType == DescriptorType)
+            return common;
+    }
+    return NULL;
+}
+
+ULONG WINAPI USBD_GetInterfaceLength(
+        PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor,
+        PUCHAR BufferEnd )
+{
+    PUSB_COMMON_DESCRIPTOR common;
+    ULONG total = InterfaceDescriptor->bLength;
+
+    TRACE( "(%p, %p)\n", InterfaceDescriptor, BufferEnd );
+
+    for (common = (PUSB_COMMON_DESCRIPTOR)(InterfaceDescriptor + 1);
+         (((PUCHAR)common) + sizeof(USB_COMMON_DESCRIPTOR)) <= BufferEnd &&
+             common->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE;
+         common = (PUSB_COMMON_DESCRIPTOR)(((char*)common) + common->bLength))
+    {
+        total += common->bLength;
+    }
+    return total;
+}
+
 NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
 {
     TRACE( "(%p, %s)\n", driver, debugstr_w(path->Buffer) );
diff --git a/dlls/usbd.sys/usbd.sys.spec b/dlls/usbd.sys/usbd.sys.spec
index c8f1d68..47e0bdb 100644
--- a/dlls/usbd.sys/usbd.sys.spec
+++ b/dlls/usbd.sys/usbd.sys.spec
@@ -1,6 +1,6 @@
 @ stub USBD_CreateConfigurationRequestEx
-@ stub USBD_ParseConfigurationDescriptorEx
-@ stub USBD_ParseDescriptors
+@ stdcall USBD_ParseConfigurationDescriptorEx(ptr ptr long long long long long)
+@ stdcall USBD_ParseDescriptors(ptr long ptr long)
 @ stub USBD_AllocateDeviceName
 @ stub USBD_CalculateUsbBandwidth
 @ stub USBD_CompleteRequest
@@ -14,15 +14,15 @@
 @ stub USBD_FreeDeviceMutex
 @ stub USBD_FreeDeviceName
 @ stub USBD_GetDeviceInformation
-@ stub USBD_GetInterfaceLength
+@ stdcall USBD_GetInterfaceLength(ptr ptr)
 @ stub USBD_GetPdoRegistryParameter
 @ stub USBD_GetSuspendPowerState
 @ stub USBD_GetUSBDIVersion
 @ stub USBD_InitializeDevice
 @ stub USBD_MakePdoName
 @ stub USBD_ParseConfigurationDescriptor
-@ stub _USBD_ParseConfigurationDescriptorEx at 28
-@ stub _USBD_ParseDescriptors at 16
+@ stdcall _USBD_ParseConfigurationDescriptorEx at 28(ptr ptr long long long long long) USBD_ParseConfigurationDescriptorEx
+@ stdcall _USBD_ParseDescriptors at 16(ptr long ptr long) USBD_ParseDescriptors
 @ stub USBD_QueryBusTime
 @ stub USBD_RegisterHcDeviceCapabilities
 @ stub USBD_RegisterHcFilter


More information about the wine-patches mailing list