usbd.sys: implement URB building functions

Damjan Jovanovic damjan.jov at gmail.com
Mon Mar 22 07:41:14 CDT 2010


Changelog:
* usbd.sys: implement URB building functions

Damjan Jovanovic
-------------- next part --------------
diff --git a/dlls/usbd.sys/usbd.c b/dlls/usbd.sys/usbd.c
index daeb5c0..4727512 100644
--- a/dlls/usbd.sys/usbd.c
+++ b/dlls/usbd.sys/usbd.c
@@ -33,6 +33,128 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(usbd);
 
+PURB WINAPI USBD_CreateConfigurationRequest(
+        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSHORT Siz )
+{
+    URB *urb = NULL;
+    USBD_INTERFACE_LIST_ENTRY *interfaceList;
+    ULONG interfaceListSize;
+    USB_INTERFACE_DESCRIPTOR *interfaceDesc;
+    int i;
+
+    TRACE( "(%p, %p)\n", ConfigurationDescriptor, Siz );
+
+    /* http://www.microsoft.com/whdc/archive/usbfaq.mspx
+     * claims USBD_CreateConfigurationRequest doesn't support > 1 interface,
+     * but is this on Windows 98 only or all versions?
+     */
+
+    *Siz = 0;
+    interfaceListSize = (ConfigurationDescriptor->bNumInterfaces + 1) * sizeof(USBD_INTERFACE_LIST_ENTRY);
+    interfaceList = ExAllocatePool( NonPagedPool, interfaceListSize );
+    if (interfaceList)
+    {
+        RtlZeroMemory( interfaceList,  interfaceListSize );
+        interfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
+            ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
+            ConfigurationDescriptor, USB_INTERFACE_DESCRIPTOR_TYPE );
+        for (i = 0; i < ConfigurationDescriptor->bNumInterfaces && interfaceDesc != NULL; i++)
+        {
+            interfaceList[i].InterfaceDescriptor = interfaceDesc;
+            interfaceDesc = (PUSB_INTERFACE_DESCRIPTOR) USBD_ParseDescriptors(
+                ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
+                interfaceDesc + 1, USB_INTERFACE_DESCRIPTOR_TYPE );
+        }
+        urb = USBD_CreateConfigurationRequestEx( ConfigurationDescriptor, interfaceList );
+        if (urb)
+            *Siz = urb->u.UrbHeader.Length;
+        ExFreePool( interfaceList );
+    }
+    return urb;
+}
+
+PURB WINAPI USBD_CreateConfigurationRequestEx(
+        PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+        PUSBD_INTERFACE_LIST_ENTRY InterfaceList )
+{
+    URB *urb;
+    ULONG size = 0;
+    USBD_INTERFACE_LIST_ENTRY *interfaceEntry;
+    ULONG interfaceCount = 0;
+
+    TRACE( "(%p, %p)\n", ConfigurationDescriptor, InterfaceList );
+
+    size = sizeof(struct _URB_SELECT_CONFIGURATION);
+    for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
+    {
+        ++interfaceCount;
+        size += (interfaceEntry->InterfaceDescriptor->bNumEndpoints - 1) *
+            sizeof(USBD_PIPE_INFORMATION);
+    }
+    size += (interfaceCount - 1) * sizeof(USBD_INTERFACE_INFORMATION);
+
+    urb = ExAllocatePool( NonPagedPool, size );
+    if (urb)
+    {
+        USBD_INTERFACE_INFORMATION *interfaceInfo;
+
+        RtlZeroMemory( urb, size );
+        urb->u.UrbSelectConfiguration.Hdr.Length = size;
+        urb->u.UrbSelectConfiguration.Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION;
+        urb->u.UrbSelectConfiguration.ConfigurationDescriptor = ConfigurationDescriptor;
+        interfaceInfo = &urb->u.UrbSelectConfiguration.Interface;
+        for (interfaceEntry = InterfaceList; interfaceEntry->InterfaceDescriptor; interfaceEntry++)
+        {
+            int i;
+            USB_INTERFACE_DESCRIPTOR *currentInterface;
+            USB_ENDPOINT_DESCRIPTOR *endpointDescriptor;
+            interfaceInfo->InterfaceNumber = interfaceEntry->InterfaceDescriptor->bInterfaceNumber;
+            interfaceInfo->AlternateSetting = interfaceEntry->InterfaceDescriptor->bAlternateSetting;
+            interfaceInfo->Class = interfaceEntry->InterfaceDescriptor->bInterfaceClass;
+            interfaceInfo->SubClass = interfaceEntry->InterfaceDescriptor->bInterfaceSubClass;
+            interfaceInfo->Protocol = interfaceEntry->InterfaceDescriptor->bInterfaceProtocol;
+            interfaceInfo->NumberOfPipes = interfaceEntry->InterfaceDescriptor->bNumEndpoints;
+            currentInterface = USBD_ParseConfigurationDescriptorEx(
+                ConfigurationDescriptor, ConfigurationDescriptor,
+                interfaceEntry->InterfaceDescriptor->bInterfaceNumber, -1, -1, -1, -1 );
+            endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
+                ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
+                currentInterface, USB_ENDPOINT_DESCRIPTOR_TYPE );
+            for (i = 0; i < interfaceInfo->NumberOfPipes && endpointDescriptor; i++)
+            {
+                interfaceInfo->Pipes[i].MaximumPacketSize = endpointDescriptor->wMaxPacketSize;
+                interfaceInfo->Pipes[i].EndpointAddress = endpointDescriptor->bEndpointAddress;
+                interfaceInfo->Pipes[i].Interval = endpointDescriptor->bInterval;
+                if (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_CONTROL)
+                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeControl;
+                else if (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_BULK)
+                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeBulk;
+                else if (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_INTERRUPT)
+                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeInterrupt;
+                else if (endpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_ISOCHRONOUS)
+                    interfaceInfo->Pipes[i].PipeType = UsbdPipeTypeIsochronous;
+                endpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(
+                    ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength,
+                    endpointDescriptor + 1, USB_ENDPOINT_DESCRIPTOR_TYPE );
+            }
+            interfaceInfo->Length = sizeof(USBD_INTERFACE_INFORMATION) +
+                (i - 1) * sizeof(USBD_PIPE_INFORMATION);
+            interfaceEntry->Interface = interfaceInfo;
+            interfaceInfo = (USBD_INTERFACE_INFORMATION*)(((char*)interfaceInfo)+interfaceInfo->Length);
+        }
+    }
+    return urb;
+}
+
+VOID WINAPI USBD_GetUSBDIVersion(
+        PUSBD_VERSION_INFORMATION VersionInformation )
+{
+    TRACE( "(%p)\n", VersionInformation );
+    /* Emulate Windows 2000 (= 0x300) for now */
+    VersionInformation->USBDI_Version = 0x300;
+    VersionInformation->Supported_USB_Version = 0x200;
+}
+
 PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(
         PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
         PVOID StartPosition, LONG InterfaceNumber,
diff --git a/dlls/usbd.sys/usbd.sys.spec b/dlls/usbd.sys/usbd.sys.spec
index 47e0bdb..1cb507e 100644
--- a/dlls/usbd.sys/usbd.sys.spec
+++ b/dlls/usbd.sys/usbd.sys.spec
@@ -1,11 +1,11 @@
-@ stub USBD_CreateConfigurationRequestEx
+@ stdcall USBD_CreateConfigurationRequestEx(ptr ptr)
 @ 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
-@ stub USBD_CreateConfigurationRequest
-@ stub _USBD_CreateConfigurationRequestEx at 8
+@ stdcall USBD_CreateConfigurationRequest(ptr ptr)
+@ stdcall _USBD_CreateConfigurationRequestEx at 8(ptr ptr) USBD_CreateConfigurationRequestEx
 @ stub USBD_CreateDevice
 @ stub USBD_Debug_GetHeap
 @ stub USBD_Debug_LogEntry
@@ -17,7 +17,7 @@
 @ stdcall USBD_GetInterfaceLength(ptr ptr)
 @ stub USBD_GetPdoRegistryParameter
 @ stub USBD_GetSuspendPowerState
-@ stub USBD_GetUSBDIVersion
+@ stdcall USBD_GetUSBDIVersion(ptr)
 @ stub USBD_InitializeDevice
 @ stub USBD_MakePdoName
 @ stub USBD_ParseConfigurationDescriptor
diff --git a/include/ddk/usb100.h b/include/ddk/usb100.h
index 534dca1..b013f21 100644
--- a/include/ddk/usb100.h
+++ b/include/ddk/usb100.h
@@ -48,6 +48,12 @@ typedef struct _USB_DEVICE_DESCRIPTOR {
 } USB_DEVICE_DESCRIPTOR;
 typedef struct _USB_DEVICE_DESCRIPTOR *PUSB_DEVICE_DESCRIPTOR;
 
+#define USB_ENDPOINT_TYPE_MASK            0x03
+#define USB_ENDPOINT_TYPE_CONTROL         0x00
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS     0x01
+#define USB_ENDPOINT_TYPE_BULK            0x02
+#define USB_ENDPOINT_TYPE_INTERRUPT       0x03
+
 typedef struct _USB_ENDPOINT_DESCRIPTOR {
     UCHAR bLength;
     UCHAR bDescriptorType;
diff --git a/include/ddk/usbdlib.h b/include/ddk/usbdlib.h
index ce3cc86..0003816 100644
--- a/include/ddk/usbdlib.h
+++ b/include/ddk/usbdlib.h
@@ -25,8 +25,11 @@ 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);
+PURB WINAPI USBD_CreateConfigurationRequest(PUSB_CONFIGURATION_DESCRIPTOR,PUSHORT);
+PURB WINAPI USBD_CreateConfigurationRequestEx(PUSB_CONFIGURATION_DESCRIPTOR,PUSBD_INTERFACE_LIST_ENTRY);
 ULONG WINAPI USBD_GetInterfaceLength(PUSB_INTERFACE_DESCRIPTOR,PUCHAR);
+VOID WINAPI USBD_GetUSBDIVersion(PUSBD_VERSION_INFORMATION);
 PUSB_COMMON_DESCRIPTOR WINAPI USBD_ParseDescriptors(PVOID,ULONG,PVOID,LONG);
+PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR,PVOID,LONG,LONG,LONG,LONG,LONG);
 
 #endif


More information about the wine-patches mailing list