[Wine-patches] [eterhack 10/23] usbhub.sys: Create devices for root hubs.
Alexander Morozov
=?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пт Июн 5 13:00:10 MSD 2009
---
dlls/usbhub.sys/usbhub.c | 109 ++++++++++++++++++++++++++++++++++++++--------
1 files changed, 91 insertions(+), 18 deletions(-)
diff --git a/dlls/usbhub.sys/usbhub.c b/dlls/usbhub.sys/usbhub.c
index 8321077..94d8b33 100644
--- a/dlls/usbhub.sys/usbhub.c
+++ b/dlls/usbhub.sys/usbhub.c
@@ -19,7 +19,7 @@
#include "config.h"
#include "wine/port.h"
-#include <stdarg.h>
+#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_LIBUSB_H
@@ -99,6 +99,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
+ if (!inst->service) goto done;
irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
urb = irpsp->Parameters.Others.Argument1;
@@ -425,6 +426,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
irpsp->Parameters.DeviceIoControl.IoControlCode );
}
+done:
irp->IoStatus.u.Status = status;
irp->IoStatus.Information = 0;
IoCompleteRequest( irp, IO_NO_INCREMENT );
@@ -444,6 +446,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
+ if (!inst->service) goto done;
irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
urb = irpsp->Parameters.Others.Argument1;
@@ -779,6 +782,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
irpsp->Parameters.DeviceIoControl.IoControlCode );
}
+done:
irp->IoStatus.u.Status = status;
irp->IoStatus.Information = 0;
IoCompleteRequest( irp, IO_NO_INCREMENT );
@@ -793,42 +797,57 @@ static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
static const WCHAR device_idW[] = {'U','S','B','\\',
'V','i','d','_','%','0','4','x','&',
'P','i','d','_','%','0','4','x',0};
+ static const WCHAR root_hub_idW[] = {'U','S','B','\\',
+ 'R','O','O','T','_','H','U','B',0};
+ struct PdoExtension *dx;
IO_STACK_LOCATION *irpsp;
NTSTATUS status;
ULONG_PTR info = 0;
TRACE( "%p, %p\n", device, irp );
+ dx = device->DeviceExtension;
irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
switch (irpsp->MinorFunction)
{
case IRP_MN_QUERY_DEVICE_RELATIONS:
- status = irp->IoStatus.u.Status;
- info = irp->IoStatus.Information;
+ /* dx->instance->service is NULL for root hubs */
+ if (dx->instance->service)
+ {
+ status = irp->IoStatus.u.Status;
+ info = irp->IoStatus.Information;
+ }
+ else
+ {
+ FIXME( "IRP_MN_QUERY_DEVICE_RELATIONS is not implemented for root hubs\n" );
+ status = STATUS_NOT_IMPLEMENTED;
+ }
break;
case IRP_MN_QUERY_ID:
switch (irpsp->Parameters.QueryId.IdType)
{
case BusQueryDeviceID:
{
- struct PdoExtension *dx = device->DeviceExtension;
- WCHAR *device_id = ExAllocatePool( PagedPool, sizeof(device_idW) );
+ WCHAR *device_id = ExAllocatePool( PagedPool, dx->instance->service ?
+ sizeof(device_idW) : sizeof(root_hub_idW) );
if (device_id == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
- snprintfW( device_id, strlenW(device_idW) + 1, device_idW,
- dx->instance->vid, dx->instance->pid );
+ if (dx->instance->service)
+ snprintfW( device_id, strlenW(device_idW) + 1, device_idW,
+ dx->instance->vid, dx->instance->pid );
+ else
+ strcpyW( device_id, root_hub_idW );
status = STATUS_SUCCESS;
info = (ULONG_PTR)device_id;
break;
}
case BusQueryInstanceID:
{
- struct PdoExtension *dx = device->DeviceExtension;
char *instance_id;
ULONG len;
ULONG size;
@@ -901,21 +920,26 @@ static BOOL start_service( const WCHAR *name )
return ret;
}
-static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst, DRIVER_OBJECT *hubdrv )
+static BOOL create_pdo_name( UNICODE_STRING *pdo_name )
{
static const WCHAR usbpdoW[] = {'\\','D','e','v','i','c','e','\\',
- 'U','S','B','P','D','O','-','%','u',0};
+ 'U','S','B','P','D','O','-','%','u',0};
static unsigned int last_pdo_num;
- UNICODE_STRING pdo_name;
- DEVICE_OBJECT *usbdev = NULL;
- WCHAR *buf;
+ WCHAR *buf = RtlAllocateHeap( GetProcessHeap(), 0, 30 * sizeof(WCHAR) );
- buf = HeapAlloc( GetProcessHeap(), 0, 30 * sizeof(WCHAR) );
- if (buf == NULL) return NULL;
+ if (buf == NULL) return FALSE;
snprintfW( buf, 30, usbpdoW, last_pdo_num++ );
- RtlInitUnicodeString( &pdo_name, buf );
+ RtlInitUnicodeString( pdo_name, buf );
+ return TRUE;
+}
+
+static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst, DRIVER_OBJECT *hubdrv )
+{
+ UNICODE_STRING pdo_name;
+ DEVICE_OBJECT *usbdev = NULL;
+ if (!create_pdo_name( &pdo_name )) return NULL;
if (IoCreateDevice( hubdrv, sizeof(struct PdoExtension), &pdo_name,
0, 0, FALSE, &usbdev ) == STATUS_SUCCESS)
{
@@ -923,10 +947,46 @@ static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst, DRIVER_OBJECT *hu
usbdev->Flags |= DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE;
usbdev->Flags &= ~DO_DEVICE_INITIALIZING;
}
- HeapFree( GetProcessHeap(), 0, buf );
+ RtlFreeUnicodeString( &pdo_name );
return usbdev;
}
+static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
+ DRIVER_OBJECT *hubdrv )
+{
+ static unsigned int instance_id;
+ struct DeviceInstance *instance = NULL;
+ DEVICE_OBJECT *hubdev;
+ UNICODE_STRING pdo_name = {0, 0, NULL};
+
+ instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
+ if (instance == NULL) return;
+ instance->instance_id = HeapAlloc( GetProcessHeap(), 0, 16 );
+ if (instance->instance_id == NULL) goto fail;
+ instance->vid = vid;
+ instance->pid = pid;
+ snprintf( instance->instance_id, 16, "%u", instance_id );
+ instance->service = NULL;
+ instance->dev = dev;
+
+ if (!create_pdo_name( &pdo_name )) goto fail;
+ if (IoCreateDevice( hubdrv, sizeof(struct PdoExtension), &pdo_name,
+ 0, 0, FALSE, &hubdev ) != STATUS_SUCCESS) goto fail;
+
+ ++instance_id;
+ list_add_tail( &Devices, &instance->entry );
+ ((struct PdoExtension *)hubdev->DeviceExtension)->instance = instance;
+ hubdev->Flags |= DO_POWER_PAGABLE;
+ hubdev->Flags &= ~DO_DEVICE_INITIALIZING;
+ return;
+fail:
+ if (instance->instance_id)
+ HeapFree( GetProcessHeap(), 0, instance->instance_id );
+ HeapFree( GetProcessHeap(), 0, instance );
+ RtlFreeUnicodeString( &pdo_name );
+ return;
+}
+
static BOOL enum_reg_usb_devices(void)
{
static const WCHAR usb[] = {'U','S','B',0};
@@ -1040,6 +1100,7 @@ static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
#else
struct usb_device *dev;
struct usb_bus *bus;
+ struct usb_device_descriptor *desc;
#endif
struct DeviceInstance *instance;
DEVICE_OBJECT *pdo;
@@ -1072,6 +1133,12 @@ static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
ERR( "failed to get USB device descriptor\n" );
continue;
}
+ if (libusb_get_device_address( dev ) == 1)
+ {
+ libusb_ref_device( dev );
+ create_root_hub_device( desc.idVendor, desc.idProduct, dev, hubdrv );
+ continue;
+ }
LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
{
if (instance->dev == NULL && desc.idVendor == instance->vid &&
@@ -1114,7 +1181,13 @@ static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
usb_find_devices();
for (bus = usb_busses; bus; bus = bus->next)
- for (dev = bus->devices; dev; dev = dev->next)
+ {
+ desc = &bus->devices->descriptor;
+ create_root_hub_device( desc->idVendor, desc->idProduct,
+ bus->devices, hubdrv );
+ }
+ for (bus = usb_busses; bus; bus = bus->next)
+ for (dev = bus->devices->next; dev; dev = dev->next)
LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
{
if (instance->dev == NULL &&
--
1.6.3.1
Подробная информация о списке рассылки Wine-patches