[Wine-patches] [eterhack 08/23] usbhub.sys: Improve URB_FUNCTION_SELECT_CONFIGURATION handler implementation.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пт Июн 5 13:00:08 MSD 2009


---
 dlls/usbhub.sys/usbhub.c |   96 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 91 insertions(+), 5 deletions(-)

diff --git a/dlls/usbhub.sys/usbhub.c b/dlls/usbhub.sys/usbhub.c
index ba77800..274839f 100644
--- a/dlls/usbhub.sys/usbhub.c
+++ b/dlls/usbhub.sys/usbhub.c
@@ -109,22 +109,61 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
         {
         case URB_FUNCTION_SELECT_CONFIGURATION:
             {
-                USB_CONFIGURATION_DESCRIPTOR *conf_desc =
-                        urb->u.UrbSelectConfiguration.ConfigurationDescriptor;
+                struct _URB_SELECT_CONFIGURATION *request =
+                        &urb->u.UrbSelectConfiguration;
                 libusb_device_handle *husb;
 
                 TRACE( "URB_FUNCTION_SELECT_CONFIGURATION\n" );
 
                 if (!libusb_open( inst->dev, &husb ))
                 {
+                    USB_CONFIGURATION_DESCRIPTOR *conf_desc =
+                            request->ConfigurationDescriptor;
+                    struct libusb_config_descriptor *conf;
                     int ret;
 
                     ret = libusb_set_configuration( husb, (conf_desc != NULL) ?
                             conf_desc->bConfigurationValue : -1 );
                     if (ret < 0)
                         ERR( "libusb_set_configuration: %d\n", ret );
-                    else
+                    else if (conf_desc == NULL)
                         status = STATUS_SUCCESS;
+                    else if (!libusb_get_active_config_descriptor( inst->dev, &conf ))
+                    {
+                        USBD_INTERFACE_INFORMATION *if_info = &request->Interface;
+                        const struct libusb_interface_descriptor *intf;
+                        ULONG k, n;
+
+                        /* FIXME: case of num_altsetting > 1 */
+
+                        for (n = 0; n < conf_desc->bNumInterfaces; ++n)
+                        {
+                            intf = &conf->interface[n].altsetting[0];
+                            if_info->Class = intf->bInterfaceClass;
+                            if_info->SubClass = intf->bInterfaceSubClass;
+                            if_info->Protocol = intf->bInterfaceProtocol;
+                            if_info->InterfaceHandle =
+                                    (void *)(intf->bInterfaceNumber + 1);
+                            for (k = 0; k < if_info->NumberOfPipes; ++k)
+                            {
+                                if_info->Pipes[k].MaximumPacketSize =
+                                        intf->endpoint[k].wMaxPacketSize;
+                                if_info->Pipes[k].EndpointAddress =
+                                        intf->endpoint[k].bEndpointAddress;
+                                if_info->Pipes[k].Interval =
+                                        intf->endpoint[k].bInterval;
+                                if_info->Pipes[k].PipeType =
+                                        intf->endpoint[k].bmAttributes & 3;
+                                if_info->Pipes[k].PipeHandle =
+                                        (void *)(intf->endpoint[k].bEndpointAddress +
+                                        ((intf->bInterfaceNumber + 1) << 8));
+                            }
+                            if_info = (USBD_INTERFACE_INFORMATION *)
+                                    ((char *)if_info + if_info->Length);
+                        }
+                        libusb_free_config_descriptor( conf );
+                        status = STATUS_SUCCESS;
+                    }
                     libusb_close( husb );
                 }
             }
@@ -380,8 +419,8 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
         {
         case URB_FUNCTION_SELECT_CONFIGURATION:
             {
-                USB_CONFIGURATION_DESCRIPTOR *conf_desc =
-                        urb->u.UrbSelectConfiguration.ConfigurationDescriptor;
+                struct _URB_SELECT_CONFIGURATION *request =
+                        &urb->u.UrbSelectConfiguration;
                 usb_dev_handle *husb;
 
                 TRACE( "URB_FUNCTION_SELECT_CONFIGURATION\n" );
@@ -389,14 +428,61 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
                 husb = usb_open( inst->dev );
                 if (husb)
                 {
+                    USB_CONFIGURATION_DESCRIPTOR *conf_desc =
+                            urb->u.UrbSelectConfiguration.ConfigurationDescriptor;
                     int ret;
 
                     ret = usb_set_configuration( husb, (conf_desc != NULL) ?
                             conf_desc->bConfigurationValue : -1 );
                     if (ret < 0)
                         ERR( "%s\n", usb_strerror() );
+                    else if (conf_desc == NULL)
+                        status = STATUS_SUCCESS;
                     else
+                    {
+                        USBD_INTERFACE_INFORMATION *if_info = &request->Interface;
+                        struct usb_config_descriptor *conf;
+                        struct usb_interface_descriptor *intf;
+                        ULONG k, n;
+
+                        /* FIXME: case of num_altsetting > 1 */
+
+                        for (n = 0; n < inst->dev->descriptor.bNumConfigurations; ++n)
+                            if (inst->dev->config[n].bConfigurationValue ==
+                                conf_desc->bConfigurationValue)
+                            {
+                                conf = &inst->dev->config[n];
+                                break;
+                            }
+                        for (n = 0; n < conf_desc->bNumInterfaces; ++n)
+                        {
+                            intf = &conf->interface[n].altsetting[0];
+                            if_info->Class = intf->bInterfaceClass;
+                            if_info->SubClass = intf->bInterfaceSubClass;
+                            if_info->Protocol = intf->bInterfaceProtocol;
+                            if_info->SubClass = intf->bInterfaceSubClass;
+                            if_info->Protocol = intf->bInterfaceProtocol;
+                            if_info->InterfaceHandle =
+                                    (void *)(intf->bInterfaceNumber + 1);
+                            for (k = 0; k < if_info->NumberOfPipes; ++k)
+                            {
+                                if_info->Pipes[k].MaximumPacketSize =
+                                        intf->endpoint[k].wMaxPacketSize;
+                                if_info->Pipes[k].EndpointAddress =
+                                        intf->endpoint[k].bEndpointAddress;
+                                if_info->Pipes[k].Interval =
+                                        intf->endpoint[k].bInterval;
+                                if_info->Pipes[k].PipeType =
+                                        intf->endpoint[k].bmAttributes & 3;
+                                if_info->Pipes[k].PipeHandle =
+                                        (void *)(intf->endpoint[k].bEndpointAddress +
+                                        ((intf->bInterfaceNumber + 1) << 8));
+                            }
+                            if_info = (USBD_INTERFACE_INFORMATION *)
+                                    ((char *)if_info + if_info->Length);
+                        }
                         status = STATUS_SUCCESS;
+                    }
                     usb_close( husb );
                 }
             }
-- 
1.6.3.1



Подробная информация о списке рассылки Wine-patches