[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