[Wine-patches] [6/23] Combine wineusb and wineusbhub into usbhub.sys, do not use wineserver to call AddDevice.
Alexander Morozov
=?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Пн Янв 19 18:23:22 MSK 2009
For eterhack branch
----------- следующая часть -----------
From 5b8eef145dc43d841e05d64f0f61102bb8dbb41e Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 12 Jan 2009 14:25:13 +0300
Subject: [PATCH] Combine wineusb and wineusbhub into usbhub.sys, do not use wineserver to call AddDevice.
---
dlls/ntoskrnl.exe/Makefile.in | 2 +-
dlls/ntoskrnl.exe/ntoskrnl.c | 212 +++++++++------
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 3 +
dlls/usbhub.sys/Makefile.in | 16 +
dlls/usbhub.sys/usbhub.c | 528 +++++++++++++++++++++++++++++++++++
dlls/usbhub.sys/usbhub.sys.spec | 1 +
dlls/wineusbhub/Makefile.in | 15 -
dlls/wineusbhub/wineusbhub.c | 319 ---------------------
dlls/wineusbhub/wineusbhub.spec | 11 -
programs/winedevice/Makefile.in | 2 +-
programs/winedevice/device.c | 97 +------
programs/wineusb/Makefile.in | 15 -
programs/wineusb/main.c | 329 ----------------------
tools/wine.inf.in | 13 +-
14 files changed, 692 insertions(+), 871 deletions(-)
create mode 100644 dlls/usbhub.sys/Makefile.in
create mode 100644 dlls/usbhub.sys/usbhub.c
create mode 100644 dlls/usbhub.sys/usbhub.sys.spec
delete mode 100644 dlls/wineusbhub/Makefile.in
delete mode 100644 dlls/wineusbhub/wineusbhub.c
delete mode 100644 dlls/wineusbhub/wineusbhub.spec
delete mode 100644 programs/wineusb/Makefile.in
delete mode 100644 programs/wineusb/main.c
diff --git a/dlls/ntoskrnl.exe/Makefile.in b/dlls/ntoskrnl.exe/Makefile.in
index 164e86e..1cd60dc 100644
--- a/dlls/ntoskrnl.exe/Makefile.in
+++ b/dlls/ntoskrnl.exe/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = ntoskrnl.exe
IMPORTLIB = ntoskrnl.exe
-IMPORTS = kernel32 ntdll wineusbhub setupapi
+IMPORTS = kernel32 ntdll setupapi
C_SRCS = \
ntoskrnl.c
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 6a0e00d..ee75766 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -47,11 +47,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
WINE_DECLARE_DEBUG_CHANNEL(relay);
-extern UNICODE_STRING * CDECL __wine_usbhub_get_pdo_name();
-extern char * CDECL __wine_usbhub_get_instance_id();
-extern USHORT CDECL __wine_usbhub_get_vid();
-extern USHORT CDECL __wine_usbhub_get_pid();
-
KSYSTEM_TIME KeTickCount = { 0, 0, 0 };
typedef struct _KSERVICE_TABLE_DESCRIPTOR
@@ -67,6 +62,22 @@ KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[4] = { { 0 } };
typedef void (WINAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
typedef void (WINAPI *PCREATE_THREAD_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
+struct DeviceInstance
+{
+ struct list entry;
+ USHORT vid;
+ USHORT pid;
+ char *instance_id;
+ WCHAR *service;
+ UNICODE_STRING pdo_name;
+ struct usb_device *dev;
+};
+
+struct PdoExtension
+{
+ struct DeviceInstance *instance;
+};
+
static struct list Irps = LIST_INIT(Irps);
struct IrpInstance
@@ -94,6 +105,24 @@ struct DriverObjExtension
void *id_addr;
};
+static struct list Drivers = LIST_INIT(Drivers);
+
+struct DriverInstance
+{
+ struct list entry;
+ DRIVER_OBJECT *driver;
+ const WCHAR *service;
+};
+
+static struct list Interfaces = LIST_INIT(Interfaces);
+
+struct InterfaceInstance
+{
+ struct list entry;
+ WCHAR *link;
+ UNICODE_STRING *target;
+};
+
#ifdef __i386__
#define mem_mask 0xffff
#define mem_size 0x10000
@@ -359,6 +388,57 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event )
/***********************************************************************
+ * __wine_add_driver_object (Not a Windows API)
+ */
+BOOL CDECL __wine_add_driver_object( DRIVER_OBJECT *driver, const WCHAR *service )
+{
+ struct DriverInstance *drv;
+
+ drv = HeapAlloc( GetProcessHeap(), 0, sizeof(*drv) );
+ if (drv == NULL) return FALSE;
+ drv->driver = driver;
+ drv->service = service;
+ list_add_tail( &Drivers, &drv->entry );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * __wine_del_driver_object (Not a Windows API)
+ */
+void CDECL __wine_del_driver_object( const DRIVER_OBJECT *driver )
+{
+ struct DriverInstance *drv;
+
+ LIST_FOR_EACH_ENTRY( drv, &Drivers, struct DriverInstance, entry )
+ {
+ if (drv->driver == driver)
+ {
+ list_remove( &drv->entry );
+ HeapFree( GetProcessHeap(), 0, drv );
+ return;
+ }
+ }
+}
+
+
+/***********************************************************************
+ * __wine_get_driver_object (Not a Windows API)
+ */
+DRIVER_OBJECT * CDECL __wine_get_driver_object( const WCHAR *service )
+{
+ struct DriverInstance *drv;
+
+ LIST_FOR_EACH_ENTRY( drv, &Drivers, struct DriverInstance, entry )
+ {
+ if (!strcmpW( drv->service, service ))
+ return drv->driver;
+ }
+ return NULL;
+}
+
+
+/***********************************************************************
* ExAcquireFastMutexUnsafe (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL1_ENTRYPOINT
@@ -872,12 +952,17 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
DWORD i = 0;
int found = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
+ struct PdoExtension *dx;
+ USHORT vid, pid;
TRACE( "%p %s %s %p\n", PhysicalDeviceObject,
debugstr_guid(InterfaceClassGuid), debugstr_us(ReferenceString),
SymbolicLinkName );
- inst_ptr = __wine_usbhub_get_instance_id();
+ dx = PhysicalDeviceObject->DeviceExtension;
+ vid = dx->instance->vid;
+ pid = dx->instance->pid;
+ inst_ptr = dx->instance->instance_id;
RtlMultiByteToUnicodeN( instance_id, MAX_DEVICE_ID_LEN, NULL,
inst_ptr, strlen( inst_ptr ) );
instance_id[strlen( inst_ptr )] = 0;
@@ -893,8 +978,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
return STATUS_NO_MEMORY;
}
/* guid_str.Buffer contains null-terminated string */
- sprintfW( buf, link_name, __wine_usbhub_get_vid(),
- __wine_usbhub_get_pid(), instance_id, guid_str.Buffer );
+ sprintfW( buf, link_name, vid, pid, instance_id, guid_str.Buffer );
RtlFreeUnicodeString( &guid_str );
hardware_id = RtlAllocateHeap( GetProcessHeap(), 0,
@@ -904,8 +988,7 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
RtlFreeHeap( GetProcessHeap(), 0, buf );
return STATUS_NO_MEMORY;
}
- sprintfW( hardware_id, device_name, __wine_usbhub_get_vid(),
- __wine_usbhub_get_pid(), instance_id );
+ sprintfW( hardware_id, device_name, vid, pid, instance_id );
set = SetupDiGetClassDevsW( NULL, usb, NULL, DIGCF_ALLCLASSES );
if (INVALID_HANDLE_VALUE == set)
@@ -933,10 +1016,31 @@ NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
{
if (!strcmpiW( id, hardware_id ))
{
+ struct InterfaceInstance *interf;
+
found = 1;
+ interf = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*interf) );
+ if (NULL == interf) break;
+ interf->link = RtlAllocateHeap( GetProcessHeap(), 0,
+ (strlenW(buf) + 1) * sizeof(WCHAR) );
+ if (NULL == interf->link)
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, interf );
+ break;
+ }
+ strcpyW( interf->link, buf );
+ interf->target = &dx->instance->pdo_name;
if (SetupDiCreateDeviceInterfaceW( set, &devInfo,
InterfaceClassGuid, NULL, 0, NULL ))
+ {
+ list_add_tail( &Interfaces, &interf->entry );
status = STATUS_SUCCESS;
+ }
+ else
+ {
+ RtlFreeHeap( GetProcessHeap(), 0, interf->link );
+ RtlFreeHeap( GetProcessHeap(), 0, interf );
+ }
break;
}
id += strlenW( id ) + 1;
@@ -990,89 +1094,25 @@ NTSTATUS WINAPI IoDeleteSymbolicLink( UNICODE_STRING *name )
NTSTATUS WINAPI IoSetDeviceInterfaceState( PUNICODE_STRING SymbolicLinkName,
BOOLEAN Enable )
{
- NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
-
TRACE( "%s %d\n", debugstr_us(SymbolicLinkName), Enable );
if (Enable)
{
- HDEVINFO set;
- UNICODE_STRING link_name;
- DWORD i, k = 0;
- SP_DEVICE_INTERFACE_DATA ifaceData;
- SP_DEVICE_INTERFACE_DETAIL_DATA_W *detail;
- SIZE_T size;
- GUID guid;
- WCHAR buf[39];
- UNICODE_STRING guid_str;
- BOOL copy = FALSE;
-
- for (i = 0; i < (SymbolicLinkName->Length / sizeof(WCHAR)) && k < 38; ++i)
+ struct InterfaceInstance *interf;
+
+ LIST_FOR_EACH_ENTRY( interf, &Interfaces, struct InterfaceInstance, entry )
{
- if (SymbolicLinkName->Buffer[i] == '{')
- copy = TRUE;
- if (copy)
- buf[k++] = SymbolicLinkName->Buffer[i];
+ if (!strncmpW( SymbolicLinkName->Buffer, interf->link,
+ SymbolicLinkName->Length ))
+ return IoCreateSymbolicLink( SymbolicLinkName, interf->target );
}
- if (k != 38)
- return STATUS_INVALID_PARAMETER;
- buf[38] = 0;
- RtlInitUnicodeString( &guid_str, buf );
- if (STATUS_SUCCESS != RtlGUIDFromString( &guid_str, &guid ))
- return STATUS_INVALID_PARAMETER;
-
- set = SetupDiGetClassDevsW( &guid, NULL, NULL, DIGCF_DEVICEINTERFACE );
- if (INVALID_HANDLE_VALUE == set)
- return STATUS_UNSUCCESSFUL;
- ifaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
- size = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + SymbolicLinkName->Length;
- detail = HeapAlloc( GetProcessHeap(), 0, size );
- if (NULL != detail)
- {
- i = 0;
- detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
- while (SetupDiEnumDeviceInterfaces( set, NULL, &guid, i++, &ifaceData ))
- {
- if (SetupDiGetDeviceInterfaceDetailW( set, &ifaceData, detail,
- size, NULL, NULL))
- if (!strncmpiW( SymbolicLinkName->Buffer + 3,
- detail->DevicePath + 3,
- SymbolicLinkName->Length / sizeof(WCHAR) - 3 ))
- {
- static const WCHAR DosDevices[] =
- {'\\','D','o','s','D','e','v','i','c','e','s',0};
- PWSTR ptr;
-
- ptr = HeapAlloc( GetProcessHeap(), 0,
- (strlenW( detail->DevicePath ) - 3
- + strlenW( DosDevices ) + 1) * sizeof(WCHAR) );
- if (NULL != ptr)
- {
- strcpyW( ptr, DosDevices );
- strcatW( ptr, detail->DevicePath + 3 );
- RtlInitUnicodeString( &link_name, ptr );
- status = IoCreateSymbolicLink( &link_name,
- __wine_usbhub_get_pdo_name() );
- HeapFree( GetProcessHeap(), 0, ptr );
- }
- else
- status = STATUS_NO_MEMORY;
- break;
- }
- }
- HeapFree( GetProcessHeap(), 0, detail );
- }
- else
- status = STATUS_NO_MEMORY;
- SetupDiDestroyDeviceInfoList( set );
+ return STATUS_OBJECT_NAME_NOT_FOUND;
}
else
{
FIXME( "Disabling interface is not supported\n" );
- status = STATUS_NOT_IMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
-
- return status;
}
@@ -1854,6 +1894,7 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
LARGE_INTEGER count;
static PVOID vectored_handler_added;
struct DriverObjExtension *ext, *ext2;
+ struct InterfaceInstance *intf, *intf2;
switch(reason)
{
@@ -1871,6 +1912,13 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
ExFreePool( ext->ptr );
ExFreePool( ext );
}
+ LIST_FOR_EACH_ENTRY_SAFE( intf, intf2, &Interfaces,
+ struct InterfaceInstance, entry )
+ {
+ list_remove( &intf->entry );
+ RtlFreeHeap( GetProcessHeap(), 0, intf->link );
+ RtlFreeHeap( GetProcessHeap(), 0, intf );
+ }
}
return TRUE;
}
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 9a30b0e..68ab9e2 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -1490,3 +1490,6 @@
@ cdecl wine_ntoskrnl_main_loop(long)
@ cdecl wine_complete_request(ptr long)
+@ cdecl __wine_add_driver_object(ptr wstr)
+@ cdecl __wine_del_driver_object(ptr)
+@ cdecl __wine_get_driver_object(wstr)
diff --git a/dlls/usbhub.sys/Makefile.in b/dlls/usbhub.sys/Makefile.in
new file mode 100644
index 0000000..ffefdda
--- /dev/null
+++ b/dlls/usbhub.sys/Makefile.in
@@ -0,0 +1,16 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = usbhub.sys
+IMPORTLIB = usbhub.sys
+IMPORTS = ntoskrnl.exe kernel32 advapi32 setupapi ntdll
+EXTRADLLFLAGS = -Wb,--subsystem,native
+EXTRALIBS = @USBLIBS@
+
+C_SRCS = \
+ usbhub.c
+
+ на MAKE_DLL_RULES@
+
+ на DEPENDENCIES@ # everything below this line is overwritten by make depend
diff --git a/dlls/usbhub.sys/usbhub.c b/dlls/usbhub.sys/usbhub.c
new file mode 100644
index 0000000..7f80b40
--- /dev/null
+++ b/dlls/usbhub.sys/usbhub.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2008 Alexander Morozov for Etersoft
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+
+#ifdef HAVE_USB_H
+#include <usb.h>
+#endif
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "winreg.h"
+#include "winsvc.h"
+#include "winuser.h"
+#include "setupapi.h"
+#include "cfgmgr32.h"
+#include "ddk/ntddk.h"
+#include "ddk/usb.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+#include "wine/list.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(usbhub);
+WINE_DECLARE_DEBUG_CHANNEL(relay);
+
+extern void CDECL wine_complete_request( IRP *irp, UCHAR priority_boost );
+extern DRIVER_OBJECT * CDECL __wine_get_driver_object( const WCHAR *service );
+
+static unsigned int last_pdo_num;
+
+static struct list Devices = LIST_INIT(Devices);
+
+struct DeviceInstance
+{
+ struct list entry;
+ USHORT vid;
+ USHORT pid;
+ char *instance_id;
+ WCHAR *service;
+ UNICODE_STRING pdo_name;
+ struct usb_device *dev;
+};
+
+struct PdoExtension
+{
+ struct DeviceInstance *instance;
+};
+
+#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
+static void add_data( char **dst, int *dst_size, void *src, int src_size )
+{
+ int copy;
+
+ copy = (src_size >= *dst_size) ? *dst_size : src_size;
+ memcpy( *dst, src, copy );
+ *dst += copy;
+ *dst_size -= copy;
+}
+
+NTSTATUS WINAPI __wine_usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
+{
+ IO_STACK_LOCATION *irpsp;
+ URB *urb;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ struct DeviceInstance *inst;
+
+ TRACE( "%p, %p\n", device, irp );
+
+ inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
+ irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
+ urb = irpsp->Parameters.Others.Argument1;
+
+ switch (urb->u.UrbHeader.Function)
+ {
+ case URB_FUNCTION_SELECT_CONFIGURATION:
+ {
+ USB_CONFIGURATION_DESCRIPTOR *conf_desc =
+ urb->u.UrbSelectConfiguration.ConfigurationDescriptor;
+ usb_dev_handle *husb;
+
+ TRACE( "URB_FUNCTION_SELECT_CONFIGURATION\n" );
+
+ husb = usb_open( inst->dev );
+ if (husb)
+ {
+ int ret;
+
+ ret = usb_set_configuration( husb, conf_desc->bConfigurationValue );
+ if (ret < 0)
+ ERR( "%s\n", usb_strerror() );
+ else
+ status = STATUS_SUCCESS;
+ usb_close( husb );
+ }
+ }
+ break;
+ case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+ {
+ struct _URB_CONTROL_DESCRIPTOR_REQUEST *request =
+ &urb->u.UrbControlDescriptorRequest;
+
+ TRACE( "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n" );
+
+ switch (request->DescriptorType)
+ {
+ case USB_DEVICE_DESCRIPTOR_TYPE:
+ TRACE( "USB_DEVICE_DESCRIPTOR_TYPE\n" );
+ if (request->TransferBuffer == NULL)
+ break;
+ if (sizeof(USB_DEVICE_DESCRIPTOR) <= request->TransferBufferLength)
+ {
+ memcpy( request->TransferBuffer, &inst->dev->descriptor,
+ sizeof(USB_DEVICE_DESCRIPTOR) );
+ status = STATUS_SUCCESS;
+ }
+ break;
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ TRACE( "USB_CONFIGURATION_DESCRIPTOR_TYPE\n" );
+ {
+ unsigned int i, k;
+ char *buf = request->TransferBuffer;
+ struct usb_config_descriptor *conf = &inst->dev->config[0];
+ struct usb_interface_descriptor *intf;
+ struct usb_endpoint_descriptor *endp;
+ int size = request->TransferBufferLength;
+
+ /* FIXME: case of num_altsetting > 1 */
+
+ if (buf == NULL)
+ break;
+ add_data( &buf, &size, conf,
+ sizeof(USB_CONFIGURATION_DESCRIPTOR) );
+ if (size > 0 && conf->extra)
+ add_data( &buf, &size, conf->extra, conf->extralen );
+ for (i = 0; i < conf->bNumInterfaces; ++i)
+ {
+ intf = &conf->interface[i].altsetting[0];
+ if (size > 0)
+ add_data( &buf, &size, intf,
+ sizeof(USB_INTERFACE_DESCRIPTOR) );
+ if (size > 0 && intf->extra)
+ add_data( &buf, &size, intf->extra, intf->extralen );
+ for (k = 0; k < intf->bNumEndpoints; ++k)
+ {
+ endp = &intf->endpoint[k];
+ if (size > 0)
+ add_data( &buf, &size, endp,
+ sizeof(USB_ENDPOINT_DESCRIPTOR) );
+ if (size > 0 && endp->extra)
+ add_data( &buf, &size, endp->extra, endp->extralen );
+ }
+ }
+ status = STATUS_SUCCESS;
+ }
+ break;
+ default:
+ FIXME( "unsupported descriptor type %x\n", request->DescriptorType );
+ }
+ }
+ break;
+ case URB_FUNCTION_VENDOR_DEVICE:
+ case URB_FUNCTION_VENDOR_INTERFACE:
+ case URB_FUNCTION_VENDOR_ENDPOINT:
+ {
+ usb_dev_handle *husb;
+ struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
+ &urb->u.UrbControlVendorClassRequest;
+
+ TRACE( "URB_FUNCTION_VENDOR_*\n" );
+
+ husb = usb_open( inst->dev );
+ if (husb)
+ {
+ UCHAR req_type = request->RequestTypeReservedBits | (2 << 5);
+ char *buf;
+ int ret;
+
+ if (urb->u.UrbHeader.Function == URB_FUNCTION_VENDOR_INTERFACE)
+ req_type |= 1;
+ else if (urb->u.UrbHeader.Function == URB_FUNCTION_VENDOR_ENDPOINT)
+ req_type |= 2;
+ buf = HeapAlloc( GetProcessHeap(), 0, request->TransferBufferLength );
+ if (buf != NULL)
+ {
+ memcpy( buf, request->TransferBuffer, request->TransferBufferLength );
+ if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ req_type |= (1 << 7);
+ ret = usb_control_msg( husb, req_type, request->Request, request->Value,
+ request->Index, buf, request->TransferBufferLength, 1000 );
+ if (ret < 0)
+ ERR( "%s\n", usb_strerror() );
+ else
+ {
+ if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ {
+ request->TransferBufferLength =
+ (ret <= request->TransferBufferLength) ?
+ ret : request->TransferBufferLength;
+ memcpy( request->TransferBuffer, buf,
+ request->TransferBufferLength );
+ }
+ status = STATUS_SUCCESS;
+ }
+ HeapFree( GetProcessHeap(), 0, buf );
+ }
+ usb_close( husb );
+ }
+ }
+ break;
+ default:
+ FIXME( "unsupported URB function %x\n", urb->u.UrbHeader.Function );
+ }
+
+ urb->u.UrbHeader.Status = status;
+ if (irp->UserIosb != NULL)
+ {
+ irp->UserIosb->u.Status = status;
+ irp->UserIosb->Information = 0;
+ }
+ irp->IoStatus.u.Status = status;
+ irp->IoStatus.Information = 0;
+ wine_complete_request( irp, IO_NO_INCREMENT );
+
+ return status;
+}
+
+NTSTATUS WINAPI __wine_usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
+{
+ TRACE( "%p, %p\n", device, irp );
+
+ irp->IoStatus.u.Status = STATUS_SUCCESS;
+ irp->IoStatus.Information = 0;
+ wine_complete_request( irp, IO_NO_INCREMENT );
+
+ return STATUS_SUCCESS;
+}
+
+static BOOL start_service( WCHAR *name )
+{
+ SC_HANDLE scm, service;
+ BOOL ret;
+
+ scm = OpenSCManagerA( NULL, NULL, SC_MANAGER_ALL_ACCESS );
+ if (scm == NULL)
+ return FALSE;
+
+ service = OpenServiceW( scm, name, SERVICE_ALL_ACCESS );
+ if (service == NULL)
+ {
+ CloseServiceHandle( scm );
+ return FALSE;
+ }
+
+ ret = StartServiceW( service, 0, NULL );
+ if (!ret && ERROR_SERVICE_ALREADY_RUNNING == GetLastError())
+ ret = TRUE;
+
+ CloseServiceHandle( service );
+ CloseServiceHandle( scm );
+
+ return ret;
+}
+
+static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst, DRIVER_OBJECT *hubdrv )
+{
+ static const WCHAR usbpdoW[] = {'\\','D','e','v','i','c','e','\\',
+ 'U','S','B','P','D','O','-','%','u',0};
+
+ DEVICE_OBJECT *usbdev;
+ WCHAR *buf;
+
+ buf = HeapAlloc( GetProcessHeap(), 0, 30 * sizeof(WCHAR) );
+ if (buf == NULL) return NULL;
+ snprintfW( buf, 30, usbpdoW, last_pdo_num++ );
+ RtlInitUnicodeString( &inst->pdo_name, buf );
+
+ if (IoCreateDevice( hubdrv, sizeof(struct PdoExtension), &inst->pdo_name,
+ 0, 0, FALSE, &usbdev ) != STATUS_SUCCESS)
+ {
+ HeapFree( GetProcessHeap(), 0, buf );
+ return NULL;
+ }
+ ((struct PdoExtension *)usbdev->DeviceExtension)->instance = inst;
+ usbdev->Flags |= DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE;
+ usbdev->Flags &= ~DO_DEVICE_INITIALIZING;
+ return usbdev;
+}
+
+static NTSTATUS add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *dev )
+{
+ NTSTATUS status;
+ NTSTATUS (WINAPI *AddDevice)( PDRIVER_OBJECT, PDEVICE_OBJECT ) =
+ driver->DriverExtension->AddDevice;
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Call AddDevice %p (%p,%p)\n",
+ GetCurrentThreadId(), AddDevice, driver, dev );
+
+ status = AddDevice( driver, dev );
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Ret AddDevice %p (%p,%p) retval=%08x\n",
+ GetCurrentThreadId(), AddDevice, driver, dev, status );
+
+ return status;
+}
+
+static void start_device( DRIVER_OBJECT *driver )
+{
+ PDRIVER_DISPATCH dispatch = driver->MajorFunction[IRP_MJ_PNP];
+ DEVICE_OBJECT *device = driver->DeviceObject;
+ IO_STACK_LOCATION *irpsp;
+ PIRP irp;
+ NTSTATUS status;
+
+ if (dispatch == NULL) return;
+ irp = IoAllocateIrp( device->StackSize, FALSE );
+ if (irp == NULL) return;
+
+ --irp->CurrentLocation;
+ irpsp = --irp->Tail.Overlay.s.u.CurrentStackLocation;
+ irp->RequestorMode = KernelMode;
+ irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
+ irpsp->MajorFunction = IRP_MJ_PNP;
+ irpsp->MinorFunction = IRP_MN_START_DEVICE;
+ irpsp->DeviceObject = device;
+ device->CurrentIrp = irp;
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
+ GetCurrentThreadId(), dispatch, device, irp );
+
+ status = dispatch( device, irp );
+
+ if (TRACE_ON(relay))
+ DPRINTF( "%04x:Ret driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
+ GetCurrentThreadId(), dispatch, device, irp, status );
+
+ IoFreeIrp( irp );
+}
+
+static BOOL enum_reg_usb_devices(void)
+{
+ static const WCHAR usb[] = {'U','S','B',0};
+
+ SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
+ char *instance_id = NULL;
+ struct DeviceInstance *instance, *instance2;
+ HDEVINFO set;
+ DWORD size, i = 0;
+ USHORT vid, pid;
+ char *str, *buf;
+ BOOL ret;
+
+ set = SetupDiGetClassDevsW( NULL, usb, 0, DIGCF_ALLCLASSES );
+ if (set == INVALID_HANDLE_VALUE) return FALSE;
+
+ while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
+ {
+ /* get VID and PID */
+ SetupDiGetDeviceRegistryPropertyA( set, &devInfo, SPDRP_HARDWAREID,
+ NULL, NULL, 0, &size );
+ buf = HeapAlloc( GetProcessHeap(), 0, size );
+ if (buf == NULL) goto fail;
+ ret = SetupDiGetDeviceRegistryPropertyA( set, &devInfo, SPDRP_HARDWAREID,
+ NULL, (BYTE *)buf, size, NULL );
+ if (!ret) goto fail;
+ str = strstr( buf, "Vid_" );
+ if (str != NULL)
+ {
+ str += 4;
+ vid = strtol( str, NULL, 16 );
+ str = strstr( str, "Pid_" );
+ }
+ if (str == NULL)
+ {
+ ERR( "bad hardware ID\n" );
+ HeapFree( GetProcessHeap(), 0, buf );
+ continue;
+ }
+ str += 4;
+ pid = strtol( str, NULL, 16 );
+ HeapFree( GetProcessHeap(), 0, buf );
+
+ /* get instance ID */
+ buf = HeapAlloc( GetProcessHeap(), 0, MAX_DEVICE_ID_LEN );
+ if (buf == NULL) goto fail;
+ ret = SetupDiGetDeviceInstanceIdA( set, &devInfo, buf,
+ MAX_DEVICE_ID_LEN, NULL );
+ if (!ret) goto fail;
+ str = strrchr( buf, '\\' );
+ if (str != NULL) ++str;
+ if (str == NULL || *str == 0)
+ {
+ ERR( "bad instance ID\n" );
+ HeapFree( GetProcessHeap(), 0, buf );
+ continue;
+ }
+ instance_id = HeapAlloc( GetProcessHeap(), 0, strlen(str) + 1 );
+ if (instance_id == NULL) goto fail;
+ strcpy( instance_id, str );
+ HeapFree( GetProcessHeap(), 0, buf );
+
+ /* get service name */
+ SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_SERVICE,
+ NULL, NULL, 0, &size );
+ buf = HeapAlloc( GetProcessHeap(), 0, size );
+ if (buf == NULL) goto fail;
+ ret = SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_SERVICE,
+ NULL, (BYTE *)buf, size, NULL );
+ if (!ret) goto fail;
+
+ /* add DeviceInstance structure to Devices list */
+ instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
+ if (instance == NULL) goto fail;
+ instance->vid = vid;
+ instance->pid = pid;
+ instance->instance_id = instance_id;
+ instance->service = (WCHAR *)buf;
+ instance->dev = NULL;
+ list_add_tail( &Devices, &instance->entry );
+ instance_id = NULL;
+ }
+
+ SetupDiDestroyDeviceInfoList( set );
+ return TRUE;
+fail:
+ if (buf) HeapFree( GetProcessHeap(), 0, buf );
+ if (instance_id) HeapFree( GetProcessHeap(), 0, instance_id );
+ SetupDiDestroyDeviceInfoList( set );
+ LIST_FOR_EACH_ENTRY_SAFE( instance, instance2, &Devices,
+ struct DeviceInstance, entry )
+ {
+ HeapFree( GetProcessHeap(), 0, instance->instance_id );
+ HeapFree( GetProcessHeap(), 0, instance->service );
+ list_remove( &instance->entry );
+ }
+ return FALSE;
+}
+
+static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
+{
+ struct DeviceInstance *instance;
+ struct usb_device *dev;
+ struct usb_bus *bus;
+ DEVICE_OBJECT *pdo;
+ DRIVER_OBJECT *driver;
+ DRIVER_OBJECT *hubdrv = usbhubdrv;
+ NTSTATUS status;
+
+ if (!enum_reg_usb_devices())
+ {
+ ERR( "failed to enumerate USB devices\n" );
+ return 1;
+ }
+
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ for (bus = usb_busses; bus; bus = bus->next)
+ for (dev = bus->devices; dev; dev = dev->next)
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev == NULL &&
+ dev->descriptor.idVendor == instance->vid &&
+ dev->descriptor.idProduct == instance->pid)
+ {
+ if (start_service( instance->service ))
+ {
+ pdo = create_pdo( instance, hubdrv );
+ if (pdo == NULL) break;
+ instance->dev = dev;
+ while (!(driver = __wine_get_driver_object(
+ instance->service )))
+ Sleep( 100 );
+ status = add_device( driver, pdo );
+ if (status != STATUS_SUCCESS) break;
+ start_device( driver );
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
+{
+#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
+ HANDLE thread;
+
+ driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = __wine_usbhub_internal_ioctl;
+ driver->MajorFunction[IRP_MJ_PNP] = __wine_usbhub_dispatch_pnp;
+
+ thread = CreateThread( NULL, 0, enum_usb_devices, driver, 0, NULL );
+ if (!thread) return STATUS_UNSUCCESSFUL;
+ CloseHandle( thread );
+#else
+ TRACE( "USB support not compiled in\n" );
+#endif
+ return STATUS_SUCCESS;
+}
diff --git a/dlls/usbhub.sys/usbhub.sys.spec b/dlls/usbhub.sys/usbhub.sys.spec
new file mode 100644
index 0000000..76421d7
--- /dev/null
+++ b/dlls/usbhub.sys/usbhub.sys.spec
@@ -0,0 +1 @@
+# nothing to export
diff --git a/dlls/wineusbhub/Makefile.in b/dlls/wineusbhub/Makefile.in
deleted file mode 100644
index 4954a5d..0000000
--- a/dlls/wineusbhub/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-TOPSRCDIR = @top_srcdir@
-TOPOBJDIR = ../..
-SRCDIR = @srcdir@
-VPATH = @srcdir@
-MODULE = wineusbhub.dll
-IMPORTLIB = wineusbhub
-IMPORTS = ntoskrnl.exe kernel32
-EXTRALIBS = @USBLIBS@
-
-C_SRCS = \
- wineusbhub.c
-
- на MAKE_DLL_RULES@
-
- на DEPENDENCIES@ # everything below this line is overwritten by make depend
diff --git a/dlls/wineusbhub/wineusbhub.c b/dlls/wineusbhub/wineusbhub.c
deleted file mode 100644
index 8023a91..0000000
--- a/dlls/wineusbhub/wineusbhub.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdarg.h>
-
-#ifdef HAVE_USB_H
-#include <usb.h>
-#endif
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "ntstatus.h"
-#define WIN32_NO_STATUS
-#include "windef.h"
-#include "winbase.h"
-#include "winternl.h"
-#include "cfgmgr32.h"
-#include "ddk/ntddk.h"
-#include "ddk/usb.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(wineusbhub);
-
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
-extern void CDECL wine_complete_request( IRP *irp, UCHAR priority_boost );
-
-DRIVER_OBJECT hubdrv;
-DEVICE_OBJECT *usbdev = NULL; /* USB PDO */
-static struct usb_device *dev;
-WCHAR bufW[20];
-UNICODE_STRING pdo_name = {0, 0, NULL};
-char instance_id[MAX_DEVICE_ID_LEN] = {0};
-
-static void add_data( char **dst, int *dst_size, void *src, int src_size )
-{
- int copy;
-
- copy = (src_size >= *dst_size) ? *dst_size : src_size;
- memcpy( *dst, src, copy );
- *dst += copy;
- *dst_size -= copy;
-}
-
-NTSTATUS WINAPI __wine_usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
-{
- IO_STACK_LOCATION *irpsp;
- URB *urb;
- NTSTATUS status = STATUS_UNSUCCESSFUL;
-
- TRACE( "%p, %p\n", device, irp );
-
- irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
- urb = irpsp->Parameters.Others.Argument1;
-
- switch (urb->u.UrbHeader.Function)
- {
- case URB_FUNCTION_SELECT_CONFIGURATION:
- {
- USB_CONFIGURATION_DESCRIPTOR *conf_desc =
- urb->u.UrbSelectConfiguration.ConfigurationDescriptor;
- usb_dev_handle *husb;
-
- TRACE( "URB_FUNCTION_SELECT_CONFIGURATION\n" );
-
- husb = usb_open( dev );
- if (husb)
- {
- int ret;
-
- ret = usb_set_configuration( husb, conf_desc->bConfigurationValue );
- if (ret < 0)
- ERR( "%s\n", usb_strerror() );
- else
- status = STATUS_SUCCESS;
- usb_close( husb );
- }
- }
- break;
- case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
- {
- struct _URB_CONTROL_DESCRIPTOR_REQUEST *request =
- &urb->u.UrbControlDescriptorRequest;
-
- TRACE( "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n" );
-
- switch (request->DescriptorType)
- {
- case USB_DEVICE_DESCRIPTOR_TYPE:
- TRACE( "USB_DEVICE_DESCRIPTOR_TYPE\n" );
- if (request->TransferBuffer == NULL)
- break;
- if (sizeof(USB_DEVICE_DESCRIPTOR) <= request->TransferBufferLength)
- {
- memcpy( request->TransferBuffer, &dev->descriptor,
- sizeof(USB_DEVICE_DESCRIPTOR) );
- status = STATUS_SUCCESS;
- }
- break;
- case USB_CONFIGURATION_DESCRIPTOR_TYPE:
- TRACE( "USB_CONFIGURATION_DESCRIPTOR_TYPE\n" );
- {
- unsigned int i, k;
- char *buf = request->TransferBuffer;
- struct usb_config_descriptor *conf = &dev->config[0];
- struct usb_interface_descriptor *intf;
- struct usb_endpoint_descriptor *endp;
- int size = request->TransferBufferLength;
-
- /* FIXME: case of num_altsetting > 1 */
-
- if (buf == NULL)
- break;
- add_data( &buf, &size, conf,
- sizeof(USB_CONFIGURATION_DESCRIPTOR) );
- if (size > 0 && conf->extra)
- add_data( &buf, &size, conf->extra, conf->extralen );
- for (i = 0; i < conf->bNumInterfaces; ++i)
- {
- intf = &conf->interface[i].altsetting[0];
- if (size > 0)
- add_data( &buf, &size, intf,
- sizeof(USB_INTERFACE_DESCRIPTOR) );
- if (size > 0 && intf->extra)
- add_data( &buf, &size, intf->extra, intf->extralen );
- for (k = 0; k < intf->bNumEndpoints; ++k)
- {
- endp = &intf->endpoint[k];
- if (size > 0)
- add_data( &buf, &size, endp,
- sizeof(USB_ENDPOINT_DESCRIPTOR) );
- if (size > 0 && endp->extra)
- add_data( &buf, &size, endp->extra, endp->extralen );
- }
- }
- status = STATUS_SUCCESS;
- }
- break;
- default:
- FIXME( "unsupported descriptor type %x\n", request->DescriptorType );
- }
- }
- break;
- case URB_FUNCTION_VENDOR_DEVICE:
- case URB_FUNCTION_VENDOR_INTERFACE:
- case URB_FUNCTION_VENDOR_ENDPOINT:
- {
- usb_dev_handle *husb;
- struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
- &urb->u.UrbControlVendorClassRequest;
-
- TRACE( "URB_FUNCTION_VENDOR_*\n" );
-
- husb = usb_open( dev );
- if (husb)
- {
- UCHAR req_type = request->RequestTypeReservedBits | (2 << 5);
- char *buf;
- int ret;
-
- if (urb->u.UrbHeader.Function == URB_FUNCTION_VENDOR_INTERFACE)
- req_type |= 1;
- else if (urb->u.UrbHeader.Function == URB_FUNCTION_VENDOR_ENDPOINT)
- req_type |= 2;
- buf = HeapAlloc( GetProcessHeap(), 0, request->TransferBufferLength );
- if (buf != NULL)
- {
- memcpy( buf, request->TransferBuffer, request->TransferBufferLength );
- if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
- req_type |= (1 << 7);
- ret = usb_control_msg( husb, req_type, request->Request, request->Value,
- request->Index, buf, request->TransferBufferLength, 1000 );
- if (ret < 0)
- ERR( "%s\n", usb_strerror() );
- else
- {
- if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
- {
- request->TransferBufferLength =
- (ret <= request->TransferBufferLength) ?
- ret : request->TransferBufferLength;
- memcpy( request->TransferBuffer, buf,
- request->TransferBufferLength );
- }
- status = STATUS_SUCCESS;
- }
- HeapFree( GetProcessHeap(), 0, buf );
- }
- usb_close( husb );
- }
- }
- break;
- default:
- FIXME( "unsupported URB function %x\n", urb->u.UrbHeader.Function );
- }
-
- urb->u.UrbHeader.Status = status;
- if (irp->UserIosb != NULL)
- {
- irp->UserIosb->u.Status = status;
- irp->UserIosb->Information = 0;
- }
- irp->IoStatus.u.Status = status;
- irp->IoStatus.Information = 0;
- wine_complete_request( irp, IO_NO_INCREMENT );
-
- return status;
-}
-
-NTSTATUS WINAPI __wine_usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
-{
- TRACE( "%p, %p\n", device, irp );
-
- irp->IoStatus.u.Status = STATUS_SUCCESS;
- irp->IoStatus.Information = 0;
- wine_complete_request( irp, IO_NO_INCREMENT );
-
- return STATUS_SUCCESS;
-}
-#endif
-
-DEVICE_OBJECT * CDECL __wine_usbhub_get_pdo( UCHAR *pdo_info )
-{
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
- static const WCHAR usbpdoW[] = {'\\','D','e','v','i','c','e','\\',
- 'U','S','B','P','D','O','-','%','u',0};
- struct usb_bus *bus;
-
- TRACE( "%u, %s, %s, %s\n", pdo_info[0], debugstr_a((char *)pdo_info + 1),
- debugstr_a((char *)pdo_info + 2 + PATH_MAX),
- debugstr_a((char *)pdo_info + 3 + 2 * PATH_MAX) );
-
- for (bus = usb_busses; bus; bus = bus->next)
- for (dev = bus->devices; dev; dev = dev->next)
- if (!strcmp( bus->dirname, (char *)(pdo_info + 1) ) &&
- !strcmp( dev->filename, (char *)(pdo_info + 2 + PATH_MAX) ))
- {
- hubdrv.MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = __wine_usbhub_internal_ioctl;
- hubdrv.MajorFunction[IRP_MJ_PNP] = __wine_usbhub_dispatch_pnp;
-
- strcpy( instance_id, (char *)pdo_info + 3 + 2 * PATH_MAX );
- snprintfW( bufW, sizeof(bufW), usbpdoW, pdo_info[0] );
- RtlInitUnicodeString( &pdo_name, bufW );
-
- if (STATUS_SUCCESS == IoCreateDevice( &hubdrv, 0, &pdo_name, 0, 0, FALSE, &usbdev ))
- {
- usbdev->Flags |= DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE;
- return usbdev;
- }
- }
-#endif
- return NULL;
-}
-
-UNICODE_STRING * CDECL __wine_usbhub_get_pdo_name()
-{
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
- if (pdo_name.Length)
- return &pdo_name;
-#endif
- return NULL;
-}
-
-char * CDECL __wine_usbhub_get_instance_id()
-{
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
- if (*instance_id)
- return instance_id;
-#endif
- return NULL;
-}
-
-USHORT CDECL __wine_usbhub_get_vid()
-{
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
- if (usbdev != NULL)
- return dev->descriptor.idVendor;
-#endif
- return 0;
-}
-
-USHORT CDECL __wine_usbhub_get_pid()
-{
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
- if (usbdev != NULL)
- return dev->descriptor.idProduct;
-#endif
- return 0;
-}
-
-BOOL WINAPI DllMain( HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv )
-{
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
- if (fdwReason == DLL_PROCESS_ATTACH)
- {
- usb_init();
- usb_find_busses();
- usb_find_devices();
- }
-#endif
- return TRUE;
-}
diff --git a/dlls/wineusbhub/wineusbhub.spec b/dlls/wineusbhub/wineusbhub.spec
deleted file mode 100644
index f277e0e..0000000
--- a/dlls/wineusbhub/wineusbhub.spec
+++ /dev/null
@@ -1,11 +0,0 @@
-##################
-# Wine extensions
-#
-# All functions must be prefixed with '__wine_' (for internal functions)
-# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
-
-@ cdecl __wine_usbhub_get_pdo(ptr)
-@ cdecl __wine_usbhub_get_pdo_name()
-@ cdecl __wine_usbhub_get_instance_id()
-@ cdecl __wine_usbhub_get_vid()
-@ cdecl __wine_usbhub_get_pid()
diff --git a/programs/winedevice/Makefile.in b/programs/winedevice/Makefile.in
index 8b8b8dd..c644b7a 100644
--- a/programs/winedevice/Makefile.in
+++ b/programs/winedevice/Makefile.in
@@ -5,7 +5,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = winedevice.exe
APPMODE = -mwindows -municode
-IMPORTS = advapi32 ntoskrnl.exe kernel32 ntdll wineusbhub
+IMPORTS = advapi32 ntoskrnl.exe kernel32 ntdll
C_SRCS = \
device.c
diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c
index adf61a4..2d83d24 100644
--- a/programs/winedevice/device.c
+++ b/programs/winedevice/device.c
@@ -22,10 +22,6 @@
#include "wine/port.h"
#include <stdarg.h>
-#include <limits.h>
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -33,19 +29,17 @@
#include "winbase.h"
#include "winternl.h"
#include "winreg.h"
-#include "winnls.h"
#include "winsvc.h"
-#include "cfgmgr32.h"
#include "ddk/ntddk.h"
#include "wine/unicode.h"
-#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(winedevice);
WINE_DECLARE_DEBUG_CHANNEL(relay);
-extern DEVICE_OBJECT * CDECL __wine_usbhub_get_pdo( UCHAR *pdo_info );
extern NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event );
+extern BOOL CDECL __wine_add_driver_object( DRIVER_OBJECT *driver, const WCHAR *service );
+extern void CDECL __wine_del_driver_object( const DRIVER_OBJECT *driver );
extern HANDLE CDECL __wine_make_process_system(void);
#define EVENT_NAME_LEN (30 * sizeof(WCHAR))
@@ -475,95 +469,16 @@ static DWORD CALLBACK driver_thread( HANDLE pipe )
&drv_name, &event_name );
if (module)
{
- UNICODE_STRING drvname;
- NTSTATUS ret = STATUS_SUCCESS;
- IRP *irp;
- IO_STACK_LOCATION *irpsp;
- PDRIVER_DISPATCH dispatch;
HANDLE loop_event;
loop_event = CreateEventW( NULL, TRUE, FALSE, event_name );
- RtlInitUnicodeString( &drvname, drv_name );
-
- if (driver_extension.AddDevice)
- {
- NTSTATUS (WINAPI *AddDevice)( PDRIVER_OBJECT, PDEVICE_OBJECT ) =
- driver_extension.AddDevice;
- PDEVICE_OBJECT pdev_obj = NULL;
- UCHAR pdo_info[2 * PATH_MAX + 3 + MAX_DEVICE_ID_LEN];
- data_size_t reply_size = 0;
- HANDLE events[2] = {loop_event, NULL};
- DWORD wait_ret;
-
- while (!reply_size)
- {
- SERVER_START_REQ( get_add_device_request )
- {
- req->event = events[1];
- wine_server_add_data( req, drvname.Buffer, drvname.Length );
- wine_server_set_reply( req, pdo_info, sizeof(pdo_info) );
- ret = wine_server_call( req );
- events[1] = reply->event;
- if (STATUS_SUCCESS == ret)
- reply_size = wine_server_reply_size( reply );
- }
- SERVER_END_REQ;
-
- if (STATUS_PENDING == ret)
- {
- wait_ret = WaitForMultipleObjects( 2, events, FALSE, INFINITE );
- if (wait_ret == WAIT_OBJECT_0)
- goto stop;
- }
- }
-
- pdev_obj = __wine_usbhub_get_pdo( pdo_info );
- if (pdev_obj)
- {
- WINE_TRACE( "calling AddDevice( %p, %p )\n", &driver_obj, pdev_obj );
- ret = AddDevice( &driver_obj, pdev_obj );
- if (STATUS_SUCCESS != ret)
- WINE_ERR( "AddDevice failed: %x\n", ret );
- }
- else
- {
- ret = STATUS_UNSUCCESSFUL;
- WINE_ERR( "wineusbhub error\n" );
- }
- }
-
- if (driver_obj.MajorFunction[IRP_MJ_PNP])
+ if (__wine_add_driver_object( &driver_obj, drv_name ))
{
- irp = IoAllocateIrp( driver_obj.DeviceObject->StackSize, FALSE );
- if (irp != NULL)
- {
- --irp->CurrentLocation;
- irpsp = --irp->Tail.Overlay.s.u.CurrentStackLocation;
-
- irp->RequestorMode = KernelMode;
- irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
-
- irpsp->MajorFunction = IRP_MJ_PNP;
- irpsp->MinorFunction = IRP_MN_START_DEVICE;
- irpsp->DeviceObject = driver_obj.DeviceObject;
-
- driver_obj.DeviceObject->CurrentIrp = irp;
-
- dispatch = driver_obj.MajorFunction[IRP_MJ_PNP];
- ret = dispatch( driver_obj.DeviceObject, irp );
- if (STATUS_SUCCESS != ret)
- WINE_ERR( "MajorFunction[IRP_MJ_PNP] failed: %x\n", ret );
-
- IoFreeIrp( irp );
- }
- else
- ret = STATUS_UNSUCCESSFUL;
+ wine_ntoskrnl_main_loop( loop_event );
+ __wine_del_driver_object( &driver_obj );
}
-
- wine_ntoskrnl_main_loop( loop_event );
- /* Stop service if wine_ntoskrnl_main_loop exits */
+ /* stop service if wine_ntoskrnl_main_loop exits */
SetEvent( loop_event );
-stop:
CloseHandle( loop_event );
unload_driver( module, &driver_obj );
HeapFree( GetProcessHeap(), 0, drv_name );
diff --git a/programs/wineusb/Makefile.in b/programs/wineusb/Makefile.in
deleted file mode 100644
index d2d0fdf..0000000
--- a/programs/wineusb/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-TOPSRCDIR = @top_srcdir@
-TOPOBJDIR = ../..
-SRCDIR = @srcdir@
-VPATH = @srcdir@
-MODULE = wineusb.exe
-APPMODE = -mwindows -municode
-IMPORTS = advapi32 ntoskrnl.exe kernel32 ntdll setupapi
-EXTRALIBS = @USBLIBS@
-
-C_SRCS = \
- main.c
-
- на MAKE_PROG_RULES@
-
- на DEPENDENCIES@ # everything below this line is overwritten by make depend
diff --git a/programs/wineusb/main.c b/programs/wineusb/main.c
deleted file mode 100644
index 18eae1d..0000000
--- a/programs/wineusb/main.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Service process to call USB driver`s AddDevice routine
- *
- * Based on winedevice
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdarg.h>
-
-#ifdef HAVE_USB_H
-#include <usb.h>
-#endif
-
-#include "ntstatus.h"
-#define WIN32_NO_STATUS
-#include "windef.h"
-#include "winbase.h"
-#include "winternl.h"
-#include "winreg.h"
-#include "winnls.h"
-#include "winsvc.h"
-#include "winuser.h"
-#include "setupapi.h"
-#include "cfgmgr32.h"
-#include "ddk/wdm.h"
-#include "ddk/usb.h"
-#include "wine/unicode.h"
-#include "wine/server.h"
-#include "wine/debug.h"
-#include "wine/list.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(wineusb);
-
-static WCHAR service_nameW[] = {'w','i','n','e','u','s','b',0};
-static SERVICE_STATUS_HANDLE service_handle;
-
-/* List of devices for which AddDevice was called */
-static struct list Devices = LIST_INIT(Devices);
-
-struct DeviceInstance
-{
- struct list entry;
- struct usb_device *dev;
-};
-
-static BOOL start_service( PWSTR name )
-{
- SC_HANDLE scm, service;
- BOOL ret;
-
- scm = OpenSCManagerA( NULL, NULL, SC_MANAGER_ALL_ACCESS );
- if (scm == NULL)
- return FALSE;
-
- service = OpenServiceW( scm, name, SERVICE_ALL_ACCESS );
- if (service == NULL)
- {
- CloseServiceHandle( scm );
- return FALSE;
- }
-
- ret = StartServiceW( service, 0, NULL );
- if (!ret && ERROR_SERVICE_ALREADY_RUNNING == GetLastError())
- ret = TRUE;
-
- CloseServiceHandle( service );
- CloseServiceHandle( scm );
-
- return ret;
-}
-
-static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
-{
- SERVICE_STATUS status;
-
- status.dwServiceType = SERVICE_WIN32;
- status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
- status.dwWin32ExitCode = 0;
- status.dwServiceSpecificExitCode = 0;
- status.dwCheckPoint = 0;
- status.dwWaitHint = 0;
-
- switch(ctrl)
- {
- case SERVICE_CONTROL_STOP:
- case SERVICE_CONTROL_SHUTDOWN:
- WINE_TRACE( "shutting down\n" );
- status.dwCurrentState = SERVICE_STOP_PENDING;
- status.dwControlsAccepted = 0;
- SetServiceStatus( service_handle, &status );
- return NO_ERROR;
- default:
- status.dwCurrentState = SERVICE_RUNNING;
- SetServiceStatus( service_handle, &status );
- return NO_ERROR;
- }
-}
-
-static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
-{
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
- HDEVINFO set;
- static const WCHAR usb[] = {'U','S','B',0};
-#endif
- SERVICE_STATUS status;
-
- WINE_TRACE( "starting service\n" );
-
- service_handle = RegisterServiceCtrlHandlerExW( service_nameW, service_handler, NULL );
- if (!service_handle)
- return;
-
- status.dwServiceType = SERVICE_WIN32;
- status.dwCurrentState = SERVICE_RUNNING;
- status.dwControlsAccepted = 0;
- status.dwWin32ExitCode = 0;
- status.dwServiceSpecificExitCode = 0;
- status.dwCheckPoint = 0;
- status.dwWaitHint = 10000;
- SetServiceStatus( service_handle, &status );
-
-#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H)
- set = SetupDiGetClassDevsW( NULL, usb, 0, DIGCF_ALLCLASSES );
- if (set != INVALID_HANDLE_VALUE)
- {
- struct DeviceInstance *instance, *instance2;
- UNICODE_STRING drvname;
- UCHAR pdo_info[2 * PATH_MAX + 3 + MAX_DEVICE_ID_LEN] = {0};
- char instance_id[MAX_DEVICE_ID_LEN];
- struct usb_device *dev;
- struct usb_bus *bus;
- SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
- DWORD size = 0, i = 0;
- USHORT vid, pid;
- char *str;
- BYTE *buf;
- BOOL ret;
-
- usb_init();
- usb_find_busses();
- usb_find_devices();
-
- while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
- {
- SetupDiGetDeviceRegistryPropertyA( set, &devInfo, SPDRP_HARDWAREID,
- NULL, NULL, 0, &size );
- buf = HeapAlloc( GetProcessHeap(), 0, size );
- if (buf == NULL)
- {
- WINE_ERR( "insufficient memory\n" );
- continue;
- }
- ret = SetupDiGetDeviceRegistryPropertyA( set, &devInfo, SPDRP_HARDWAREID,
- NULL, buf, size, NULL );
- if (!ret)
- {
- WINE_ERR( "SetupDiGetDeviceRegistryPropertyA failed\n" );
- HeapFree( GetProcessHeap(), 0, buf );
- continue;
- }
- str = strstr( (char *)buf, "Vid_" );
- if (str != NULL)
- {
- str += 4;
- vid = strtol( str, NULL, 16 );
- str = strstr( str, "Pid_" );
- }
- if (str == NULL)
- {
- WINE_ERR( "bad hardware ID\n" );
- HeapFree( GetProcessHeap(), 0, buf );
- continue;
- }
- str += 4;
- pid = strtol( str, NULL, 16 );
- HeapFree( GetProcessHeap(), 0, buf );
-
- SetupDiGetDeviceInstanceIdA( set, &devInfo, NULL, 0, &size );
- buf = HeapAlloc( GetProcessHeap(), 0, size );
- if (buf == NULL)
- {
- WINE_ERR( "insufficient memory\n" );
- continue;
- }
- ret = SetupDiGetDeviceInstanceIdA( set, &devInfo, (PSTR)buf, size, NULL );
- if (!ret)
- {
- WINE_ERR( "SetupDiGetDeviceInstanceIdA failed\n" );
- HeapFree( GetProcessHeap(), 0, buf );
- continue;
- }
- str = strrchr( (char *)buf, '\\' );
- if (str != NULL)
- ++str;
- if (str == NULL || *str == 0 || strlen( str ) >= MAX_DEVICE_ID_LEN)
- {
- WINE_ERR( "bad instance ID\n" );
- HeapFree( GetProcessHeap(), 0, buf );
- continue;
- }
- strcpy( instance_id, str );
- HeapFree( GetProcessHeap(), 0, buf );
-
- for (bus = usb_busses; bus && ret; bus = bus->next)
- for (dev = bus->devices; dev && ret; dev = dev->next)
- if (dev->descriptor.idVendor == vid &&
- dev->descriptor.idProduct == pid)
- {
- int found = 0;
-
- LIST_FOR_EACH_ENTRY( instance, &Devices,
- struct DeviceInstance, entry )
- {
- if (instance->dev == dev)
- {
- found = 1;
- break;
- }
- }
- if (found)
- continue;
-
- instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
- if (instance == NULL)
- {
- WINE_ERR( "insufficient memory\n" );
- ret = FALSE;
- break;
- }
-
- SetupDiGetDeviceRegistryPropertyW( set, &devInfo,
- SPDRP_SERVICE, NULL, NULL, 0, &size );
- buf = HeapAlloc( GetProcessHeap(), 0, size );
- if (buf == NULL)
- {
- WINE_ERR( "insufficient memory\n" );
- ret = FALSE;
- break;
- }
- ret = SetupDiGetDeviceRegistryPropertyW( set, &devInfo,
- SPDRP_SERVICE, NULL, buf, size, NULL );
- if (!ret)
- {
- WINE_ERR( "SetupDiGetDeviceRegistryPropertyW failed\n" );
- HeapFree( GetProcessHeap(), 0, buf );
- break;
- }
-
- if (!start_service( (PWSTR)buf ))
- {
- HeapFree( GetProcessHeap(), 0, buf );
- HeapFree( GetProcessHeap(), 0, instance );
- ret = FALSE;
- break;
- }
-
- RtlInitUnicodeString( &drvname, (PWSTR)buf );
- str = (char *)pdo_info + 1;
- strcpy( str, bus->dirname );
- str += 1 + PATH_MAX;
- strcpy( str, dev->filename );
- str += 1 + PATH_MAX;
- strcpy( str, instance_id );
-
- SERVER_START_REQ( call_add_device )
- {
- req->drvname_len = drvname.Length;
- wine_server_add_data( req, drvname.Buffer, drvname.Length );
- wine_server_add_data( req, pdo_info, sizeof(pdo_info) );
- wine_server_call( req );
- }
- SERVER_END_REQ;
-
- instance->dev = dev;
- list_add_tail( &Devices, &instance->entry );
-
- ++pdo_info[0];
- HeapFree( GetProcessHeap(), 0, buf );
- ret = FALSE;
- break;
- }
- }
- SetupDiDestroyDeviceInfoList( set );
-
- LIST_FOR_EACH_ENTRY_SAFE( instance, instance2, &Devices,
- struct DeviceInstance, entry )
- {
- list_remove( &instance->entry );
- HeapFree( GetProcessHeap(), 0, instance );
- }
- }
- else
- WINE_ERR( "SetupDiGetClassDevsW failed\n" );
-#endif
-
- status.dwCurrentState = SERVICE_STOPPED;
- status.dwControlsAccepted = 0;
- SetServiceStatus( service_handle, &status );
- WINE_TRACE( "service stopped\n" );
-}
-
-int wmain( int argc, WCHAR *argv[] )
-{
- SERVICE_TABLE_ENTRYW service_table[2];
-
- service_table[0].lpServiceName = service_nameW;
- service_table[0].lpServiceProc = ServiceMain;
- service_table[1].lpServiceName = NULL;
- service_table[1].lpServiceProc = NULL;
-
- StartServiceCtrlDispatcherW( service_table );
- return 0;
-}
diff --git a/tools/wine.inf.in b/tools/wine.inf.in
index 2857403..f08ecf8 100644
--- a/tools/wine.inf.in
+++ b/tools/wine.inf.in
@@ -80,12 +80,12 @@ AddReg=\
[DefaultInstall.Services]
AddService=MountMgr,0x800,MountMgrService
AddService=Spooler,0,SpoolerService
-AddService=Wineusb,0,WineusbService
+AddService=Usbhub,0,UsbhubService
[DefaultInstall.NT.Services]
AddService=MountMgr,0x800,MountMgrService
AddService=Spooler,0,SpoolerService
-AddService=Wineusb,0,WineusbService
+AddService=Usbhub,0,UsbhubService
[Strings]
MciExtStr="Software\Microsoft\Windows NT\CurrentVersion\MCI Extensions"
@@ -2324,6 +2324,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G"
11,,ws2_32.dll
11,,wsock32.dll
12,,mountmgr.sys
+12,,usbhub.sys
16422,Internet Explorer,iexplore.exe
[SystemIni]
@@ -2719,11 +2720,9 @@ StartType=4
ErrorControl=1
LoadOrderGroup="SpoolerGroup"
-[WineusbService]
-Description="WineUSB"
-DisplayName="WineUSB"
-ServiceBinary="%11%\wineusb.exe"
-ServiceType=0x10
+[UsbhubService]
+ServiceBinary="%12%\usbhub.sys"
+ServiceType=1
StartType=2
ErrorControl=1
--
1.6.0.2.GIT
Подробная информация о списке рассылки Wine-patches