Damjan Jovanovic : usbd.sys: Add USB descriptor parsing functions.
Alexandre Julliard
julliard at winehq.org
Fri Mar 19 11:16:37 CDT 2010
Module: wine
Branch: master
Commit: 6e4873691c15bd87fda4cf6aa10d7882b1c435aa
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6e4873691c15bd87fda4cf6aa10d7882b1c435aa
Author: Damjan Jovanovic <damjan.jov at gmail.com>
Date: Thu Mar 18 21:29:01 2010 +0200
usbd.sys: Add USB descriptor parsing functions.
---
dlls/usbd.sys/usbd.c | 77 +++++++++++++++++++++++++++++++++++++++++++
dlls/usbd.sys/usbd.sys.spec | 10 +++---
include/ddk/usbdlib.h | 4 ++
3 files changed, 86 insertions(+), 5 deletions(-)
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
diff --git a/include/ddk/usbdlib.h b/include/ddk/usbdlib.h
index c0adc46..ce3cc86 100644
--- a/include/ddk/usbdlib.h
+++ b/include/ddk/usbdlib.h
@@ -25,4 +25,8 @@ typedef struct _USBD_INTERFACE_LIST_ENTRY {
} USBD_INTERFACE_LIST_ENTRY;
typedef struct _USBD_INTERFACE_LIST_ENTRY *PUSBD_INTERFACE_LIST_ENTRY;
+PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR,PVOID,LONG,LONG,LONG,LONG,LONG);
+ULONG WINAPI USBD_GetInterfaceLength(PUSB_INTERFACE_DESCRIPTOR,PUCHAR);
+PUSB_COMMON_DESCRIPTOR WINAPI USBD_ParseDescriptors(PVOID,ULONG,PVOID,LONG);
+
#endif
More information about the wine-cvs
mailing list