[Wine-patches] [eterhack] eterbug #6247
Alexander Morozov
amorozov на etersoft.ru
Вт Апр 26 16:48:01 MSD 2011
----------- следующая часть -----------
From c4d327524cf5931a4da1b6a2a0599e0c9f7415b7 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 19 Apr 2011 20:35:11 +0400
Subject: [eterhack 1/7] Add int 0x2e support (eterbug #6247).
---
dlls/kernel32/Makefile.in | 1 +
dlls/kernel32/instr.c | 131 ++++++++++++++++++++++++++++++++++++++++
dlls/kernel32/kernel_main.c | 2 +
dlls/kernel32/kernel_private.h | 2 +
tools/winebuild/spec32.c | 89 +++++++++++++++++++++++++++
5 files changed, 225 insertions(+), 0 deletions(-)
create mode 100644 dlls/kernel32/instr.c
diff --git a/dlls/kernel32/Makefile.in b/dlls/kernel32/Makefile.in
index 6c60623..4309a04 100644
--- a/dlls/kernel32/Makefile.in
+++ b/dlls/kernel32/Makefile.in
@@ -21,6 +21,7 @@ C_SRCS = \
file.c \
format_msg.c \
heap.c \
+ instr.c \
kernel_main.c \
lcformat.c \
locale.c \
diff --git a/dlls/kernel32/instr.c b/dlls/kernel32/instr.c
new file mode 100644
index 0000000..329db88
--- /dev/null
+++ b/dlls/kernel32/instr.c
@@ -0,0 +1,131 @@
+/*
+ * Emulation of privileged instructions
+ *
+ * Copyright 1995 Alexandre Julliard
+ * Copyright 2005 Ivan Leo Puoti
+ * Copyright 2005 Laurent Pinchart
+ * Copyright 2011 Alexander Morozov
+ *
+ * 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 __i386__
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "excpt.h"
+#include "wine/debug.h"
+#include "wine/exception.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(int);
+
+static void *INSTR_get_ntdll_func( DWORD n )
+{
+ static const WCHAR ntdllW[] = {'n','t','d','l','l','.','d','l','l',0};
+
+ HANDLE ntdll = GetModuleHandleW( ntdllW );
+ IMAGE_EXPORT_DIRECTORY *exports;
+ DWORD *func_addr, *func_name, size, k;
+ void *fptr;
+
+ exports = RtlImageDirectoryEntryToData( ntdll, TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
+ func_addr = (DWORD *)((char *)ntdll + exports->AddressOfFunctions);
+ func_name = (DWORD *)((char *)ntdll + exports->AddressOfNames);
+ for (k = 0; k < exports->NumberOfFunctions; ++k)
+ {
+ if (func_addr[k] + (DWORD)ntdll > (DWORD)exports &&
+ func_addr[k] + (DWORD)ntdll < (DWORD)exports + size)
+ continue; /* function is forwarded */
+ if (strncmp( (char *)((DWORD)ntdll + func_name[k]), "Nt", 2 ))
+ continue; /* skip functions with names which do not begin from Nt */
+ fptr = (void *)((DWORD)ntdll + func_addr[k]);
+ if (*(DWORD *)((char *)fptr + 1) == n)
+ {
+ TRACE( "%d -> %p\n", n, fptr );
+ return fptr;
+ }
+ }
+ return NULL;
+}
+
+extern int CDECL INSTR_syscall( void *func, DWORD params );
+__ASM_GLOBAL_FUNC( INSTR_syscall,
+ "pushl %ebp\n\t"
+ "movl %esp,%ebp\n\t"
+ "movl 12(%ebp),%esi\n\t"
+ "subl $80,%esp\n\t"
+ "movl %esp,%edi\n\t"
+ "movl $20,%ecx\n\t"
+ "rep movsl\n\t"
+ "call *8(%ebp)\n\t"
+ "movl %ebp,%esp\n\t"
+ "popl %ebp\n\t"
+ "ret" )
+
+
+/***********************************************************************
+ * emulate_instruction
+ *
+ * Emulate a privileged instruction.
+ * Returns exception continuation status.
+ */
+static DWORD emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT *context )
+{
+ BYTE *instr;
+
+ instr = (BYTE *)context->Eip;
+ if (!instr) return ExceptionContinueSearch;
+
+ if (*(WORD *)instr == 0x2ecd) /* int 0x2e */
+ {
+ void *ptr = INSTR_get_ntdll_func( context->Eax );
+
+ if (!ptr) return ExceptionContinueSearch;
+ context->Eax = INSTR_syscall( ptr, context->Edx );
+ context->Eip += 2;
+ return ExceptionContinueExecution;
+ }
+ return ExceptionContinueSearch; /* Unable to emulate it */
+}
+
+
+/***********************************************************************
+ * INSTR_vectored_handler
+ *
+ * Vectored exception handler used to emulate protected instructions
+ * from 32-bit code.
+ */
+LONG CALLBACK INSTR_vectored_handler( EXCEPTION_POINTERS *ptrs )
+{
+ EXCEPTION_RECORD *record = ptrs->ExceptionRecord;
+ CONTEXT *context = ptrs->ContextRecord;
+
+ if (record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
+ record->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION)
+ {
+ if (emulate_instruction( record, context ) == ExceptionContinueExecution)
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+#endif /* __i386__ */
diff --git a/dlls/kernel32/kernel_main.c b/dlls/kernel32/kernel_main.c
index fc0bc90..5976557 100644
--- a/dlls/kernel32/kernel_main.c
+++ b/dlls/kernel32/kernel_main.c
@@ -114,6 +114,8 @@ static BOOL process_attach( HMODULE module )
* ole implementation works right we need the shared heap*/
/* create the shared heap for broken win95 native dlls */
HeapCreate( HEAP_SHARED, 0, 0 );
+ /* setup emulation of protected instructions from 32-bit code */
+ RtlAddVectoredExceptionHandler( TRUE, INSTR_vectored_handler );
#endif
}
else LoadLibraryA( "krnl386.exe16" );
diff --git a/dlls/kernel32/kernel_private.h b/dlls/kernel32/kernel_private.h
index f180e7d..288bc38 100644
--- a/dlls/kernel32/kernel_private.h
+++ b/dlls/kernel32/kernel_private.h
@@ -62,6 +62,8 @@ extern void FILE_SetDosError(void);
extern WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc );
extern DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen );
+extern LONG CALLBACK INSTR_vectored_handler( EXCEPTION_POINTERS *ptrs );
+
/* return values for MODULE_GetBinaryType */
enum binary_type
{
diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c
index e16260a..efafa26 100644
--- a/tools/winebuild/spec32.c
+++ b/tools/winebuild/spec32.c
@@ -46,6 +46,8 @@
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+static int *ntdll_ep;
+
/* check if entry point needs a relay thunk */
static inline int needs_relay( const ORDDEF *odp )
{
@@ -81,6 +83,86 @@ int has_relays( DLLSPEC *spec )
return 0;
}
+static int needs_ntdll_ep( const DLLSPEC *spec, const ORDDEF *odp )
+{
+ if (target_cpu != CPU_x86 || strcmp(spec->file_name, "ntdll.dll"))
+ return 0;
+ if (!odp)
+ return 1;
+ else
+ return (odp->type == TYPE_STDCALL || odp->type == TYPE_STUB) &&
+ !(odp->flags & (FLAG_FORWARD | FLAG_EXT_LINK | FLAG_REGISTER)) &&
+ (!strncmp(odp->name, "Nt", 2) || !strncmp(odp->name, "Zw", 2));
+}
+
+static void generate_ntdll_call_nums( const DLLSPEC *spec )
+{
+ int nt, nt_end, zw, zw_end, r, i = 0;
+
+ if (!needs_ntdll_ep( spec, NULL )) return;
+ ntdll_ep = xmalloc( spec->limit * sizeof(int) );
+
+ for (nt = spec->base; nt <= spec->limit; nt++)
+ if (!strncmp(spec->ordinals[nt]->name, "Nt", 2))
+ break;
+ for (nt_end = nt; nt_end <= spec->limit; nt_end++)
+ if (strncmp(spec->ordinals[nt_end]->name, "Nt", 2))
+ break;
+ for (zw = nt_end; zw <= spec->limit; zw++)
+ if (!strncmp(spec->ordinals[zw]->name, "Zw", 2))
+ break;
+ for (zw_end = zw; zw_end <= spec->limit; zw_end++)
+ if (strncmp(spec->ordinals[zw_end]->name, "Zw", 2))
+ break;
+
+ while (nt < nt_end && zw < zw_end)
+ {
+ r = strcmp(spec->ordinals[nt]->name + 2, spec->ordinals[zw]->name + 2);
+ if (!r)
+ {
+ ntdll_ep[nt++] = i;
+ ntdll_ep[zw++] = i++;
+ }
+ else if (r < 0)
+ ntdll_ep[nt++] = i++;
+ else
+ ntdll_ep[zw++] = i++;
+ }
+}
+
+static const char *get_ntdll_ep_name( int i )
+{
+ static char buffer[256];
+ sprintf( buffer, ".L__wine_spec_ntdll_entry_point_%d", i );
+ return buffer;
+}
+
+static void output_ntdll_entry_points( const DLLSPEC *spec )
+{
+ int i;
+
+ if (!needs_ntdll_ep( spec, NULL )) return;
+
+ output( "\t.text\n" );
+ output( "__wine_spec_ntdll_entry_points:\n" );
+
+ for (i = spec->base; i <= spec->limit; i++)
+ {
+ ORDDEF *odp = spec->ordinals[i];
+
+ if (!needs_ntdll_ep( spec, odp )) continue;
+
+ output( "\t.align %d\n", get_alignment(4) );
+ output( "%s:\n", asm_name(get_ntdll_ep_name(i)) );
+ output( "\tmovl $%d,%%eax\n", ntdll_ep[i] );
+
+ if (odp->type == TYPE_STUB)
+ output( "\tjmp %s\n", asm_name(get_stub_name( odp, spec )) );
+ else
+ output( "\tjmp %s\n", asm_name(odp->link_name) );
+ }
+}
+
/*******************************************************************
* output_relay_debug
*
@@ -156,6 +238,8 @@ static void output_relay_debug( DLLSPEC *spec )
switch (target_cpu)
{
case CPU_x86:
+ if (needs_ntdll_ep( spec, odp ))
+ output( "\tmovl $%d,%%eax\n", ntdll_ep[i] );
if (odp->type == TYPE_THISCALL) /* add the this pointer */
{
output( "\tpopl %%eax\n" );
@@ -266,6 +350,8 @@ void output_exports( DLLSPEC *spec )
{
ORDDEF *odp = spec->ordinals[i];
if (!odp) output( "\t%s 0\n", get_asm_ptr_keyword() );
+ else if (needs_ntdll_ep( spec, odp ))
+ output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(get_ntdll_ep_name(i)) );
else switch(odp->type)
{
case TYPE_EXTERN:
@@ -363,7 +449,10 @@ void output_exports( DLLSPEC *spec )
output( "\t%s .L__wine_spec_relay_entry_point_offsets\n", get_asm_ptr_keyword() );
output( "\t%s .L__wine_spec_relay_arg_types\n", get_asm_ptr_keyword() );
+ generate_ntdll_call_nums( spec );
output_relay_debug( spec );
+ output_ntdll_entry_points( spec );
+ free( ntdll_ep );
}
--
1.7.4.4
----------- следующая часть -----------
From d5754cab4cbecb72f7dd6347239d0f42b8d7eef2 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 21 Apr 2011 21:55:09 +0400
Subject: [eterhack 2/7] mountmgr.sys: Create HCD* devices (eterbug #6247).
---
dlls/mountmgr.sys/usbhub.c | 74 ++++++++++++++++++++++++++++++++++++++------
1 files changed, 64 insertions(+), 10 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index ef9e174..ab33fe5 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -65,6 +65,7 @@ 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 HostControllers = LIST_INIT(HostControllers);
static struct list Devices = LIST_INIT(Devices);
struct RootDevInstance
@@ -73,6 +74,13 @@ struct RootDevInstance
DEVICE_OBJECT *pdo;
};
+struct HCDInstance
+{
+ struct list entry;
+ DEVICE_OBJECT *dev;
+ WCHAR *root_hub_name;
+};
+
struct DeviceInstance
{
struct list entry;
@@ -1278,7 +1286,8 @@ static DEVICE_OBJECT *create_pdo( struct DeviceInstance *inst,
return usbdev;
}
-static void register_root_hub_device( DEVICE_OBJECT *dev, unsigned int instance_id )
+static BOOL register_root_hub_device( DEVICE_OBJECT *dev,
+ unsigned int instance_id, UNICODE_STRING *link )
{
static const WCHAR root_hub_idW[] = {'U','S','B',
'\\','R','O','O','T','_','H','U','B',
@@ -1289,12 +1298,11 @@ static void register_root_hub_device( DEVICE_OBJECT *dev, unsigned int instance_
WCHAR *devnameW;
ULONG size;
BOOL ret;
- UNICODE_STRING link;
- NTSTATUS status;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
size = sizeof(root_hub_idW) + 16 * sizeof(WCHAR);
devnameW = HeapAlloc( GetProcessHeap(), 0, size );
- if (devnameW == NULL) return;
+ if (devnameW == NULL) return FALSE;
snprintfW( devnameW, size / sizeof(WCHAR), root_hub_idW, instance_id );
set = SetupDiGetClassDevsW( NULL, usbW, 0, DIGCF_ALLCLASSES );
@@ -1310,16 +1318,57 @@ static void register_root_hub_device( DEVICE_OBJECT *dev, unsigned int instance_
else if (ERROR_DEVINST_ALREADY_EXISTS != GetLastError()) goto done;
status = IoRegisterDeviceInterface( dev, &GUID_DEVINTERFACE_USB_HUB,
- NULL, &link );
+ NULL, link );
if (status == STATUS_SUCCESS)
- {
- IoSetDeviceInterfaceState( &link, TRUE );
- RtlFreeUnicodeString( &link );
- }
+ IoSetDeviceInterfaceState( link, TRUE );
done:
if (set != INVALID_HANDLE_VALUE)
SetupDiDestroyDeviceInfoList( set );
HeapFree( GetProcessHeap(), 0, devnameW );
+ return (status == STATUS_SUCCESS) ? TRUE : FALSE;
+}
+
+static void create_hcd_device( unsigned int instance_id, DRIVER_OBJECT *hubdrv,
+ UNICODE_STRING *link )
+{
+ static const WCHAR usbfdoW[] = {'\\','D','e','v','i','c','e',
+ '\\','U','S','B','F','D','O','-','%','u',0};
+ static const WCHAR usbhcdW[] = {'\\','D','o','s','D','e','v','i','c','e','s',
+ '\\','H','C','D','%','u',0};
+
+ WCHAR *fdo_buf = RtlAllocateHeap( GetProcessHeap(), 0, 30 * sizeof(WCHAR) );
+ WCHAR *hcd_buf = RtlAllocateHeap( GetProcessHeap(), 0, 30 * sizeof(WCHAR) );
+ UNICODE_STRING fdo_name, hcd_name;
+ struct HCDInstance *instance = NULL;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+
+ if (fdo_buf == NULL || hcd_buf == NULL) goto done;
+ instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
+ if (instance == NULL) goto done;
+ instance->root_hub_name = HeapAlloc( GetProcessHeap(), 0,
+ link->Length + sizeof(WCHAR) );
+ if (instance->root_hub_name == NULL) goto done;
+ memcpy( instance->root_hub_name, link->Buffer, link->Length );
+ instance->root_hub_name[link->Length / sizeof(WCHAR)] = 0;
+
+ snprintfW( fdo_buf, 30, usbfdoW, instance_id );
+ RtlInitUnicodeString( &fdo_name, fdo_buf );
+ snprintfW( hcd_buf, 30, usbhcdW, instance_id );
+ RtlInitUnicodeString( &hcd_name, hcd_buf );
+
+ status = IoCreateDevice( hubdrv, 0, &fdo_name, 0, 0, FALSE, &instance->dev );
+ if (status != STATUS_SUCCESS) goto done;
+ IoCreateSymbolicLink( &hcd_name, &fdo_name );
+ instance->dev->Flags &= ~DO_DEVICE_INITIALIZING;
+ list_add_tail( &HostControllers, &instance->entry );
+done:
+ if (status != STATUS_SUCCESS && instance != NULL)
+ {
+ HeapFree( GetProcessHeap(), 0, instance->root_hub_name );
+ HeapFree( GetProcessHeap(), 0, instance );
+ }
+ RtlFreeUnicodeString( &fdo_name );
+ RtlFreeUnicodeString( &hcd_name );
}
static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
@@ -1327,6 +1376,7 @@ static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
{
static unsigned int instance_id;
struct DeviceInstance *instance = NULL;
+ UNICODE_STRING link;
instance = HeapAlloc( GetProcessHeap(), 0, sizeof(*instance) );
if (instance == NULL) return;
@@ -1341,7 +1391,11 @@ static void create_root_hub_device( USHORT vid, USHORT pid, void *dev,
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( instance->pdo, instance_id );
+ if (register_root_hub_device( instance->pdo, instance_id, &link ))
+ {
+ create_hcd_device( instance_id, hubdrv, &link );
+ RtlFreeUnicodeString( &link );
+ }
++instance_id;
return;
fail:
--
1.7.4.4
----------- следующая часть -----------
From fa0332408a880d366cdd209bb946ddd1d2f865a5 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 21 Apr 2011 19:30:44 +0400
Subject: [eterhack 3/7] include: Add IOCTL_USB_GET_ROOT_HUB_NAME declaration
(eterbug #6247).
---
include/ddk/usbioctl.h | 2 ++
include/ddk/usbiodef.h | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/include/ddk/usbioctl.h b/include/ddk/usbioctl.h
index fd80b11..89fc9a6 100644
--- a/include/ddk/usbioctl.h
+++ b/include/ddk/usbioctl.h
@@ -26,6 +26,8 @@
#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_USB_GET_ROOT_HUB_NAME CTL_CODE(FILE_DEVICE_USB, HCD_GET_ROOT_HUB_NAME, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
/* Wine extensions */
#ifdef WINE_USBHUB_EXTENSIONS
diff --git a/include/ddk/usbiodef.h b/include/ddk/usbiodef.h
index 7d26f48..05da9ae 100644
--- a/include/ddk/usbiodef.h
+++ b/include/ddk/usbiodef.h
@@ -25,6 +25,8 @@
#define USB_GET_NODE_CONNECTION_INFORMATION 259
#define USB_GET_NODE_CONNECTION_DRIVERKEY_NAME 264
+#define HCD_GET_ROOT_HUB_NAME 258
+
#ifdef WINE_USBHUB_EXTENSIONS
#define USB_GET_DEVICE_INFO 280
#endif
--
1.7.4.4
----------- следующая часть -----------
From 164e6ce41cb0fe47d8537e4ffe09a48a65d0a5c6 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Fri, 22 Apr 2011 20:10:58 +0400
Subject: [eterhack 4/7] mountmgr.sys: Use separate functions for various
IOCTLs (eterbug #6247).
---
dlls/mountmgr.sys/usbhub.c | 457 ++++++++++++++++++++++----------------------
1 files changed, 230 insertions(+), 227 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index ab33fe5..ac9770d 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -63,6 +63,9 @@ extern BOOL CDECL __wine_start_service( const WCHAR *name );
#define NUMBER_OF_PORTS 8
static const WCHAR usbW[] = {'U','S','B',0};
+static const WCHAR device_idW[] = {'U','S','B','\\',
+ 'V','i','d','_','%','0','4','x','&',
+ 'P','i','d','_','%','0','4','x','\\',0};
static struct list RootDevices = LIST_INIT(RootDevices);
static struct list HostControllers = LIST_INIT(HostControllers);
@@ -134,268 +137,268 @@ static void add_data( unsigned char **dst, ULONG *dst_size, const void *src, ULO
*dst_size -= copy;
}
-static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
+#ifdef HAVE_LIBUSB_H
+
+struct DeviceInstance *get_device_by_index( libusb_device *device,
+ ULONG connection_index, ULONG *addr )
{
- 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 DeviceInstance *instance;
+ uint8_t bus_number = libusb_get_bus_number( device );
+ ULONG index = 0;
- IO_STACK_LOCATION *irpsp;
- NTSTATUS status = STATUS_UNSUCCESSFUL;
- struct DeviceInstance *inst;
- ULONG_PTR info = 0;
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ if (instance->dev && instance->dev != device &&
+ libusb_get_bus_number( instance->dev ) == bus_number &&
+ ++index == connection_index)
+ {
+ if (addr)
+ *addr = libusb_get_device_address( instance->dev );
+ return instance;
+ }
+ return NULL;
+}
- TRACE( "%p, %p\n", device, irp );
+#else /* HAVE_LIBUSB_H */
- EnterCriticalSection( &usbhub_cs );
- if (!device_exists( device )) goto done;
- inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
- if (inst->service) goto done;
- irpsp = IoGetCurrentIrpStackLocation( irp );
+struct DeviceInstance *get_device_by_index( struct usb_device *device,
+ ULONG connection_index, ULONG *addr )
+{
+ struct DeviceInstance *instance;
+ struct usb_device *dev;
+ ULONG index = 0;
- switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_USB_GET_NODE_INFORMATION:
- {
- USB_NODE_INFORMATION *node_info = irp->AssociatedIrp.SystemBuffer;
+ for (dev = device->next; dev; dev = dev->next)
+ if (++index == connection_index)
+ LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ if (instance->dev == dev)
+ {
+ if (addr)
+ *addr = dev->devnum;
+ return instance;
+ }
+ return NULL;
+}
+
+#endif /* HAVE_LIBUSB_H */
+
+static NTSTATUS get_node_info( void *buff, ULONG size, ULONG_PTR *outsize )
+{
+ USB_NODE_INFORMATION *node_info = buff;
+
+ if (size < sizeof(*node_info))
+ return STATUS_BUFFER_TOO_SMALL;
+ 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;
+ *outsize = sizeof(*node_info);
+ return STATUS_SUCCESS;
+}
- 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))
+static NTSTATUS get_node_conn_info( struct DeviceInstance *inst, void *buff,
+ ULONG size, ULONG_PTR *outsize )
+{
+ USB_NODE_CONNECTION_INFORMATION *conn_info = buff;
+ ULONG index = 0;
+ struct DeviceInstance *instance;
+ uint8_t bus_number = libusb_get_bus_number( inst->dev );
+
+ if (size < sizeof(*conn_info))
+ return STATUS_BUFFER_TOO_SMALL;
+ if (!conn_info->ConnectionIndex ||
+ conn_info->ConnectionIndex > NUMBER_OF_PORTS)
+ return STATUS_INVALID_PARAMETER;
+ RtlZeroMemory( (ULONG *)conn_info + 1, sizeof(*conn_info) - sizeof(ULONG) );
+ 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)
{
- status = STATUS_BUFFER_TOO_SMALL;
+ 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;
}
- if (!conn_info->ConnectionIndex || conn_info->ConnectionIndex > NUMBER_OF_PORTS)
+ }
+ *outsize = sizeof(*conn_info);
+ return STATUS_SUCCESS;
+}
+
+#else /* HAVE_LIBUSB_H */
+
+static NTSTATUS get_node_conn_info( struct DeviceInstance *inst, void *buff,
+ ULONG size, ULONG_PTR *outsize )
+{
+ USB_NODE_CONNECTION_INFORMATION *conn_info = buff;
+ ULONG index = 0;
+ struct usb_device *dev;
+
+ if (size < sizeof(*conn_info))
+ return STATUS_BUFFER_TOO_SMALL;
+ if (!conn_info->ConnectionIndex ||
+ conn_info->ConnectionIndex > NUMBER_OF_PORTS)
+ return STATUS_INVALID_PARAMETER;
+ RtlZeroMemory( (ULONG *)conn_info + 1, sizeof(*conn_info) - sizeof(ULONG) );
+ for (dev = inst->dev->next; dev; dev = dev->next)
+ if (++index == conn_info->ConnectionIndex)
{
- status = STATUS_INVALID_PARAMETER;
+ memcpy( &conn_info->DeviceDescriptor, &dev->descriptor,
+ sizeof(USB_DEVICE_DESCRIPTOR) );
+ conn_info->ConnectionStatus = 1;
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;
+ *outsize = sizeof(*conn_info);
+ return STATUS_SUCCESS;
+}
- 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;
+#endif /* HAVE_LIBUSB_H */
+
+static NTSTATUS get_node_conn_driverkey_name( struct DeviceInstance *inst,
+ void *buff, ULONG size, ULONG_PTR *outsize )
+{
+ USB_NODE_CONNECTION_DRIVERKEY_NAME *driver_key_name = buff;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ WCHAR *dev_instance_idW, *bufW;
+ struct DeviceInstance *instance;
+ HDEVINFO set;
+ SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
+ ULONG len, index = 0;
+
+ if (size < sizeof(*driver_key_name))
+ return STATUS_BUFFER_TOO_SMALL;
+ instance = get_device_by_index( inst->dev,
+ driver_key_name->ConnectionIndex, NULL );
+ if (instance == NULL)
+ return STATUS_INVALID_PARAMETER;
+ bufW = HeapAlloc( GetProcessHeap(), 0,
+ 2 * MAX_DEVICE_ID_LEN * sizeof(WCHAR) );
+ if (bufW == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ 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 );
+ return STATUS_UNSUCCESSFUL;
}
- case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
+ while (SetupDiEnumDeviceInfo( set, index++, &devInfo ))
{
- 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;
+ if (!SetupDiGetDeviceInstanceIdW( set, &devInfo, bufW,
+ MAX_DEVICE_ID_LEN, NULL ))
break;
- }
-#ifdef HAVE_LIBUSB_H
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
+ if (!strcmpiW( dev_instance_idW, bufW ))
{
- if (instance->dev && instance->dev != inst->dev &&
- libusb_get_bus_number( instance->dev ) == bus_number &&
- ++index == driver_key_name->ConnectionIndex)
+ SetupDiGetDeviceRegistryPropertyW( set, &devInfo, SPDRP_DRIVER,
+ NULL, NULL, 0, &len );
+ driver_key_name->ActualLength = 2 * sizeof(ULONG) + len;
+ if (size < driver_key_name->ActualLength)
{
- found = 1;
- break;
+ status = STATUS_SUCCESS;
+ *outsize = sizeof(*driver_key_name);
}
- }
-#else
- for (dev = inst->dev->next; dev; dev = dev->next)
- if (++index == driver_key_name->ConnectionIndex)
+ else if (SetupDiGetDeviceRegistryPropertyW( set, &devInfo,
+ SPDRP_DRIVER, NULL, (BYTE *)driver_key_name->DriverKeyName,
+ len, NULL ))
{
- LIST_FOR_EACH_ENTRY( instance, &Devices, struct DeviceInstance, entry )
- {
- if (instance->dev == dev)
- {
- found = 1;
- break;
- }
- }
- break;
+ status = STATUS_SUCCESS;
+ *outsize = driver_key_name->ActualLength;
}
-#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,
+ }
+ SetupDiDestroyDeviceInfoList( set );
+ HeapFree( GetProcessHeap(), 0, bufW );
+ return status;
+}
+
+static NTSTATUS get_device_info( struct DeviceInstance *inst, void *buff,
+ ULONG size, ULONG_PTR *outsize )
+{
+ static const WCHAR root_hub_idW[] = {'U','S','B','\\',
+ 'R','O','O','T','_','H','U','B',0};
+
+ struct usb_device_info *dev_info = buff;
+ struct DeviceInstance *instance;
+ ULONG len;
+
+ if (size < sizeof(*dev_info))
+ return STATUS_BUFFER_TOO_SMALL;
+ if (!dev_info->connection_index ||
+ dev_info->connection_index > NUMBER_OF_PORTS)
+ return STATUS_INVALID_PARAMETER;
+ 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 );
+ instance = get_device_by_index( inst->dev, dev_info->connection_index,
+ &dev_info->device_address );
+ if (dev_info->device_address)
+ {
+ snprintfW( dev_info->device_id, MAX_DEVICE_ID_LEN, device_idW,
instance->vid, instance->pid );
- len = strlenW(dev_instance_idW);
- RtlMultiByteToUnicodeN( dev_instance_idW + len,
+ 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 );
- 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:
+ *outsize = sizeof(*dev_info);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
+{
+ IO_STACK_LOCATION *irpsp;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ struct DeviceInstance *inst;
+ ULONG_PTR info = 0;
+
+ TRACE( "%p, %p\n", device, irp );
+
+ EnterCriticalSection( &usbhub_cs );
+ irpsp = IoGetCurrentIrpStackLocation( irp );
+ if (device_exists( device ))
{
- 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
+ inst = ((struct PdoExtension *)device->DeviceExtension)->instance;
+ if (inst->service) goto done;
- if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*dev_info))
+ switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
{
- status = STATUS_BUFFER_TOO_SMALL;
+ case IOCTL_USB_GET_NODE_INFORMATION:
+ status = get_node_info( irp->AssociatedIrp.SystemBuffer,
+ irpsp->Parameters.DeviceIoControl.OutputBufferLength, &info );
break;
- }
- if (!dev_info->connection_index || dev_info->connection_index > NUMBER_OF_PORTS)
- {
- status = STATUS_INVALID_PARAMETER;
+ case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
+ status = get_node_conn_info( inst, irp->AssociatedIrp.SystemBuffer,
+ irpsp->Parameters.DeviceIoControl.OutputBufferLength, &info );
break;
+ case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
+ status = get_node_conn_driverkey_name( inst,
+ irp->AssociatedIrp.SystemBuffer,
+ irpsp->Parameters.DeviceIoControl.OutputBufferLength, &info );
+ break;
+ case IOCTL_USB_GET_DEVICE_INFO:
+ status = get_device_info( inst, irp->AssociatedIrp.SystemBuffer,
+ irpsp->Parameters.DeviceIoControl.OutputBufferLength, &info );
+ break;
+ default:
+ FIXME( "IOCTL %08x is not implemented\n",
+ irpsp->Parameters.DeviceIoControl.IoControlCode );
}
- 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:
--
1.7.4.4
----------- следующая часть -----------
From 3b9dda85ead2e581d73f196b069051ced93826b6 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Fri, 22 Apr 2011 20:15:26 +0400
Subject: [eterhack 5/7] mountmgr.sys: Add support for
IOCTL_USB_GET_ROOT_HUB_NAME (eterbug #6247).
---
dlls/mountmgr.sys/usbhub.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
include/ddk/usbioctl.h | 5 ++++
2 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index ac9770d..6eea21a 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -127,6 +127,16 @@ static BOOL device_exists( DEVICE_OBJECT *device )
return FALSE;
}
+static struct HCDInstance *get_hcd_instance( DEVICE_OBJECT *device )
+{
+ struct HCDInstance *instance;
+
+ LIST_FOR_EACH_ENTRY( instance, &HostControllers, struct HCDInstance, entry )
+ if (instance->dev == device)
+ return instance;
+ return NULL;
+}
+
static void add_data( unsigned char **dst, ULONG *dst_size, const void *src, ULONG src_size )
{
int copy;
@@ -181,6 +191,27 @@ struct DeviceInstance *get_device_by_index( struct usb_device *device,
#endif /* HAVE_LIBUSB_H */
+static NTSTATUS get_root_hub_name( struct HCDInstance *instance, void *buff,
+ ULONG size, ULONG_PTR *outsize )
+{
+ USB_HCD_DRIVERKEY_NAME *name = buff;
+ ULONG name_size;
+
+ if (size < sizeof(*name))
+ return STATUS_BUFFER_TOO_SMALL;
+ RtlZeroMemory( buff, size );
+ name_size = (strlenW(instance->root_hub_name) - 4 + 1) * sizeof(WCHAR);
+ name->ActualLength = sizeof(*name) - sizeof(WCHAR) + name_size;
+ if (size >= name->ActualLength)
+ {
+ memcpy( name->DriverKeyName, instance->root_hub_name + 4, name_size );
+ *outsize = name->ActualLength;
+ }
+ else
+ *outsize = sizeof(*name);
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS get_node_info( void *buff, ULONG size, ULONG_PTR *outsize )
{
USB_NODE_INFORMATION *node_info = buff;
@@ -365,6 +396,7 @@ static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
IO_STACK_LOCATION *irpsp;
NTSTATUS status = STATUS_UNSUCCESSFUL;
struct DeviceInstance *inst;
+ struct HCDInstance *hcd_inst;
ULONG_PTR info = 0;
TRACE( "%p, %p\n", device, irp );
@@ -400,6 +432,19 @@ static NTSTATUS WINAPI usbhub_ioctl( DEVICE_OBJECT *device, IRP *irp )
irpsp->Parameters.DeviceIoControl.IoControlCode );
}
}
+ else if ((hcd_inst = get_hcd_instance( device )))
+ {
+ switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_USB_GET_ROOT_HUB_NAME:
+ status = get_root_hub_name( hcd_inst, irp->AssociatedIrp.SystemBuffer,
+ irpsp->Parameters.DeviceIoControl.OutputBufferLength, &info );
+ break;
+ default:
+ FIXME( "IOCTL %08x is not implemented for HCD\n",
+ irpsp->Parameters.DeviceIoControl.IoControlCode );
+ }
+ }
done:
LeaveCriticalSection( &usbhub_cs );
diff --git a/include/ddk/usbioctl.h b/include/ddk/usbioctl.h
index 89fc9a6..6e1dcb5 100644
--- a/include/ddk/usbioctl.h
+++ b/include/ddk/usbioctl.h
@@ -102,6 +102,11 @@ typedef struct _USB_NODE_CONNECTION_DRIVERKEY_NAME {
WCHAR DriverKeyName[1];
} USB_NODE_CONNECTION_DRIVERKEY_NAME, *PUSB_NODE_CONNECTION_DRIVERKEY_NAME;
+typedef struct _USB_HCD_DRIVERKEY_NAME {
+ ULONG ActualLength;
+ WCHAR DriverKeyName[1];
+} USB_HCD_DRIVERKEY_NAME, *PUSB_HCD_DRIVERKEY_NAME;
+
#include <poppack.h>
#endif /* __USBIOCTL_H__ */
--
1.7.4.4
----------- следующая часть -----------
From 32ca3612de146186ce529d636c2e298b61a3d3f9 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 25 Apr 2011 20:32:55 +0400
Subject: [eterhack 6/7] mountmgr.sys: Add CurrentConfigurationValue field
support (eterbug #6247).
---
dlls/mountmgr.sys/usbhub.c | 43 +++++++++++++++++++++++++++++++++++++------
1 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index 6eea21a..ee31eee 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -235,6 +235,7 @@ static NTSTATUS get_node_conn_info( struct DeviceInstance *inst, void *buff,
ULONG index = 0;
struct DeviceInstance *instance;
uint8_t bus_number = libusb_get_bus_number( inst->dev );
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
if (size < sizeof(*conn_info))
return STATUS_BUFFER_TOO_SMALL;
@@ -249,17 +250,31 @@ static NTSTATUS get_node_conn_info( struct DeviceInstance *inst, void *buff,
++index == conn_info->ConnectionIndex)
{
struct libusb_device_descriptor desc;
+ libusb_device_handle *husb;
+ int config, ret;
if (libusb_get_device_descriptor( instance->dev, &desc ))
break;
memcpy( &conn_info->DeviceDescriptor, &desc,
sizeof(USB_DEVICE_DESCRIPTOR) );
- conn_info->ConnectionStatus = 1;
+ ret = libusb_open( instance->dev, &husb );
+ if (!ret)
+ {
+ ret = libusb_get_configuration( husb, &config );
+ if (!ret)
+ conn_info->CurrentConfigurationValue = config;
+ libusb_close( husb );
+ }
+ if (!ret)
+ {
+ conn_info->ConnectionStatus = 1;
+ *outsize = sizeof(*conn_info);
+ status = STATUS_SUCCESS;
+ }
break;
}
}
- *outsize = sizeof(*conn_info);
- return STATUS_SUCCESS;
+ return status;
}
#else /* HAVE_LIBUSB_H */
@@ -270,6 +285,7 @@ static NTSTATUS get_node_conn_info( struct DeviceInstance *inst, void *buff,
USB_NODE_CONNECTION_INFORMATION *conn_info = buff;
ULONG index = 0;
struct usb_device *dev;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
if (size < sizeof(*conn_info))
return STATUS_BUFFER_TOO_SMALL;
@@ -280,13 +296,28 @@ static NTSTATUS get_node_conn_info( struct DeviceInstance *inst, void *buff,
for (dev = inst->dev->next; dev; dev = dev->next)
if (++index == conn_info->ConnectionIndex)
{
+ usb_dev_handle *husb;
+ int ret = -1;
+
memcpy( &conn_info->DeviceDescriptor, &dev->descriptor,
sizeof(USB_DEVICE_DESCRIPTOR) );
- conn_info->ConnectionStatus = 1;
+ husb = usb_open( inst->dev );
+ if (husb)
+ {
+ ret = usb_control_msg( husb, 1 << 7, USB_REQ_GET_CONFIGURATION,
+ 0, 0, (char *)&conn_info->CurrentConfigurationValue,
+ sizeof(UCHAR), 0 );
+ usb_close( husb );
+ }
+ if (ret >= 0)
+ {
+ conn_info->ConnectionStatus = 1;
+ *outsize = sizeof(*conn_info);
+ status = STATUS_SUCCESS;
+ }
break;
}
- *outsize = sizeof(*conn_info);
- return STATUS_SUCCESS;
+ return status;
}
#endif /* HAVE_LIBUSB_H */
--
1.7.4.4
----------- следующая часть -----------
From 5f69535e3aff671ca41fa5ddaf98ad50b6280709 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 25 Apr 2011 20:54:08 +0400
Subject: [eterhack 7/7] mountmgr.sys: Do not use ERR for USB devices errors.
---
dlls/mountmgr.sys/usbhub.c | 20 ++++++--------------
1 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/dlls/mountmgr.sys/usbhub.c b/dlls/mountmgr.sys/usbhub.c
index ee31eee..287f89c 100644
--- a/dlls/mountmgr.sys/usbhub.c
+++ b/dlls/mountmgr.sys/usbhub.c
@@ -527,7 +527,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
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 ))
@@ -799,9 +799,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
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 (ret >= 0)
{
if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
{
@@ -877,7 +875,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
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
@@ -1072,9 +1070,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
{
ret = usb_get_string( husb, request->Index,
request->LanguageId, (void *)buf, size );
- if (ret < 0)
- ERR( "%s\n", usb_strerror() );
- else
+ if (ret >= 0)
status = STATUS_SUCCESS;
usb_close( husb );
}
@@ -1104,9 +1100,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
{
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
+ if (ret >= 0)
status = STATUS_SUCCESS;
usb_close( husb );
}
@@ -1158,9 +1152,7 @@ static NTSTATUS WINAPI usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
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 (ret >= 0)
{
if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
{
--
1.7.4.4
Подробная информация о списке рассылки Wine-patches