[Wine-patches] [eterhack] eterbug #4301
Alexander Morozov
amorozov на etersoft.ru
Чт Мар 3 22:09:57 MSK 2011
----------- следующая часть -----------
From ea6f2340eeccbf178ce0195b90207200f638b6c3 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 3 Mar 2011 21:22:27 +0300
Subject: [eterhack 01/20] Move parport and usbhub drivers to mountmgr.sys (eterbug #4301).
---
configure | 2 -
configure.ac | 2 -
dlls/hal/hal.c | 10 +-
dlls/mountmgr.sys/Makefile.in | 7 +-
dlls/mountmgr.sys/device.c | 2 -
dlls/mountmgr.sys/mountmgr.c | 8 +
dlls/mountmgr.sys/mountmgr.h | 4 +
dlls/mountmgr.sys/mountmgr.sys.spec | 9 +-
dlls/mountmgr.sys/parport.c | 361 ++++++++
dlls/mountmgr.sys/usbhub.c | 1726 ++++++++++++++++++++++++++++++++++
dlls/ntoskrnl.exe/instr.c | 10 +-
dlls/parport.sys/Makefile.in | 10 -
dlls/parport.sys/parport.c | 393 --------
dlls/parport.sys/parport.sys.spec | 8 -
dlls/usbhub.sys/Makefile.in | 10 -
dlls/usbhub.sys/usbhub.c | 1733 -----------------------------------
dlls/usbhub.sys/usbhub.sys.spec | 1 -
programs/services/services.c | 4 +-
tools/wine.inf.in | 18 -
19 files changed, 2124 insertions(+), 2194 deletions(-)
create mode 100644 dlls/mountmgr.sys/parport.c
create mode 100644 dlls/mountmgr.sys/usbhub.c
delete mode 100644 dlls/parport.sys/Makefile.in
delete mode 100644 dlls/parport.sys/parport.c
delete mode 100644 dlls/parport.sys/parport.sys.spec
delete mode 100644 dlls/usbhub.sys/Makefile.in
delete mode 100644 dlls/usbhub.sys/usbhub.c
delete mode 100644 dlls/usbhub.sys/usbhub.sys.spec
diff --git a/configure b/configure
index 47d7c04..80c5c7d 100755
--- a/configure
+++ b/configure
@@ -15539,7 +15539,6 @@ wine_fn_config_dll openal32 enable_openal32
wine_fn_config_dll opencl enable_opencl
wine_fn_config_dll opengl32 enable_opengl32 implib
wine_fn_config_test dlls/opengl32/tests opengl32_test
-wine_fn_config_dll parport.sys enable_parport_sys implib
wine_fn_config_dll pdh enable_pdh implib
wine_fn_config_test dlls/pdh/tests pdh_test
wine_fn_config_dll pidgen enable_pidgen
@@ -15633,7 +15632,6 @@ wine_fn_config_dll url enable_url implib
wine_fn_config_dll urlmon enable_urlmon implib
wine_fn_config_test dlls/urlmon/tests urlmon_test
wine_fn_config_dll usbd.sys enable_usbd_sys implib
-wine_fn_config_dll usbhub.sys enable_usbhub_sys
wine_fn_config_dll user.exe16 enable_win16
wine_fn_config_dll user32 enable_user32 po,implib
wine_fn_config_test dlls/user32/tests user32_test
diff --git a/configure.ac b/configure.ac
index 1a80dc9..32eb80e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2734,7 +2734,6 @@ WINE_CONFIG_DLL(openal32)
WINE_CONFIG_DLL(opencl)
WINE_CONFIG_DLL(opengl32,,[implib])
WINE_CONFIG_TEST(dlls/opengl32/tests)
-WINE_CONFIG_DLL(parport.sys,,[implib])
WINE_CONFIG_DLL(pdh,,[implib])
WINE_CONFIG_TEST(dlls/pdh/tests)
WINE_CONFIG_DLL(pidgen)
@@ -2828,7 +2827,6 @@ WINE_CONFIG_DLL(url,,[implib])
WINE_CONFIG_DLL(urlmon,,[implib])
WINE_CONFIG_TEST(dlls/urlmon/tests)
WINE_CONFIG_DLL(usbd.sys,,[implib])
-WINE_CONFIG_DLL(usbhub.sys)
WINE_CONFIG_DLL(user.exe16,enable_win16)
WINE_CONFIG_DLL(user32,,[po,implib])
WINE_CONFIG_TEST(dlls/user32/tests)
diff --git a/dlls/hal/hal.c b/dlls/hal/hal.c
index d1f3764..7d1a23a 100644
--- a/dlls/hal/hal.c
+++ b/dlls/hal/hal.c
@@ -194,14 +194,14 @@ void WINAPI KeStallExecutionProcessor(ULONG MicroSeconds)
static void init_parport(void)
{
- static const WCHAR parportW[] = {'p','a','r','p','o','r','t','.','s','y','s',0};
+ static const WCHAR mountmgrW[] = {'m','o','u','n','t','m','g','r','.','s','y','s',0};
- HMODULE parport = GetModuleHandleW( parportW );
+ HMODULE mountmgr = GetModuleHandleW( mountmgrW );
- if (parport)
+ if (mountmgr)
{
- pp_read = (void *)GetProcAddress( parport, "__wine_read_parport" );
- pp_write = (void *)GetProcAddress( parport, "__wine_write_parport" );
+ pp_read = (void *)GetProcAddress( mountmgr, "__wine_read_parport" );
+ pp_write = (void *)GetProcAddress( mountmgr, "__wine_write_parport" );
}
if (!pp_read || !pp_write)
ERR( "failed to load parport functions\n" );
diff --git a/dlls/mountmgr.sys/Makefile.in b/dlls/mountmgr.sys/Makefile.in
index c4605e4..14b033f 100644
--- a/dlls/mountmgr.sys/Makefile.in
+++ b/dlls/mountmgr.sys/Makefile.in
@@ -3,12 +3,15 @@ IMPORTS = uuid advapi32 ntoskrnl.exe setupapi
DELAYIMPORTS = user32
EXTRADLLFLAGS = -Wb,--subsystem,native
EXTRADEFS = @HALINCL@
-EXTRALIBS = @DISKARBITRATIONLIB@
+EXTRAINCL = @USBINCL@
+EXTRALIBS = @DISKARBITRATIONLIB@ @USBLIBS@ @IEEE1284LIBS@
C_SRCS = \
device.c \
diskarb.c \
hal.c \
- mountmgr.c
+ mountmgr.c \
+ parport.c \
+ usbhub.c
@MAKE_DLL_RULES@
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index ed8e8c6..8142c93 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -29,8 +29,6 @@
#include <sys/types.h>
#include <dirent.h>
-#define INITGUID
-
#include "mountmgr.h"
#include "winreg.h"
#include "winuser.h"
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index c6dca13..191d969 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -445,6 +445,8 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
static const WCHAR device_mountmgrW[] = {'\\','D','e','v','i','c','e','\\','M','o','u','n','t','P','o','i','n','t','M','a','n','a','g','e','r',0};
static const WCHAR link_mountmgrW[] = {'\\','?','?','\\','M','o','u','n','t','P','o','i','n','t','M','a','n','a','g','e','r',0};
static const WCHAR harddiskW[] = {'\\','D','r','i','v','e','r','\\','H','a','r','d','d','i','s','k',0};
+ static const WCHAR parportW[] = {'\\','D','r','i','v','e','r','\\','P','a','r','p','o','r','t',0};
+ static const WCHAR usbhubW[] = {'\\','D','r','i','v','e','r','\\','u','s','b','h','u','b',0};
static const WCHAR devicemapW[] = {'H','A','R','D','W','A','R','E','\\','D','E','V','I','C','E','M','A','P',0};
static const WCHAR parallelW[] = {'P','A','R','A','L','L','E','L',' ','P','O','R','T','S',0};
static const WCHAR serialW[] = {'S','E','R','I','A','L','C','O','M','M',0};
@@ -486,6 +488,12 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
RtlInitUnicodeString( &nameW, harddiskW );
status = IoCreateDriver( &nameW, harddisk_driver_entry );
+ RtlInitUnicodeString( &nameW, parportW );
+ status = IoCreateDriver( &nameW, parport_driver_entry );
+
+ RtlInitUnicodeString( &nameW, usbhubW );
+ status = IoCreateDriver( &nameW, usbhub_driver_entry );
+
if (automount_enabled())
{
initialize_hal();
diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h
index 6d29c2f..ba62543 100644
--- a/dlls/mountmgr.sys/mountmgr.h
+++ b/dlls/mountmgr.sys/mountmgr.h
@@ -32,12 +32,16 @@
#define WINE_MOUNTMGR_EXTENSIONS
#include "ntddstor.h"
#include "ntddcdrm.h"
+#include "ntddpar.h"
#include "ddk/wdm.h"
#include "ddk/mountmgr.h"
extern void initialize_hal(void);
extern void initialize_diskarbitration(void);
+extern NTSTATUS WINAPI usbhub_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path );
+extern NTSTATUS WINAPI parport_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path );
+
/* device functions */
enum device_type
diff --git a/dlls/mountmgr.sys/mountmgr.sys.spec b/dlls/mountmgr.sys/mountmgr.sys.spec
index 76421d7..4848c4a 100644
--- a/dlls/mountmgr.sys/mountmgr.sys.spec
+++ b/dlls/mountmgr.sys/mountmgr.sys.spec
@@ -1 +1,8 @@
-# nothing to export
+################################################################
+# Wine internal extensions
+#
+# All functions must be prefixed with '__wine_' (for internal functions)
+# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
+
+@ cdecl __wine_read_parport(ptr)
+@ cdecl __wine_write_parport(ptr long)
diff --git a/dlls/mountmgr.sys/parport.c b/dlls/mountmgr.sys/parport.c
new file mode 100644
index 0000000..4f460d0
--- /dev/null
+++ b/dlls/mountmgr.sys/parport.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2009 - 2011 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"
+
+#ifdef HAVE_LIBIEEE1284
+#include <ieee1284.h>
+#endif
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "mountmgr.h"
+#include "winreg.h"
+#include "winuser.h"
+#include "setupapi.h"
+#include "ddk/parallel.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(parport);
+
+#ifdef HAVE_LIBIEEE1284
+static const WCHAR device_idW[] = {'A','C','P','I','\\',
+ 'P','N','P','0','4','0','0','\\','%','d',0};
+
+struct ParPortExtension
+{
+ struct parport *pp;
+ int claimed;
+ int n;
+ UNICODE_STRING interface;
+};
+
+static struct parport_list pp_list;
+
+static DRIVER_OBJECT *parport_driver;
+
+static BOOLEAN WINAPI parport_try( void *context )
+{
+ struct ParPortExtension *ppe = context;
+
+ if (ieee1284_open( ppe->pp, 0, NULL ) != E1284_OK)
+ return FALSE;
+ if (ieee1284_claim( ppe->pp ) != E1284_OK)
+ {
+ ieee1284_close( ppe->pp );
+ return FALSE;
+ }
+ ppe->claimed = 1;
+ return TRUE;
+}
+
+static void WINAPI parport_free( void *context )
+{
+ struct ParPortExtension *ppe = context;
+
+ if (ppe->claimed)
+ {
+ ieee1284_release( ppe->pp );
+ ieee1284_close( ppe->pp );
+ ppe->claimed = 0;
+ }
+}
+
+static ULONG WINAPI parport_query_waiters( void *context )
+{
+ FIXME( "stub: %p\n", context );
+ return 0;
+}
+
+static NTSTATUS WINAPI parport_ioctl( DEVICE_OBJECT *device, IRP *irp )
+{
+ IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ NTSTATUS status = STATUS_NOT_SUPPORTED;
+
+ TRACE( "%p, %p\n", device, irp );
+
+ switch(irpsp->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_INTERNAL_PARALLEL_PORT_ALLOCATE:
+ if (parport_try( device->DeviceExtension ))
+ status = STATUS_SUCCESS;
+ else
+ status = STATUS_UNSUCCESSFUL;
+ break;
+ case IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO:
+ {
+ PARALLEL_PORT_INFORMATION *ppi = irp->AssociatedIrp.SystemBuffer;
+ struct ParPortExtension *ppe = device->DeviceExtension;
+
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength
+ < sizeof(PARALLEL_PORT_INFORMATION))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ RtlZeroMemory( ppi, sizeof(*ppi) );
+ ppi->OriginalController.QuadPart = ppe->pp->base_addr;
+ ppi->Controller = (PUCHAR)ppe->pp->base_addr;
+ ppi->TryAllocatePort = parport_try;
+ ppi->FreePort = parport_free;
+ ppi->QueryNumWaiters = parport_query_waiters;
+ ppi->Context = ppe;
+ irp->IoStatus.Information = sizeof(PARALLEL_PORT_INFORMATION);
+ status = STATUS_SUCCESS;
+ break;
+ }
+ case IOCTL_INTERNAL_GET_MORE_PARALLEL_PORT_INFO:
+ TRACE( "IOCTL_INTERNAL_GET_MORE_PARALLEL_PORT_INFO: stub\n" );
+ irp->IoStatus.Information = 0;
+ status = STATUS_SUCCESS;
+ break;
+ case IOCTL_INTERNAL_PARALLEL_PORT_FREE:
+ parport_free( device->DeviceExtension );
+ status = STATUS_SUCCESS;
+ break;
+ default:
+ FIXME( "IOCTL %08x is not implemented\n",
+ irpsp->Parameters.DeviceIoControl.IoControlCode );
+ status = STATUS_NOT_IMPLEMENTED;
+ }
+ irp->IoStatus.u.Status = status;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+ return status;
+}
+
+static NTSTATUS WINAPI parport_pnp( DEVICE_OBJECT *device, IRP *irp )
+{
+ static const WCHAR fmtW[] = {'%','d',0};
+
+ IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ NTSTATUS status;
+
+ TRACE( "%p, %p\n", device, irp );
+
+ switch (irpsp->MinorFunction)
+ {
+ case IRP_MN_QUERY_ID:
+ switch (irpsp->Parameters.QueryId.IdType)
+ {
+ case BusQueryDeviceID:
+ {
+ WCHAR *device_id = ExAllocatePool( PagedPool, sizeof(device_idW) );
+
+ if (device_id == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+ strcpyW( device_id, device_idW );
+ *strrchrW( device_id, '\\' ) = 0;
+ status = STATUS_SUCCESS;
+ irp->IoStatus.Information = (ULONG_PTR)device_id;
+ break;
+ }
+ case BusQueryInstanceID:
+ {
+ ULONG len = 16;
+ struct ParPortExtension *ppe = device->DeviceExtension;
+ WCHAR *instance_id = ExAllocatePool( PagedPool, len * sizeof(WCHAR) );
+
+ if (instance_id == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+ snprintfW( instance_id, len, fmtW, ppe->n );
+ status = STATUS_SUCCESS;
+ irp->IoStatus.Information = (ULONG_PTR)instance_id;
+ break;
+ }
+ default:
+ FIXME( "IRP_MN_QUERY_ID: IdType %u is not implemented\n",
+ irpsp->Parameters.QueryId.IdType );
+ status = STATUS_NOT_IMPLEMENTED;
+ }
+ break;
+ default:
+ FIXME( "function %08x is not implemented\n", irpsp->MinorFunction );
+ status = STATUS_NOT_IMPLEMENTED;
+ }
+ irp->IoStatus.u.Status = status;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+ return STATUS_SUCCESS;
+}
+
+static void register_parport_device( DEVICE_OBJECT *parport_dev, int n )
+{
+ static const WCHAR acpiW[] = {'A','C','P','I',0};
+
+ struct ParPortExtension *ppe;
+ HDEVINFO set;
+ SP_DEVINFO_DATA devInfo;
+ WCHAR *devnameW;
+ ULONG size;
+ NTSTATUS status;
+
+ size = sizeof(device_idW) + 16 * sizeof(WCHAR);
+ devnameW = ExAllocatePool( PagedPool, size );
+ if (devnameW == NULL) return;
+ snprintfW( devnameW, size / sizeof(WCHAR), device_idW, n );
+
+ set = SetupDiGetClassDevsW( NULL, acpiW, 0, DIGCF_ALLCLASSES );
+ if (set == INVALID_HANDLE_VALUE) goto done;
+ devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
+ if (SetupDiCreateDeviceInfoW( set, devnameW, &GUID_SERENUM_BUS_ENUMERATOR,
+ NULL, NULL, 0, &devInfo ))
+ {
+ if (!SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL ))
+ goto done;
+ }
+ else
+ {
+ if (ERROR_DEVINST_ALREADY_EXISTS != GetLastError())
+ goto done;
+ }
+
+ ppe = parport_dev->DeviceExtension;
+ status = IoRegisterDeviceInterface( parport_dev, &GUID_DEVINTERFACE_PARALLEL,
+ NULL, &ppe->interface );
+ if (status == STATUS_SUCCESS)
+ IoSetDeviceInterfaceState( &ppe->interface, TRUE );
+done:
+ if (set != INVALID_HANDLE_VALUE)
+ SetupDiDestroyDeviceInfoList( set );
+ ExFreePool( devnameW );
+}
+
+static void create_parport_device( DRIVER_OBJECT *driver, int n, struct parport *pp )
+{
+ static const WCHAR parallel_portW[] = {'\\','D','e','v','i','c','e',
+ '\\','P','a','r','a','l','l','e','l',
+ 'P','o','r','t','%','d',0};
+
+ struct ParPortExtension *ppe;
+ UNICODE_STRING parallel_port;
+ DEVICE_OBJECT *parport_dev;
+ WCHAR device_name[MAX_PATH];
+ NTSTATUS status;
+
+ snprintfW( device_name, MAX_PATH, parallel_portW, n );
+ RtlInitUnicodeString( ¶llel_port, device_name );
+ status = IoCreateDevice( driver, sizeof(struct ParPortExtension), ¶llel_port,
+ FILE_DEVICE_PARALLEL_PORT, FILE_DEVICE_SECURE_OPEN, FALSE, &parport_dev );
+ if (status == STATUS_SUCCESS)
+ {
+ ppe = parport_dev->DeviceExtension;
+ RtlZeroMemory( ppe, sizeof(*ppe) );
+ ppe->pp = pp;
+ ppe->n = n;
+ register_parport_device( parport_dev, n );
+ parport_dev->Flags &= ~DO_DEVICE_INITIALIZING;
+ }
+}
+
+static void enum_par_devices( DRIVER_OBJECT *driver )
+{
+ struct parport *pp;
+ int k;
+
+ ieee1284_find_ports( &pp_list, 0 );
+ for (k = 0; k < pp_list.portc; ++k)
+ {
+ pp = pp_list.portv[k];
+ create_parport_device( driver, k, pp );
+ }
+}
+
+static struct ParPortExtension *get_parport_ext( UCHAR *port, ULONG *offset )
+{
+ DEVICE_OBJECT *device = parport_driver->DeviceObject;
+ struct ParPortExtension *ppe;
+
+ while (device)
+ {
+ ppe = device->DeviceExtension;
+ *offset = (ULONG)port - ppe->pp->base_addr;
+ if (*offset <= DCR_OFFSET) return ppe;
+ device = device->NextDevice;
+ }
+ return NULL;
+}
+
+static int read_parport( struct parport *pp, ULONG offset )
+{
+ if (DATA_OFFSET == offset) return ieee1284_read_data( pp );
+ if (DSR_OFFSET == offset) return ieee1284_read_status( pp ) ^ S1284_INVERTED;
+ if (DCR_OFFSET == offset) return ieee1284_read_control( pp ) ^ C1284_INVERTED;
+ return -1;
+}
+
+static void write_parport( struct parport *pp, UCHAR value, ULONG offset )
+{
+ if (DATA_OFFSET == offset) ieee1284_write_data( pp, value );
+ /* FIXME: see NOTE in ieee1284.h */
+ else if (DCR_OFFSET == offset) ieee1284_write_control( pp, value ^ C1284_INVERTED );
+}
+#endif /* HAVE_LIBIEEE1284 */
+
+UCHAR CDECL __wine_read_parport( UCHAR *port )
+{
+#ifdef HAVE_LIBIEEE1284
+ int ret = -1;
+ ULONG offset;
+ struct ParPortExtension *ppe = get_parport_ext( port, &offset );
+
+ if (!ppe) return 0xff;
+ if (ppe->claimed) ret = read_parport( ppe->pp, offset );
+ else if (parport_try( ppe ))
+ {
+ ret = read_parport( ppe->pp, offset );
+ parport_free( ppe );
+ }
+ if (ret >= 0) return ret;
+#endif
+ return 0xff;
+}
+
+void CDECL __wine_write_parport( UCHAR *port, UCHAR value )
+{
+#ifdef HAVE_LIBIEEE1284
+ ULONG offset;
+ struct ParPortExtension *ppe = get_parport_ext( port, &offset );
+
+ if (!ppe) return;
+ if (ppe->claimed) write_parport( ppe->pp, value, offset );
+ else if (parport_try( ppe ))
+ {
+ write_parport( ppe->pp, value, offset );
+ parport_free( ppe );
+ }
+#endif
+}
+
+NTSTATUS WINAPI parport_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
+{
+#ifdef HAVE_LIBIEEE1284
+ driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = parport_ioctl;
+ driver->MajorFunction[IRP_MJ_PNP] = parport_pnp;
+ parport_driver = driver;
+ enum_par_devices( driver );
+#endif
+ return STATUS_SUCCESS;
+}
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
new file mode 100644
index 0000000..2ec236e
--- /dev/null
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -0,0 +1,1726 @@
+/*
+ * Copyright 2008 - 2011 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 <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_LIBUSB_H
+#include <libusb.h>
+#elif defined(HAVE_USB_H)
+#include <usb.h>
+#endif
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#define INITGUID
+
+#include "mountmgr.h"
+#include "winreg.h"
+#include "winsvc.h"
+#include "winuser.h"
+#include "setupapi.h"
+#include "cfgmgr32.h"
+#include "devguid.h"
+#define WINE_USBHUB_EXTENSIONS
+#include "ddk/usbdrivr.h"
+#include "ddk/usbioctl.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+#include "wine/list.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(usbhub);
+
+extern NTSTATUS CDECL __wine_add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *dev );
+extern DRIVER_OBJECT * CDECL __wine_get_driver_object( const WCHAR *service );
+extern NTSTATUS CDECL __wine_start_device( DEVICE_OBJECT *device );
+
+#define NUMBER_OF_PORTS 8
+
+static const WCHAR usbW[] = {'U','S','B',0};
+
+static struct list Devices = LIST_INIT(Devices);
+
+struct DeviceInstance
+{
+ struct list entry;
+ USHORT vid;
+ USHORT pid;
+ char *instance_id;
+ WCHAR *service;
+#ifdef HAVE_LIBUSB_H
+ libusb_device *dev;
+#else
+ struct usb_device *dev;
+#endif
+};
+
+struct PdoExtension
+{
+ struct DeviceInstance *instance;
+};
+
+#ifdef HAVE_LIBUSB
+
+static void add_data( unsigned char **dst, ULONG *dst_size, const void *src, ULONG src_size )
+{
+ int copy;
+
+ copy = (src_size >= *dst_size) ? *dst_size : src_size;
+ memcpy( *dst, src, copy );
+ *dst += copy;
+ *dst_size -= copy;
+}
+
+static NTSTATUS WINAPI usbhub_ioctl( 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};
+
+ IO_STACK_LOCATION *irpsp;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ struct DeviceInstance *inst;
+ ULONG_PTR info = 0;
+
+ TRACE( "%p, %p\n", device, irp );
+
+ inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
+ if (inst->service) goto done;
+ irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+
+ switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_USB_GET_NODE_INFORMATION:
+ {
+ USB_NODE_INFORMATION *node_info = irp->AssociatedIrp.SystemBuffer;
+
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*node_info))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ RtlZeroMemory( node_info, sizeof(*node_info) );
+ node_info->u.HubInformation.HubDescriptor.bDescriptorLength = 9;
+ node_info->u.HubInformation.HubDescriptor.bDescriptorType = 41;
+ node_info->u.HubInformation.HubDescriptor.bNumberOfPorts = NUMBER_OF_PORTS;
+ status = STATUS_SUCCESS;
+ info = sizeof(*node_info);
+ break;
+ }
+ case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
+ {
+ USB_NODE_CONNECTION_INFORMATION *conn_info = irp->AssociatedIrp.SystemBuffer;
+ ULONG index = 0;
+#ifdef HAVE_LIBUSB_H
+ struct DeviceInstance *instance;
+ uint8_t bus_number = libusb_get_bus_number( inst->dev );
+#else
+ struct usb_device *dev;
+#endif
+
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*conn_info))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ if (!conn_info->ConnectionIndex || conn_info->ConnectionIndex > NUMBER_OF_PORTS)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ RtlZeroMemory( (ULONG *)conn_info + 1, sizeof(*conn_info) - sizeof(ULONG) );
+#ifdef HAVE_LIBUSB_H
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev && instance->dev != inst->dev &&
+ libusb_get_bus_number( instance->dev ) == bus_number &&
+ ++index == conn_info->ConnectionIndex)
+ {
+ struct libusb_device_descriptor desc;
+
+ if (libusb_get_device_descriptor( instance->dev, &desc ))
+ break;
+ memcpy( &conn_info->DeviceDescriptor, &desc,
+ sizeof(USB_DEVICE_DESCRIPTOR) );
+ conn_info->ConnectionStatus = 1;
+ break;
+ }
+ }
+#else
+ for (dev = inst->dev->next; dev; dev = dev->next)
+ if (++index == conn_info->ConnectionIndex)
+ {
+ memcpy( &conn_info->DeviceDescriptor, &dev->descriptor,
+ sizeof(USB_DEVICE_DESCRIPTOR) );
+ conn_info->ConnectionStatus = 1;
+ break;
+ }
+#endif
+ status = STATUS_SUCCESS;
+ info = sizeof(*conn_info);
+ break;
+ }
+ case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
+ {
+ USB_NODE_CONNECTION_DRIVERKEY_NAME *driver_key_name =
+ irp->AssociatedIrp.SystemBuffer;
+ WCHAR *dev_instance_idW, *bufW;
+ struct DeviceInstance *instance;
+ HDEVINFO set;
+ SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
+ ULONG len, index = 0, found = 0;
+#ifdef HAVE_LIBUSB_H
+ uint8_t bus_number = libusb_get_bus_number( inst->dev );
+#else
+ struct usb_device *dev;
+#endif
+
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
+ sizeof(*driver_key_name))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+#ifdef HAVE_LIBUSB_H
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev && instance->dev != inst->dev &&
+ libusb_get_bus_number( instance->dev ) == bus_number &&
+ ++index == driver_key_name->ConnectionIndex)
+ {
+ found = 1;
+ break;
+ }
+ }
+#else
+ for (dev = inst->dev->next; dev; dev = dev->next)
+ if (++index == driver_key_name->ConnectionIndex)
+ {
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev == dev)
+ {
+ found = 1;
+ break;
+ }
+ }
+ break;
+ }
+#endif
+ if (!found)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ bufW = HeapAlloc( GetProcessHeap(), 0,
+ 2 * MAX_DEVICE_ID_LEN * sizeof(WCHAR) );
+ if (bufW == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+ dev_instance_idW = bufW + MAX_DEVICE_ID_LEN;
+ snprintfW( dev_instance_idW, MAX_DEVICE_ID_LEN, device_idW,
+ instance->vid, instance->pid );
+ len = strlenW(dev_instance_idW);
+ RtlMultiByteToUnicodeN( dev_instance_idW + len,
+ (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
+ instance->instance_id, strlen(instance->instance_id) + 1 );
+ set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
+ if (set == INVALID_HANDLE_VALUE)
+ {
+ HeapFree( GetProcessHeap(), 0, bufW );
+ break;
+ }
+ index = 0;
+ while (SetupDiEnumDeviceInfo( set, index++, &devInfo ))
+ {
+ if (!SetupDiGetDeviceInstanceIdW( set, &devInfo, bufW,
+ MAX_DEVICE_ID_LEN, NULL ))
+ break;
+ if (!strcmpiW( dev_instance_idW, bufW ))
+ {
+ SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_DRIVER,
+ NULL, NULL, 0, &len );
+ driver_key_name->ActualLength = 2 * sizeof(ULONG) + len;
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
+ driver_key_name->ActualLength)
+ {
+ status = STATUS_SUCCESS;
+ info = sizeof(*driver_key_name);
+ }
+ else if (SetupDiGetDeviceRegistryPropertyW( set, &devInfo,
+ SPDRP_DRIVER, NULL, (BYTE *)driver_key_name->DriverKeyName,
+ len, NULL ))
+ {
+ status = STATUS_SUCCESS;
+ info = driver_key_name->ActualLength;
+ }
+ break;
+ }
+ }
+ SetupDiDestroyDeviceInfoList( set );
+ HeapFree( GetProcessHeap(), 0, bufW );
+ break;
+ }
+ case IOCTL_USB_GET_DEVICE_INFO:
+ {
+ struct usb_device_info *dev_info = irp->AssociatedIrp.SystemBuffer;
+ struct DeviceInstance *instance;
+ ULONG len, index = 0;
+#ifdef HAVE_LIBUSB_H
+ uint8_t bus_number = libusb_get_bus_number( inst->dev );
+#else
+ struct usb_device *dev;
+#endif
+
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*dev_info))
+ {
+ status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+ if (!dev_info->connection_index || dev_info->connection_index > NUMBER_OF_PORTS)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ RtlZeroMemory( (ULONG *)dev_info + 1, sizeof(*dev_info) - sizeof(ULONG) );
+ memcpy( dev_info->root_hub_id, root_hub_idW, sizeof(root_hub_idW) );
+ len = strlenW(root_hub_idW);
+ RtlMultiByteToUnicodeN( dev_info->root_hub_id + len,
+ (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
+ inst->instance_id, strlen(inst->instance_id) + 1 );
+#ifdef HAVE_LIBUSB_H
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev && instance->dev != inst->dev &&
+ libusb_get_bus_number( instance->dev ) == bus_number &&
+ ++index == dev_info->connection_index)
+ {
+ dev_info->device_address = libusb_get_device_address( instance->dev );
+ break;
+ }
+ }
+#else
+ for (dev = inst->dev->next; dev; dev = dev->next)
+ if (++index == dev_info->connection_index)
+ {
+ dev_info->device_address = dev->devnum;
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev == dev) break;
+ }
+ break;
+ }
+#endif
+ if (dev_info->device_address)
+ {
+ snprintfW( dev_info->device_id, MAX_DEVICE_ID_LEN, device_idW,
+ instance->vid, instance->pid );
+ len = strlenW(dev_info->device_id);
+ RtlMultiByteToUnicodeN( dev_info->device_id + len,
+ (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
+ instance->instance_id, strlen(instance->instance_id) + 1 );
+ }
+ status = STATUS_SUCCESS;
+ info = sizeof(*dev_info);
+ break;
+ }
+ default:
+ FIXME( "IOCTL %08x is not implemented\n",
+ irpsp->Parameters.DeviceIoControl.IoControlCode );
+ }
+
+done:
+ irp->IoStatus.u.Status = status;
+ irp->IoStatus.Information = info;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+
+ return status;
+}
+
+#ifdef HAVE_LIBUSB_H
+
+static NTSTATUS WINAPI 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;
+ if (!inst->service) goto done;
+ irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ urb = irpsp->Parameters.Others.Argument1;
+
+ switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_INTERNAL_USB_SUBMIT_URB:
+ switch (urb->u.UrbHeader.Function)
+ {
+ case URB_FUNCTION_SELECT_CONFIGURATION:
+ {
+ 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 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 );
+ }
+ }
+ break;
+ case URB_FUNCTION_SELECT_INTERFACE:
+ {
+ struct _URB_SELECT_INTERFACE *request =
+ &urb->u.UrbSelectInterface;
+ libusb_device_handle *husb;
+
+ TRACE( "URB_FUNCTION_SELECT_INTERFACE\n" );
+
+ if (!libusb_open( inst->dev, &husb ))
+ {
+ int ret;
+
+ ret = libusb_claim_interface( husb,
+ request->Interface.InterfaceNumber );
+ if (!ret)
+ {
+ ret = libusb_set_interface_alt_setting( husb,
+ request->Interface.InterfaceNumber,
+ request->Interface.AlternateSetting );
+ if (!libusb_release_interface( husb,
+ request->Interface.InterfaceNumber ) && !ret)
+ status = STATUS_SUCCESS;
+ }
+ libusb_close( husb );
+ }
+ }
+ break;
+ case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
+ {
+ struct _URB_BULK_OR_INTERRUPT_TRANSFER *request =
+ &urb->u.UrbBulkOrInterruptTransfer;
+ unsigned char *buf = request->TransferBuffer;
+ libusb_device_handle *husb;
+
+ TRACE( "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n" );
+
+ if (buf == NULL && request->TransferBufferMDL != NULL)
+ buf = request->TransferBufferMDL->MappedSystemVa;
+ if (!libusb_open( inst->dev, &husb ))
+ {
+ int ret, transferred;
+
+ ret = libusb_claim_interface( husb,
+ ((int)request->PipeHandle >> 8) - 1 );
+ if (!ret)
+ {
+ /* FIXME: add support for an interrupt transfer */
+ ret = libusb_bulk_transfer( husb,
+ (unsigned int)request->PipeHandle,
+ buf, request->TransferBufferLength,
+ &transferred, 0 );
+ if (!libusb_release_interface( husb,
+ ((int)request->PipeHandle >> 8) - 1 ) && !ret)
+ {
+ request->TransferBufferLength = transferred;
+ status = STATUS_SUCCESS;
+ }
+ }
+ libusb_close( husb );
+ }
+ }
+ break;
+ case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+ {
+ struct _URB_CONTROL_DESCRIPTOR_REQUEST *request =
+ &urb->u.UrbControlDescriptorRequest;
+ ULONG size = request->TransferBufferLength;
+ unsigned char *buf = request->TransferBuffer;
+
+ TRACE( "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n" );
+
+ if (!size)
+ {
+ status = STATUS_SUCCESS;
+ break;
+ }
+ if (buf == NULL && request->TransferBufferMDL != NULL)
+ buf = request->TransferBufferMDL->MappedSystemVa;
+ if (buf == NULL)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ switch (request->DescriptorType)
+ {
+ case USB_DEVICE_DESCRIPTOR_TYPE:
+ TRACE( "USB_DEVICE_DESCRIPTOR_TYPE\n" );
+ {
+ struct libusb_device_descriptor desc;
+
+ if (libusb_get_device_descriptor( inst->dev, &desc ))
+ break;
+ memcpy( buf, &desc, (size < sizeof(USB_DEVICE_DESCRIPTOR)) ?
+ size : sizeof(USB_DEVICE_DESCRIPTOR) );
+ status = STATUS_SUCCESS;
+ }
+ break;
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ TRACE( "USB_CONFIGURATION_DESCRIPTOR_TYPE\n" );
+ {
+ unsigned int i, k;
+ struct libusb_config_descriptor *conf;
+ const struct libusb_interface_descriptor *intf;
+ const struct libusb_endpoint_descriptor *endp;
+
+ /* FIXME: case of num_altsetting > 1 */
+
+ if (libusb_get_active_config_descriptor( inst->dev, &conf ))
+ break;
+ add_data( &buf, &size, conf,
+ sizeof(USB_CONFIGURATION_DESCRIPTOR) );
+ if (size > 0 && conf->extra)
+ add_data( &buf, &size, conf->extra, conf->extra_length );
+ 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->extra_length );
+ 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->extra_length );
+ }
+ }
+ libusb_free_config_descriptor( conf );
+ status = STATUS_SUCCESS;
+ }
+ break;
+ case USB_STRING_DESCRIPTOR_TYPE:
+ TRACE( "USB_STRING_DESCRIPTOR_TYPE\n" );
+ {
+ libusb_device_handle *husb;
+ int ret;
+
+ if (!libusb_open( inst->dev, &husb ))
+ {
+ ret = libusb_get_string_descriptor( husb, request->Index,
+ request->LanguageId, buf, size );
+ libusb_close( husb );
+ if (ret < 0) break;
+ status = STATUS_SUCCESS;
+ }
+ }
+ }
+ }
+ break;
+ case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
+ {
+ struct _URB_CONTROL_GET_STATUS_REQUEST *request =
+ &urb->u.UrbControlGetStatusRequest;
+ void *buf = request->TransferBuffer;
+ libusb_device_handle *husb;
+ int ret;
+
+ TRACE( "URB_FUNCTION_GET_STATUS_FROM_DEVICE\n" );
+
+ if (buf == NULL && request->TransferBufferMDL != NULL)
+ buf = request->TransferBufferMDL->MappedSystemVa;
+ if (buf == NULL || request->TransferBufferLength < sizeof(USHORT))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ if (!libusb_open( inst->dev, &husb ))
+ {
+ ret = libusb_control_transfer( husb, 1 << 7,
+ LIBUSB_REQUEST_GET_STATUS, 0, request->Index, buf,
+ sizeof(USHORT), 0 );
+ libusb_close( husb );
+ if (ret < 0) break;
+ status = STATUS_SUCCESS;
+ }
+ }
+ break;
+ case URB_FUNCTION_VENDOR_DEVICE:
+ case URB_FUNCTION_VENDOR_INTERFACE:
+ case URB_FUNCTION_VENDOR_ENDPOINT:
+ case URB_FUNCTION_CLASS_DEVICE:
+ case URB_FUNCTION_CLASS_INTERFACE:
+ case URB_FUNCTION_CLASS_ENDPOINT:
+ {
+ libusb_device_handle *husb;
+ struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
+ &urb->u.UrbControlVendorClassRequest;
+ unsigned char *req_buf = request->TransferBuffer;
+ ULONG size = request->TransferBufferLength;
+
+ TRACE( "URB_FUNCTION_{VENDOR,CLASS}_*\n" );
+
+ if (req_buf == NULL && request->TransferBufferMDL != NULL)
+ req_buf = request->TransferBufferMDL->MappedSystemVa;
+ if (size && req_buf == NULL)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ if (!libusb_open( inst->dev, &husb ))
+ {
+ UCHAR req_type = request->RequestTypeReservedBits;
+ unsigned char *buf;
+ int ret;
+
+ switch (urb->u.UrbHeader.Function)
+ {
+ case URB_FUNCTION_VENDOR_DEVICE: req_type |= 0x40; break;
+ case URB_FUNCTION_VENDOR_INTERFACE: req_type |= 0x41; break;
+ case URB_FUNCTION_VENDOR_ENDPOINT: req_type |= 0x42; break;
+ case URB_FUNCTION_CLASS_DEVICE: req_type |= 0x20; break;
+ case URB_FUNCTION_CLASS_INTERFACE: req_type |= 0x21; break;
+ case URB_FUNCTION_CLASS_ENDPOINT: req_type |= 0x22; break;
+ }
+ buf = HeapAlloc( GetProcessHeap(), 0, size );
+ if (buf != NULL)
+ {
+ memcpy( buf, req_buf, size );
+ if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ req_type |= (1 << 7);
+ ret = libusb_control_transfer( husb, req_type,
+ request->Request, request->Value, request->Index,
+ buf, size, 0 );
+ if (ret < 0)
+ ERR( "libusb_control_transfer: %d\n", ret );
+ else
+ {
+ if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ {
+ request->TransferBufferLength =
+ (ret < size) ? ret : size;
+ memcpy( req_buf, buf, request->TransferBufferLength );
+ }
+ status = STATUS_SUCCESS;
+ }
+ HeapFree( GetProcessHeap(), 0, buf );
+ }
+ libusb_close( husb );
+ }
+ }
+ break;
+ default:
+ FIXME( "unsupported URB function %x\n", urb->u.UrbHeader.Function );
+ }
+ urb->u.UrbHeader.Status = status;
+ break;
+ default:
+ FIXME( "IOCTL %08x is not implemented\n",
+ irpsp->Parameters.DeviceIoControl.IoControlCode );
+ }
+
+done:
+ irp->IoStatus.u.Status = status;
+ irp->IoStatus.Information = 0;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+
+ return status;
+}
+
+#else
+
+static NTSTATUS WINAPI 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;
+ if (!inst->service) goto done;
+ irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ urb = irpsp->Parameters.Others.Argument1;
+
+ switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_INTERNAL_USB_SUBMIT_URB:
+ switch (urb->u.UrbHeader.Function)
+ {
+ case URB_FUNCTION_SELECT_CONFIGURATION:
+ {
+ struct _URB_SELECT_CONFIGURATION *request =
+ &urb->u.UrbSelectConfiguration;
+ usb_dev_handle *husb;
+
+ TRACE( "URB_FUNCTION_SELECT_CONFIGURATION\n" );
+
+ 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 );
+ }
+ }
+ break;
+ case URB_FUNCTION_SELECT_INTERFACE:
+ {
+ struct _URB_SELECT_INTERFACE *request =
+ &urb->u.UrbSelectInterface;
+ usb_dev_handle *husb;
+
+ TRACE( "URB_FUNCTION_SELECT_INTERFACE\n" );
+
+ husb = usb_open( inst->dev );
+ if (husb)
+ {
+ int ret;
+
+ ret = usb_claim_interface( husb,
+ request->Interface.InterfaceNumber );
+ if (!ret)
+ {
+ ret = usb_set_altinterface( husb,
+ request->Interface.AlternateSetting );
+ if (!usb_release_interface( husb,
+ request->Interface.InterfaceNumber ) && !ret)
+ status = STATUS_SUCCESS;
+ }
+ usb_close( husb );
+ }
+ }
+ break;
+ case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
+ {
+ struct _URB_BULK_OR_INTERRUPT_TRANSFER *request =
+ &urb->u.UrbBulkOrInterruptTransfer;
+ char *buf = request->TransferBuffer;
+ usb_dev_handle *husb;
+
+ TRACE( "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n" );
+
+ if (buf == NULL && request->TransferBufferMDL != NULL)
+ buf = request->TransferBufferMDL->MappedSystemVa;
+ husb = usb_open( inst->dev );
+ if (husb)
+ {
+ int ret;
+
+ ret = usb_claim_interface( husb,
+ ((int)request->PipeHandle >> 8) - 1 );
+ if (!ret)
+ {
+ /* FIXME: add support for an interrupt transfer */
+ if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ ret = usb_bulk_read( husb, (int)request->PipeHandle & 0xff,
+ buf, request->TransferBufferLength, 0 );
+ else
+ ret = usb_bulk_write( husb, (int)request->PipeHandle & 0xff,
+ buf, request->TransferBufferLength, 0 );
+ if (!usb_release_interface( husb,
+ ((int)request->PipeHandle >> 8) - 1 ) && ret >= 0)
+ {
+ request->TransferBufferLength = ret;
+ status = STATUS_SUCCESS;
+ }
+ }
+ usb_close( husb );
+ }
+ }
+ break;
+ case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+ {
+ struct _URB_CONTROL_DESCRIPTOR_REQUEST *request =
+ &urb->u.UrbControlDescriptorRequest;
+ ULONG size = request->TransferBufferLength;
+ unsigned char *buf = request->TransferBuffer;
+
+ TRACE( "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n" );
+
+ if (!size)
+ {
+ status = STATUS_SUCCESS;
+ break;
+ }
+ if (buf == NULL && request->TransferBufferMDL != NULL)
+ buf = request->TransferBufferMDL->MappedSystemVa;
+ if (buf == NULL)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ switch (request->DescriptorType)
+ {
+ case USB_DEVICE_DESCRIPTOR_TYPE:
+ TRACE( "USB_DEVICE_DESCRIPTOR_TYPE\n" );
+ memcpy( buf, &inst->dev->descriptor,
+ (size < sizeof(USB_DEVICE_DESCRIPTOR)) ?
+ size : sizeof(USB_DEVICE_DESCRIPTOR) );
+ status = STATUS_SUCCESS;
+ break;
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ TRACE( "USB_CONFIGURATION_DESCRIPTOR_TYPE\n" );
+ {
+ unsigned int i, k;
+ struct usb_config_descriptor *conf = &inst->dev->config[0];
+ struct usb_interface_descriptor *intf;
+ struct usb_endpoint_descriptor *endp;
+
+ /* FIXME: case of num_altsetting > 1 */
+
+ 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;
+ case USB_STRING_DESCRIPTOR_TYPE:
+ TRACE( "USB_STRING_DESCRIPTOR_TYPE\n" );
+ {
+ usb_dev_handle *husb;
+ int ret;
+
+ husb = usb_open( inst->dev );
+ if (husb)
+ {
+ ret = usb_get_string( husb, request->Index,
+ request->LanguageId, (void *)buf, size );
+ if (ret < 0)
+ ERR( "%s\n", usb_strerror() );
+ else
+ status = STATUS_SUCCESS;
+ usb_close( husb );
+ }
+ }
+ }
+ }
+ break;
+ case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
+ {
+ struct _URB_CONTROL_GET_STATUS_REQUEST *request =
+ &urb->u.UrbControlGetStatusRequest;
+ void *buf = request->TransferBuffer;
+ usb_dev_handle *husb;
+ int ret;
+
+ TRACE( "URB_FUNCTION_GET_STATUS_FROM_DEVICE\n" );
+
+ if (buf == NULL && request->TransferBufferMDL != NULL)
+ buf = request->TransferBufferMDL->MappedSystemVa;
+ if (buf == NULL || request->TransferBufferLength < sizeof(USHORT))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ husb = usb_open( inst->dev );
+ if (husb)
+ {
+ ret = usb_control_msg( husb, 1 << 7, USB_REQ_GET_STATUS, 0,
+ request->Index, buf, sizeof(USHORT), 0 );
+ if (ret < 0)
+ ERR( "%s\n", usb_strerror() );
+ else
+ status = STATUS_SUCCESS;
+ usb_close( husb );
+ }
+ }
+ break;
+ case URB_FUNCTION_VENDOR_DEVICE:
+ case URB_FUNCTION_VENDOR_INTERFACE:
+ case URB_FUNCTION_VENDOR_ENDPOINT:
+ case URB_FUNCTION_CLASS_DEVICE:
+ case URB_FUNCTION_CLASS_INTERFACE:
+ case URB_FUNCTION_CLASS_ENDPOINT:
+ {
+ usb_dev_handle *husb;
+ struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
+ &urb->u.UrbControlVendorClassRequest;
+ unsigned char *req_buf = request->TransferBuffer;
+ ULONG size = request->TransferBufferLength;
+
+ TRACE( "URB_FUNCTION_{VENDOR,CLASS}_*\n" );
+
+ if (req_buf == NULL && request->TransferBufferMDL != NULL)
+ req_buf = request->TransferBufferMDL->MappedSystemVa;
+ if (size && req_buf == NULL)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ husb = usb_open( inst->dev );
+ if (husb)
+ {
+ UCHAR req_type = request->RequestTypeReservedBits;
+ char *buf;
+ int ret;
+
+ switch (urb->u.UrbHeader.Function)
+ {
+ case URB_FUNCTION_VENDOR_DEVICE: req_type |= 0x40; break;
+ case URB_FUNCTION_VENDOR_INTERFACE: req_type |= 0x41; break;
+ case URB_FUNCTION_VENDOR_ENDPOINT: req_type |= 0x42; break;
+ case URB_FUNCTION_CLASS_DEVICE: req_type |= 0x20; break;
+ case URB_FUNCTION_CLASS_INTERFACE: req_type |= 0x21; break;
+ case URB_FUNCTION_CLASS_ENDPOINT: req_type |= 0x22; break;
+ }
+ buf = HeapAlloc( GetProcessHeap(), 0, size );
+ if (buf != NULL)
+ {
+ memcpy( buf, req_buf, size );
+ 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, size, 0 );
+ if (ret < 0)
+ ERR( "%s\n", usb_strerror() );
+ else
+ {
+ if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ {
+ request->TransferBufferLength =
+ (ret < size) ? ret : size;
+ memcpy( req_buf, 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;
+ break;
+ default:
+ FIXME( "IOCTL %08x is not implemented\n",
+ irpsp->Parameters.DeviceIoControl.IoControlCode );
+ }
+
+done:
+ irp->IoStatus.u.Status = status;
+ irp->IoStatus.Information = 0;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+
+ return status;
+}
+
+#endif
+
+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.u2.CurrentStackLocation;
+ switch (irpsp->MinorFunction)
+ {
+ case IRP_MN_QUERY_DEVICE_RELATIONS:
+ /* 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:
+ {
+ WCHAR *device_id = ExAllocatePool( PagedPool, dx->instance->service ?
+ sizeof(device_idW) : sizeof(root_hub_idW) );
+
+ if (device_id == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+ 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:
+ {
+ char *instance_id;
+ ULONG len;
+ ULONG size;
+ WCHAR *instance_idW;
+
+ instance_id = strrchr( dx->instance->instance_id, '&' );
+ instance_id = instance_id ? (instance_id + 1) : dx->instance->instance_id;
+ len = strlen(instance_id) + 1;
+ size = len * sizeof(WCHAR);
+ instance_idW = ExAllocatePool( PagedPool, size );
+ if (instance_idW == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ }
+ RtlMultiByteToUnicodeN( instance_idW, size, NULL, instance_id, len );
+ status = STATUS_SUCCESS;
+ info = (ULONG_PTR)instance_idW;
+ break;
+ }
+ default:
+ FIXME( "IRP_MN_QUERY_ID: IdType %u is not implemented\n",
+ irpsp->Parameters.QueryId.IdType );
+ status = STATUS_NOT_IMPLEMENTED;
+ }
+ break;
+ default:
+ status = STATUS_SUCCESS;
+ }
+
+ irp->IoStatus.u.Status = status;
+ irp->IoStatus.Information = info;
+ IoCompleteRequest( irp, IO_NO_INCREMENT );
+
+ return STATUS_SUCCESS;
+}
+
+static BOOL start_service( const 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;
+ }
+
+ do {
+ ret = StartServiceW( service, 0, NULL );
+ if (!ret)
+ {
+ if (ERROR_SERVICE_ALREADY_RUNNING == GetLastError())
+ ret = TRUE;
+ else if (ERROR_SERVICE_DATABASE_LOCKED == GetLastError())
+ Sleep( 100 );
+ else
+ break;
+ }
+ } while (!ret);
+
+ CloseServiceHandle( service );
+ CloseServiceHandle( scm );
+
+ return ret;
+}
+
+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};
+
+ static unsigned int last_pdo_num;
+ WCHAR *buf = RtlAllocateHeap( GetProcessHeap(), 0, 30 * sizeof(WCHAR) );
+
+ if (buf == NULL) return FALSE;
+ snprintfW( buf, 30, usbpdoW, last_pdo_num++ );
+ 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)
+ {
+ ((struct PdoExtension *)usbdev->DeviceExtension)->instance = inst;
+ usbdev->Flags |= DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE;
+ usbdev->Flags &= ~DO_DEVICE_INITIALIZING;
+ }
+ RtlFreeUnicodeString( &pdo_name );
+ return usbdev;
+}
+
+static void register_root_hub_device( DEVICE_OBJECT *dev, unsigned int instance_id )
+{
+ static const WCHAR root_hub_idW[] = {'U','S','B',
+ '\\','R','O','O','T','_','H','U','B',
+ '\\','%','u',0};
+
+ HDEVINFO set;
+ SP_DEVINFO_DATA devInfo;
+ WCHAR *devnameW;
+ ULONG size;
+ BOOL ret;
+ UNICODE_STRING link;
+ NTSTATUS status;
+
+ size = sizeof(root_hub_idW) + 16 * sizeof(WCHAR);
+ devnameW = HeapAlloc( GetProcessHeap(), 0, size );
+ if (devnameW == NULL) return;
+ snprintfW( devnameW, size / sizeof(WCHAR), root_hub_idW, instance_id );
+
+ set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
+ if (set == INVALID_HANDLE_VALUE) goto done;
+ devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
+ ret = SetupDiCreateDeviceInfoW( set, devnameW, &GUID_DEVCLASS_USB,
+ NULL, NULL, 0, &devInfo );
+ if (ret)
+ {
+ ret = SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL );
+ if (!ret) goto done;
+ }
+ else if (ERROR_DEVINST_ALREADY_EXISTS != GetLastError()) goto done;
+
+ status = IoRegisterDeviceInterface( dev, &GUID_DEVINTERFACE_USB_HUB,
+ NULL, &link );
+ if (status == STATUS_SUCCESS)
+ {
+ IoSetDeviceInterfaceState( &link, TRUE );
+ RtlFreeUnicodeString( &link );
+ }
+done:
+ if (set != INVALID_HANDLE_VALUE)
+ SetupDiDestroyDeviceInfoList( set );
+ HeapFree( GetProcessHeap(), 0, devnameW );
+}
+
+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;
+
+ list_add_tail( &Devices, &instance->entry );
+ ((struct PdoExtension *)hubdev->DeviceExtension)->instance = instance;
+ hubdev->Flags |= DO_POWER_PAGABLE;
+ hubdev->Flags &= ~DO_DEVICE_INITIALIZING;
+ register_root_hub_device( hubdev, instance_id );
+ ++instance_id;
+ 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)
+{
+ 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, usbW, 0, DIGCF_ALLCLASSES );
+ if (set == INVALID_HANDLE_VALUE) return FALSE;
+
+ while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
+ {
+ /* get VID, PID and 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 = strstr( buf, "VID_" );
+ if (str != NULL)
+ {
+ str += 4;
+ vid = strtol( str, NULL, 16 );
+ str = strstr( str, "PID_" );
+ }
+ if (str == NULL)
+ {
+ HeapFree( GetProcessHeap(), 0, buf );
+ continue;
+ }
+ str += 4;
+ pid = strtol( str, NULL, 16 );
+ str = strrchr( str, '\\' );
+ 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)
+ {
+ HeapFree( GetProcessHeap(), 0, buf );
+ buf = NULL;
+ }
+
+ /* 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 );
+ HeapFree( GetProcessHeap(), 0, instance );
+ }
+ return FALSE;
+}
+
+static char *new_instance_id( USHORT vid, USHORT pid )
+{
+ struct DeviceInstance *instance;
+ char *p, *prefix = NULL;
+ unsigned int id = 0, n, prefix_len = 0;
+ char *ret;
+
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (vid == instance->vid && pid == instance->pid)
+ {
+ if (prefix == NULL)
+ {
+ prefix = instance->instance_id;
+ p = strrchr( instance->instance_id, '&' );
+ if (p == NULL) prefix_len = 0;
+ else prefix_len = p + 1 - prefix;
+ id = strtoul( prefix + prefix_len, NULL, 10 ) + 1;
+ }
+ else
+ {
+ p = strrchr( instance->instance_id, '&' );
+ if (prefix_len)
+ {
+ if (p == NULL || p + 1 - instance->instance_id != prefix_len ||
+ strncmp( instance->instance_id, prefix, prefix_len ))
+ continue;
+ }
+ else if (p != NULL) continue;
+ n = strtoul( instance->instance_id + prefix_len, NULL, 10 ) + 1;
+ if (n > id) id = n;
+ }
+ }
+ }
+ ret = HeapAlloc( GetProcessHeap(), 0, prefix_len + 16 );
+ if (ret == NULL) return NULL;
+ memcpy( ret, prefix, prefix_len );
+ snprintf( ret + prefix_len, prefix_len + 16, "%d", id );
+ return ret;
+}
+
+#ifdef HAVE_LIBUSB_H
+
+static BOOL is_mass_storage( libusb_device *dev )
+{
+ struct libusb_config_descriptor *conf;
+ int i, k;
+ BOOL ret = FALSE;
+
+ if (libusb_get_active_config_descriptor( dev, &conf ))
+ return FALSE;
+ for (i = 0; !ret && i < conf->bNumInterfaces; ++i)
+ for (k = 0; !ret && k < conf->interface[i].num_altsetting; ++k)
+ if (conf->interface[i].altsetting[k].bInterfaceClass == 8)
+ ret = TRUE;
+ libusb_free_config_descriptor( conf );
+ return ret;
+}
+
+#else
+
+static BOOL is_mass_storage( struct usb_device *dev )
+{
+ struct usb_config_descriptor *conf = &dev->config[0];
+ int i, k;
+ BOOL ret = FALSE;
+
+ for (i = 0; !ret && i < conf->bNumInterfaces; ++i)
+ for (k = 0; !ret && k < conf->interface[i].num_altsetting; ++k)
+ if (conf->interface[i].altsetting[k].bInterfaceClass == 8)
+ ret = TRUE;
+ return ret;
+}
+
+#endif
+
+static void register_usb_device( USHORT vid, USHORT pid, void *dev )
+{
+ static const WCHAR id_fmtW[] = {'U','S','B',
+ '\\','V','i','d','_','%','0','4','x',
+ '&','P','i','d','_','%','0','4','x',
+ '\\','%','s',0};
+ static const WCHAR driverW[] = {'{','3','6','F','C','9','E','6','0','-',
+ 'C','4','6','5','-','1','1','C','F','-',
+ '8','0','5','6','-','4','4','4','5',
+ '5','3','5','4','0','0','0','0','}',
+ '\\','0','0','0','0',0};
+
+ struct DeviceInstance *instance;
+ HDEVINFO set = INVALID_HANDLE_VALUE;
+ SP_DEVINFO_DATA devInfo;
+ WCHAR *devnameW = NULL, *instance_idW = NULL;
+ char *instance_id;
+ ULONG size;
+
+ instance_id = new_instance_id( vid, pid );
+ if (instance_id == NULL) return;
+
+ instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
+ if (instance == NULL)
+ {
+ HeapFree( GetProcessHeap(), 0, instance_id );
+ goto done;
+ }
+ instance->vid = vid;
+ instance->pid = pid;
+ instance->instance_id = instance_id;
+ instance->service = NULL;
+ instance->dev = dev;
+ list_add_tail( &Devices, &instance->entry );
+
+ size = (strlen(instance_id) + 1) * sizeof(WCHAR);
+ instance_idW = HeapAlloc( GetProcessHeap(), 0, size );
+ if (instance_idW == NULL) goto done;
+ RtlMultiByteToUnicodeN( instance_idW, size, NULL,
+ instance_id, strlen(instance_id) + 1 );
+
+ size = sizeof(id_fmtW) + (strlenW(instance_idW) - 2) * sizeof(WCHAR);
+ devnameW = HeapAlloc( GetProcessHeap(), 0, size );
+ if (devnameW == NULL) goto done;
+ snprintfW( devnameW, size / sizeof(WCHAR), id_fmtW, vid, pid, instance_idW );
+
+ set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
+ if (set == INVALID_HANDLE_VALUE) goto done;
+ devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
+ if (SetupDiCreateDeviceInfoW( set, devnameW, &GUID_DEVCLASS_USB,
+ NULL, NULL, 0, &devInfo ))
+ {
+ SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL );
+ /* This is need for Consultant+ for flash drive */
+ if (is_mass_storage( dev ))
+ SetupDiSetDeviceRegistryPropertyW( set, &devInfo, SPDRP_DRIVER,
+ (BYTE *)driverW, sizeof(driverW) );
+ }
+done:
+ if (set != INVALID_HANDLE_VALUE)
+ SetupDiDestroyDeviceInfoList( set );
+ if (devnameW) HeapFree( GetProcessHeap(), 0, devnameW );
+ if (instance_idW) HeapFree( GetProcessHeap(), 0, instance_idW );
+}
+
+static void start_root_devices( DRIVER_OBJECT *driver_obj )
+{
+ static const WCHAR rootW[] = {'r','o','o','t',0};
+
+ SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
+ HDEVINFO set;
+ DRIVER_OBJECT *driver;
+ DEVICE_OBJECT *pdo;
+ NTSTATUS status;
+ DWORD size, i = 0;
+ WCHAR *serviceW;
+
+ set = SetupDiGetClassDevsW( NULL, rootW, 0, DIGCF_ALLCLASSES );
+ if (set == INVALID_HANDLE_VALUE) return;
+ while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
+ {
+ SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_SERVICE,
+ NULL, NULL, 0, &size );
+ serviceW = HeapAlloc( GetProcessHeap(), 0, size );
+ if (serviceW == NULL) break;
+ if (SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_SERVICE,
+ NULL, (BYTE *)serviceW, size, NULL ) && start_service( serviceW ))
+ {
+ status = IoCreateDevice( driver_obj, 0, NULL, 0, 0, FALSE, &pdo );
+ if (status == STATUS_SUCCESS)
+ {
+ while (!(driver = __wine_get_driver_object( serviceW )))
+ Sleep( 100 );
+ status = __wine_add_device( driver, pdo );
+ if (status == STATUS_SUCCESS && pdo->AttachedDevice != NULL)
+ __wine_start_device( pdo->AttachedDevice );
+ }
+ }
+ HeapFree( GetProcessHeap(), 0, serviceW );
+ }
+ SetupDiDestroyDeviceInfoList( set );
+}
+
+static void start_device_drivers( DRIVER_OBJECT *hubdrv )
+{
+ struct DeviceInstance *instance;
+ DRIVER_OBJECT *driver;
+ DEVICE_OBJECT *pdo;
+ NTSTATUS status;
+
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->service == NULL || instance->dev == NULL) continue;
+ if (start_service( instance->service ))
+ {
+ pdo = create_pdo( instance, hubdrv );
+ if (pdo == NULL) continue;
+ while (!(driver = __wine_get_driver_object(
+ instance->service )))
+ Sleep( 100 );
+ status = __wine_add_device( driver, pdo );
+ if (status == STATUS_SUCCESS && pdo->AttachedDevice != NULL)
+ __wine_start_device( pdo->AttachedDevice );
+ }
+ }
+}
+
+static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
+{
+ static const WCHAR usbhub_started_eventW[] = {'_','_','w','i','n','e',
+ '_','U','s','b','h','u','b',
+ 'S','t','a','r','t','e','d',0};
+
+#ifdef HAVE_LIBUSB_H
+ libusb_device **devs, *dev;
+ struct libusb_device_descriptor desc;
+ unsigned int i = 0;
+#else
+ struct usb_device *dev;
+ struct usb_bus *bus;
+ struct usb_device_descriptor *desc;
+#endif
+ struct DeviceInstance *instance;
+ HANDLE event;
+ BOOL new_device;
+
+ if (!enum_reg_usb_devices())
+ {
+ ERR( "failed to enumerate USB devices\n" );
+ goto end;
+ }
+
+#ifdef HAVE_LIBUSB_H
+ if (libusb_init( NULL ))
+ {
+ ERR( "failed to initialize libusb\n" );
+ goto end;
+ }
+ if (libusb_get_device_list( NULL, &devs ) < 0)
+ {
+ libusb_exit( NULL );
+ goto end;
+ }
+ while ((dev = devs[i++]))
+ {
+ if (libusb_get_device_descriptor( dev, &desc ))
+ {
+ ERR( "failed to get USB device descriptor\n" );
+ continue;
+ }
+ libusb_ref_device( dev );
+ if (libusb_get_device_address( dev ) == 1)
+ {
+ create_root_hub_device( desc.idVendor, desc.idProduct, dev, usbhubdrv );
+ continue;
+ }
+ new_device = TRUE;
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev == NULL && desc.idVendor == instance->vid &&
+ desc.idProduct == instance->pid)
+ {
+ instance->dev = dev;
+ new_device = FALSE;
+ break;
+ }
+ }
+ if (new_device)
+ register_usb_device( desc.idVendor, desc.idProduct, dev );
+ }
+ libusb_free_device_list( devs, 1 );
+#else
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ for (bus = usb_busses; bus; bus = bus->next)
+ for (dev = bus->devices; dev; dev = dev->next)
+ {
+ if (dev->devnum > 1) continue;
+ desc = &bus->devices->descriptor;
+ create_root_hub_device( desc->idVendor, desc->idProduct,
+ bus->devices, usbhubdrv );
+ }
+ for (bus = usb_busses; bus; bus = bus->next)
+ for (dev = bus->devices; dev; dev = dev->next)
+ {
+ if (dev->devnum <= 1) continue;
+ new_device = TRUE;
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ {
+ if (instance->dev == NULL &&
+ dev->descriptor.idVendor == instance->vid &&
+ dev->descriptor.idProduct == instance->pid)
+ {
+ instance->dev = dev;
+ new_device = FALSE;
+ break;
+ }
+ }
+ if (new_device)
+ register_usb_device( dev->descriptor.idVendor,
+ dev->descriptor.idProduct, dev );
+ }
+#endif
+ start_root_devices( usbhubdrv );
+ start_device_drivers( usbhubdrv );
+end:
+ event = CreateEventW( NULL, TRUE, FALSE, usbhub_started_eventW );
+ SetEvent( event );
+ CloseHandle( event );
+ return 0;
+}
+
+#endif
+
+NTSTATUS WINAPI usbhub_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
+{
+#ifdef HAVE_LIBUSB
+ HANDLE thread;
+
+ driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = usbhub_ioctl;
+ driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = usbhub_internal_ioctl;
+ driver->MajorFunction[IRP_MJ_PNP] = 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/ntoskrnl.exe/instr.c b/dlls/ntoskrnl.exe/instr.c
index 53e79fb..7accf3e 100644
--- a/dlls/ntoskrnl.exe/instr.c
+++ b/dlls/ntoskrnl.exe/instr.c
@@ -253,14 +253,14 @@ static BYTE *INSTR_GetOperandAddr( CONTEXT *context, BYTE *instr,
*/
static void init_parport(void)
{
- static const WCHAR parportW[] = {'p','a','r','p','o','r','t','.','s','y','s',0};
+ static const WCHAR mountmgrW[] = {'m','o','u','n','t','m','g','r','.','s','y','s',0};
- HMODULE parport = GetModuleHandleW( parportW );
+ HMODULE mountmgr = GetModuleHandleW( mountmgrW );
- if (parport)
+ if (mountmgr)
{
- pp_read = (void *)GetProcAddress( parport, "__wine_read_parport" );
- pp_write = (void *)GetProcAddress( parport, "__wine_write_parport" );
+ pp_read = (void *)GetProcAddress( mountmgr, "__wine_read_parport" );
+ pp_write = (void *)GetProcAddress( mountmgr, "__wine_write_parport" );
}
if (!pp_read || !pp_write)
ERR( "failed to load parport functions\n" );
diff --git a/dlls/parport.sys/Makefile.in b/dlls/parport.sys/Makefile.in
deleted file mode 100644
index c59e329..0000000
--- a/dlls/parport.sys/Makefile.in
+++ /dev/null
@@ -1,10 +0,0 @@
-MODULE = parport.sys
-IMPORTLIB = parport.sys
-IMPORTS = ntoskrnl.exe setupapi
-EXTRADLLFLAGS = -Wb,--subsystem,native
-EXTRALIBS = @IEEE1284LIBS@
-
-C_SRCS = \
- parport.c
-
- на MAKE_DLL_RULES@
diff --git a/dlls/parport.sys/parport.c b/dlls/parport.sys/parport.c
deleted file mode 100644
index 903ee74..0000000
--- a/dlls/parport.sys/parport.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright 2009 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"
-
-#ifdef HAVE_LIBIEEE1284
-#include <ieee1284.h>
-#endif
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-#define INITGUID
-
-#include "ntstatus.h"
-#define WIN32_NO_STATUS
-#include "windef.h"
-#include "winternl.h"
-#include "winioctl.h"
-#include "winbase.h"
-#include "winuser.h"
-#include "winreg.h"
-#include "setupapi.h"
-#include "ntddpar.h"
-#include "ddk/ntddk.h"
-#include "ddk/parallel.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(parport);
-
-
-#ifdef HAVE_LIBIEEE1284
-static const WCHAR device_idW[] = {'A','C','P','I','\\',
- 'P','N','P','0','4','0','0','\\','%','d',0};
-
-struct ParPortExtension
-{
- struct parport *pp;
- int claimed;
- int n;
- UNICODE_STRING interface;
-};
-
-static struct parport_list pp_list;
-
-static DRIVER_OBJECT *parport_driver;
-
-static BOOLEAN WINAPI parport_try( void *context )
-{
- struct ParPortExtension *ppe = context;
-
- if (ieee1284_open( ppe->pp, 0, NULL ) != E1284_OK)
- return FALSE;
- if (ieee1284_claim( ppe->pp ) != E1284_OK)
- {
- ieee1284_close( ppe->pp );
- return FALSE;
- }
- ppe->claimed = 1;
- return TRUE;
-}
-
-static void WINAPI parport_free( void *context )
-{
- struct ParPortExtension *ppe = context;
-
- if (ppe->claimed)
- {
- ieee1284_release( ppe->pp );
- ieee1284_close( ppe->pp );
- ppe->claimed = 0;
- }
-}
-
-static ULONG WINAPI parport_query_waiters( void *context )
-{
- FIXME( "stub: %p\n", context );
- return 0;
-}
-
-static NTSTATUS WINAPI parport_ioctl( DEVICE_OBJECT *device, IRP *irp )
-{
- IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
- NTSTATUS status = STATUS_NOT_SUPPORTED;
-
- TRACE( "%p, %p\n", device, irp );
-
- switch(irpsp->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_INTERNAL_PARALLEL_PORT_ALLOCATE:
- if (parport_try( device->DeviceExtension ))
- status = STATUS_SUCCESS;
- else
- status = STATUS_UNSUCCESSFUL;
- break;
- case IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO:
- {
- PARALLEL_PORT_INFORMATION *ppi = irp->AssociatedIrp.SystemBuffer;
- struct ParPortExtension *ppe = device->DeviceExtension;
-
- if (irpsp->Parameters.DeviceIoControl.OutputBufferLength
- < sizeof(PARALLEL_PORT_INFORMATION))
- {
- status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
- RtlZeroMemory( ppi, sizeof(*ppi) );
- ppi->OriginalController.QuadPart = ppe->pp->base_addr;
- ppi->Controller = (PUCHAR)ppe->pp->base_addr;
- ppi->TryAllocatePort = parport_try;
- ppi->FreePort = parport_free;
- ppi->QueryNumWaiters = parport_query_waiters;
- ppi->Context = ppe;
- irp->IoStatus.Information = sizeof(PARALLEL_PORT_INFORMATION);
- status = STATUS_SUCCESS;
- break;
- }
- case IOCTL_INTERNAL_GET_MORE_PARALLEL_PORT_INFO:
- TRACE( "IOCTL_INTERNAL_GET_MORE_PARALLEL_PORT_INFO: stub\n" );
- irp->IoStatus.Information = 0;
- status = STATUS_SUCCESS;
- break;
- case IOCTL_INTERNAL_PARALLEL_PORT_FREE:
- parport_free( device->DeviceExtension );
- status = STATUS_SUCCESS;
- break;
- default:
- FIXME( "IOCTL %08x is not implemented\n",
- irpsp->Parameters.DeviceIoControl.IoControlCode );
- status = STATUS_NOT_IMPLEMENTED;
- }
- irp->IoStatus.u.Status = status;
- IoCompleteRequest( irp, IO_NO_INCREMENT );
- return status;
-}
-
-static NTSTATUS WINAPI parport_pnp( DEVICE_OBJECT *device, IRP *irp )
-{
- static const WCHAR fmtW[] = {'%','d',0};
-
- IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
- NTSTATUS status;
-
- TRACE( "%p, %p\n", device, irp );
-
- switch (irpsp->MinorFunction)
- {
- case IRP_MN_QUERY_ID:
- switch (irpsp->Parameters.QueryId.IdType)
- {
- case BusQueryDeviceID:
- {
- WCHAR *device_id = ExAllocatePool( PagedPool, sizeof(device_idW) );
-
- if (device_id == NULL)
- {
- status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
- strcpyW( device_id, device_idW );
- *strrchrW( device_id, '\\' ) = 0;
- status = STATUS_SUCCESS;
- irp->IoStatus.Information = (ULONG_PTR)device_id;
- break;
- }
- case BusQueryInstanceID:
- {
- ULONG len = 16;
- struct ParPortExtension *ppe = device->DeviceExtension;
- WCHAR *instance_id = ExAllocatePool( PagedPool, len * sizeof(WCHAR) );
-
- if (instance_id == NULL)
- {
- status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
- snprintfW( instance_id, len, fmtW, ppe->n );
- status = STATUS_SUCCESS;
- irp->IoStatus.Information = (ULONG_PTR)instance_id;
- break;
- }
- default:
- FIXME( "IRP_MN_QUERY_ID: IdType %u is not implemented\n",
- irpsp->Parameters.QueryId.IdType );
- status = STATUS_NOT_IMPLEMENTED;
- }
- break;
- default:
- FIXME( "function %08x is not implemented\n", irpsp->MinorFunction );
- status = STATUS_NOT_IMPLEMENTED;
- }
- irp->IoStatus.u.Status = status;
- IoCompleteRequest( irp, IO_NO_INCREMENT );
- return STATUS_SUCCESS;
-}
-
-static void register_parport_device( DEVICE_OBJECT *parport_dev, int n )
-{
- static const WCHAR acpiW[] = {'A','C','P','I',0};
-
- struct ParPortExtension *ppe;
- HDEVINFO set;
- SP_DEVINFO_DATA devInfo;
- WCHAR *devnameW;
- ULONG size;
- NTSTATUS status;
-
- size = sizeof(device_idW) + 16 * sizeof(WCHAR);
- devnameW = ExAllocatePool( PagedPool, size );
- if (devnameW == NULL) return;
- snprintfW( devnameW, size / sizeof(WCHAR), device_idW, n );
-
- set = SetupDiGetClassDevsW( NULL, acpiW, 0, DIGCF_ALLCLASSES );
- if (set == INVALID_HANDLE_VALUE) goto done;
- devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
- if (SetupDiCreateDeviceInfoW( set, devnameW, &GUID_SERENUM_BUS_ENUMERATOR,
- NULL, NULL, 0, &devInfo ))
- {
- if (!SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL ))
- goto done;
- }
- else
- {
- if (ERROR_DEVINST_ALREADY_EXISTS != GetLastError())
- goto done;
- }
-
- ppe = parport_dev->DeviceExtension;
- status = IoRegisterDeviceInterface( parport_dev, &GUID_DEVINTERFACE_PARALLEL,
- NULL, &ppe->interface );
- if (status == STATUS_SUCCESS)
- IoSetDeviceInterfaceState( &ppe->interface, TRUE );
-done:
- if (set != INVALID_HANDLE_VALUE)
- SetupDiDestroyDeviceInfoList( set );
- ExFreePool( devnameW );
-}
-
-static void create_parport_device( DRIVER_OBJECT *driver, int n, struct parport *pp )
-{
- static const WCHAR parallel_portW[] = {'\\','D','e','v','i','c','e',
- '\\','P','a','r','a','l','l','e','l',
- 'P','o','r','t','%','d',0};
-
- struct ParPortExtension *ppe;
- UNICODE_STRING parallel_port;
- DEVICE_OBJECT *parport_dev;
- WCHAR device_name[MAX_PATH];
- NTSTATUS status;
-
- snprintfW( device_name, MAX_PATH, parallel_portW, n );
- RtlInitUnicodeString( ¶llel_port, device_name );
- status = IoCreateDevice( driver, sizeof(struct ParPortExtension), ¶llel_port,
- FILE_DEVICE_PARALLEL_PORT, FILE_DEVICE_SECURE_OPEN, FALSE, &parport_dev );
- if (status == STATUS_SUCCESS)
- {
- ppe = parport_dev->DeviceExtension;
- RtlZeroMemory( ppe, sizeof(*ppe) );
- ppe->pp = pp;
- ppe->n = n;
- register_parport_device( parport_dev, n );
- parport_dev->Flags &= ~DO_DEVICE_INITIALIZING;
- }
-}
-
-static void enum_par_devices( DRIVER_OBJECT *driver )
-{
- struct parport *pp;
- int k;
-
- ieee1284_find_ports( &pp_list, 0 );
- for (k = 0; k < pp_list.portc; ++k)
- {
- pp = pp_list.portv[k];
- create_parport_device( driver, k, pp );
- }
-}
-
-static struct ParPortExtension *get_parport_ext( UCHAR *port, ULONG *offset )
-{
- DEVICE_OBJECT *device = parport_driver->DeviceObject;
- struct ParPortExtension *ppe;
-
- while (device)
- {
- ppe = device->DeviceExtension;
- *offset = (ULONG)port - ppe->pp->base_addr;
- if (*offset <= DCR_OFFSET) return ppe;
- device = device->NextDevice;
- }
- return NULL;
-}
-
-static int read_parport( struct parport *pp, ULONG offset )
-{
- if (DATA_OFFSET == offset) return ieee1284_read_data( pp );
- if (DSR_OFFSET == offset) return ieee1284_read_status( pp ) ^ S1284_INVERTED;
- if (DCR_OFFSET == offset) return ieee1284_read_control( pp ) ^ C1284_INVERTED;
- return -1;
-}
-
-static void write_parport( struct parport *pp, UCHAR value, ULONG offset )
-{
- if (DATA_OFFSET == offset) ieee1284_write_data( pp, value );
- /* FIXME: see NOTE in ieee1284.h */
- else if (DCR_OFFSET == offset) ieee1284_write_control( pp, value ^ C1284_INVERTED );
-}
-#endif /* HAVE_LIBIEEE1284 */
-
-UCHAR CDECL __wine_read_parport( UCHAR *port )
-{
-#ifdef HAVE_LIBIEEE1284
- int ret = -1;
- ULONG offset;
- struct ParPortExtension *ppe = get_parport_ext( port, &offset );
-
- if (!ppe) return 0xff;
- if (ppe->claimed) ret = read_parport( ppe->pp, offset );
- else if (parport_try( ppe ))
- {
- ret = read_parport( ppe->pp, offset );
- parport_free( ppe );
- }
- if (ret >= 0) return ret;
-#endif
- return 0xff;
-}
-
-void CDECL __wine_write_parport( UCHAR *port, UCHAR value )
-{
-#ifdef HAVE_LIBIEEE1284
- ULONG offset;
- struct ParPortExtension *ppe = get_parport_ext( port, &offset );
-
- if (!ppe) return;
- if (ppe->claimed) write_parport( ppe->pp, value, offset );
- else if (parport_try( ppe ))
- {
- write_parport( ppe->pp, value, offset );
- parport_free( ppe );
- }
-#endif
-}
-
-static void WINAPI parport_unload( DRIVER_OBJECT *driver )
-{
-#ifdef HAVE_LIBIEEE1284
- DEVICE_OBJECT *device = driver->DeviceObject, *device2;
- struct ParPortExtension *ppe;
-
- while (device)
- {
- device2 = device->NextDevice;
- ppe = device->DeviceExtension;
- if (ppe->interface.Buffer)
- {
- IoSetDeviceInterfaceState( &ppe->interface, FALSE );
- RtlFreeUnicodeString( &ppe->interface );
- }
- IoDeleteDevice( device );
- device = device2;
- }
- ieee1284_free_ports( &pp_list );
-#endif
-}
-
-NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
-{
- driver->DriverUnload = parport_unload;
-#ifdef HAVE_LIBIEEE1284
- driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = parport_ioctl;
- driver->MajorFunction[IRP_MJ_PNP] = parport_pnp;
- parport_driver = driver;
- enum_par_devices( driver );
-#endif
- return STATUS_SUCCESS;
-}
diff --git a/dlls/parport.sys/parport.sys.spec b/dlls/parport.sys/parport.sys.spec
deleted file mode 100644
index 4848c4a..0000000
--- a/dlls/parport.sys/parport.sys.spec
+++ /dev/null
@@ -1,8 +0,0 @@
-################################################################
-# Wine internal extensions
-#
-# All functions must be prefixed with '__wine_' (for internal functions)
-# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
-
-@ cdecl __wine_read_parport(ptr)
-@ cdecl __wine_write_parport(ptr long)
diff --git a/dlls/usbhub.sys/Makefile.in b/dlls/usbhub.sys/Makefile.in
deleted file mode 100644
index 7594887..0000000
--- a/dlls/usbhub.sys/Makefile.in
+++ /dev/null
@@ -1,10 +0,0 @@
-MODULE = usbhub.sys
-IMPORTS = ntoskrnl.exe advapi32 setupapi
-EXTRADLLFLAGS = -Wb,--subsystem,native
-EXTRAINCL = @USBINCL@
-EXTRALIBS = @USBLIBS@
-
-C_SRCS = \
- usbhub.c
-
- на MAKE_DLL_RULES@
diff --git a/dlls/usbhub.sys/usbhub.c b/dlls/usbhub.sys/usbhub.c
deleted file mode 100644
index 2bed715..0000000
--- a/dlls/usbhub.sys/usbhub.c
+++ /dev/null
@@ -1,1733 +0,0 @@
-/*
- * Copyright 2008-2009 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 <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#ifdef HAVE_LIBUSB_H
-#include <libusb.h>
-#elif defined(HAVE_USB_H)
-#include <usb.h>
-#endif
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-#define INITGUID
-
-#include "ntstatus.h"
-#define WIN32_NO_STATUS
-#include "windef.h"
-#include "winbase.h"
-#include "winternl.h"
-#include "winioctl.h"
-#include "winreg.h"
-#include "winsvc.h"
-#include "winuser.h"
-#include "setupapi.h"
-#include "cfgmgr32.h"
-#include "devguid.h"
-#include "ddk/ntddk.h"
-#define WINE_USBHUB_EXTENSIONS
-#include "ddk/usbdrivr.h"
-#include "ddk/usbioctl.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
-#include "wine/list.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(usbhub);
-
-extern NTSTATUS CDECL __wine_add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *dev );
-extern DRIVER_OBJECT * CDECL __wine_get_driver_object( const WCHAR *service );
-extern NTSTATUS CDECL __wine_start_device( DEVICE_OBJECT *device );
-
-#define NUMBER_OF_PORTS 8
-
-static const WCHAR usbW[] = {'U','S','B',0};
-
-static struct list Devices = LIST_INIT(Devices);
-
-struct DeviceInstance
-{
- struct list entry;
- USHORT vid;
- USHORT pid;
- char *instance_id;
- WCHAR *service;
-#ifdef HAVE_LIBUSB_H
- libusb_device *dev;
-#else
- struct usb_device *dev;
-#endif
-};
-
-struct PdoExtension
-{
- struct DeviceInstance *instance;
-};
-
-#ifdef HAVE_LIBUSB
-
-static void add_data( unsigned char **dst, ULONG *dst_size, const void *src, ULONG src_size )
-{
- int copy;
-
- copy = (src_size >= *dst_size) ? *dst_size : src_size;
- memcpy( *dst, src, copy );
- *dst += copy;
- *dst_size -= copy;
-}
-
-static NTSTATUS WINAPI usbhub_ioctl( 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};
-
- IO_STACK_LOCATION *irpsp;
- NTSTATUS status = STATUS_UNSUCCESSFUL;
- struct DeviceInstance *inst;
- ULONG_PTR info = 0;
-
- TRACE( "%p, %p\n", device, irp );
-
- inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
- if (inst->service) goto done;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
-
- switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_USB_GET_NODE_INFORMATION:
- {
- USB_NODE_INFORMATION *node_info = irp->AssociatedIrp.SystemBuffer;
-
- if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*node_info))
- {
- status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
- RtlZeroMemory( node_info, sizeof(*node_info) );
- node_info->u.HubInformation.HubDescriptor.bDescriptorLength = 9;
- node_info->u.HubInformation.HubDescriptor.bDescriptorType = 41;
- node_info->u.HubInformation.HubDescriptor.bNumberOfPorts = NUMBER_OF_PORTS;
- status = STATUS_SUCCESS;
- info = sizeof(*node_info);
- break;
- }
- case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
- {
- USB_NODE_CONNECTION_INFORMATION *conn_info = irp->AssociatedIrp.SystemBuffer;
- ULONG index = 0;
-#ifdef HAVE_LIBUSB_H
- struct DeviceInstance *instance;
- uint8_t bus_number = libusb_get_bus_number( inst->dev );
-#else
- struct usb_device *dev;
-#endif
-
- if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*conn_info))
- {
- status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
- if (!conn_info->ConnectionIndex || conn_info->ConnectionIndex > NUMBER_OF_PORTS)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- RtlZeroMemory( (ULONG *)conn_info + 1, sizeof(*conn_info) - sizeof(ULONG) );
-#ifdef HAVE_LIBUSB_H
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->dev && instance->dev != inst->dev &&
- libusb_get_bus_number( instance->dev ) == bus_number &&
- ++index == conn_info->ConnectionIndex)
- {
- struct libusb_device_descriptor desc;
-
- if (libusb_get_device_descriptor( instance->dev, &desc ))
- break;
- memcpy( &conn_info->DeviceDescriptor, &desc,
- sizeof(USB_DEVICE_DESCRIPTOR) );
- conn_info->ConnectionStatus = 1;
- break;
- }
- }
-#else
- for (dev = inst->dev->next; dev; dev = dev->next)
- if (++index == conn_info->ConnectionIndex)
- {
- memcpy( &conn_info->DeviceDescriptor, &dev->descriptor,
- sizeof(USB_DEVICE_DESCRIPTOR) );
- conn_info->ConnectionStatus = 1;
- break;
- }
-#endif
- status = STATUS_SUCCESS;
- info = sizeof(*conn_info);
- break;
- }
- case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
- {
- USB_NODE_CONNECTION_DRIVERKEY_NAME *driver_key_name =
- irp->AssociatedIrp.SystemBuffer;
- WCHAR *dev_instance_idW, *bufW;
- struct DeviceInstance *instance;
- HDEVINFO set;
- SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
- ULONG len, index = 0, found = 0;
-#ifdef HAVE_LIBUSB_H
- uint8_t bus_number = libusb_get_bus_number( inst->dev );
-#else
- struct usb_device *dev;
-#endif
-
- if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
- sizeof(*driver_key_name))
- {
- status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-#ifdef HAVE_LIBUSB_H
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->dev && instance->dev != inst->dev &&
- libusb_get_bus_number( instance->dev ) == bus_number &&
- ++index == driver_key_name->ConnectionIndex)
- {
- found = 1;
- break;
- }
- }
-#else
- for (dev = inst->dev->next; dev; dev = dev->next)
- if (++index == driver_key_name->ConnectionIndex)
- {
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->dev == dev)
- {
- found = 1;
- break;
- }
- }
- break;
- }
-#endif
- if (!found)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- bufW = HeapAlloc( GetProcessHeap(), 0,
- 2 * MAX_DEVICE_ID_LEN * sizeof(WCHAR) );
- if (bufW == NULL)
- {
- status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
- dev_instance_idW = bufW + MAX_DEVICE_ID_LEN;
- snprintfW( dev_instance_idW, MAX_DEVICE_ID_LEN, device_idW,
- instance->vid, instance->pid );
- len = strlenW(dev_instance_idW);
- RtlMultiByteToUnicodeN( dev_instance_idW + len,
- (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
- instance->instance_id, strlen(instance->instance_id) + 1 );
- set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
- if (set == INVALID_HANDLE_VALUE)
- {
- HeapFree( GetProcessHeap(), 0, bufW );
- break;
- }
- index = 0;
- while (SetupDiEnumDeviceInfo( set, index++, &devInfo ))
- {
- if (!SetupDiGetDeviceInstanceIdW( set, &devInfo, bufW,
- MAX_DEVICE_ID_LEN, NULL ))
- break;
- if (!strcmpiW( dev_instance_idW, bufW ))
- {
- SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_DRIVER,
- NULL, NULL, 0, &len );
- driver_key_name->ActualLength = 2 * sizeof(ULONG) + len;
- if (irpsp->Parameters.DeviceIoControl.OutputBufferLength <
- driver_key_name->ActualLength)
- {
- status = STATUS_SUCCESS;
- info = sizeof(*driver_key_name);
- }
- else if (SetupDiGetDeviceRegistryPropertyW( set, &devInfo,
- SPDRP_DRIVER, NULL, (BYTE *)driver_key_name->DriverKeyName,
- len, NULL ))
- {
- status = STATUS_SUCCESS;
- info = driver_key_name->ActualLength;
- }
- break;
- }
- }
- SetupDiDestroyDeviceInfoList( set );
- HeapFree( GetProcessHeap(), 0, bufW );
- break;
- }
- case IOCTL_USB_GET_DEVICE_INFO:
- {
- struct usb_device_info *dev_info = irp->AssociatedIrp.SystemBuffer;
- struct DeviceInstance *instance;
- ULONG len, index = 0;
-#ifdef HAVE_LIBUSB_H
- uint8_t bus_number = libusb_get_bus_number( inst->dev );
-#else
- struct usb_device *dev;
-#endif
-
- if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*dev_info))
- {
- status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
- if (!dev_info->connection_index || dev_info->connection_index > NUMBER_OF_PORTS)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- RtlZeroMemory( (ULONG *)dev_info + 1, sizeof(*dev_info) - sizeof(ULONG) );
- memcpy( dev_info->root_hub_id, root_hub_idW, sizeof(root_hub_idW) );
- len = strlenW(root_hub_idW);
- RtlMultiByteToUnicodeN( dev_info->root_hub_id + len,
- (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
- inst->instance_id, strlen(inst->instance_id) + 1 );
-#ifdef HAVE_LIBUSB_H
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->dev && instance->dev != inst->dev &&
- libusb_get_bus_number( instance->dev ) == bus_number &&
- ++index == dev_info->connection_index)
- {
- dev_info->device_address = libusb_get_device_address( instance->dev );
- break;
- }
- }
-#else
- for (dev = inst->dev->next; dev; dev = dev->next)
- if (++index == dev_info->connection_index)
- {
- dev_info->device_address = dev->devnum;
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->dev == dev) break;
- }
- break;
- }
-#endif
- if (dev_info->device_address)
- {
- snprintfW( dev_info->device_id, MAX_DEVICE_ID_LEN, device_idW,
- instance->vid, instance->pid );
- len = strlenW(dev_info->device_id);
- RtlMultiByteToUnicodeN( dev_info->device_id + len,
- (MAX_DEVICE_ID_LEN - len) * sizeof(WCHAR), NULL,
- instance->instance_id, strlen(instance->instance_id) + 1 );
- }
- status = STATUS_SUCCESS;
- info = sizeof(*dev_info);
- break;
- }
- default:
- FIXME( "IOCTL %08x is not implemented\n",
- irpsp->Parameters.DeviceIoControl.IoControlCode );
- }
-
-done:
- irp->IoStatus.u.Status = status;
- irp->IoStatus.Information = info;
- IoCompleteRequest( irp, IO_NO_INCREMENT );
-
- return status;
-}
-
-#ifdef HAVE_LIBUSB_H
-
-static NTSTATUS WINAPI 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;
- if (!inst->service) goto done;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
- urb = irpsp->Parameters.Others.Argument1;
-
- switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_INTERNAL_USB_SUBMIT_URB:
- switch (urb->u.UrbHeader.Function)
- {
- case URB_FUNCTION_SELECT_CONFIGURATION:
- {
- 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 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 );
- }
- }
- break;
- case URB_FUNCTION_SELECT_INTERFACE:
- {
- struct _URB_SELECT_INTERFACE *request =
- &urb->u.UrbSelectInterface;
- libusb_device_handle *husb;
-
- TRACE( "URB_FUNCTION_SELECT_INTERFACE\n" );
-
- if (!libusb_open( inst->dev, &husb ))
- {
- int ret;
-
- ret = libusb_claim_interface( husb,
- request->Interface.InterfaceNumber );
- if (!ret)
- {
- ret = libusb_set_interface_alt_setting( husb,
- request->Interface.InterfaceNumber,
- request->Interface.AlternateSetting );
- if (!libusb_release_interface( husb,
- request->Interface.InterfaceNumber ) && !ret)
- status = STATUS_SUCCESS;
- }
- libusb_close( husb );
- }
- }
- break;
- case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
- {
- struct _URB_BULK_OR_INTERRUPT_TRANSFER *request =
- &urb->u.UrbBulkOrInterruptTransfer;
- unsigned char *buf = request->TransferBuffer;
- libusb_device_handle *husb;
-
- TRACE( "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n" );
-
- if (buf == NULL && request->TransferBufferMDL != NULL)
- buf = request->TransferBufferMDL->MappedSystemVa;
- if (!libusb_open( inst->dev, &husb ))
- {
- int ret, transferred;
-
- ret = libusb_claim_interface( husb,
- ((int)request->PipeHandle >> 8) - 1 );
- if (!ret)
- {
- /* FIXME: add support for an interrupt transfer */
- ret = libusb_bulk_transfer( husb,
- (unsigned int)request->PipeHandle,
- buf, request->TransferBufferLength,
- &transferred, 0 );
- if (!libusb_release_interface( husb,
- ((int)request->PipeHandle >> 8) - 1 ) && !ret)
- {
- request->TransferBufferLength = transferred;
- status = STATUS_SUCCESS;
- }
- }
- libusb_close( husb );
- }
- }
- break;
- case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
- {
- struct _URB_CONTROL_DESCRIPTOR_REQUEST *request =
- &urb->u.UrbControlDescriptorRequest;
- ULONG size = request->TransferBufferLength;
- unsigned char *buf = request->TransferBuffer;
-
- TRACE( "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n" );
-
- if (!size)
- {
- status = STATUS_SUCCESS;
- break;
- }
- if (buf == NULL && request->TransferBufferMDL != NULL)
- buf = request->TransferBufferMDL->MappedSystemVa;
- if (buf == NULL)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- switch (request->DescriptorType)
- {
- case USB_DEVICE_DESCRIPTOR_TYPE:
- TRACE( "USB_DEVICE_DESCRIPTOR_TYPE\n" );
- {
- struct libusb_device_descriptor desc;
-
- if (libusb_get_device_descriptor( inst->dev, &desc ))
- break;
- memcpy( buf, &desc, (size < sizeof(USB_DEVICE_DESCRIPTOR)) ?
- size : sizeof(USB_DEVICE_DESCRIPTOR) );
- status = STATUS_SUCCESS;
- }
- break;
- case USB_CONFIGURATION_DESCRIPTOR_TYPE:
- TRACE( "USB_CONFIGURATION_DESCRIPTOR_TYPE\n" );
- {
- unsigned int i, k;
- struct libusb_config_descriptor *conf;
- const struct libusb_interface_descriptor *intf;
- const struct libusb_endpoint_descriptor *endp;
-
- /* FIXME: case of num_altsetting > 1 */
-
- if (libusb_get_active_config_descriptor( inst->dev, &conf ))
- break;
- add_data( &buf, &size, conf,
- sizeof(USB_CONFIGURATION_DESCRIPTOR) );
- if (size > 0 && conf->extra)
- add_data( &buf, &size, conf->extra, conf->extra_length );
- 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->extra_length );
- 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->extra_length );
- }
- }
- libusb_free_config_descriptor( conf );
- status = STATUS_SUCCESS;
- }
- break;
- case USB_STRING_DESCRIPTOR_TYPE:
- TRACE( "USB_STRING_DESCRIPTOR_TYPE\n" );
- {
- libusb_device_handle *husb;
- int ret;
-
- if (!libusb_open( inst->dev, &husb ))
- {
- ret = libusb_get_string_descriptor( husb, request->Index,
- request->LanguageId, buf, size );
- libusb_close( husb );
- if (ret < 0) break;
- status = STATUS_SUCCESS;
- }
- }
- }
- }
- break;
- case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
- {
- struct _URB_CONTROL_GET_STATUS_REQUEST *request =
- &urb->u.UrbControlGetStatusRequest;
- void *buf = request->TransferBuffer;
- libusb_device_handle *husb;
- int ret;
-
- TRACE( "URB_FUNCTION_GET_STATUS_FROM_DEVICE\n" );
-
- if (buf == NULL && request->TransferBufferMDL != NULL)
- buf = request->TransferBufferMDL->MappedSystemVa;
- if (buf == NULL || request->TransferBufferLength < sizeof(USHORT))
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- if (!libusb_open( inst->dev, &husb ))
- {
- ret = libusb_control_transfer( husb, 1 << 7,
- LIBUSB_REQUEST_GET_STATUS, 0, request->Index, buf,
- sizeof(USHORT), 0 );
- libusb_close( husb );
- if (ret < 0) break;
- status = STATUS_SUCCESS;
- }
- }
- break;
- case URB_FUNCTION_VENDOR_DEVICE:
- case URB_FUNCTION_VENDOR_INTERFACE:
- case URB_FUNCTION_VENDOR_ENDPOINT:
- case URB_FUNCTION_CLASS_DEVICE:
- case URB_FUNCTION_CLASS_INTERFACE:
- case URB_FUNCTION_CLASS_ENDPOINT:
- {
- libusb_device_handle *husb;
- struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
- &urb->u.UrbControlVendorClassRequest;
- unsigned char *req_buf = request->TransferBuffer;
- ULONG size = request->TransferBufferLength;
-
- TRACE( "URB_FUNCTION_{VENDOR,CLASS}_*\n" );
-
- if (req_buf == NULL && request->TransferBufferMDL != NULL)
- req_buf = request->TransferBufferMDL->MappedSystemVa;
- if (size && req_buf == NULL)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- if (!libusb_open( inst->dev, &husb ))
- {
- UCHAR req_type = request->RequestTypeReservedBits;
- unsigned char *buf;
- int ret;
-
- switch (urb->u.UrbHeader.Function)
- {
- case URB_FUNCTION_VENDOR_DEVICE: req_type |= 0x40; break;
- case URB_FUNCTION_VENDOR_INTERFACE: req_type |= 0x41; break;
- case URB_FUNCTION_VENDOR_ENDPOINT: req_type |= 0x42; break;
- case URB_FUNCTION_CLASS_DEVICE: req_type |= 0x20; break;
- case URB_FUNCTION_CLASS_INTERFACE: req_type |= 0x21; break;
- case URB_FUNCTION_CLASS_ENDPOINT: req_type |= 0x22; break;
- }
- buf = HeapAlloc( GetProcessHeap(), 0, size );
- if (buf != NULL)
- {
- memcpy( buf, req_buf, size );
- if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
- req_type |= (1 << 7);
- ret = libusb_control_transfer( husb, req_type,
- request->Request, request->Value, request->Index,
- buf, size, 0 );
- if (ret < 0)
- ERR( "libusb_control_transfer: %d\n", ret );
- else
- {
- if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
- {
- request->TransferBufferLength =
- (ret < size) ? ret : size;
- memcpy( req_buf, buf, request->TransferBufferLength );
- }
- status = STATUS_SUCCESS;
- }
- HeapFree( GetProcessHeap(), 0, buf );
- }
- libusb_close( husb );
- }
- }
- break;
- default:
- FIXME( "unsupported URB function %x\n", urb->u.UrbHeader.Function );
- }
- urb->u.UrbHeader.Status = status;
- break;
- default:
- FIXME( "IOCTL %08x is not implemented\n",
- irpsp->Parameters.DeviceIoControl.IoControlCode );
- }
-
-done:
- irp->IoStatus.u.Status = status;
- irp->IoStatus.Information = 0;
- IoCompleteRequest( irp, IO_NO_INCREMENT );
-
- return status;
-}
-
-#else
-
-static NTSTATUS WINAPI 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;
- if (!inst->service) goto done;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
- urb = irpsp->Parameters.Others.Argument1;
-
- switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_INTERNAL_USB_SUBMIT_URB:
- switch (urb->u.UrbHeader.Function)
- {
- case URB_FUNCTION_SELECT_CONFIGURATION:
- {
- struct _URB_SELECT_CONFIGURATION *request =
- &urb->u.UrbSelectConfiguration;
- usb_dev_handle *husb;
-
- TRACE( "URB_FUNCTION_SELECT_CONFIGURATION\n" );
-
- 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 );
- }
- }
- break;
- case URB_FUNCTION_SELECT_INTERFACE:
- {
- struct _URB_SELECT_INTERFACE *request =
- &urb->u.UrbSelectInterface;
- usb_dev_handle *husb;
-
- TRACE( "URB_FUNCTION_SELECT_INTERFACE\n" );
-
- husb = usb_open( inst->dev );
- if (husb)
- {
- int ret;
-
- ret = usb_claim_interface( husb,
- request->Interface.InterfaceNumber );
- if (!ret)
- {
- ret = usb_set_altinterface( husb,
- request->Interface.AlternateSetting );
- if (!usb_release_interface( husb,
- request->Interface.InterfaceNumber ) && !ret)
- status = STATUS_SUCCESS;
- }
- usb_close( husb );
- }
- }
- break;
- case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
- {
- struct _URB_BULK_OR_INTERRUPT_TRANSFER *request =
- &urb->u.UrbBulkOrInterruptTransfer;
- char *buf = request->TransferBuffer;
- usb_dev_handle *husb;
-
- TRACE( "URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n" );
-
- if (buf == NULL && request->TransferBufferMDL != NULL)
- buf = request->TransferBufferMDL->MappedSystemVa;
- husb = usb_open( inst->dev );
- if (husb)
- {
- int ret;
-
- ret = usb_claim_interface( husb,
- ((int)request->PipeHandle >> 8) - 1 );
- if (!ret)
- {
- /* FIXME: add support for an interrupt transfer */
- if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
- ret = usb_bulk_read( husb, (int)request->PipeHandle & 0xff,
- buf, request->TransferBufferLength, 0 );
- else
- ret = usb_bulk_write( husb, (int)request->PipeHandle & 0xff,
- buf, request->TransferBufferLength, 0 );
- if (!usb_release_interface( husb,
- ((int)request->PipeHandle >> 8) - 1 ) && ret >= 0)
- {
- request->TransferBufferLength = ret;
- status = STATUS_SUCCESS;
- }
- }
- usb_close( husb );
- }
- }
- break;
- case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
- {
- struct _URB_CONTROL_DESCRIPTOR_REQUEST *request =
- &urb->u.UrbControlDescriptorRequest;
- ULONG size = request->TransferBufferLength;
- unsigned char *buf = request->TransferBuffer;
-
- TRACE( "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n" );
-
- if (!size)
- {
- status = STATUS_SUCCESS;
- break;
- }
- if (buf == NULL && request->TransferBufferMDL != NULL)
- buf = request->TransferBufferMDL->MappedSystemVa;
- if (buf == NULL)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- switch (request->DescriptorType)
- {
- case USB_DEVICE_DESCRIPTOR_TYPE:
- TRACE( "USB_DEVICE_DESCRIPTOR_TYPE\n" );
- memcpy( buf, &inst->dev->descriptor,
- (size < sizeof(USB_DEVICE_DESCRIPTOR)) ?
- size : sizeof(USB_DEVICE_DESCRIPTOR) );
- status = STATUS_SUCCESS;
- break;
- case USB_CONFIGURATION_DESCRIPTOR_TYPE:
- TRACE( "USB_CONFIGURATION_DESCRIPTOR_TYPE\n" );
- {
- unsigned int i, k;
- struct usb_config_descriptor *conf = &inst->dev->config[0];
- struct usb_interface_descriptor *intf;
- struct usb_endpoint_descriptor *endp;
-
- /* FIXME: case of num_altsetting > 1 */
-
- 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;
- case USB_STRING_DESCRIPTOR_TYPE:
- TRACE( "USB_STRING_DESCRIPTOR_TYPE\n" );
- {
- usb_dev_handle *husb;
- int ret;
-
- husb = usb_open( inst->dev );
- if (husb)
- {
- ret = usb_get_string( husb, request->Index,
- request->LanguageId, (void *)buf, size );
- if (ret < 0)
- ERR( "%s\n", usb_strerror() );
- else
- status = STATUS_SUCCESS;
- usb_close( husb );
- }
- }
- }
- }
- break;
- case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
- {
- struct _URB_CONTROL_GET_STATUS_REQUEST *request =
- &urb->u.UrbControlGetStatusRequest;
- void *buf = request->TransferBuffer;
- usb_dev_handle *husb;
- int ret;
-
- TRACE( "URB_FUNCTION_GET_STATUS_FROM_DEVICE\n" );
-
- if (buf == NULL && request->TransferBufferMDL != NULL)
- buf = request->TransferBufferMDL->MappedSystemVa;
- if (buf == NULL || request->TransferBufferLength < sizeof(USHORT))
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- husb = usb_open( inst->dev );
- if (husb)
- {
- ret = usb_control_msg( husb, 1 << 7, USB_REQ_GET_STATUS, 0,
- request->Index, buf, sizeof(USHORT), 0 );
- if (ret < 0)
- ERR( "%s\n", usb_strerror() );
- else
- status = STATUS_SUCCESS;
- usb_close( husb );
- }
- }
- break;
- case URB_FUNCTION_VENDOR_DEVICE:
- case URB_FUNCTION_VENDOR_INTERFACE:
- case URB_FUNCTION_VENDOR_ENDPOINT:
- case URB_FUNCTION_CLASS_DEVICE:
- case URB_FUNCTION_CLASS_INTERFACE:
- case URB_FUNCTION_CLASS_ENDPOINT:
- {
- usb_dev_handle *husb;
- struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
- &urb->u.UrbControlVendorClassRequest;
- unsigned char *req_buf = request->TransferBuffer;
- ULONG size = request->TransferBufferLength;
-
- TRACE( "URB_FUNCTION_{VENDOR,CLASS}_*\n" );
-
- if (req_buf == NULL && request->TransferBufferMDL != NULL)
- req_buf = request->TransferBufferMDL->MappedSystemVa;
- if (size && req_buf == NULL)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- husb = usb_open( inst->dev );
- if (husb)
- {
- UCHAR req_type = request->RequestTypeReservedBits;
- char *buf;
- int ret;
-
- switch (urb->u.UrbHeader.Function)
- {
- case URB_FUNCTION_VENDOR_DEVICE: req_type |= 0x40; break;
- case URB_FUNCTION_VENDOR_INTERFACE: req_type |= 0x41; break;
- case URB_FUNCTION_VENDOR_ENDPOINT: req_type |= 0x42; break;
- case URB_FUNCTION_CLASS_DEVICE: req_type |= 0x20; break;
- case URB_FUNCTION_CLASS_INTERFACE: req_type |= 0x21; break;
- case URB_FUNCTION_CLASS_ENDPOINT: req_type |= 0x22; break;
- }
- buf = HeapAlloc( GetProcessHeap(), 0, size );
- if (buf != NULL)
- {
- memcpy( buf, req_buf, size );
- 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, size, 0 );
- if (ret < 0)
- ERR( "%s\n", usb_strerror() );
- else
- {
- if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
- {
- request->TransferBufferLength =
- (ret < size) ? ret : size;
- memcpy( req_buf, 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;
- break;
- default:
- FIXME( "IOCTL %08x is not implemented\n",
- irpsp->Parameters.DeviceIoControl.IoControlCode );
- }
-
-done:
- irp->IoStatus.u.Status = status;
- irp->IoStatus.Information = 0;
- IoCompleteRequest( irp, IO_NO_INCREMENT );
-
- return status;
-}
-
-#endif
-
-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.u2.CurrentStackLocation;
- switch (irpsp->MinorFunction)
- {
- case IRP_MN_QUERY_DEVICE_RELATIONS:
- /* 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:
- {
- WCHAR *device_id = ExAllocatePool( PagedPool, dx->instance->service ?
- sizeof(device_idW) : sizeof(root_hub_idW) );
-
- if (device_id == NULL)
- {
- status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
- 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:
- {
- char *instance_id;
- ULONG len;
- ULONG size;
- WCHAR *instance_idW;
-
- instance_id = strrchr( dx->instance->instance_id, '&' );
- instance_id = instance_id ? (instance_id + 1) : dx->instance->instance_id;
- len = strlen(instance_id) + 1;
- size = len * sizeof(WCHAR);
- instance_idW = ExAllocatePool( PagedPool, size );
- if (instance_idW == NULL)
- {
- status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
- RtlMultiByteToUnicodeN( instance_idW, size, NULL, instance_id, len );
- status = STATUS_SUCCESS;
- info = (ULONG_PTR)instance_idW;
- break;
- }
- default:
- FIXME( "IRP_MN_QUERY_ID: IdType %u is not implemented\n",
- irpsp->Parameters.QueryId.IdType );
- status = STATUS_NOT_IMPLEMENTED;
- }
- break;
- default:
- status = STATUS_SUCCESS;
- }
-
- irp->IoStatus.u.Status = status;
- irp->IoStatus.Information = info;
- IoCompleteRequest( irp, IO_NO_INCREMENT );
-
- return STATUS_SUCCESS;
-}
-
-static BOOL start_service( const 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;
- }
-
- do {
- ret = StartServiceW( service, 0, NULL );
- if (!ret)
- {
- if (ERROR_SERVICE_ALREADY_RUNNING == GetLastError())
- ret = TRUE;
- else if (ERROR_SERVICE_DATABASE_LOCKED == GetLastError())
- Sleep( 100 );
- else
- break;
- }
- } while (!ret);
-
- CloseServiceHandle( service );
- CloseServiceHandle( scm );
-
- return ret;
-}
-
-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};
-
- static unsigned int last_pdo_num;
- WCHAR *buf = RtlAllocateHeap( GetProcessHeap(), 0, 30 * sizeof(WCHAR) );
-
- if (buf == NULL) return FALSE;
- snprintfW( buf, 30, usbpdoW, last_pdo_num++ );
- 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)
- {
- ((struct PdoExtension *)usbdev->DeviceExtension)->instance = inst;
- usbdev->Flags |= DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE;
- usbdev->Flags &= ~DO_DEVICE_INITIALIZING;
- }
- RtlFreeUnicodeString( &pdo_name );
- return usbdev;
-}
-
-static void register_root_hub_device( DEVICE_OBJECT *dev, unsigned int instance_id )
-{
- static const WCHAR root_hub_idW[] = {'U','S','B',
- '\\','R','O','O','T','_','H','U','B',
- '\\','%','u',0};
-
- HDEVINFO set;
- SP_DEVINFO_DATA devInfo;
- WCHAR *devnameW;
- ULONG size;
- BOOL ret;
- UNICODE_STRING link;
- NTSTATUS status;
-
- size = sizeof(root_hub_idW) + 16 * sizeof(WCHAR);
- devnameW = HeapAlloc( GetProcessHeap(), 0, size );
- if (devnameW == NULL) return;
- snprintfW( devnameW, size / sizeof(WCHAR), root_hub_idW, instance_id );
-
- set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
- if (set == INVALID_HANDLE_VALUE) goto done;
- devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
- ret = SetupDiCreateDeviceInfoW( set, devnameW, &GUID_DEVCLASS_USB,
- NULL, NULL, 0, &devInfo );
- if (ret)
- {
- ret = SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL );
- if (!ret) goto done;
- }
- else if (ERROR_DEVINST_ALREADY_EXISTS != GetLastError()) goto done;
-
- status = IoRegisterDeviceInterface( dev, &GUID_DEVINTERFACE_USB_HUB,
- NULL, &link );
- if (status == STATUS_SUCCESS)
- {
- IoSetDeviceInterfaceState( &link, TRUE );
- RtlFreeUnicodeString( &link );
- }
-done:
- if (set != INVALID_HANDLE_VALUE)
- SetupDiDestroyDeviceInfoList( set );
- HeapFree( GetProcessHeap(), 0, devnameW );
-}
-
-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;
-
- list_add_tail( &Devices, &instance->entry );
- ((struct PdoExtension *)hubdev->DeviceExtension)->instance = instance;
- hubdev->Flags |= DO_POWER_PAGABLE;
- hubdev->Flags &= ~DO_DEVICE_INITIALIZING;
- register_root_hub_device( hubdev, instance_id );
- ++instance_id;
- 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)
-{
- 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, usbW, 0, DIGCF_ALLCLASSES );
- if (set == INVALID_HANDLE_VALUE) return FALSE;
-
- while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
- {
- /* get VID, PID and 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 = strstr( buf, "VID_" );
- if (str != NULL)
- {
- str += 4;
- vid = strtol( str, NULL, 16 );
- str = strstr( str, "PID_" );
- }
- if (str == NULL)
- {
- HeapFree( GetProcessHeap(), 0, buf );
- continue;
- }
- str += 4;
- pid = strtol( str, NULL, 16 );
- str = strrchr( str, '\\' );
- 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)
- {
- HeapFree( GetProcessHeap(), 0, buf );
- buf = NULL;
- }
-
- /* 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 );
- HeapFree( GetProcessHeap(), 0, instance );
- }
- return FALSE;
-}
-
-static char *new_instance_id( USHORT vid, USHORT pid )
-{
- struct DeviceInstance *instance;
- char *p, *prefix = NULL;
- unsigned int id = 0, n, prefix_len = 0;
- char *ret;
-
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (vid == instance->vid && pid == instance->pid)
- {
- if (prefix == NULL)
- {
- prefix = instance->instance_id;
- p = strrchr( instance->instance_id, '&' );
- if (p == NULL) prefix_len = 0;
- else prefix_len = p + 1 - prefix;
- id = strtoul( prefix + prefix_len, NULL, 10 ) + 1;
- }
- else
- {
- p = strrchr( instance->instance_id, '&' );
- if (prefix_len)
- {
- if (p == NULL || p + 1 - instance->instance_id != prefix_len ||
- strncmp( instance->instance_id, prefix, prefix_len ))
- continue;
- }
- else if (p != NULL) continue;
- n = strtoul( instance->instance_id + prefix_len, NULL, 10 ) + 1;
- if (n > id) id = n;
- }
- }
- }
- ret = HeapAlloc( GetProcessHeap(), 0, prefix_len + 16 );
- if (ret == NULL) return NULL;
- memcpy( ret, prefix, prefix_len );
- snprintf( ret + prefix_len, prefix_len + 16, "%d", id );
- return ret;
-}
-
-#ifdef HAVE_LIBUSB_H
-
-static BOOL is_mass_storage( libusb_device *dev )
-{
- struct libusb_config_descriptor *conf;
- int i, k;
- BOOL ret = FALSE;
-
- if (libusb_get_active_config_descriptor( dev, &conf ))
- return FALSE;
- for (i = 0; !ret && i < conf->bNumInterfaces; ++i)
- for (k = 0; !ret && k < conf->interface[i].num_altsetting; ++k)
- if (conf->interface[i].altsetting[k].bInterfaceClass == 8)
- ret = TRUE;
- libusb_free_config_descriptor( conf );
- return ret;
-}
-
-#else
-
-static BOOL is_mass_storage( struct usb_device *dev )
-{
- struct usb_config_descriptor *conf = &dev->config[0];
- int i, k;
- BOOL ret = FALSE;
-
- for (i = 0; !ret && i < conf->bNumInterfaces; ++i)
- for (k = 0; !ret && k < conf->interface[i].num_altsetting; ++k)
- if (conf->interface[i].altsetting[k].bInterfaceClass == 8)
- ret = TRUE;
- return ret;
-}
-
-#endif
-
-static void register_usb_device( USHORT vid, USHORT pid, void *dev )
-{
- static const WCHAR id_fmtW[] = {'U','S','B',
- '\\','V','i','d','_','%','0','4','x',
- '&','P','i','d','_','%','0','4','x',
- '\\','%','s',0};
- static const WCHAR driverW[] = {'{','3','6','F','C','9','E','6','0','-',
- 'C','4','6','5','-','1','1','C','F','-',
- '8','0','5','6','-','4','4','4','5',
- '5','3','5','4','0','0','0','0','}',
- '\\','0','0','0','0',0};
-
- struct DeviceInstance *instance;
- HDEVINFO set = INVALID_HANDLE_VALUE;
- SP_DEVINFO_DATA devInfo;
- WCHAR *devnameW = NULL, *instance_idW = NULL;
- char *instance_id;
- ULONG size;
-
- instance_id = new_instance_id( vid, pid );
- if (instance_id == NULL) return;
-
- instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
- if (instance == NULL)
- {
- HeapFree( GetProcessHeap(), 0, instance_id );
- goto done;
- }
- instance->vid = vid;
- instance->pid = pid;
- instance->instance_id = instance_id;
- instance->service = NULL;
- instance->dev = dev;
- list_add_tail( &Devices, &instance->entry );
-
- size = (strlen(instance_id) + 1) * sizeof(WCHAR);
- instance_idW = HeapAlloc( GetProcessHeap(), 0, size );
- if (instance_idW == NULL) goto done;
- RtlMultiByteToUnicodeN( instance_idW, size, NULL,
- instance_id, strlen(instance_id) + 1 );
-
- size = sizeof(id_fmtW) + (strlenW(instance_idW) - 2) * sizeof(WCHAR);
- devnameW = HeapAlloc( GetProcessHeap(), 0, size );
- if (devnameW == NULL) goto done;
- snprintfW( devnameW, size / sizeof(WCHAR), id_fmtW, vid, pid, instance_idW );
-
- set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
- if (set == INVALID_HANDLE_VALUE) goto done;
- devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
- if (SetupDiCreateDeviceInfoW( set, devnameW, &GUID_DEVCLASS_USB,
- NULL, NULL, 0, &devInfo ))
- {
- SetupDiRegisterDeviceInfo( set, &devInfo, 0, NULL, NULL, NULL );
- /* This is need for Consultant+ for flash drive */
- if (is_mass_storage( dev ))
- SetupDiSetDeviceRegistryPropertyW( set, &devInfo, SPDRP_DRIVER,
- (BYTE *)driverW, sizeof(driverW) );
- }
-done:
- if (set != INVALID_HANDLE_VALUE)
- SetupDiDestroyDeviceInfoList( set );
- if (devnameW) HeapFree( GetProcessHeap(), 0, devnameW );
- if (instance_idW) HeapFree( GetProcessHeap(), 0, instance_idW );
-}
-
-static void start_root_devices( DRIVER_OBJECT *driver_obj )
-{
- static const WCHAR rootW[] = {'r','o','o','t',0};
-
- SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
- HDEVINFO set;
- DRIVER_OBJECT *driver;
- DEVICE_OBJECT *pdo;
- NTSTATUS status;
- DWORD size, i = 0;
- WCHAR *serviceW;
-
- set = SetupDiGetClassDevsW( NULL, rootW, 0, DIGCF_ALLCLASSES );
- if (set == INVALID_HANDLE_VALUE) return;
- while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
- {
- SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_SERVICE,
- NULL, NULL, 0, &size );
- serviceW = HeapAlloc( GetProcessHeap(), 0, size );
- if (serviceW == NULL) break;
- if (SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_SERVICE,
- NULL, (BYTE *)serviceW, size, NULL ) && start_service( serviceW ))
- {
- status = IoCreateDevice( driver_obj, 0, NULL, 0, 0, FALSE, &pdo );
- if (status == STATUS_SUCCESS)
- {
- while (!(driver = __wine_get_driver_object( serviceW )))
- Sleep( 100 );
- status = __wine_add_device( driver, pdo );
- if (status == STATUS_SUCCESS && pdo->AttachedDevice != NULL)
- __wine_start_device( pdo->AttachedDevice );
- }
- }
- HeapFree( GetProcessHeap(), 0, serviceW );
- }
- SetupDiDestroyDeviceInfoList( set );
-}
-
-static void start_device_drivers( DRIVER_OBJECT *hubdrv )
-{
- struct DeviceInstance *instance;
- DRIVER_OBJECT *driver;
- DEVICE_OBJECT *pdo;
- NTSTATUS status;
-
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->service == NULL || instance->dev == NULL) continue;
- if (start_service( instance->service ))
- {
- pdo = create_pdo( instance, hubdrv );
- if (pdo == NULL) continue;
- while (!(driver = __wine_get_driver_object(
- instance->service )))
- Sleep( 100 );
- status = __wine_add_device( driver, pdo );
- if (status == STATUS_SUCCESS && pdo->AttachedDevice != NULL)
- __wine_start_device( pdo->AttachedDevice );
- }
- }
-}
-
-static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
-{
- static const WCHAR usbhub_started_eventW[] = {'_','_','w','i','n','e',
- '_','U','s','b','h','u','b',
- 'S','t','a','r','t','e','d',0};
-
-#ifdef HAVE_LIBUSB_H
- libusb_device **devs, *dev;
- struct libusb_device_descriptor desc;
- unsigned int i = 0;
-#else
- struct usb_device *dev;
- struct usb_bus *bus;
- struct usb_device_descriptor *desc;
-#endif
- struct DeviceInstance *instance;
- HANDLE event;
- BOOL new_device;
-
- if (!enum_reg_usb_devices())
- {
- ERR( "failed to enumerate USB devices\n" );
- goto end;
- }
-
-#ifdef HAVE_LIBUSB_H
- if (libusb_init( NULL ))
- {
- ERR( "failed to initialize libusb\n" );
- goto end;
- }
- if (libusb_get_device_list( NULL, &devs ) < 0)
- {
- libusb_exit( NULL );
- goto end;
- }
- while ((dev = devs[i++]))
- {
- if (libusb_get_device_descriptor( dev, &desc ))
- {
- ERR( "failed to get USB device descriptor\n" );
- continue;
- }
- libusb_ref_device( dev );
- if (libusb_get_device_address( dev ) == 1)
- {
- create_root_hub_device( desc.idVendor, desc.idProduct, dev, usbhubdrv );
- continue;
- }
- new_device = TRUE;
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->dev == NULL && desc.idVendor == instance->vid &&
- desc.idProduct == instance->pid)
- {
- instance->dev = dev;
- new_device = FALSE;
- break;
- }
- }
- if (new_device)
- register_usb_device( desc.idVendor, desc.idProduct, dev );
- }
- libusb_free_device_list( devs, 1 );
-#else
- usb_init();
- usb_find_busses();
- usb_find_devices();
-
- for (bus = usb_busses; bus; bus = bus->next)
- for (dev = bus->devices; dev; dev = dev->next)
- {
- if (dev->devnum > 1) continue;
- desc = &bus->devices->descriptor;
- create_root_hub_device( desc->idVendor, desc->idProduct,
- bus->devices, usbhubdrv );
- }
- for (bus = usb_busses; bus; bus = bus->next)
- for (dev = bus->devices; dev; dev = dev->next)
- {
- if (dev->devnum <= 1) continue;
- new_device = TRUE;
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->dev == NULL &&
- dev->descriptor.idVendor == instance->vid &&
- dev->descriptor.idProduct == instance->pid)
- {
- instance->dev = dev;
- new_device = FALSE;
- break;
- }
- }
- if (new_device)
- register_usb_device( dev->descriptor.idVendor,
- dev->descriptor.idProduct, dev );
- }
-#endif
- start_root_devices( usbhubdrv );
- start_device_drivers( usbhubdrv );
-end:
- event = CreateEventW( NULL, TRUE, FALSE, usbhub_started_eventW );
- SetEvent( event );
- CloseHandle( event );
- return 0;
-}
-
-#endif
-
-NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
-{
-#ifdef HAVE_LIBUSB
- HANDLE thread;
-
- driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = usbhub_ioctl;
- driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = usbhub_internal_ioctl;
- driver->MajorFunction[IRP_MJ_PNP] = 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
deleted file mode 100644
index 76421d7..0000000
--- a/dlls/usbhub.sys/usbhub.sys.spec
+++ /dev/null
@@ -1 +0,0 @@
-# nothing to export
diff --git a/programs/services/services.c b/programs/services/services.c
index 12b4437..9743c25 100644
--- a/programs/services/services.c
+++ b/programs/services/services.c
@@ -254,7 +254,7 @@ static void scmdatabase_autostart_services(struct scmdatabase *db)
#ifdef HAVE_LIBUSB
static const WCHAR usbhub_started_event[] = {'_','_','w','i','n','e',
'_','U','s','b','h','u','b','S','t','a','r','t','e','d',0};
- static const WCHAR usbhub[] = {'U','s','b','h','u','b',0};
+ static const WCHAR mountmgr[] = {'M','o','u','n','t','M','g','r',0};
#endif
struct service_entry **services_list;
unsigned int i = 0;
@@ -302,7 +302,7 @@ static void scmdatabase_autostart_services(struct scmdatabase *db)
argv[0] = service->name;
argv[1] = NULL;
#ifdef HAVE_LIBUSB
- if (!strcmpW(service->name, usbhub))
+ if (!strcmpW(service->name, mountmgr))
event = CreateEventW(NULL, TRUE, FALSE, usbhub_started_event);
#endif
err = service_start(service, 1, argv);
diff --git a/tools/wine.inf.in b/tools/wine.inf.in
index 395c6db..8f94c06 100644
--- a/tools/wine.inf.in
+++ b/tools/wine.inf.in
@@ -127,17 +127,13 @@ AddReg=\
[DefaultInstall.Services]
AddService=MountMgr,0x800,MountMgrService
-AddService=Parport,0,ParPortService
AddService=Spooler,0,SpoolerService
-AddService=Usbhub,0,UsbhubService
AddService=TermService,0,TerminalServices
AddService=PlugPlay,0,PlugPlayService
[DefaultInstall.NT.Services]
AddService=MountMgr,0x800,MountMgrService
-AddService=Parport,0,ParPortService
AddService=Spooler,0,SpoolerService
-AddService=Usbhub,0,UsbhubService
AddService=TermService,0,TerminalServices
AddService=PlugPlay,0,PlugPlayService
@@ -2608,8 +2604,6 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G"
11,,notepad.exe
11,,winetest.exe,-
12,,mountmgr.sys
-12,,parport.sys
-12,,usbhub.sys
10,Microsoft.NET\Framework\v1.1.4322,aspnet_regiis.exe
10,Microsoft.NET\Framework\v1.1.4322,ngen.exe
10,Microsoft.NET\Framework\v1.1.4322,fusion.dll
@@ -3010,12 +3004,6 @@ ServiceType=1
StartType=2
ErrorControl=1
-[ParPortService]
-ServiceBinary="%12%\parport.sys"
-ServiceType=1
-StartType=2
-ErrorControl=1
-
[SpoolerService]
Description="Loads files to memory for later printing"
DisplayName="Print Spooler"
@@ -3025,12 +3013,6 @@ StartType=4
ErrorControl=1
LoadOrderGroup="SpoolerGroup"
-[UsbhubService]
-ServiceBinary="%12%\usbhub.sys"
-ServiceType=1
-StartType=2
-ErrorControl=1
-
[TerminalServices]
Description="Remote desktop access"
DisplayName="Terminal Services"
--
1.7.4.1
----------- следующая часть -----------
From aca1800ca905c45c7b5aea9969e2db23d8a29328 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Wed, 9 Feb 2011 17:44:00 +0300
Subject: [eterhack 02/20] mountmgr.sys: Fix enumerating USB devices with libusb-0.1 (eterbug #4301).
---
dlls/mountmgr.sys/usbhub.c | 15 +++++++--------
1 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 2ec236e..899714f 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -1671,20 +1671,20 @@ static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
for (dev = bus->devices; dev; dev = dev->next)
{
if (dev->devnum > 1) continue;
- desc = &bus->devices->descriptor;
- create_root_hub_device( desc->idVendor, desc->idProduct,
- bus->devices, usbhubdrv );
+ desc = &dev->descriptor;
+ create_root_hub_device( desc->idVendor, desc->idProduct, dev,
+ usbhubdrv );
}
for (bus = usb_busses; bus; bus = bus->next)
for (dev = bus->devices; dev; dev = dev->next)
{
if (dev->devnum <= 1) continue;
+ desc = &dev->descriptor;
new_device = TRUE;
LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
{
- if (instance->dev == NULL &&
- dev->descriptor.idVendor == instance->vid &&
- dev->descriptor.idProduct == instance->pid)
+ if (instance->dev == NULL && desc->idVendor == instance->vid &&
+ desc->idProduct == instance->pid)
{
instance->dev = dev;
new_device = FALSE;
@@ -1692,8 +1692,7 @@ static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
}
}
if (new_device)
- register_usb_device( dev->descriptor.idVendor,
- dev->descriptor.idProduct, dev );
+ register_usb_device( desc->idVendor, desc->idProduct, dev );
}
#endif
start_root_devices( usbhubdrv );
--
1.7.4.1
----------- следующая часть -----------
From 41de9d53fe857c96c3914ed4c31de91049393d24 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 8 Feb 2011 17:50:02 +0300
Subject: [eterhack 03/20] mountmgr.sys: Move WINEAUTOMOUNT check to hal.c (eterbug #4301).
---
dlls/mountmgr.sys/hal.c | 15 +++++++++++++++
dlls/mountmgr.sys/mountmgr.c | 16 +++-------------
2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/dlls/mountmgr.sys/hal.c b/dlls/mountmgr.sys/hal.c
index e87ee0c..1b31fca 100644
--- a/dlls/mountmgr.sys/hal.c
+++ b/dlls/mountmgr.sys/hal.c
@@ -134,6 +134,18 @@ static GUID *parse_uuid( GUID *guid, const char *str )
return NULL;
}
+static int automount_disabled(void)
+{
+ static int disabled = -1;
+
+ if (disabled < 0)
+ {
+ char *automount = getenv( "WINEAUTOMOUNT" );
+ disabled = (automount && !strcmp( automount, "no" ));
+ }
+ return disabled;
+}
+
static int get_num_from_file( const char *path, const char *filename )
{
char *fullpath, str[16];
@@ -182,6 +194,9 @@ static void new_device( LibHalContext *ctx, const char *udi )
p_dbus_error_init( &error );
+ if (automount_disabled())
+ goto done;
+
if (!(device = p_libhal_device_get_property_string( ctx, udi, "block.device", &error )))
goto done;
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index 191d969..20e6dde 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -19,7 +19,6 @@
*/
#include <stdarg.h>
-#include <stdlib.h>
#include <unistd.h>
#define NONAMELESSUNION
@@ -431,13 +430,6 @@ static NTSTATUS WINAPI mountmgr_ioctl( DEVICE_OBJECT *device, IRP *irp )
return status;
}
-static int automount_enabled(void)
-{
- char *automount = getenv( "WINEAUTOMOUNT" );
- if (automount && !strcmp( automount, "no" )) return 0;
- return 1;
-}
-
/* main entry point for the mount point manager driver */
NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
{
@@ -494,10 +486,8 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
RtlInitUnicodeString( &nameW, usbhubW );
status = IoCreateDriver( &nameW, usbhub_driver_entry );
- if (automount_enabled())
- {
- initialize_hal();
- initialize_diskarbitration();
- }
+ initialize_hal();
+ initialize_diskarbitration();
+
return status;
}
--
1.7.4.1
----------- следующая часть -----------
From d6bf99942de8ef877d9711e664af04c226e5656e Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Wed, 9 Feb 2011 15:32:44 +0300
Subject: [eterhack 04/20] mountmgr.sys: Use create_pdo for creating PDO (eterbug #4301).
---
dlls/mountmgr.sys/usbhub.c | 19 +++++++------------
1 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 899714f..73dac2c 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -1206,7 +1206,8 @@ static BOOL create_pdo_name( UNICODE_STRING *pdo_name )
return TRUE;
}
-static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst, DRIVER_OBJECT *hubdrv )
+static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst,
+ DRIVER_OBJECT *hubdrv, ULONG flags )
{
UNICODE_STRING pdo_name;
DEVICE_OBJECT *usbdev = NULL;
@@ -1216,7 +1217,7 @@ static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst, DRIVER_OBJECT *hu
0, 0, FALSE, &usbdev ) == STATUS_SUCCESS)
{
((struct PdoExtension *)usbdev->DeviceExtension)->instance = inst;
- usbdev->Flags |= DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE;
+ usbdev->Flags |= flags;
usbdev->Flags &= ~DO_DEVICE_INITIALIZING;
}
RtlFreeUnicodeString( &pdo_name );
@@ -1273,7 +1274,6 @@ static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
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;
@@ -1285,14 +1285,9 @@ static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
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;
-
+ hubdev = create_pdo( instance, hubdrv, DO_POWER_PAGABLE );
+ if (hubdev == NULL) goto fail;
list_add_tail( &Devices, &instance->entry );
- ((struct PdoExtension *)hubdev->DeviceExtension)->instance = instance;
- hubdev->Flags |= DO_POWER_PAGABLE;
- hubdev->Flags &= ~DO_DEVICE_INITIALIZING;
register_root_hub_device( hubdev, instance_id );
++instance_id;
return;
@@ -1300,7 +1295,6 @@ fail:
if (instance->instance_id)
HeapFree( GetProcessHeap(), 0, instance->instance_id );
HeapFree( GetProcessHeap(), 0, instance );
- RtlFreeUnicodeString( &pdo_name );
return;
}
@@ -1586,7 +1580,8 @@ static void start_device_drivers( DRIVER_OBJECT *hubdrv )
if (instance->service == NULL || instance->dev == NULL) continue;
if (start_service( instance->service ))
{
- pdo = create_pdo( instance, hubdrv );
+ pdo = create_pdo( instance, hubdrv,
+ DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE );
if (pdo == NULL) continue;
while (!(driver = __wine_get_driver_object(
instance->service )))
--
1.7.4.1
----------- следующая часть -----------
From 0ad76ef6b9fdb30cfc4fb224bf3f5e60ba1bb7e5 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 8 Feb 2011 21:21:02 +0300
Subject: [eterhack 05/20] mountmgr.sys: Load drivers for keys plugged in after starting wine (eterbug #4301).
---
dlls/mountmgr.sys/hal.c | 6 ++
dlls/mountmgr.sys/mountmgr.h | 4 +
dlls/mountmgr.sys/usbhub.c | 177 ++++++++++++++++++++++++++++++------------
3 files changed, 138 insertions(+), 49 deletions(-)
diff --git a/dlls/mountmgr.sys/hal.c b/dlls/mountmgr.sys/hal.c
index 1b31fca..a0e8c68 100644
--- a/dlls/mountmgr.sys/hal.c
+++ b/dlls/mountmgr.sys/hal.c
@@ -174,6 +174,7 @@ static int get_num_from_file( const char *path, const char *filename )
static void new_device( LibHalContext *ctx, const char *udi )
{
DBusError error;
+ char *subsys = NULL;
char *parent = NULL;
char *mount_point = NULL;
char *device = NULL;
@@ -194,6 +195,10 @@ static void new_device( LibHalContext *ctx, const char *udi )
p_dbus_error_init( &error );
+ if ((subsys = p_libhal_device_get_property_string( ctx, udi, "info.subsystem", NULL )) &&
+ !strcmp( subsys, "usb_device" ))
+ enum_usb_devices();
+
if (automount_disabled())
goto done;
@@ -258,6 +263,7 @@ static void new_device( LibHalContext *ctx, const char *udi )
else if (guid_ptr) add_volume( udi, device, mount_point, DEVICE_HARDDISK_VOL, guid_ptr );
done:
+ if (subsys) p_libhal_free_string( subsys );
if (type) p_libhal_free_string( type );
if (parent) p_libhal_free_string( parent );
if (device) p_libhal_free_string( device );
diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h
index ba62543..e0571f4 100644
--- a/dlls/mountmgr.sys/mountmgr.h
+++ b/dlls/mountmgr.sys/mountmgr.h
@@ -76,3 +76,7 @@ extern struct mount_point *add_volume_mount_point( DEVICE_OBJECT *device, UNICOD
const GUID *guid );
extern void delete_mount_point( struct mount_point *mount );
extern void set_mount_point_id( struct mount_point *mount, const void *id, unsigned int id_len );
+
+/* usb functions */
+
+extern void enum_usb_devices(void);
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 73dac2c..93d8f94 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -26,6 +26,11 @@
#include <libusb.h>
#elif defined(HAVE_USB_H)
#include <usb.h>
+#undef USB_ENDPOINT_TYPE_MASK
+#undef USB_ENDPOINT_TYPE_CONTROL
+#undef USB_ENDPOINT_TYPE_ISOCHRONOUS
+#undef USB_ENDPOINT_TYPE_BULK
+#undef USB_ENDPOINT_TYPE_INTERRUPT
#endif
#define NONAMELESSUNION
@@ -48,6 +53,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(usbhub);
+#ifdef HAVE_LIBUSB
+
extern NTSTATUS CDECL __wine_add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *dev );
extern DRIVER_OBJECT * CDECL __wine_get_driver_object( const WCHAR *service );
extern NTSTATUS CDECL __wine_start_device( DEVICE_OBJECT *device );
@@ -65,6 +72,7 @@ struct DeviceInstance
USHORT pid;
char *instance_id;
WCHAR *service;
+ DEVICE_OBJECT *pdo;
#ifdef HAVE_LIBUSB_H
libusb_device *dev;
#else
@@ -77,7 +85,18 @@ struct PdoExtension
struct DeviceInstance *instance;
};
-#ifdef HAVE_LIBUSB
+static DRIVER_OBJECT *usbhub_driver;
+
+static CRITICAL_SECTION usbhub_cs;
+static CRITICAL_SECTION_DEBUG usbhub_cs_debug =
+{
+ 0, 0, &usbhub_cs,
+ { &usbhub_cs_debug.ProcessLocksList, &usbhub_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": usbhub_cs") }
+};
+static CRITICAL_SECTION usbhub_cs = { &usbhub_cs_debug, -1, 0, 0, 0, 0 };
+
+static BOOL libusb_initialized;
static void add_data( unsigned char **dst, ULONG *dst_size, const void *src, ULONG src_size )
{
@@ -104,6 +123,7 @@ static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
+ EnterCriticalSection( &usbhub_cs );
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (inst->service) goto done;
irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
@@ -352,6 +372,7 @@ static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
}
done:
+ LeaveCriticalSection( &usbhub_cs );
irp->IoStatus.u.Status = status;
irp->IoStatus.Information = info;
IoCompleteRequest( irp, IO_NO_INCREMENT );
@@ -370,6 +391,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
+ EnterCriticalSection( &usbhub_cs );
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (!inst->service) goto done;
irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
@@ -699,6 +721,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
}
done:
+ LeaveCriticalSection( &usbhub_cs );
irp->IoStatus.u.Status = status;
irp->IoStatus.Information = 0;
IoCompleteRequest( irp, IO_NO_INCREMENT );
@@ -717,6 +740,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
+ EnterCriticalSection( &usbhub_cs );
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (!inst->service) goto done;
irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
@@ -1055,6 +1079,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
}
done:
+ LeaveCriticalSection( &usbhub_cs );
irp->IoStatus.u.Status = status;
irp->IoStatus.Information = 0;
IoCompleteRequest( irp, IO_NO_INCREMENT );
@@ -1079,6 +1104,7 @@ static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
+ EnterCriticalSection( &usbhub_cs );
dx = device->DeviceExtension;
irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
switch (irpsp->MinorFunction)
@@ -1150,6 +1176,7 @@ static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
status = STATUS_SUCCESS;
}
+ LeaveCriticalSection( &usbhub_cs );
irp->IoStatus.u.Status = status;
irp->IoStatus.Information = info;
IoCompleteRequest( irp, IO_NO_INCREMENT );
@@ -1273,7 +1300,6 @@ static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
{
static unsigned int instance_id;
struct DeviceInstance *instance = NULL;
- DEVICE_OBJECT *hubdev;
instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
if (instance == NULL) return;
@@ -1285,10 +1311,10 @@ static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
instance->service = NULL;
instance->dev = dev;
- hubdev = create_pdo( instance, hubdrv, DO_POWER_PAGABLE );
- if (hubdev == NULL) goto fail;
+ instance->pdo = create_pdo( instance, hubdrv, DO_POWER_PAGABLE );
+ if (instance->pdo == NULL) goto fail;
list_add_tail( &Devices, &instance->entry );
- register_root_hub_device( hubdev, instance_id );
+ register_root_hub_device( instance->pdo, instance_id );
++instance_id;
return;
fail:
@@ -1367,6 +1393,7 @@ static BOOL enum_reg_usb_devices(void)
instance->pid = pid;
instance->instance_id = instance_id;
instance->service = (WCHAR *)buf;
+ instance->pdo = NULL;
instance->dev = NULL;
list_add_tail( &Devices, &instance->entry );
instance_id = NULL;
@@ -1497,6 +1524,7 @@ static void register_usb_device( USHORT vid, USHORT pid, void *dev )
instance->pid = pid;
instance->instance_id = instance_id;
instance->service = NULL;
+ instance->pdo = NULL;
instance->dev = dev;
list_add_tail( &Devices, &instance->entry );
@@ -1572,74 +1600,70 @@ static void start_device_drivers( DRIVER_OBJECT *hubdrv )
{
struct DeviceInstance *instance;
DRIVER_OBJECT *driver;
- DEVICE_OBJECT *pdo;
+ DEVICE_OBJECT *dev;
NTSTATUS status;
LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
{
- if (instance->service == NULL || instance->dev == NULL) continue;
+ if (instance->service == NULL || instance->dev == NULL ||
+ instance->pdo != NULL) continue;
if (start_service( instance->service ))
{
- pdo = create_pdo( instance, hubdrv,
+ instance->pdo = create_pdo( instance, hubdrv,
DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE );
- if (pdo == NULL) continue;
- while (!(driver = __wine_get_driver_object(
- instance->service )))
+ if (instance->pdo == NULL) continue;
+ while (!(driver = __wine_get_driver_object( instance->service )))
Sleep( 100 );
- status = __wine_add_device( driver, pdo );
- if (status == STATUS_SUCCESS && pdo->AttachedDevice != NULL)
- __wine_start_device( pdo->AttachedDevice );
+ status = __wine_add_device( driver, instance->pdo );
+ dev = instance->pdo->AttachedDevice;
+ if (status == STATUS_SUCCESS && dev != NULL)
+ __wine_start_device( dev );
}
}
}
-static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
+static BOOL is_new( void *dev )
{
- static const WCHAR usbhub_started_eventW[] = {'_','_','w','i','n','e',
- '_','U','s','b','h','u','b',
- 'S','t','a','r','t','e','d',0};
+ struct DeviceInstance *instance;
+
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ if (instance->dev == dev)
+ return FALSE;
+ return TRUE;
+}
#ifdef HAVE_LIBUSB_H
+
+static int initialize_libusb(void)
+{
+ return libusb_init( NULL );
+}
+
+void enum_usb_devices(void)
+{
libusb_device **devs, *dev;
struct libusb_device_descriptor desc;
unsigned int i = 0;
-#else
- struct usb_device *dev;
- struct usb_bus *bus;
- struct usb_device_descriptor *desc;
-#endif
struct DeviceInstance *instance;
- HANDLE event;
BOOL new_device;
- if (!enum_reg_usb_devices())
- {
- ERR( "failed to enumerate USB devices\n" );
+ EnterCriticalSection( &usbhub_cs );
+ if (!libusb_initialized || libusb_get_device_list( NULL, &devs ) < 0)
goto end;
- }
-
-#ifdef HAVE_LIBUSB_H
- if (libusb_init( NULL ))
- {
- ERR( "failed to initialize libusb\n" );
- goto end;
- }
- if (libusb_get_device_list( NULL, &devs ) < 0)
- {
- libusb_exit( NULL );
- goto end;
- }
while ((dev = devs[i++]))
{
+ if (!is_new( dev ))
+ continue;
if (libusb_get_device_descriptor( dev, &desc ))
{
ERR( "failed to get USB device descriptor\n" );
continue;
}
+ TRACE( "add %04x:%04x\n", desc.idVendor, desc.idProduct );
libusb_ref_device( dev );
if (libusb_get_device_address( dev ) == 1)
{
- create_root_hub_device( desc.idVendor, desc.idProduct, dev, usbhubdrv );
+ create_root_hub_device( desc.idVendor, desc.idProduct, dev, usbhub_driver );
continue;
}
new_device = TRUE;
@@ -1657,24 +1681,47 @@ static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
register_usb_device( desc.idVendor, desc.idProduct, dev );
}
libusb_free_device_list( devs, 1 );
+ start_device_drivers( usbhub_driver );
+end:
+ LeaveCriticalSection( &usbhub_cs );
+}
+
#else
+
+static int initialize_libusb(void)
+{
usb_init();
+ return 0;
+}
+
+void enum_usb_devices(void)
+{
+ struct usb_device *dev;
+ struct usb_bus *bus;
+ struct usb_device_descriptor *desc;
+ struct DeviceInstance *instance;
+ BOOL new_device;
+
+ EnterCriticalSection( &usbhub_cs );
+ if (!libusb_initialized)
+ goto end;
usb_find_busses();
usb_find_devices();
-
for (bus = usb_busses; bus; bus = bus->next)
for (dev = bus->devices; dev; dev = dev->next)
{
- if (dev->devnum > 1) continue;
+ if (dev->devnum > 1 || !is_new( dev )) continue;
desc = &dev->descriptor;
+ TRACE( "add %04x:%04x\n", desc->idVendor, desc->idProduct );
create_root_hub_device( desc->idVendor, desc->idProduct, dev,
- usbhubdrv );
+ usbhub_driver );
}
for (bus = usb_busses; bus; bus = bus->next)
for (dev = bus->devices; dev; dev = dev->next)
{
- if (dev->devnum <= 1) continue;
+ if (dev->devnum <= 1 || !is_new( dev )) continue;
desc = &dev->descriptor;
+ TRACE( "add %04x:%04x\n", desc->idVendor, desc->idProduct );
new_device = TRUE;
LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
{
@@ -1689,10 +1736,41 @@ static DWORD CALLBACK enum_usb_devices( void *usbhubdrv )
if (new_device)
register_usb_device( desc->idVendor, desc->idProduct, dev );
}
-#endif
- start_root_devices( usbhubdrv );
- start_device_drivers( usbhubdrv );
+ start_device_drivers( usbhub_driver );
end:
+ LeaveCriticalSection( &usbhub_cs );
+}
+
+#endif
+
+#else
+
+void enum_usb_devices(void)
+{
+}
+
+#endif
+
+#ifdef HAVE_LIBUSB
+
+static DWORD CALLBACK initialize_usbhub( void *arg )
+{
+ static const WCHAR usbhub_started_eventW[] = {'_','_','w','i','n','e',
+ '_','U','s','b','h','u','b',
+ 'S','t','a','r','t','e','d',0};
+
+ HANDLE event;
+
+ start_root_devices( usbhub_driver );
+ EnterCriticalSection( &usbhub_cs );
+ if (!enum_reg_usb_devices())
+ ERR( "failed to enumerate USB devices\n" );
+ else if (initialize_libusb())
+ ERR( "failed to initialize libusb\n" );
+ else
+ libusb_initialized = TRUE;
+ LeaveCriticalSection( &usbhub_cs );
+ enum_usb_devices();
event = CreateEventW( NULL, TRUE, FALSE, usbhub_started_eventW );
SetEvent( event );
CloseHandle( event );
@@ -1706,11 +1784,12 @@ NTSTATUS WINAPI usbhub_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path
#ifdef HAVE_LIBUSB
HANDLE thread;
+ usbhub_driver = driver;
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = usbhub_ioctl;
driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = usbhub_internal_ioctl;
driver->MajorFunction[IRP_MJ_PNP] = usbhub_dispatch_pnp;
- thread = CreateThread( NULL, 0, enum_usb_devices, driver, 0, NULL );
+ thread = CreateThread( NULL, 0, initialize_usbhub, NULL, 0, NULL );
if (!thread) return STATUS_UNSUCCESSFUL;
CloseHandle( thread );
#else
--
1.7.4.1
----------- следующая часть -----------
From cbdd5731d99b9111616559c9a489542d29a8471e Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 10 Feb 2011 17:02:42 +0300
Subject: [eterhack 06/20] ntoskrnl.exe: Add stub for IoDetachDevice (eterbug #4301).
---
dlls/ntoskrnl.exe/ntoskrnl.c | 9 +++++++++
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +-
include/ddk/wdm.h | 1 +
3 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 60bc6dd..a6e6b5e 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -1161,6 +1161,15 @@ PDEVICE_OBJECT WINAPI IoAttachDeviceToDeviceStack( DEVICE_OBJECT *source,
/***********************************************************************
+ * IoDetachDevice (NTOSKRNL.EXE.@)
+ */
+void WINAPI IoDetachDevice( DEVICE_OBJECT *device )
+{
+ FIXME( "stub: %p\n", device );
+}
+
+
+/***********************************************************************
* IoBuildDeviceIoControlRequest (NTOSKRNL.EXE.@)
*/
PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 3e21d5a..dd379fe 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -356,7 +356,7 @@
@ stdcall IoDeleteDevice(ptr)
@ stdcall IoDeleteDriver(ptr)
@ stdcall IoDeleteSymbolicLink(ptr)
-@ stub IoDetachDevice
+@ stdcall IoDetachDevice(ptr)
@ stub IoDeviceHandlerObjectSize
@ stub IoDeviceHandlerObjectType
@ stub IoDeviceObjectType
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 40a331c..27d96f9 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1191,6 +1191,7 @@ NTSTATUS WINAPI IoCreateSymbolicLink(UNICODE_STRING*,UNICODE_STRING*);
void WINAPI IoDeleteDevice(DEVICE_OBJECT*);
void WINAPI IoDeleteDriver(DRIVER_OBJECT*);
NTSTATUS WINAPI IoDeleteSymbolicLink(UNICODE_STRING*);
+void WINAPI IoDetachDevice(DEVICE_OBJECT*);
void WINAPI IoFreeIrp(IRP*);
PDEVICE_OBJECT WINAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT);
PEPROCESS WINAPI IoGetCurrentProcess(void);
--
1.7.4.1
----------- следующая часть -----------
From 678b55777f6c23c0e956dde6280407f3d49a5dfc Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 10 Feb 2011 21:13:06 +0300
Subject: [eterhack 07/20] mountmgr.sys: Fix return value (eterbug #4301).
---
dlls/mountmgr.sys/usbhub.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 93d8f94..22cc411 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -1181,7 +1181,7 @@ static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
irp->IoStatus.Information = info;
IoCompleteRequest( irp, IO_NO_INCREMENT );
- return STATUS_SUCCESS;
+ return status;
}
static BOOL start_service( const WCHAR *name )
--
1.7.4.1
----------- следующая часть -----------
From 5fe95791d917ef084585e4dd10a82f1678d0a78d Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 22 Feb 2011 17:41:53 +0300
Subject: [eterhack 08/20] mountmgr.sys: Add support for removing USB devices (eterbug #4301).
---
dlls/mountmgr.sys/hal.c | 3 +-
dlls/mountmgr.sys/mountmgr.h | 3 +-
dlls/mountmgr.sys/usbhub.c | 215 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 213 insertions(+), 8 deletions(-)
diff --git a/dlls/mountmgr.sys/hal.c b/dlls/mountmgr.sys/hal.c
index a0e8c68..889d2b7 100644
--- a/dlls/mountmgr.sys/hal.c
+++ b/dlls/mountmgr.sys/hal.c
@@ -197,7 +197,7 @@ static void new_device( LibHalContext *ctx, const char *udi )
if ((subsys = p_libhal_device_get_property_string( ctx, udi, "info.subsystem", NULL )) &&
!strcmp( subsys, "usb_device" ))
- enum_usb_devices();
+ add_usb_devices();
if (automount_disabled())
goto done;
@@ -285,6 +285,7 @@ static void removed_device( LibHalContext *ctx, const char *udi )
TRACE( "removed %s\n", wine_dbgstr_a(udi) );
+ remove_usb_devices();
if (!remove_dos_device( -1, udi ))
{
p_dbus_error_init( &error );
diff --git a/dlls/mountmgr.sys/mountmgr.h b/dlls/mountmgr.sys/mountmgr.h
index e0571f4..2e97272 100644
--- a/dlls/mountmgr.sys/mountmgr.h
+++ b/dlls/mountmgr.sys/mountmgr.h
@@ -79,4 +79,5 @@ extern void set_mount_point_id( struct mount_point *mount, const void *id, unsig
/* usb functions */
-extern void enum_usb_devices(void);
+extern void add_usb_devices(void);
+extern void remove_usb_devices(void);
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 22cc411..8812f79 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -98,6 +98,16 @@ static CRITICAL_SECTION usbhub_cs = { &usbhub_cs_debug, -1, 0, 0, 0, 0 };
static BOOL libusb_initialized;
+static BOOL device_exists( DEVICE_OBJECT *device )
+{
+ struct DeviceInstance *instance;
+
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ if (instance->pdo == device)
+ return TRUE;
+ return FALSE;
+}
+
static void add_data( unsigned char **dst, ULONG *dst_size, const void *src, ULONG src_size )
{
int copy;
@@ -124,6 +134,7 @@ static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
EnterCriticalSection( &usbhub_cs );
+ if (!device_exists( device )) goto done;
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (inst->service) goto done;
irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
@@ -392,6 +403,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
EnterCriticalSection( &usbhub_cs );
+ if (!device_exists( device )) goto done;
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (!inst->service) goto done;
irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
@@ -741,6 +753,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
EnterCriticalSection( &usbhub_cs );
+ if (!device_exists( device )) goto done;
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (!inst->service) goto done;
irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
@@ -1099,14 +1112,21 @@ static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
struct PdoExtension *dx;
IO_STACK_LOCATION *irpsp;
- NTSTATUS status;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG_PTR info = 0;
TRACE( "%p, %p\n", device, irp );
EnterCriticalSection( &usbhub_cs );
- dx = device->DeviceExtension;
irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ if (!device_exists( device ))
+ {
+ if (irpsp->MinorFunction == IRP_MN_SURPRISE_REMOVAL ||
+ irpsp->MinorFunction == IRP_MN_REMOVE_DEVICE)
+ status = STATUS_SUCCESS;
+ goto done;
+ }
+ dx = device->DeviceExtension;
switch (irpsp->MinorFunction)
{
case IRP_MN_QUERY_DEVICE_RELATIONS:
@@ -1176,6 +1196,7 @@ static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
status = STATUS_SUCCESS;
}
+done:
LeaveCriticalSection( &usbhub_cs );
irp->IoStatus.u.Status = status;
irp->IoStatus.Information = info;
@@ -1219,6 +1240,28 @@ static BOOL start_service( const WCHAR *name )
return ret;
}
+static void stop_service( const WCHAR *name )
+{
+ SC_HANDLE scm, service;
+ SERVICE_STATUS ss;
+
+ scm = OpenSCManagerA( NULL, NULL, SC_MANAGER_ALL_ACCESS );
+ if (scm == NULL)
+ return;
+
+ service = OpenServiceW( scm, name, SERVICE_ALL_ACCESS );
+ if (service == NULL)
+ {
+ CloseServiceHandle( scm );
+ return;
+ }
+
+ ControlService( service, SERVICE_CONTROL_STOP, &ss );
+
+ CloseServiceHandle( service );
+ CloseServiceHandle( scm );
+}
+
static BOOL create_pdo_name( UNICODE_STRING *pdo_name )
{
static const WCHAR usbpdoW[] = {'\\','D','e','v','i','c','e','\\',
@@ -1622,6 +1665,72 @@ static void start_device_drivers( DRIVER_OBJECT *hubdrv )
}
}
+static NTSTATUS call_pnp_func( DEVICE_OBJECT *device, UCHAR minor_func )
+{
+ DRIVER_OBJECT *driver = device->DriverObject;
+ IO_STACK_LOCATION *irpsp;
+ PIRP irp;
+ NTSTATUS status;
+
+ if (driver->MajorFunction[IRP_MJ_PNP] == NULL)
+ return STATUS_NOT_SUPPORTED;
+ irp = IoAllocateIrp( device->StackSize, FALSE );
+ if (irp == NULL) return STATUS_NO_MEMORY;
+
+ irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irp->RequestorMode = KernelMode;
+ irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
+ irpsp->MajorFunction = IRP_MJ_PNP;
+ irpsp->MinorFunction = minor_func;
+ irpsp->DeviceObject = device;
+ device->CurrentIrp = irp;
+ status = IoCallDriver( device, irp );
+ IoFreeIrp( irp );
+ return status;
+}
+
+static void stop_device_driver( struct DeviceInstance *instance )
+{
+ if (instance->pdo)
+ {
+ NTSTATUS status;
+ DEVICE_OBJECT *attd = instance->pdo->AttachedDevice;
+ DEVICE_OBJECT *dev = (attd != NULL) ? attd : instance->pdo;
+
+ status = call_pnp_func( dev, IRP_MN_SURPRISE_REMOVAL );
+ if (status != STATUS_SUCCESS)
+ WARN( "handling IRP_MN_SURPRISE_REMOVAL failed: %08x\n", status );
+ status = call_pnp_func( dev, IRP_MN_REMOVE_DEVICE );
+ if (status != STATUS_SUCCESS)
+ WARN( "handling IRP_MN_REMOVE_DEVICE failed: %08x\n", status );
+ IoDeleteDevice( instance->pdo );
+ }
+ if (instance->service)
+ {
+ struct DeviceInstance *it;
+ BOOL stop = TRUE;
+
+ EnterCriticalSection( &usbhub_cs );
+ LIST_FOR_EACH_ENTRY( it, &Devices, struct DeviceInstance, entry )
+ if (it->pdo != NULL && it->service != NULL &&
+ !strcmpiW( it->service, instance->service ))
+ {
+ stop = FALSE;
+ break;
+ }
+ LeaveCriticalSection( &usbhub_cs );
+ if (stop)
+ stop_service( instance->service );
+ }
+ else
+ HeapFree( GetProcessHeap(), 0, instance->instance_id );
+#ifdef HAVE_LIBUSB_H
+ libusb_unref_device( instance->dev );
+#endif
+ list_remove( &instance->entry );
+ HeapFree( GetProcessHeap(), 0, instance );
+}
+
static BOOL is_new( void *dev )
{
struct DeviceInstance *instance;
@@ -1632,6 +1741,24 @@ static BOOL is_new( void *dev )
return TRUE;
}
+static int add_to_remove_list( struct DeviceInstance *it, struct list *remove )
+{
+ struct DeviceInstance *copy;
+
+ if (it->service)
+ {
+ copy = HeapAlloc( GetProcessHeap(), 0, sizeof(*copy) );
+ if (!copy) return 1;
+ memcpy( copy, it, sizeof(struct DeviceInstance) );
+ copy->pdo = NULL;
+ copy->dev = NULL;
+ list_add_tail( &Devices, ©->entry);
+ }
+ list_remove( &it->entry );
+ list_add_tail( remove, &it->entry );
+ return 0;
+}
+
#ifdef HAVE_LIBUSB_H
static int initialize_libusb(void)
@@ -1639,7 +1766,7 @@ static int initialize_libusb(void)
return libusb_init( NULL );
}
-void enum_usb_devices(void)
+void add_usb_devices(void)
{
libusb_device **devs, *dev;
struct libusb_device_descriptor desc;
@@ -1686,6 +1813,41 @@ end:
LeaveCriticalSection( &usbhub_cs );
}
+void remove_usb_devices(void)
+{
+ struct list remove_list = LIST_INIT(remove_list);
+ libusb_device **devs, *dev;
+ struct DeviceInstance *it, *next;
+ unsigned int i;
+ BOOL found;
+
+ EnterCriticalSection( &usbhub_cs );
+ if (!libusb_initialized || libusb_get_device_list( NULL, &devs ) < 0)
+ goto end;
+ LIST_FOR_EACH_ENTRY_SAFE( it, next, &Devices, struct DeviceInstance, entry )
+ {
+ if (!it->dev)
+ continue;
+ found = FALSE;
+ i = 0;
+ while ((dev = devs[i++]))
+ if (it->dev == dev)
+ {
+ found = TRUE;
+ break;
+ }
+ if (!found && add_to_remove_list( it, &remove_list ))
+ break;
+ }
+end:
+ LeaveCriticalSection( &usbhub_cs );
+ LIST_FOR_EACH_ENTRY_SAFE( it, next, &remove_list, struct DeviceInstance, entry )
+ {
+ TRACE( "remove %04x:%04x\n", it->vid, it->pid );
+ stop_device_driver( it );
+ }
+}
+
#else
static int initialize_libusb(void)
@@ -1694,7 +1856,7 @@ static int initialize_libusb(void)
return 0;
}
-void enum_usb_devices(void)
+void add_usb_devices(void)
{
struct usb_device *dev;
struct usb_bus *bus;
@@ -1741,11 +1903,52 @@ end:
LeaveCriticalSection( &usbhub_cs );
}
+void remove_usb_devices(void)
+{
+ struct list remove_list = LIST_INIT(remove_list);
+ struct usb_device *dev;
+ struct usb_bus *bus;
+ struct DeviceInstance *it, *next;
+ BOOL found;
+
+ EnterCriticalSection( &usbhub_cs );
+ if (!libusb_initialized)
+ goto end;
+ usb_find_busses();
+ usb_find_devices();
+ LIST_FOR_EACH_ENTRY_SAFE( it, next, &Devices, struct DeviceInstance, entry )
+ {
+ if (!it->dev)
+ continue;
+ found = FALSE;
+ for (bus = usb_busses; bus; bus = bus->next)
+ for (dev = bus->devices; dev; dev = dev->next)
+ if (it->dev == dev)
+ {
+ found = TRUE;
+ break;
+ }
+ if (!found && add_to_remove_list( it, &remove_list ))
+ break;
+ }
+end:
+ LeaveCriticalSection( &usbhub_cs );
+ LIST_FOR_EACH_ENTRY_SAFE( it, next, &remove_list, struct DeviceInstance, entry )
+ {
+ TRACE( "remove %04x:%04x\n", it->vid, it->pid );
+ stop_device_driver( it );
+ }
+}
+
#endif
#else
-void enum_usb_devices(void)
+void add_usb_devices(void)
+{
+}
+
+void remove_usb_devices(void)
{
}
@@ -1770,7 +1973,7 @@ static DWORD CALLBACK initialize_usbhub( void *arg )
else
libusb_initialized = TRUE;
LeaveCriticalSection( &usbhub_cs );
- enum_usb_devices();
+ add_usb_devices();
event = CreateEventW( NULL, TRUE, FALSE, usbhub_started_eventW );
SetEvent( event );
CloseHandle( event );
--
1.7.4.1
----------- следующая часть -----------
From 099bcb1b17c04201098cb91783f364d5acf29d00 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 28 Feb 2011 19:47:08 +0300
Subject: [eterhack 09/20] ntoskrnl.exe: Implement IoDetachDevice (eterbug #4301).
---
dlls/ntoskrnl.exe/ntoskrnl.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index a6e6b5e..c75c21d 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -1165,7 +1165,8 @@ PDEVICE_OBJECT WINAPI IoAttachDeviceToDeviceStack( DEVICE_OBJECT *source,
*/
void WINAPI IoDetachDevice( DEVICE_OBJECT *device )
{
- FIXME( "stub: %p\n", device );
+ TRACE( "%p\n", device );
+ device->AttachedDevice = NULL;
}
--
1.7.4.1
----------- следующая часть -----------
From 047c829f9b2c2ada1667f8cbc95cb50aeedec221 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 28 Feb 2011 19:49:42 +0300
Subject: [eterhack 10/20] ntoskrnl.exe: Attach to the highest device object (eterbug #4301).
---
dlls/ntoskrnl.exe/ntoskrnl.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index c75c21d..bd8fa35 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -1154,6 +1154,8 @@ PDEVICE_OBJECT WINAPI IoAttachDeviceToDeviceStack( DEVICE_OBJECT *source,
DEVICE_OBJECT *target )
{
TRACE( "%p, %p\n", source, target );
+ while (target->AttachedDevice)
+ target = target->AttachedDevice;
target->AttachedDevice = source;
source->StackSize = target->StackSize + 1;
return target;
--
1.7.4.1
----------- следующая часть -----------
From 5195111a8350b7071c0facff11d1d19d19dd65e0 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 22 Feb 2011 21:29:10 +0300
Subject: [eterhack 11/20] ntoskrnl.exe: Fix merge error.
---
dlls/ntoskrnl.exe/ntoskrnl.c | 9 ---------
1 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index bd8fa35..e58a55d 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -1203,15 +1203,6 @@ PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
if (irp == NULL)
return NULL;
- instance = HeapAlloc( GetProcessHeap(), 0, sizeof(struct IrpInstance) );
- if (instance == NULL)
- {
- IoFreeIrp( irp );
- return NULL;
- }
- instance->irp = irp;
- list_add_tail( &Irps, &instance->entry );
-
irpsp = IoGetNextIrpStackLocation( irp );
irpsp->MajorFunction = InternalDeviceIoControl ?
IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
--
1.7.4.1
----------- следующая часть -----------
From f612a0b1105a55a07a47c6adbf75b52f392e96d7 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 28 Feb 2011 16:09:53 +0300
Subject: [eterhack 12/20] mountmgr.sys: Remove unneeded checks.
---
dlls/mountmgr.sys/device.c | 2 +-
dlls/mountmgr.sys/usbhub.c | 11 +++++------
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index 8142c93..550263f 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -819,7 +819,7 @@ static void register_usbstor_device( struct dos_drive *drive, const char *vendor
RtlInitUnicodeString( &target, diskW );
IoCreateSymbolicLink( &drive->volume->device->usbstor, &target );
done:
- if (detail) RtlFreeHeap( GetProcessHeap(), 0, detail );
+ RtlFreeHeap( GetProcessHeap(), 0, detail );
SetupDiDestroyDeviceInfoList( set );
RtlFreeHeap( GetProcessHeap(), 0, devnameW );
}
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 8812f79..90ed1d9 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -1361,8 +1361,7 @@ static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
++instance_id;
return;
fail:
- if (instance->instance_id)
- HeapFree( GetProcessHeap(), 0, instance->instance_id );
+ HeapFree( GetProcessHeap(), 0, instance->instance_id );
HeapFree( GetProcessHeap(), 0, instance );
return;
}
@@ -1445,8 +1444,8 @@ static BOOL enum_reg_usb_devices(void)
SetupDiDestroyDeviceInfoList( set );
return TRUE;
fail:
- if (buf) HeapFree( GetProcessHeap(), 0, buf );
- if (instance_id) HeapFree( GetProcessHeap(), 0, instance_id );
+ HeapFree( GetProcessHeap(), 0, buf );
+ HeapFree( GetProcessHeap(), 0, instance_id );
SetupDiDestroyDeviceInfoList( set );
LIST_FOR_EACH_ENTRY_SAFE( instance, instance2, &Devices,
struct DeviceInstance, entry )
@@ -1597,8 +1596,8 @@ static void register_usb_device( USHORT vid, USHORT pid, void *dev )
done:
if (set != INVALID_HANDLE_VALUE)
SetupDiDestroyDeviceInfoList( set );
- if (devnameW) HeapFree( GetProcessHeap(), 0, devnameW );
- if (instance_idW) HeapFree( GetProcessHeap(), 0, instance_idW );
+ HeapFree( GetProcessHeap(), 0, devnameW );
+ HeapFree( GetProcessHeap(), 0, instance_idW );
}
static void start_root_devices( DRIVER_OBJECT *driver_obj )
--
1.7.4.1
----------- следующая часть -----------
From 8a3ceaa1e5f20ea9ecbf0c6cad10caa3cff3c38e Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 28 Feb 2011 22:10:35 +0300
Subject: [eterhack 13/20] mountmgr.sys: Remove old symlink before creating new one (eterbug #4301).
---
dlls/mountmgr.sys/device.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index 550263f..f84ff5e 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -815,6 +815,11 @@ static void register_usbstor_device( struct dos_drive *drive, const char *vendor
if (!linkW) goto done;
strcpyW( linkW, dos_devicesW );
strcatW( linkW, detail->DevicePath + 3 );
+ if (drive->volume->device->usbstor.Buffer)
+ {
+ IoDeleteSymbolicLink( &drive->volume->device->usbstor );
+ RtlFreeUnicodeString( &drive->volume->device->usbstor );
+ }
RtlInitUnicodeString( &drive->volume->device->usbstor, linkW );
RtlInitUnicodeString( &target, diskW );
IoCreateSymbolicLink( &drive->volume->device->usbstor, &target );
--
1.7.4.1
----------- следующая часть -----------
From 423c04336b3252779eae4ee449659aedd8e5a086 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 1 Mar 2011 17:40:53 +0300
Subject: [eterhack 14/20] mountmgr.sys: Device ID does not contain spaces (eterbug #4301).
---
dlls/mountmgr.sys/device.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index f84ff5e..4f4956a 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -720,6 +720,16 @@ NTSTATUS remove_volume( const char *udi )
return status;
}
+/* replace spaces with '_' */
+static void replace_spcW( WCHAR *str )
+{
+ while (*str)
+ {
+ if (*str == ' ') *str = '_';
+ ++str;
+ }
+}
+
/* write information about USBSTOR device to registry and create symbolic link */
static void register_usbstor_device( struct dos_drive *drive, const char *vendor,
const char *product, const char *revision,
@@ -767,6 +777,7 @@ static void register_usbstor_device( struct dos_drive *drive, const char *vendor
MultiByteToWideChar( CP_ACP, 0, serial, -1, serialW, size );
sprintfW( devnameW, disk_idW, usbstorW, vendorW, productW, revisionW, serialW );
+ replace_spcW( devnameW );
set = SetupDiGetClassDevsW( NULL, usbstorW, 0, DIGCF_ALLCLASSES );
if (set == INVALID_HANDLE_VALUE)
--
1.7.4.1
----------- следующая часть -----------
From 67dfcb66293e5c797739371ce8c30a00c251e03c Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Wed, 2 Mar 2011 19:37:24 +0300
Subject: [eterhack 15/20] Do not duplicate a function for starting service (eterbug #4301).
---
dlls/mountmgr.sys/usbhub.c | 41 +++-------------------------------
dlls/ntoskrnl.exe/ntoskrnl.c | 4 +-
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 1 +
3 files changed, 7 insertions(+), 39 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 90ed1d9..4328964 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -58,6 +58,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(usbhub);
extern NTSTATUS CDECL __wine_add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *dev );
extern DRIVER_OBJECT * CDECL __wine_get_driver_object( const WCHAR *service );
extern NTSTATUS CDECL __wine_start_device( DEVICE_OBJECT *device );
+extern BOOL CDECL __wine_start_service( const WCHAR *name );
#define NUMBER_OF_PORTS 8
@@ -1205,41 +1206,6 @@ done:
return status;
}
-static BOOL start_service( const 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;
- }
-
- do {
- ret = StartServiceW( service, 0, NULL );
- if (!ret)
- {
- if (ERROR_SERVICE_ALREADY_RUNNING == GetLastError())
- ret = TRUE;
- else if (ERROR_SERVICE_DATABASE_LOCKED == GetLastError())
- Sleep( 100 );
- else
- break;
- }
- } while (!ret);
-
- CloseServiceHandle( service );
- CloseServiceHandle( scm );
-
- return ret;
-}
-
static void stop_service( const WCHAR *name )
{
SC_HANDLE scm, service;
@@ -1621,7 +1587,8 @@ static void start_root_devices( DRIVER_OBJECT *driver_obj )
serviceW = HeapAlloc( GetProcessHeap(), 0, size );
if (serviceW == NULL) break;
if (SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_SERVICE,
- NULL, (BYTE *)serviceW, size, NULL ) && start_service( serviceW ))
+ NULL, (BYTE *)serviceW, size, NULL ) &&
+ __wine_start_service( serviceW ))
{
status = IoCreateDevice( driver_obj, 0, NULL, 0, 0, FALSE, &pdo );
if (status == STATUS_SUCCESS)
@@ -1649,7 +1616,7 @@ static void start_device_drivers( DRIVER_OBJECT *hubdrv )
{
if (instance->service == NULL || instance->dev == NULL ||
instance->pdo != NULL) continue;
- if (start_service( instance->service ))
+ if (__wine_start_service( instance->service ))
{
instance->pdo = create_pdo( instance, hubdrv,
DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE );
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index e58a55d..c775b6d 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -172,7 +172,7 @@ static inline LPCSTR debugstr_us( const UNICODE_STRING *us )
return debugstr_wn( us->Buffer, us->Length / sizeof(WCHAR) );
}
-static BOOL start_service( WCHAR *name )
+BOOL CDECL __wine_start_service( const WCHAR *name )
{
SC_HANDLE scm, service;
BOOL ret;
@@ -1467,7 +1467,7 @@ void WINAPI IoInvalidateDeviceRelations( PDEVICE_OBJECT DeviceObject,
WCHAR *service;
if (get_service( (WCHAR *)irp->IoStatus.Information, &service )
- && start_service( service ))
+ && __wine_start_service( service ))
{
DRIVER_OBJECT *driver;
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index dd379fe..a60953a 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -1494,3 +1494,4 @@
@ cdecl __wine_del_driver_object(ptr)
@ cdecl __wine_get_driver_object(wstr)
@ cdecl __wine_start_device(ptr)
+@ cdecl __wine_start_service(wstr)
--
1.7.4.1
----------- следующая часть -----------
From 3dbc7c7fc3cc96118d236645704572f1c3160d2e Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Wed, 2 Mar 2011 22:11:23 +0300
Subject: [eterhack 16/20] mountmgr.sys: Fix processing PnP requests for ROOT devices (eterbug #4301).
---
dlls/mountmgr.sys/usbhub.c | 32 +++++++++++++++++++++++++++++++-
1 files changed, 31 insertions(+), 1 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 4328964..640a145 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -64,8 +64,15 @@ extern BOOL CDECL __wine_start_service( const WCHAR *name );
static const WCHAR usbW[] = {'U','S','B',0};
+static struct list RootDevices = LIST_INIT(RootDevices);
static struct list Devices = LIST_INIT(Devices);
+struct RootDevInstance
+{
+ struct list entry;
+ DEVICE_OBJECT *pdo;
+};
+
struct DeviceInstance
{
struct list entry;
@@ -1103,6 +1110,16 @@ done:
#endif
+static BOOL is_root_dev( DEVICE_OBJECT *device )
+{
+ struct RootDevInstance *instance;
+
+ LIST_FOR_EACH_ENTRY( instance, &RootDevices, struct RootDevInstance, entry )
+ if (instance->pdo == device)
+ return TRUE;
+ return FALSE;
+}
+
static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
{
static const WCHAR device_idW[] = {'U','S','B','\\',
@@ -1123,7 +1140,8 @@ static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
if (!device_exists( device ))
{
if (irpsp->MinorFunction == IRP_MN_SURPRISE_REMOVAL ||
- irpsp->MinorFunction == IRP_MN_REMOVE_DEVICE)
+ irpsp->MinorFunction == IRP_MN_REMOVE_DEVICE ||
+ is_root_dev( device ))
status = STATUS_SUCCESS;
goto done;
}
@@ -1593,6 +1611,18 @@ static void start_root_devices( DRIVER_OBJECT *driver_obj )
status = IoCreateDevice( driver_obj, 0, NULL, 0, 0, FALSE, &pdo );
if (status == STATUS_SUCCESS)
{
+ struct RootDevInstance *instance;
+
+ instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
+ if (instance == NULL)
+ {
+ HeapFree( GetProcessHeap(), 0, serviceW );
+ break;
+ }
+ instance->pdo = pdo;
+ EnterCriticalSection( &usbhub_cs );
+ list_add_tail( &RootDevices, &instance->entry );
+ LeaveCriticalSection( &usbhub_cs );
while (!(driver = __wine_get_driver_object( serviceW )))
Sleep( 100 );
status = __wine_add_device( driver, pdo );
--
1.7.4.1
----------- следующая часть -----------
From 30277336186f60209ce85a48c5a648d8c0a7a1be Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 3 Mar 2011 14:48:50 +0300
Subject: [eterhack 17/20] mountmgr.sys: Add comments to conditional inclusion preprocessing directives (eterbug #4301).
---
dlls/mountmgr.sys/usbhub.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 640a145..e4d8211 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -749,7 +749,7 @@ done:
return status;
}
-#else
+#else /* HAVE_LIBUSB_H */
static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
{
@@ -1108,7 +1108,7 @@ done:
return status;
}
-#endif
+#endif /* HAVE_LIBUSB_H */
static BOOL is_root_dev( DEVICE_OBJECT *device )
{
@@ -1844,7 +1844,7 @@ end:
}
}
-#else
+#else /* HAVE_LIBUSB_H */
static int initialize_libusb(void)
{
@@ -1936,9 +1936,9 @@ end:
}
}
-#endif
+#endif /* HAVE_LIBUSB_H */
-#else
+#else /* HAVE_LIBUSB */
void add_usb_devices(void)
{
@@ -1948,7 +1948,7 @@ void remove_usb_devices(void)
{
}
-#endif
+#endif /* HAVE_LIBUSB */
#ifdef HAVE_LIBUSB
@@ -1976,7 +1976,7 @@ static DWORD CALLBACK initialize_usbhub( void *arg )
return 0;
}
-#endif
+#endif /* HAVE_LIBUSB */
NTSTATUS WINAPI usbhub_driver_entry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
{
--
1.7.4.1
----------- следующая часть -----------
From 2df0a2cd0d7bf9530bc51680cf38b26bf1fa2c1c Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 3 Mar 2011 15:38:09 +0300
Subject: [eterhack 18/20] ntoskrnl.exe: Initialize critical section statically.
---
dlls/ntoskrnl.exe/ntoskrnl.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index c775b6d..6da50b2 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -68,6 +68,13 @@ typedef void (WINAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
typedef void (WINAPI *PCREATE_THREAD_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
static CRITICAL_SECTION cs;
+static CRITICAL_SECTION_DEBUG cs_debug =
+{
+ 0, 0, &cs,
+ { &cs_debug.ProcessLocksList, &cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": cs") }
+};
+static CRITICAL_SECTION cs = { &cs_debug, -1, 0, 0, 0, 0 };
static struct list Irps = LIST_INIT(Irps);
@@ -3243,10 +3250,8 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
handler = RtlAddVectoredExceptionHandler( TRUE, vectored_handler );
#endif
KeQueryTickCount( &count ); /* initialize the global KeTickCount */
- InitializeCriticalSection( &cs );
break;
case DLL_PROCESS_DETACH:
- DeleteCriticalSection( &cs );
RtlRemoveVectoredExceptionHandler( handler );
LIST_FOR_EACH_ENTRY_SAFE( ext, ext2, &DriverObjExtensions,
struct DriverObjExtension, entry )
--
1.7.4.1
----------- следующая часть -----------
From de3033a4e5d76a88f9caf26e2bd9cb968203acba Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 3 Mar 2011 17:12:17 +0300
Subject: [eterhack 19/20] mountmgr.sys: Handling IRP in WINE на Etersoft is different from upstream.
---
dlls/mountmgr.sys/device.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index 4f4956a..59cc68d 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -1111,9 +1111,9 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
DWORD len = min( 32, irpsp->Parameters.DeviceIoControl.OutputBufferLength );
FIXME( "returning zero-filled buffer for ioctl 0x560000\n" );
- memset( irp->MdlAddress->StartVa, 0, len );
+ memset( irp->AssociatedIrp.SystemBuffer, 0, len );
irp->IoStatus.Information = len;
- irp->IoStatus.u.Status = STATUS_SUCCESS;
+ status = STATUS_SUCCESS;
break;
}
default:
--
1.7.4.1
----------- следующая часть -----------
From 96109ba364ae9dab647d627fc4dad70d70235533 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 3 Mar 2011 21:17:45 +0300
Subject: [eterhack 20/20] Use IoGet*IrpStackLocation.
---
dlls/mountmgr.sys/parport.c | 4 ++--
dlls/mountmgr.sys/usbhub.c | 10 +++++-----
dlls/ntoskrnl.exe/ntoskrnl.c | 16 ++++++++--------
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/dlls/mountmgr.sys/parport.c b/dlls/mountmgr.sys/parport.c
index 4f460d0..4193476 100644
--- a/dlls/mountmgr.sys/parport.c
+++ b/dlls/mountmgr.sys/parport.c
@@ -87,7 +87,7 @@ static ULONG WINAPI parport_query_waiters( void *context )
static NTSTATUS WINAPI parport_ioctl( DEVICE_OBJECT *device, IRP *irp )
{
- IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
NTSTATUS status = STATUS_NOT_SUPPORTED;
TRACE( "%p, %p\n", device, irp );
@@ -145,7 +145,7 @@ static NTSTATUS WINAPI parport_pnp( DEVICE_OBJECT *device, IRP *irp )
{
static const WCHAR fmtW[] = {'%','d',0};
- IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
NTSTATUS status;
TRACE( "%p, %p\n", device, irp );
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index e4d8211..3005771 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -145,7 +145,7 @@ static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
if (!device_exists( device )) goto done;
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (inst->service) goto done;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ irpsp = IoGetCurrentIrpStackLocation( irp );
switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
{
@@ -414,7 +414,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
if (!device_exists( device )) goto done;
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (!inst->service) goto done;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ irpsp = IoGetCurrentIrpStackLocation( irp );
urb = irpsp->Parameters.Others.Argument1;
switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
@@ -764,7 +764,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
if (!device_exists( device )) goto done;
inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
if (!inst->service) goto done;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ irpsp = IoGetCurrentIrpStackLocation( irp );
urb = irpsp->Parameters.Others.Argument1;
switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
@@ -1136,7 +1136,7 @@ static NTSTATUS WINAPI usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
TRACE( "%p, %p\n", device, irp );
EnterCriticalSection( &usbhub_cs );
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ irpsp = IoGetCurrentIrpStackLocation( irp );
if (!device_exists( device ))
{
if (irpsp->MinorFunction == IRP_MN_SURPRISE_REMOVAL ||
@@ -1673,7 +1673,7 @@ static NTSTATUS call_pnp_func( DEVICE_OBJECT *device, UCHAR minor_func )
irp = IoAllocateIrp( device->StackSize, FALSE );
if (irp == NULL) return STATUS_NO_MEMORY;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irpsp = IoGetNextIrpStackLocation( irp );
irp->RequestorMode = KernelMode;
irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
irpsp->MajorFunction = IRP_MJ_PNP;
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 6da50b2..690ccbf 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -274,7 +274,7 @@ static NTSTATUS get_device_id( DEVICE_OBJECT *pdo, BUS_QUERY_ID_TYPE id_type,
*id = NULL;
irp = IoAllocateIrp( pdo->StackSize, FALSE );
if (irp == NULL) return STATUS_NO_MEMORY;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irpsp = IoGetNextIrpStackLocation( irp );
irpsp->MajorFunction = IRP_MJ_PNP;
irpsp->MinorFunction = IRP_MN_QUERY_ID;
irpsp->Parameters.QueryId.IdType = id_type;
@@ -563,7 +563,7 @@ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff,
status = STATUS_NO_MEMORY;
goto end;
}
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irpsp = IoGetNextIrpStackLocation( irp );
irp->RequestorMode = UserMode;
irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
irp->Tail.Overlay.OriginalFileObject = file;
@@ -598,7 +598,7 @@ static NTSTATUS process_read( DEVICE_OBJECT *device, void *buff, ULONG *size )
if (irp == NULL)
return STATUS_NO_MEMORY;
irp->RequestorMode = UserMode;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irpsp = IoGetNextIrpStackLocation( irp );
irpsp->DeviceObject = device;
irpsp->MajorFunction = IRP_MJ_READ;
irpsp->Parameters.Read.Length = *size;
@@ -639,7 +639,7 @@ static NTSTATUS process_write( DEVICE_OBJECT *device, void *buff, ULONG *size )
if (irp == NULL)
return STATUS_NO_MEMORY;
irp->RequestorMode = UserMode;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irpsp = IoGetNextIrpStackLocation( irp );
irpsp->DeviceObject = device;
irpsp->MajorFunction = IRP_MJ_WRITE;
irpsp->Parameters.Write.Length = *size;
@@ -865,7 +865,7 @@ NTSTATUS CDECL __wine_start_device( DEVICE_OBJECT *device )
irp = IoAllocateIrp( device->StackSize, FALSE );
if (irp == NULL) return STATUS_NO_MEMORY;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irpsp = IoGetNextIrpStackLocation( irp );
irp->RequestorMode = KernelMode;
irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
irpsp->MajorFunction = IRP_MJ_PNP;
@@ -1449,7 +1449,7 @@ void WINAPI IoInvalidateDeviceRelations( PDEVICE_OBJECT DeviceObject,
irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );
if (irp == NULL) return;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irpsp = IoGetNextIrpStackLocation( irp );
irpsp->MajorFunction = IRP_MJ_PNP;
irpsp->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
irpsp->Parameters.QueryDeviceRelations.Type = BusRelations;
@@ -1464,7 +1464,7 @@ void WINAPI IoInvalidateDeviceRelations( PDEVICE_OBJECT DeviceObject,
IoFreeIrp( irp );
irp = IoAllocateIrp( rel->Objects[k]->StackSize, FALSE );
if (irp == NULL) return;
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation - 1;
+ irpsp = IoGetNextIrpStackLocation( irp );
irpsp->MajorFunction = IRP_MJ_PNP;
irpsp->MinorFunction = IRP_MN_QUERY_ID;
irpsp->Parameters.QueryId.IdType = BusQueryDeviceID;
@@ -2172,7 +2172,7 @@ VOID WINAPI IoCompleteRequest( IRP *irp, UCHAR priority_boost )
status = irp->IoStatus.u.Status;
while (irp->CurrentLocation <= irp->StackCount)
{
- irpsp = irp->Tail.Overlay.s.u2.CurrentStackLocation;
+ irpsp = IoGetCurrentIrpStackLocation( irp );
routine = irpsp->CompletionRoutine;
call_flag = 0;
/* FIXME: add SL_INVOKE_ON_CANCEL support */
--
1.7.4.1
Подробная информация о списке рассылки Wine-patches