[Wine-devel] [eterhack branch] [try 3] support of native Windows drivers for USB tokens (bug 1660)
Alexander Morozov
=?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Вт Июн 17 20:03:11 MSD 2008
----------- следующая часть -----------
From 6d14fde505ff42d332310b956affe786cd0dd2b2 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 17 Jun 2008 19:58:23 +0400
Subject: [PATCH] Support of native Windows drivers for USB tokens
---
Makefile.in | 6 +
configure | 9 +
configure.ac | 3 +
dlls/Makefile.in | 6 +
dlls/hal/hal.c | 6 +
dlls/hal/hal.spec | 2 +-
dlls/ntoskrnl.exe/ntoskrnl.c | 433 ++++++++++++++++++++++++++++++++---
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 36 ++--
dlls/usbd.sys/Makefile.in | 15 ++
dlls/usbd.sys/usbd.c | 129 +++++++++++
dlls/usbd.sys/usbd.sys.spec | 35 +++
dlls/wineusbhub/Makefile.in | 15 ++
dlls/wineusbhub/wineusbhub.c | 334 +++++++++++++++++++++++++++
dlls/wineusbhub/wineusbhub.spec | 7 +
include/ddk/ntddk.h | 9 +
include/ddk/usb.h | 340 +++++++++++++++++++++++++++
include/ddk/usb100.h | 99 ++++++++
include/ddk/usb200.h | 22 ++
include/ddk/usbdlib.h | 26 ++
include/ddk/wdm.h | 130 ++++++++++-
include/wine/server_protocol.h | 35 +++-
programs/Makefile.in | 2 +
programs/winedevice/Makefile.in | 2 +-
programs/winedevice/device.c | 102 ++++++++-
programs/wineusb/Makefile.in | 15 ++
programs/wineusb/main.c | 217 ++++++++++++++++++
server/device.c | 111 +++++++++
server/protocol.def | 16 ++
server/request.h | 4 +
server/trace.c | 28 +++
tools/wine.inf.in | 10 +
31 files changed, 2149 insertions(+), 55 deletions(-)
create mode 100644 dlls/usbd.sys/Makefile.in
create mode 100644 dlls/usbd.sys/usbd.c
create mode 100644 dlls/usbd.sys/usbd.sys.spec
create mode 100644 dlls/wineusbhub/Makefile.in
create mode 100644 dlls/wineusbhub/wineusbhub.c
create mode 100644 dlls/wineusbhub/wineusbhub.spec
create mode 100644 include/ddk/usb.h
create mode 100644 include/ddk/usb100.h
create mode 100644 include/ddk/usb200.h
create mode 100644 include/ddk/usbdlib.h
create mode 100644 programs/wineusb/Makefile.in
create mode 100644 programs/wineusb/main.c
diff --git a/Makefile.in b/Makefile.in
index b372ec8..fb05bc5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -459,6 +459,7 @@ ALL_MAKEFILES = \
dlls/url/Makefile \
dlls/urlmon/Makefile \
dlls/urlmon/tests/Makefile \
+ dlls/usbd.sys/Makefile \
dlls/user32/Makefile \
dlls/user32/tests/Makefile \
dlls/userenv/Makefile \
@@ -493,6 +494,7 @@ ALL_MAKEFILES = \
dlls/wineoss.drv/Makefile \
dlls/wineps.drv/Makefile \
dlls/winequartz.drv/Makefile \
+ dlls/wineusbhub/Makefile \
dlls/winex11.drv/Makefile \
dlls/wing32/Makefile \
dlls/winhttp/Makefile \
@@ -564,6 +566,7 @@ ALL_MAKEFILES = \
programs/winemine/Makefile \
programs/winepath/Makefile \
programs/winetest/Makefile \
+ programs/wineusb/Makefile \
programs/winevdm/Makefile \
programs/winhlp32/Makefile \
programs/winver/Makefile \
@@ -888,6 +891,7 @@ dlls/unicows/Makefile: dlls/unicows/Makefile.in dlls/Makedll.rules
dlls/url/Makefile: dlls/url/Makefile.in dlls/Makedll.rules
dlls/urlmon/Makefile: dlls/urlmon/Makefile.in dlls/Makedll.rules
dlls/urlmon/tests/Makefile: dlls/urlmon/tests/Makefile.in dlls/Maketest.rules
+dlls/usbd.sys/Makefile: dlls/usbd.sys/Makefile.in dlls/Makedll.rules
dlls/user32/Makefile: dlls/user32/Makefile.in dlls/Makedll.rules
dlls/user32/tests/Makefile: dlls/user32/tests/Makefile.in dlls/Maketest.rules
dlls/userenv/Makefile: dlls/userenv/Makefile.in dlls/Makedll.rules
@@ -921,6 +925,7 @@ dlls/winenas.drv/Makefile: dlls/winenas.drv/Makefile.in dlls/Makedll.rules
dlls/wineoss.drv/Makefile: dlls/wineoss.drv/Makefile.in dlls/Makedll.rules
dlls/wineps.drv/Makefile: dlls/wineps.drv/Makefile.in dlls/Makedll.rules
dlls/winequartz.drv/Makefile: dlls/winequartz.drv/Makefile.in dlls/Makedll.rules
+dlls/wineusbhub/Makefile: dlls/wineusbhub/Makefile.in dlls/Makedll.rules
dlls/winex11.drv/Makefile: dlls/winex11.drv/Makefile.in dlls/Makedll.rules
dlls/wing32/Makefile: dlls/wing32/Makefile.in dlls/Makedll.rules
dlls/winhttp/Makefile: dlls/winhttp/Makefile.in dlls/Makedll.rules
@@ -991,6 +996,7 @@ programs/winemenubuilder/Makefile: programs/winemenubuilder/Makefile.in programs
programs/winemine/Makefile: programs/winemine/Makefile.in programs/Makeprog.rules
programs/winepath/Makefile: programs/winepath/Makefile.in programs/Makeprog.rules
programs/winetest/Makefile: programs/winetest/Makefile.in programs/Makeprog.rules
+programs/wineusb/Makefile: programs/wineusb/Makefile.in programs/Makeprog.rules
programs/winevdm/Makefile: programs/winevdm/Makefile.in programs/Makeprog.rules
programs/winhlp32/Makefile: programs/winhlp32/Makefile.in programs/Makeprog.rules
programs/winver/Makefile: programs/winver/Makefile.in programs/Makeprog.rules
diff --git a/configure b/configure
index 550be0a..d00c617 100755
--- a/configure
+++ b/configure
@@ -22853,6 +22853,8 @@ ac_config_files="$ac_config_files dlls/urlmon/Makefile"
ac_config_files="$ac_config_files dlls/urlmon/tests/Makefile"
+ac_config_files="$ac_config_files dlls/usbd.sys/Makefile"
+
ac_config_files="$ac_config_files dlls/user32/Makefile"
ac_config_files="$ac_config_files dlls/user32/tests/Makefile"
@@ -22921,6 +22923,8 @@ ac_config_files="$ac_config_files dlls/wineps.drv/Makefile"
ac_config_files="$ac_config_files dlls/winequartz.drv/Makefile"
+ac_config_files="$ac_config_files dlls/wineusbhub/Makefile"
+
ac_config_files="$ac_config_files dlls/winex11.drv/Makefile"
ac_config_files="$ac_config_files dlls/wing32/Makefile"
@@ -23063,6 +23067,8 @@ ac_config_files="$ac_config_files programs/winepath/Makefile"
ac_config_files="$ac_config_files programs/winetest/Makefile"
+ac_config_files="$ac_config_files programs/wineusb/Makefile"
+
ac_config_files="$ac_config_files programs/winevdm/Makefile"
ac_config_files="$ac_config_files programs/winhlp32/Makefile"
@@ -23955,6 +23961,7 @@ do
"dlls/url/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/url/Makefile" ;;
"dlls/urlmon/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/urlmon/Makefile" ;;
"dlls/urlmon/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/urlmon/tests/Makefile" ;;
+ "dlls/usbd.sys/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/usbd.sys/Makefile" ;;
"dlls/user32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/user32/Makefile" ;;
"dlls/user32/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/user32/tests/Makefile" ;;
"dlls/userenv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/userenv/Makefile" ;;
@@ -23989,6 +23996,7 @@ do
"dlls/wineoss.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/wineoss.drv/Makefile" ;;
"dlls/wineps.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/wineps.drv/Makefile" ;;
"dlls/winequartz.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winequartz.drv/Makefile" ;;
+ "dlls/wineusbhub/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/wineusbhub/Makefile" ;;
"dlls/winex11.drv/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winex11.drv/Makefile" ;;
"dlls/wing32/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/wing32/Makefile" ;;
"dlls/winhttp/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/winhttp/Makefile" ;;
@@ -24060,6 +24068,7 @@ do
"programs/winemine/Makefile") CONFIG_FILES="$CONFIG_FILES programs/winemine/Makefile" ;;
"programs/winepath/Makefile") CONFIG_FILES="$CONFIG_FILES programs/winepath/Makefile" ;;
"programs/winetest/Makefile") CONFIG_FILES="$CONFIG_FILES programs/winetest/Makefile" ;;
+ "programs/wineusb/Makefile") CONFIG_FILES="$CONFIG_FILES programs/wineusb/Makefile" ;;
"programs/winevdm/Makefile") CONFIG_FILES="$CONFIG_FILES programs/winevdm/Makefile" ;;
"programs/winhlp32/Makefile") CONFIG_FILES="$CONFIG_FILES programs/winhlp32/Makefile" ;;
"programs/winver/Makefile") CONFIG_FILES="$CONFIG_FILES programs/winver/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index 10399e7..caa61de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1975,6 +1975,7 @@ AC_CONFIG_FILES([dlls/unicows/Makefile])
AC_CONFIG_FILES([dlls/url/Makefile])
AC_CONFIG_FILES([dlls/urlmon/Makefile])
AC_CONFIG_FILES([dlls/urlmon/tests/Makefile])
+AC_CONFIG_FILES([dlls/usbd.sys/Makefile])
AC_CONFIG_FILES([dlls/user32/Makefile])
AC_CONFIG_FILES([dlls/user32/tests/Makefile])
AC_CONFIG_FILES([dlls/userenv/Makefile])
@@ -2009,6 +2010,7 @@ AC_CONFIG_FILES([dlls/winenas.drv/Makefile])
AC_CONFIG_FILES([dlls/wineoss.drv/Makefile])
AC_CONFIG_FILES([dlls/wineps.drv/Makefile])
AC_CONFIG_FILES([dlls/winequartz.drv/Makefile])
+AC_CONFIG_FILES([dlls/wineusbhub/Makefile])
AC_CONFIG_FILES([dlls/winex11.drv/Makefile])
AC_CONFIG_FILES([dlls/wing32/Makefile])
AC_CONFIG_FILES([dlls/winhttp/Makefile])
@@ -2080,6 +2082,7 @@ AC_CONFIG_FILES([programs/winemenubuilder/Makefile])
AC_CONFIG_FILES([programs/winemine/Makefile])
AC_CONFIG_FILES([programs/winepath/Makefile])
AC_CONFIG_FILES([programs/winetest/Makefile])
+AC_CONFIG_FILES([programs/wineusb/Makefile])
AC_CONFIG_FILES([programs/winevdm/Makefile])
AC_CONFIG_FILES([programs/winhlp32/Makefile])
AC_CONFIG_FILES([programs/winver/Makefile])
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index c4f1872..4d05a45 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -232,6 +232,7 @@ BASEDIRS = \
unicows \
url \
urlmon \
+ usbd.sys \
user32 \
userenv \
usp10 \
@@ -258,6 +259,7 @@ BASEDIRS = \
winenas.drv \
wineoss.drv \
wineps.drv \
+ wineusbhub \
wing32 \
winhttp \
wininet \
@@ -660,6 +662,7 @@ IMPORT_LIBS = \
version/libversion.$(IMPLIBEXT) \
wined3d/libwined3d.$(IMPLIBEXT) \
winedos/libwinedos.$(IMPLIBEXT) \
+ wineusbhub/libwineusbhub.$(IMPLIBEXT) \
wininet/libwininet.$(IMPLIBEXT) \
winmm/libwinmm.$(IMPLIBEXT) \
winnls32/libwinnls32.$(IMPLIBEXT) \
@@ -1038,6 +1041,9 @@ wined3d/libwined3d.$(IMPLIBEXT): wined3d/wined3d.spec $(WINEBUILD)
winedos/libwinedos.$(IMPLIBEXT): winedos/winedos.spec $(WINEBUILD)
@cd winedos && $(MAKE) libwinedos.$(IMPLIBEXT)
+wineusbhub/libwineusbhub.$(IMPLIBEXT): wineusbhub/wineusbhub.spec $(WINEBUILD)
+ @cd wineusbhub && $(MAKE) libwineusbhub.$(IMPLIBEXT)
+
wininet/libwininet.$(IMPLIBEXT): wininet/wininet.spec $(WINEBUILD)
@cd wininet && $(MAKE) libwininet.$(IMPLIBEXT)
diff --git a/dlls/hal/hal.c b/dlls/hal/hal.c
index 0b64809..253e01f 100644
--- a/dlls/hal/hal.c
+++ b/dlls/hal/hal.c
@@ -106,3 +106,9 @@ ULONG WINAPI HalGetBusData(BUS_DATA_TYPE BusDataType, ULONG BusNumber, ULONG Slo
/* Claim that there is no such bus */
return 0;
}
+
+KIRQL WINAPI KeGetCurrentIrql(void)
+{
+ FIXME( "stub!\n" );
+ return 0;
+}
diff --git a/dlls/hal/hal.spec b/dlls/hal/hal.spec
index 5afbee0..84945eb 100644
--- a/dlls/hal/hal.spec
+++ b/dlls/hal/hal.spec
@@ -70,7 +70,7 @@
@ stub KdComPortInUse
@ stub KeAcquireSpinLock
@ stub KeFlushWriteBuffer
-@ stub KeGetCurrentIrql
+@ stdcall KeGetCurrentIrql()
@ stub KeLowerIrql
@ stub KeQueryPerformanceCounter
@ stub KeRaiseIrql
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index cda3476..0dc8be3 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -31,9 +31,11 @@
#include "windef.h"
#include "winternl.h"
#include "excpt.h"
-#include "ddk/wdm.h"
+#include "winioctl.h"
+#include "ddk/ntddk.h"
#include "wine/unicode.h"
#include "wine/server.h"
+#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
@@ -54,6 +56,14 @@ KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[4];
typedef void (WINAPI *PCREATE_PROCESS_NOTIFY_ROUTINE)(HANDLE,HANDLE,BOOLEAN);
+static struct list Irps = LIST_INIT(Irps);
+
+struct IrpInstance
+{
+ struct list entry;
+ IRP *irp;
+};
+
#ifdef __i386__
#define DEFINE_FASTCALL1_ENTRYPOINT( name ) \
__ASM_GLOBAL_FUNC( name, \
@@ -125,55 +135,81 @@ static LONG CALLBACK vectored_handler( EXCEPTION_POINTERS *ptrs )
static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff, ULONG in_size,
void *out_buff, ULONG *out_size )
{
- IRP irp;
+ PIRP irp;
MDL mdl;
- IO_STACK_LOCATION irpsp;
+ PIO_STACK_LOCATION irpsp;
PDRIVER_DISPATCH dispatch = device->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
NTSTATUS status;
LARGE_INTEGER count;
+ CHAR *buf = NULL;
TRACE( "ioctl %x device %p in_size %u out_size %u\n", code, device, in_size, *out_size );
- /* so we can spot things that we should initialize */
- memset( &irp, 0x55, sizeof(irp) );
- memset( &irpsp, 0x66, sizeof(irpsp) );
- memset( &mdl, 0x77, sizeof(mdl) );
+ irp = IoAllocateIrp( device->StackSize, FALSE );
+ if (irp == NULL)
+ return STATUS_UNSUCCESSFUL;
- irp.RequestorMode = UserMode;
- irp.AssociatedIrp.SystemBuffer = in_buff;
- irp.UserBuffer = out_buff;
- irp.MdlAddress = &mdl;
- irp.Tail.Overlay.s.u.CurrentStackLocation = &irpsp;
+ --irp->CurrentLocation;
+ irpsp = --irp->Tail.Overlay.s.u.CurrentStackLocation;
- irpsp.MajorFunction = IRP_MJ_DEVICE_CONTROL;
- irpsp.Parameters.DeviceIoControl.OutputBufferLength = *out_size;
- irpsp.Parameters.DeviceIoControl.InputBufferLength = in_size;
- irpsp.Parameters.DeviceIoControl.IoControlCode = code;
- irpsp.Parameters.DeviceIoControl.Type3InputBuffer = in_buff;
- irpsp.DeviceObject = device;
-
- mdl.Next = NULL;
- mdl.Size = 0;
- mdl.StartVa = out_buff;
- mdl.ByteCount = *out_size;
- mdl.ByteOffset = 0;
+ switch (code & 3)
+ {
+ case METHOD_BUFFERED:
+ buf = ExAllocatePool( NonPagedPool, (*out_size > in_size) ? *out_size : in_size );
+ if (buf == NULL)
+ {
+ IoFreeIrp( irp );
+ return STATUS_UNSUCCESSFUL;
+ }
+ memcpy( buf, in_buff, in_size );
+ irp->AssociatedIrp.SystemBuffer = buf;
+ irp->UserBuffer = out_buff;
+ break;
+ case METHOD_NEITHER:
+ irpsp->Parameters.DeviceIoControl.Type3InputBuffer = in_buff;
+ irp->UserBuffer = out_buff;
+ break;
+ default:
+ irp->AssociatedIrp.SystemBuffer = in_buff;
+ irp->MdlAddress = &mdl;
+ mdl.Next = NULL;
+ mdl.Size = 0;
+ mdl.StartVa = out_buff;
+ mdl.ByteCount = *out_size;
+ mdl.ByteOffset = 0;
+ }
- device->CurrentIrp = &irp;
+ irp->RequestorMode = UserMode;
+ irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
+ irpsp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
+ irpsp->Parameters.DeviceIoControl.OutputBufferLength = *out_size;
+ irpsp->Parameters.DeviceIoControl.InputBufferLength = in_size;
+ irpsp->Parameters.DeviceIoControl.IoControlCode = code;
+ irpsp->DeviceObject = device;
+ device->CurrentIrp = irp;
KeQueryTickCount( &count ); /* update the global KeTickCount */
if (TRACE_ON(relay))
DPRINTF( "%04x:Call driver dispatch %p (device=%p,irp=%p)\n",
- GetCurrentThreadId(), dispatch, device, &irp );
+ GetCurrentThreadId(), dispatch, device, irp );
- status = dispatch( device, &irp );
+ status = dispatch( device, irp );
if (TRACE_ON(relay))
DPRINTF( "%04x:Ret driver dispatch %p (device=%p,irp=%p) retval=%08x\n",
- GetCurrentThreadId(), dispatch, device, &irp, status );
+ GetCurrentThreadId(), dispatch, device, irp, status );
- *out_size = (irp.IoStatus.u.Status >= 0) ? irp.IoStatus.Information : 0;
- return irp.IoStatus.u.Status;
+ status = irp->IoStatus.u.Status;
+ *out_size = (status >= 0) ? irp->IoStatus.Information : 0;
+ IoFreeIrp( irp );
+ if (buf != NULL)
+ {
+ memcpy( out_buff, buf, *out_size );
+ ExFreePool( buf );
+ }
+
+ return status;
}
@@ -248,6 +284,71 @@ NTSTATUS wine_ntoskrnl_main_loop( HANDLE stop_event )
}
/***********************************************************************
+ * IoAcquireCancelSpinLock (NTOSKRNL.EXE.@)
+ */
+void WINAPI IoAcquireCancelSpinLock( PKIRQL Irql )
+{
+ FIXME( "%p\n", Irql );
+}
+
+/***********************************************************************
+ * IoReleaseCancelSpinLock (NTOSKRNL.EXE.@)
+ */
+void WINAPI IoReleaseCancelSpinLock( KIRQL Irql )
+{
+ FIXME( "%u\n", Irql );
+}
+
+/***********************************************************************
+ * IoInitializeIrp (NTOSKRNL.EXE.@)
+ */
+void WINAPI IoInitializeIrp( IRP *irp, USHORT size, CCHAR stack_size )
+{
+ TRACE( "%p, %u, %d\n", irp, size, stack_size );
+
+ RtlZeroMemory( irp, size );
+
+ irp->Type = 6;
+ irp->Size = size;
+ InitializeListHead( &irp->ThreadListEntry );
+ irp->StackCount = stack_size;
+ irp->CurrentLocation = stack_size + 1;
+ irp->Tail.Overlay.s.u.CurrentStackLocation =
+ (PIO_STACK_LOCATION)(irp + 1) + stack_size;
+}
+
+/***********************************************************************
+ * IoAllocateIrp (NTOSKRNL.EXE.@)
+ */
+PIRP WINAPI IoAllocateIrp( CCHAR stack_size, BOOLEAN charge_quota )
+{
+ SIZE_T size;
+ PIRP irp;
+
+ TRACE( "%d, %d\n", stack_size, charge_quota );
+
+ size = sizeof(IRP) + stack_size * sizeof(IO_STACK_LOCATION);
+ irp = ExAllocatePool( NonPagedPool, size );
+ if (irp != NULL)
+ IoInitializeIrp( irp, size, stack_size );
+ irp->AllocationFlags = IRP_ALLOCATED_FIXED_SIZE;
+ if (charge_quota)
+ irp->AllocationFlags |= IRP_LOOKASIDE_ALLOCATION;
+
+ return irp;
+}
+
+/***********************************************************************
+ * IoFreeIrp (NTOSKRNL.EXE.@)
+ */
+void WINAPI IoFreeIrp( IRP *irp )
+{
+ TRACE( "%p\n", irp );
+
+ ExFreePool( irp );
+}
+
+/***********************************************************************
* IoAllocateMdl (NTOSKRNL.EXE.@)
*/
PMDL WINAPI IoAllocateMdl( PVOID VirtualAddress, ULONG Length, BOOLEAN SecondaryBuffer, BOOLEAN ChargeQuota, PIRP Irp )
@@ -266,6 +367,65 @@ PIO_WORKITEM WINAPI IoAllocateWorkItem( PDEVICE_OBJECT DeviceObject )
return NULL;
}
+/***********************************************************************
+ * IoAttachDeviceToDeviceStack (NTOSKRNL.EXE.@)
+ */
+PDEVICE_OBJECT WINAPI IoAttachDeviceToDeviceStack( DEVICE_OBJECT *source,
+ DEVICE_OBJECT *target )
+{
+ TRACE( "%p, %p\n", source, target );
+ target->AttachedDevice = source;
+ source->StackSize = target->StackSize + 1;
+ return target;
+}
+
+/***********************************************************************
+ * IoBuildDeviceIoControlRequest (NTOSKRNL.EXE.@)
+ */
+PIRP WINAPI IoBuildDeviceIoControlRequest( ULONG IoControlCode,
+ PDEVICE_OBJECT DeviceObject,
+ PVOID InputBuffer,
+ ULONG InputBufferLength,
+ PVOID OutputBuffer,
+ ULONG OutputBufferLength,
+ BOOLEAN InternalDeviceIoControl,
+ PKEVENT Event,
+ PIO_STATUS_BLOCK IoStatusBlock )
+{
+ PIRP irp;
+ PIO_STACK_LOCATION irpsp;
+ struct IrpInstance *instance;
+
+ TRACE( "%x, %p, %p, %u, %p, %u, %u, %p, %p\n",
+ IoControlCode, DeviceObject, InputBuffer, InputBufferLength,
+ OutputBuffer, OutputBufferLength, InternalDeviceIoControl,
+ Event, IoStatusBlock );
+
+ if (DeviceObject == NULL)
+ return NULL;
+
+ irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );
+ 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 = irp->Tail.Overlay.s.u.CurrentStackLocation - 1;
+ irpsp->MajorFunction = InternalDeviceIoControl ?
+ IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
+ irpsp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
+ irp->UserIosb = IoStatusBlock;
+ irp->UserEvent = Event;
+
+ return irp;
+}
/***********************************************************************
* IoCreateDriver (NTOSKRNL.EXE.@)
@@ -347,9 +507,14 @@ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size,
if (status == STATUS_SUCCESS)
{
+ device->Type = 3;
+ device->Size = sizeof(*device) + ext_size;
device->DriverObject = driver;
+ device->Flags = DO_DEVICE_INITIALIZING;
+ if (name) device->Flags |= DO_DEVICE_HAS_NAME;
device->DeviceExtension = device + 1;
device->DeviceType = type;
+ device->StackSize = 1;
device->Reserved = handle;
device->NextDevice = driver->DeviceObject;
@@ -412,6 +577,58 @@ NTSTATUS WINAPI IoCreateSymbolicLink( UNICODE_STRING *name, UNICODE_STRING *targ
/***********************************************************************
+ * IoRegisterDeviceInterface (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI IoRegisterDeviceInterface( PDEVICE_OBJECT PhysicalDeviceObject,
+ CONST GUID *InterfaceClassGuid,
+ PUNICODE_STRING ReferenceString,
+ PUNICODE_STRING SymbolicLinkName )
+{
+ FIXME( "%p %p %p %p\n", PhysicalDeviceObject, InterfaceClassGuid,
+ ReferenceString, SymbolicLinkName );
+ return STATUS_SUCCESS;
+}
+
+
+/***********************************************************************
+ * IoSetDeviceInterfaceState (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI IoSetDeviceInterfaceState( PUNICODE_STRING SymbolicLinkName,
+ BOOLEAN Enable )
+{
+ FIXME( "%p %d\n", SymbolicLinkName, Enable );
+ return STATUS_SUCCESS;
+}
+
+
+/***********************************************************************
+ * IofCallDriver (NTOSKRNL.EXE.@)
+ */
+#ifdef DEFINE_FASTCALL2_ENTRYPOINT
+DEFINE_FASTCALL2_ENTRYPOINT( IofCallDriver )
+NTSTATUS WINAPI __regs_IofCallDriver( DEVICE_OBJECT *device, IRP *irp )
+#else
+NTSTATUS WINAPI IofCallDriver( DEVICE_OBJECT *device, IRP *irp )
+#endif
+{
+ PDRIVER_DISPATCH dispatch;
+ IO_STACK_LOCATION *irpsp;
+ NTSTATUS status;
+
+ TRACE( "%p %p\n", device, irp );
+
+ --irp->CurrentLocation;
+ irpsp = --irp->Tail.Overlay.s.u.CurrentStackLocation;
+ dispatch = device->DriverObject->MajorFunction[irpsp->MajorFunction];
+ status = dispatch( device, irp );
+ ++irp->CurrentLocation;
+ ++irp->Tail.Overlay.s.u.CurrentStackLocation;
+
+ return status;
+}
+
+
+/***********************************************************************
* IofCompleteRequest (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL2_ENTRYPOINT
@@ -421,8 +638,57 @@ void WINAPI __regs_IofCompleteRequest( IRP *irp, UCHAR priority_boost )
void WINAPI IofCompleteRequest( IRP *irp, UCHAR priority_boost )
#endif
{
+ IO_STACK_LOCATION *irpsp;
+ PIO_COMPLETION_ROUTINE routine;
+
TRACE( "%p %u\n", irp, priority_boost );
- /* nothing to do for now */
+
+ irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
+ routine = irpsp->CompletionRoutine;
+ /* FIXME: check other stack locations */
+ if (routine)
+ {
+ NTSTATUS status;
+ int call_flag = 0;
+
+ switch (irp->IoStatus.u.Status)
+ {
+ case STATUS_SUCCESS:
+ if (irpsp->Control & SL_INVOKE_ON_SUCCESS)
+ call_flag = 1;
+ break;
+ case STATUS_CANCELLED:
+ if (irpsp->Control & SL_INVOKE_ON_CANCEL)
+ call_flag = 1;
+ break;
+ default:
+ if (irpsp->Control & SL_INVOKE_ON_ERROR)
+ call_flag = 1;
+ }
+
+ if (call_flag)
+ {
+ TRACE( "calling %p( %p, %p, %p )\n", routine, irpsp->DeviceObject,
+ irp, irpsp->Context );
+ status = routine( irpsp->DeviceObject, irp, irpsp->Context );
+ TRACE( "CompletionRoutine returned %x\n", status );
+ if (status != STATUS_MORE_PROCESSING_REQUIRED)
+ {
+ struct IrpInstance *instance;
+
+ LIST_FOR_EACH_ENTRY( instance, &Irps, struct IrpInstance, entry )
+ {
+ if (instance->irp == irp)
+ {
+ list_remove( &instance->entry );
+ HeapFree( GetProcessHeap(), 0, instance );
+ IoFreeIrp( irp );
+ break;
+ }
+ }
+ }
+ }
+ }
}
@@ -555,6 +821,88 @@ void WINAPI ExFreePoolWithTag( void *ptr, ULONG tag )
/***********************************************************************
+ * KeInitializeEvent (NTOSKRNL.EXE.@)
+ */
+void WINAPI KeInitializeEvent( PRKEVENT Event, EVENT_TYPE Type,
+ BOOLEAN State )
+{
+ FIXME( "%p %u %u\n", Event, Type, State );
+ RtlZeroMemory( Event, sizeof(KEVENT) );
+ Event->Header.Type = Type;
+ Event->Header.Size = 4;
+ if (State)
+ Event->Header.SignalState = 1;
+ InitializeListHead( &Event->Header.WaitListHead );
+}
+
+
+/***********************************************************************
+ * KeClearEvent (NTOSKRNL.EXE.@)
+ */
+void WINAPI KeClearEvent( PRKEVENT Event )
+{
+ FIXME( "%p\n", Event );
+ Event->Header.SignalState = 0;
+}
+
+
+/***********************************************************************
+ * KeResetEvent (NTOSKRNL.EXE.@)
+ */
+LONG WINAPI KeResetEvent( PRKEVENT Event )
+{
+ LONG ret;
+
+ FIXME( "%p\n", Event );
+
+ ret = Event->Header.SignalState;
+ Event->Header.SignalState = 0;
+ return ret;
+}
+
+
+/***********************************************************************
+ * KeSetEvent (NTOSKRNL.EXE.@)
+ */
+LONG WINAPI KeSetEvent( PRKEVENT Event, KPRIORITY Increment,
+ BOOLEAN Wait )
+{
+ LONG ret;
+
+ FIXME("%p %d %d\n", Event, Increment, Wait);
+
+ ret = Event->Header.SignalState;
+ Event->Header.SignalState = 1;
+ return ret;
+}
+
+
+/***********************************************************************
+ * KeInitializeMutex (NTOSKRNL.EXE.@)
+ */
+void WINAPI KeInitializeMutex( PRKMUTEX Mutex, ULONG Level )
+{
+ FIXME( "%p %u\n", Mutex, Level );
+ RtlZeroMemory( Mutex, sizeof(KMUTEX) );
+ Mutex->Header.Type = 2;
+ Mutex->Header.Size = 8;
+ Mutex->Header.SignalState = 1;
+ InitializeListHead( &Mutex->Header.WaitListHead );
+ Mutex->ApcDisable = 1;
+}
+
+
+/***********************************************************************
+ * KeReleaseMutex (NTOSKRNL.EXE.@)
+ */
+LONG WINAPI KeReleaseMutex( PRKMUTEX Mutex, BOOLEAN Wait )
+{
+ FIXME("%p %d\n", Mutex, Wait);
+ return STATUS_SUCCESS;
+}
+
+
+/***********************************************************************
* KeInitializeSpinLock (NTOSKRNL.EXE.@)
*/
void WINAPI KeInitializeSpinLock( PKSPIN_LOCK SpinLock )
@@ -564,6 +912,17 @@ void WINAPI KeInitializeSpinLock( PKSPIN_LOCK SpinLock )
/***********************************************************************
+ * PoSetPowerState (NTOSKRNL.EXE.@)
+ */
+UINT WINAPI PoSetPowerState( PDEVICE_OBJECT DeviceObject,
+ POWER_STATE_TYPE Type, POWER_STATE State )
+{
+ FIXME("%p %u %u\n", DeviceObject, Type, State.DeviceState);
+ return State.DeviceState;
+}
+
+
+/***********************************************************************
* KeInitializeTimerEx (NTOSKRNL.EXE.@)
*/
void WINAPI KeInitializeTimerEx( PKTIMER Timer, TIMER_TYPE Type )
@@ -646,6 +1005,18 @@ ULONG WINAPI KeQueryTimeIncrement(void)
/***********************************************************************
+ * KeWaitForSingleObject (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI KeWaitForSingleObject( PVOID Object, KWAIT_REASON WaitReason,
+ KPROCESSOR_MODE WaitMode, BOOLEAN Alertable,
+ PLARGE_INTEGER Timeout )
+{
+ FIXME("%p %u %d %d %p\n", Object, WaitReason, WaitMode, Alertable, Timeout);
+ return STATUS_SUCCESS;
+}
+
+
+/***********************************************************************
* MmAllocateNonCachedMemory (NTOSKRNL.EXE.@)
*/
PVOID WINAPI MmAllocateNonCachedMemory( SIZE_T size )
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 0e7b8e8..729ed54 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -39,7 +39,7 @@
@ stub IoReadPartitionTable
@ stub IoSetPartitionInformation
@ stub IoWritePartitionTable
-@ stub IofCallDriver
+@ stdcall -norelay IofCallDriver(ptr ptr)
@ stdcall -norelay IofCompleteRequest(ptr long)
@ stub KeAcquireInStackQueuedSpinLockAtDpcLevel
@ stub KeReleaseInStackQueuedSpinLockFromDpcLevel
@@ -303,7 +303,7 @@
@ stub InbvSetTextColor
@ stub InbvSolidColorFill
@ stub InitSafeBootMode
-@ stub IoAcquireCancelSpinLock
+@ stdcall IoAcquireCancelSpinLock(ptr)
@ stub IoAcquireRemoveLockEx
@ stub IoAcquireVpbSpinLock
@ stub IoAdapterObjectType
@@ -311,16 +311,16 @@
@ stub IoAllocateController
@ stub IoAllocateDriverObjectExtension
@ stub IoAllocateErrorLogEntry
-@ stub IoAllocateIrp
+@ stdcall IoAllocateIrp(long long)
@ stdcall IoAllocateMdl(ptr long long long ptr)
@ stdcall IoAllocateWorkItem(ptr)
@ stub IoAssignResources
@ stub IoAttachDevice
@ stub IoAttachDeviceByPointer
-@ stub IoAttachDeviceToDeviceStack
+@ stdcall IoAttachDeviceToDeviceStack(ptr ptr)
@ stub IoAttachDeviceToDeviceStackSafe
@ stub IoBuildAsynchronousFsdRequest
-@ stub IoBuildDeviceIoControlRequest
+@ stdcall IoBuildDeviceIoControlRequest(long ptr ptr long ptr long long ptr ptr)
@ stub IoBuildPartialMdl
@ stub IoBuildSynchronousFsdRequest
@ stub IoCallDriver
@@ -370,7 +370,7 @@
@ stub IoForwardIrpSynchronously
@ stub IoFreeController
@ stub IoFreeErrorLogEntry
-@ stub IoFreeIrp
+@ stdcall IoFreeIrp(ptr)
@ stub IoFreeMdl
@ stub IoFreeWorkItem
@ stub IoGetAttachedDevice
@@ -397,7 +397,7 @@
@ stub IoGetRequestorSessionId
@ stub IoGetStackLimits
@ stub IoGetTopLevelIrp
-@ stub IoInitializeIrp
+@ stdcall IoInitializeIrp(ptr long long)
@ stub IoInitializeRemoveLockEx
@ stub IoInitializeTimer
@ stub IoInvalidateDeviceRelations
@@ -425,14 +425,14 @@
@ stub IoReadPartitionTableEx
@ stub IoReadTransferCount
@ stub IoRegisterBootDriverReinitialization
-@ stub IoRegisterDeviceInterface
+@ stdcall IoRegisterDeviceInterface(ptr ptr ptr ptr)
@ stub IoRegisterDriverReinitialization
@ stub IoRegisterFileSystem
@ stub IoRegisterFsRegistrationChange
@ stub IoRegisterLastChanceShutdownNotification
@ stub IoRegisterPlugPlayNotification
@ stub IoRegisterShutdownNotification
-@ stub IoReleaseCancelSpinLock
+@ stdcall IoReleaseCancelSpinLock(long)
@ stub IoReleaseRemoveLockAndWaitEx
@ stub IoReleaseRemoveLockEx
@ stub IoReleaseVpbSpinLock
@@ -446,7 +446,7 @@
@ stub IoRequestDeviceEject
@ stub IoReuseIrp
@ stub IoSetCompletionRoutineEx
-@ stub IoSetDeviceInterfaceState
+@ stdcall IoSetDeviceInterfaceState(ptr long)
@ stub IoSetDeviceToVerify
@ stub IoSetFileOrigin
@ stub IoSetHardErrorOrVerifyDevice
@@ -515,7 +515,7 @@
@ stub KeBugCheckEx
@ stub KeCancelTimer
@ stub KeCapturePersistentThreadState
-@ stub KeClearEvent
+@ stdcall KeClearEvent(ptr)
@ stub KeConnectInterrupt
@ stub KeDcacheFlushCount
@ stub KeDelayExecutionThread
@@ -546,10 +546,10 @@
@ stub KeInitializeApc
@ stub KeInitializeDeviceQueue
@ stub KeInitializeDpc
-@ stub KeInitializeEvent
+@ stdcall KeInitializeEvent(ptr long long)
@ stub KeInitializeInterrupt
@ stub KeInitializeMutant
-@ stub KeInitializeMutex
+@ stdcall KeInitializeMutex(ptr long)
@ stub KeInitializeQueue
@ stub KeInitializeSemaphore
@ stdcall KeInitializeSpinLock(ptr)
@@ -587,7 +587,7 @@
@ stub KeRegisterBugCheckReasonCallback
@ stub KeReleaseInterruptSpinLock
@ stub KeReleaseMutant
-@ stub KeReleaseMutex
+@ stdcall KeReleaseMutex(ptr long)
@ stub KeReleaseSemaphore
@ stub KeReleaseSpinLockFromDpcLevel
@ stub KeRemoveByKeyDeviceQueue
@@ -597,7 +597,7 @@
@ stub KeRemoveQueue
@ stub KeRemoveQueueDpc
@ stub KeRemoveSystemServiceTable
-@ stub KeResetEvent
+@ stdcall KeResetEvent(ptr)
@ stub KeRestoreFloatingPointState
@ stub KeRevertToUserAffinityThread
@ stub KeRundownQueue
@@ -607,7 +607,7 @@
@ stub KeSetAffinityThread
@ stub KeSetBasePriorityThread
@ stub KeSetDmaIoCoherency
-@ stub KeSetEvent
+@ stdcall KeSetEvent(ptr long long)
@ stub KeSetEventBoostPriority
@ stub KeSetIdealProcessorThread
@ stub KeSetImportanceDpc
@@ -629,7 +629,7 @@
@ stub KeUserModeCallback
@ stub KeWaitForMultipleObjects
@ stub KeWaitForMutexObject
-@ stub KeWaitForSingleObject
+@ stdcall KeWaitForSingleObject(ptr long long long ptr)
@ stub KiBugCheckData
@ stub KiCoprocessorError
@ stub KiDeliverApc
@@ -830,7 +830,7 @@
@ stub PoRequestPowerIrp
@ stub PoRequestShutdownEvent
@ stub PoSetHiberRange
-@ stub PoSetPowerState
+@ stdcall PoSetPowerState(ptr long long)
@ stub PoSetSystemState
@ stub PoShutdownBugCheck
@ stub PoStartNextPowerIrp
diff --git a/dlls/usbd.sys/Makefile.in b/dlls/usbd.sys/Makefile.in
new file mode 100644
index 0000000..f745ffb
--- /dev/null
+++ b/dlls/usbd.sys/Makefile.in
@@ -0,0 +1,15 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = usbd.sys
+IMPORTLIB = usbd.sys
+IMPORTS = kernel32 ntoskrnl.exe
+EXTRADLLFLAGS = -Wb,--subsystem,native
+
+C_SRCS = \
+ usbd.c
+
+ на MAKE_DLL_RULES@
+
+ на DEPENDENCIES@ # everything below this line is overwritten by make depend
diff --git a/dlls/usbd.sys/usbd.c b/dlls/usbd.sys/usbd.c
new file mode 100644
index 0000000..cec3015
--- /dev/null
+++ b/dlls/usbd.sys/usbd.c
@@ -0,0 +1,129 @@
+/*
+ * 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 <stdarg.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "ddk/wdm.h"
+#include "ddk/usb.h"
+#include "ddk/usbdlib.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(usbd);
+
+static int find_descriptor( PUSB_CONFIGURATION_DESCRIPTOR conf,
+ void **from, UCHAR type )
+{
+ USB_COMMON_DESCRIPTOR *desc = *from;
+
+ while ((char *)desc < (char *)conf + conf->wTotalLength)
+ {
+ if (desc->bDescriptorType == type)
+ {
+ *from = desc;
+ return 1;
+ }
+ desc = (USB_COMMON_DESCRIPTOR *)((char *)desc + desc->bLength);
+ }
+ return 0;
+}
+
+PURB WINAPI USBD_CreateConfigurationRequestEx(
+ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+ PUSBD_INTERFACE_LIST_ENTRY InterfaceList )
+{
+ URB *urb;
+ UCHAR k, num_interfaces = 0;
+ SIZE_T size;
+ struct _URB_SELECT_CONFIGURATION *sel_conf;
+ USBD_INTERFACE_INFORMATION *if_info;
+ USB_INTERFACE_DESCRIPTOR *if_desc;
+ USB_ENDPOINT_DESCRIPTOR *ep_desc;
+ USBD_INTERFACE_LIST_ENTRY *entry;
+
+ TRACE( "%p, %p\n", ConfigurationDescriptor, InterfaceList );
+
+ entry = InterfaceList;
+ size = sizeof(struct _URB_SELECT_CONFIGURATION);
+ while (entry->InterfaceDescriptor)
+ {
+ size += (entry->InterfaceDescriptor->bNumEndpoints - 1) *
+ sizeof(USBD_PIPE_INFORMATION);
+ ++num_interfaces;
+ ++entry;
+ }
+ size += (num_interfaces - 1) * sizeof(USBD_INTERFACE_INFORMATION);
+
+ urb = ExAllocatePool( NonPagedPool, size );
+ RtlZeroMemory( urb, size );
+
+ sel_conf = &urb->u.UrbSelectConfiguration;
+ sel_conf->Hdr.Length = size;
+ sel_conf->Hdr.Function = URB_FUNCTION_SELECT_CONFIGURATION;
+ sel_conf->ConfigurationDescriptor = ConfigurationDescriptor;
+
+ entry = InterfaceList;
+ if_info = &sel_conf->Interface;
+ while (entry->InterfaceDescriptor)
+ {
+ if_desc = entry->InterfaceDescriptor;
+ entry->Interface = if_info;
+ if_info->InterfaceNumber = if_desc->bInterfaceNumber;
+ if_info->Class = if_desc->bInterfaceClass;
+ if_info->SubClass = if_desc->bInterfaceSubClass;
+ if_info->Protocol = if_desc->bInterfaceProtocol;
+ if_info->NumberOfPipes = if_desc->bNumEndpoints;
+ ep_desc = (USB_ENDPOINT_DESCRIPTOR *)(if_desc + 1);
+ k = 0;
+ while (find_descriptor( ConfigurationDescriptor, (void **)&ep_desc,
+ USB_ENDPOINT_DESCRIPTOR_TYPE ))
+ {
+ if_info->Pipes[k].MaximumPacketSize = ep_desc->wMaxPacketSize;
+ if_info->Pipes[k].EndpointAddress = ep_desc->bEndpointAddress;
+ if_info->Pipes[k].Interval = ep_desc->bInterval;
+ ++k;
+ }
+ if_info->Length = sizeof(USBD_INTERFACE_INFORMATION) +
+ (k - 1) * sizeof(USBD_PIPE_INFORMATION);
+ ++entry;
+ }
+
+ return urb;
+}
+
+PUSB_INTERFACE_DESCRIPTOR WINAPI USBD_ParseConfigurationDescriptorEx(
+ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
+ PVOID StartPosition, LONG InterfaceNumber,
+ LONG AlternateSetting, LONG InterfaceClass,
+ LONG InterfaceSubClass, LONG InterfaceProtocol )
+{
+ FIXME( "%p, %p, %d, %d, %d, %d, %d\n", ConfigurationDescriptor,
+ StartPosition, InterfaceNumber, AlternateSetting,
+ InterfaceClass, InterfaceSubClass, InterfaceProtocol );
+ return (PUSB_INTERFACE_DESCRIPTOR)++ConfigurationDescriptor;
+}
+
+NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
+{
+ return STATUS_SUCCESS;
+}
diff --git a/dlls/usbd.sys/usbd.sys.spec b/dlls/usbd.sys/usbd.sys.spec
new file mode 100644
index 0000000..8384f77
--- /dev/null
+++ b/dlls/usbd.sys/usbd.sys.spec
@@ -0,0 +1,35 @@
+@ stdcall USBD_CreateConfigurationRequestEx(ptr ptr)
+@ stdcall USBD_ParseConfigurationDescriptorEx(ptr ptr)
+@ stub USBD_ParseDescriptors
+@ stub DllInitialize
+@ stub DllUnload
+@ stub USBD_AllocateDeviceName
+@ stub USBD_CalculateUsbBandwidth
+@ stub USBD_CompleteRequest
+@ stub USBD_CreateConfigurationRequest
+@ stdcall _USBD_CreateConfigurationRequestEx\@8(ptr ptr) USBD_CreateConfigurationRequestEx
+@ stub USBD_CreateDevice
+@ stub USBD_Debug_GetHeap
+@ stub USBD_Debug_LogEntry
+@ stub USBD_Debug_RetHeap
+@ stub USBD_Dispatch
+@ stub USBD_FreeDeviceMutex
+@ stub USBD_FreeDeviceName
+@ stub USBD_GetDeviceInformation
+@ stub USBD_GetInterfaceLength
+@ stub USBD_GetPdoRegistryParameter
+@ stub USBD_GetSuspendPowerState
+@ stub USBD_GetUSBDIVersion
+@ stub USBD_InitializeDevice
+@ stub USBD_MakePdoName
+@ stub USBD_ParseConfigurationDescriptor
+@ stdcall _USBD_ParseConfigurationDescriptorEx\@28(ptr ptr long long long long long) USBD_ParseConfigurationDescriptorEx
+@ stub _USBD_ParseDescriptors\@16
+@ stub USBD_QueryBusTime
+@ stub USBD_RegisterHcDeviceCapabilities
+@ stub USBD_RegisterHcFilter
+@ stub USBD_RegisterHostController
+@ stub USBD_RemoveDevice
+@ stub USBD_RestoreDevice
+@ stub USBD_SetSuspendPowerState
+@ stub USBD_WaitDeviceMutex
diff --git a/dlls/wineusbhub/Makefile.in b/dlls/wineusbhub/Makefile.in
new file mode 100644
index 0000000..5fc0556
--- /dev/null
+++ b/dlls/wineusbhub/Makefile.in
@@ -0,0 +1,15 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = wineusbhub.dll
+IMPORTLIB = wineusbhub
+IMPORTS = ntoskrnl.exe kernel32
+EXTRALIBS = -lusb
+
+C_SRCS = \
+ wineusbhub.c
+
+ на MAKE_DLL_RULES@
+
+ на DEPENDENCIES@ # everything below this line is overwritten by make depend
diff --git a/dlls/wineusbhub/wineusbhub.c b/dlls/wineusbhub/wineusbhub.c
new file mode 100644
index 0000000..a855253
--- /dev/null
+++ b/dlls/wineusbhub/wineusbhub.c
@@ -0,0 +1,334 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#include <usb.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "ddk/ntddk.h"
+#include "ddk/usb.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wineusbhub);
+
+extern void WINAPI IofCompleteRequest( IRP *irp, UCHAR priority_boost );
+
+DRIVER_OBJECT hubdrv;
+DEVICE_OBJECT *usbdev; /* USB PDO */
+static struct usb_device *dev;
+
+static void add_data( char **dst, int *dst_size, void *src, int src_size )
+{
+ int copy;
+
+ copy = (src_size >= *dst_size) ? *dst_size : src_size;
+ memcpy( *dst, src, copy );
+ *dst += copy;
+ *dst_size -= copy;
+}
+
+void WINAPI __wine_IofCompleteRequest( IRP *irp, UCHAR priority_boost )
+{
+ #ifdef __i386__
+ __asm__( "movl %1,%%edx\n\t"
+ "movl %0,%%ecx\n\t"
+ "call " __ASM_NAME("IofCompleteRequest")
+ : : "g" (irp), "g" (priority_boost) );
+ #else
+ IofCompleteRequest( irp, priority_boost );
+ #endif
+}
+
+NTSTATUS WINAPI __wine_usbhub_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
+{
+ IO_STACK_LOCATION *irpsp;
+ URB *urb;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+
+ TRACE( "%p, %p\n", device, irp );
+
+ irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
+ urb = irpsp->Parameters.Others.Argument1;
+
+ switch (urb->u.UrbHeader.Function)
+ {
+ case URB_FUNCTION_SELECT_CONFIGURATION:
+ {
+ USB_CONFIGURATION_DESCRIPTOR *conf_desc =
+ urb->u.UrbSelectConfiguration.ConfigurationDescriptor;
+ usb_dev_handle *husb;
+
+ TRACE( "URB_FUNCTION_SELECT_CONFIGURATION\n" );
+
+ husb = usb_open( dev );
+ if (husb)
+ {
+ int ret;
+
+ ret = usb_set_configuration( husb, conf_desc->bConfigurationValue );
+ if (ret < 0)
+ ERR( "%s\n", usb_strerror() );
+ else
+ status = STATUS_SUCCESS;
+ usb_close( husb );
+ }
+ }
+ break;
+ case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+ {
+ struct _URB_CONTROL_DESCRIPTOR_REQUEST *request =
+ &urb->u.UrbControlDescriptorRequest;
+
+ TRACE( "URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n" );
+
+ switch (request->DescriptorType)
+ {
+ case USB_DEVICE_DESCRIPTOR_TYPE:
+ TRACE( "USB_DEVICE_DESCRIPTOR_TYPE\n" );
+ if (request->TransferBuffer == NULL)
+ break;
+ if (sizeof(USB_DEVICE_DESCRIPTOR) <= request->TransferBufferLength)
+ {
+ memcpy( request->TransferBuffer, &dev->descriptor,
+ sizeof(USB_DEVICE_DESCRIPTOR) );
+ status = STATUS_SUCCESS;
+ }
+ break;
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ TRACE( "USB_CONFIGURATION_DESCRIPTOR_TYPE\n" );
+ {
+ unsigned int i, k;
+ char *buf = request->TransferBuffer;
+ struct usb_config_descriptor *conf = &dev->config[0];
+ struct usb_interface_descriptor *intf;
+ struct usb_endpoint_descriptor *endp;
+ int size = request->TransferBufferLength;
+
+ /* FIXME: case of num_altsetting > 1 */
+
+ if (buf == NULL)
+ break;
+ add_data( &buf, &size, conf,
+ sizeof(USB_CONFIGURATION_DESCRIPTOR) );
+ if (size > 0 && conf->extra)
+ add_data( &buf, &size, conf->extra, conf->extralen );
+ for (i = 0; i < conf->bNumInterfaces; ++i)
+ {
+ intf = &conf->interface[i].altsetting[0];
+ if (size > 0)
+ add_data( &buf, &size, intf,
+ sizeof(USB_INTERFACE_DESCRIPTOR) );
+ if (size > 0 && intf->extra)
+ add_data( &buf, &size, intf->extra, intf->extralen );
+ for (k = 0; k < intf->bNumEndpoints; ++k)
+ {
+ endp = &intf->endpoint[k];
+ if (size > 0)
+ add_data( &buf, &size, endp,
+ sizeof(USB_ENDPOINT_DESCRIPTOR) );
+ if (size > 0 && endp->extra)
+ add_data( &buf, &size, endp->extra, endp->extralen );
+ }
+ }
+ status = STATUS_SUCCESS;
+ }
+ break;
+ default:
+ FIXME( "unsupported descriptor type %x\n", request->DescriptorType );
+ }
+ }
+ break;
+ case URB_FUNCTION_VENDOR_DEVICE:
+ case URB_FUNCTION_VENDOR_INTERFACE:
+ {
+ usb_dev_handle *husb;
+ struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *request =
+ &urb->u.UrbControlVendorClassRequest;
+
+ TRACE( "%s\n", (urb->u.UrbHeader.Function == URB_FUNCTION_VENDOR_DEVICE) ?
+ "URB_FUNCTION_VENDOR_DEVICE" : "URB_FUNCTION_VENDOR_INTERFACE" );
+
+ husb = usb_open( dev );
+ if (husb)
+ {
+ UCHAR req_type = request->RequestTypeReservedBits | (2 << 5);
+ char *buf;
+ int ret;
+
+ if (urb->u.UrbHeader.Function == URB_FUNCTION_VENDOR_INTERFACE)
+ req_type |= 1;
+ buf = HeapAlloc( GetProcessHeap(), 0, request->TransferBufferLength );
+ if (buf != NULL)
+ {
+ memcpy( buf, request->TransferBuffer, request->TransferBufferLength );
+ if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ req_type |= (1 << 7);
+ ret = usb_control_msg( husb, req_type, request->Request, request->Value,
+ request->Index, buf, request->TransferBufferLength, 1000 );
+ if (ret < 0)
+ ERR( "%s\n", usb_strerror() );
+ else
+ {
+ if (request->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+ {
+ request->TransferBufferLength =
+ (ret <= request->TransferBufferLength) ?
+ ret : request->TransferBufferLength;
+ memcpy( request->TransferBuffer, buf,
+ request->TransferBufferLength );
+ }
+ status = STATUS_SUCCESS;
+ }
+ HeapFree( GetProcessHeap(), 0, buf );
+ }
+ usb_close( husb );
+ }
+ }
+ break;
+ default:
+ FIXME( "unsupported URB function %x\n", urb->u.UrbHeader.Function );
+ }
+
+ urb->u.UrbHeader.Status = status;
+ if (irp->UserIosb != NULL)
+ {
+ irp->UserIosb->u.Status = status;
+ irp->UserIosb->Information = 0;
+ }
+ irp->IoStatus.u.Status = status;
+ irp->IoStatus.Information = 0;
+ __wine_IofCompleteRequest( irp, IO_NO_INCREMENT );
+
+ return status;
+}
+
+NTSTATUS WINAPI __wine_usbhub_dispatch_pnp( DEVICE_OBJECT *device, IRP *irp )
+{
+ IO_STACK_LOCATION *irpsp = irp->Tail.Overlay.s.u.CurrentStackLocation;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+
+ TRACE( "%p, %p\n", device, irp );
+
+ switch (irpsp->MinorFunction)
+ {
+ case IRP_MN_START_DEVICE:
+ status = STATUS_SUCCESS;
+ break;
+ case IRP_MN_QUERY_DEVICE_RELATIONS:
+ FIXME( "IRP_MN_QUERY_DEVICE_RELATIONS\n" );
+ status = STATUS_SUCCESS;
+ break;
+ case IRP_MN_QUERY_CAPABILITIES:
+ FIXME( "IRP_MN_QUERY_CAPABILITIES\n" );
+ {
+ PDEVICE_CAPABILITIES devCapab = irpsp->Parameters.DeviceCapabilities.Capabilities;
+
+ if (devCapab != NULL)
+ {
+ devCapab->Removable = 1;
+ devCapab->Address = 1;
+ devCapab->UINumber = 0;
+ devCapab->DeviceState[PowerSystemUnspecified] = PowerDeviceUnspecified;
+ devCapab->DeviceState[PowerSystemWorking] = PowerDeviceD0;
+ devCapab->DeviceState[PowerSystemSleeping1] = PowerDeviceD3;
+ devCapab->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
+ devCapab->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
+ devCapab->DeviceState[PowerSystemHibernate] = PowerDeviceD3;
+ devCapab->DeviceState[PowerSystemShutdown] = PowerDeviceD3;
+ devCapab->DeviceState[PowerSystemMaximum] = PowerDeviceD1;
+ devCapab->SystemWake = PowerSystemSleeping1;
+ devCapab->DeviceWake = PowerDeviceD0;
+ status = STATUS_SUCCESS;
+ }
+ }
+ break;
+ case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+ FIXME( "IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n" );
+ status = STATUS_SUCCESS;
+ break;
+ case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
+ FIXME( "IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n" );
+ status = STATUS_SUCCESS;
+ break;
+ case IRP_MN_QUERY_PNP_DEVICE_STATE:
+ FIXME( "IRP_MN_QUERY_PNP_DEVICE_STATE\n" );
+ status = STATUS_SUCCESS;
+ break;
+ case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
+ FIXME( "IRP_MN_QUERY_LEGACY_BUS_INFORMATION\n" );
+ status = STATUS_SUCCESS;
+ break;
+ default:
+ FIXME( "unsupported MinorFunction %x\n", irpsp->MinorFunction );
+ }
+
+ irp->IoStatus.u.Status = status;
+ irp->IoStatus.Information = 0;
+ __wine_IofCompleteRequest( irp, IO_NO_INCREMENT );
+
+ return status;
+}
+
+DEVICE_OBJECT *__wine_usbhub_get_pdo( ULONG pdonum, ULONG location, ULONG devnum )
+{
+ static const WCHAR usbpdoW[] = {'\\','D','e','v','i','c','e','\\',
+ 'U','S','B','P','D','O','-','%','u',0};
+ static WCHAR bufW[20];
+ UNICODE_STRING pdo_name;
+ struct usb_bus *bus;
+
+
+ TRACE( "%u, %u, %u\n", pdonum, location, devnum );
+
+ for (bus = usb_busses; bus; bus = bus->next)
+ for (dev = bus->devices; dev; dev = dev->next)
+ if (bus->location == location && dev->devnum == devnum)
+ {
+ hubdrv.MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = __wine_usbhub_internal_ioctl;
+ hubdrv.MajorFunction[IRP_MJ_PNP] = __wine_usbhub_dispatch_pnp;
+
+ snprintfW( bufW, sizeof(bufW), usbpdoW, pdonum );
+ RtlInitUnicodeString( &pdo_name, bufW );
+
+ if (STATUS_SUCCESS == IoCreateDevice( &hubdrv, 0, &pdo_name, 0, 0, FALSE, &usbdev ))
+ {
+ usbdev->Flags |= DO_BUS_ENUMERATED_DEVICE | DO_POWER_PAGABLE;
+ return usbdev;
+ }
+ }
+
+ return NULL;
+}
+
+BOOL WINAPI DllMain( HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv )
+{
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ return TRUE;
+}
diff --git a/dlls/wineusbhub/wineusbhub.spec b/dlls/wineusbhub/wineusbhub.spec
new file mode 100644
index 0000000..e91487e
--- /dev/null
+++ b/dlls/wineusbhub/wineusbhub.spec
@@ -0,0 +1,7 @@
+##################
+# Wine extensions
+#
+# All functions must be prefixed with '__wine_' (for internal functions)
+# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
+
+@ cdecl __wine_usbhub_get_pdo(long long)
diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h
index 47b6b1e..fdc9179 100644
--- a/include/ddk/ntddk.h
+++ b/include/ddk/ntddk.h
@@ -46,4 +46,13 @@ typedef enum _BUS_DATA_TYPE
MaximumBusDataType
} BUS_DATA_TYPE, *PBUS_DATA_TYPE;
+#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
+
+#define DO_VERIFY_VOLUME 0x00000002
+#define DO_DEVICE_HAS_NAME 0x00000040
+#define DO_SYSTEM_BOOT_PARTITION 0x00000100
+#define DO_LONG_TERM_REQUESTS 0x00000200
+#define DO_NEVER_LAST_DEVICE 0x00000400
+#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000
+
#endif
diff --git a/include/ddk/usb.h b/include/ddk/usb.h
new file mode 100644
index 0000000..31cef46
--- /dev/null
+++ b/include/ddk/usb.h
@@ -0,0 +1,340 @@
+/*
+ * 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
+ */
+
+#ifndef _USB_
+#define _USB_
+
+#include "usb200.h"
+
+#define URB_FUNCTION_SELECT_CONFIGURATION 0x0000
+#define URB_FUNCTION_SELECT_INTERFACE 0x0001
+#define URB_FUNCTION_ABORT_PIPE 0x0002
+#define URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL 0x0003
+#define URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL 0x0004
+#define URB_FUNCTION_GET_FRAME_LENGTH 0x0005
+#define URB_FUNCTION_SET_FRAME_LENGTH 0x0006
+#define URB_FUNCTION_GET_CURRENT_FRAME_NUMBER 0x0007
+#define URB_FUNCTION_CONTROL_TRANSFER 0x0008
+#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER 0x0009
+#define URB_FUNCTION_ISOCH_TRANSFER 0x000A
+#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 0x000B
+#define URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE 0x000C
+#define URB_FUNCTION_SET_FEATURE_TO_DEVICE 0x000D
+#define URB_FUNCTION_SET_FEATURE_TO_INTERFACE 0x000E
+#define URB_FUNCTION_SET_FEATURE_TO_ENDPOINT 0x000F
+#define URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE 0x0010
+#define URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE 0x0011
+#define URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT 0x0012
+#define URB_FUNCTION_GET_STATUS_FROM_DEVICE 0x0013
+#define URB_FUNCTION_GET_STATUS_FROM_INTERFACE 0x0014
+#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT 0x0015
+#define URB_FUNCTION_RESERVED_0X0016 0x0016
+#define URB_FUNCTION_VENDOR_DEVICE 0x0017
+#define URB_FUNCTION_VENDOR_INTERFACE 0x0018
+#define URB_FUNCTION_VENDOR_ENDPOINT 0x0019
+#define URB_FUNCTION_CLASS_DEVICE 0x001A
+#define URB_FUNCTION_CLASS_INTERFACE 0x001B
+#define URB_FUNCTION_CLASS_ENDPOINT 0x001C
+#define URB_FUNCTION_RESERVE_0X001D 0x001D
+#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 0x001E
+#define URB_FUNCTION_CLASS_OTHER 0x001F
+#define URB_FUNCTION_VENDOR_OTHER 0x0020
+#define URB_FUNCTION_GET_STATUS_FROM_OTHER 0x0021
+#define URB_FUNCTION_CLEAR_FEATURE_TO_OTHER 0x0022
+#define URB_FUNCTION_SET_FEATURE_TO_OTHER 0x0023
+#define URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT 0x0024
+#define URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT 0x0025
+#define URB_FUNCTION_GET_CONFIGURATION 0x0026
+#define URB_FUNCTION_GET_INTERFACE 0x0027
+#define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE 0x0028
+#define URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE 0x0029
+#define URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR 0x002A
+#define URB_FUNCTION_RESERVE_0X002B 0x002B
+#define URB_FUNCTION_RESERVE_0X002C 0x002C
+#define URB_FUNCTION_RESERVE_0X002D 0x002D
+#define URB_FUNCTION_RESERVE_0X002E 0x002E
+#define URB_FUNCTION_RESERVE_0X002F 0x002F
+#define URB_FUNCTION_SYNC_RESET_PIPE 0x0030
+#define URB_FUNCTION_SYNC_CLEAR_STALL 0x0031
+
+#define USBD_SHORT_TRANSFER_OK 0x00000002
+#define USBD_TRANSFER_DIRECTION_OUT 0
+#define USBD_TRANSFER_DIRECTION_IN 1
+
+typedef LONG USBD_STATUS;
+
+typedef PVOID USBD_PIPE_HANDLE;
+typedef PVOID USBD_CONFIGURATION_HANDLE;
+typedef PVOID USBD_INTERFACE_HANDLE;
+
+typedef enum _USBD_PIPE_TYPE {
+ UsbdPipeTypeControl,
+ UsbdPipeTypeIsochronous,
+ UsbdPipeTypeBulk,
+ UsbdPipeTypeInterrupt
+} USBD_PIPE_TYPE;
+
+typedef struct _USBD_PIPE_INFORMATION {
+ USHORT MaximumPacketSize;
+ UCHAR EndpointAddress;
+ UCHAR Interval;
+ USBD_PIPE_TYPE PipeType;
+ USBD_PIPE_HANDLE PipeHandle;
+ ULONG MaximumTransferSize;
+ ULONG PipeFlags;
+} USBD_PIPE_INFORMATION;
+typedef struct _USBD_PIPE_INFORMATION *PUSBD_PIPE_INFORMATION;
+
+typedef struct _USBD_INTERFACE_INFORMATION {
+ USHORT Length;
+ UCHAR InterfaceNumber;
+ UCHAR AlternateSetting;
+ UCHAR Class;
+ UCHAR SubClass;
+ UCHAR Protocol;
+ UCHAR Reserved;
+ USBD_INTERFACE_HANDLE InterfaceHandle;
+ ULONG NumberOfPipes;
+ USBD_PIPE_INFORMATION Pipes[1];
+} USBD_INTERFACE_INFORMATION;
+typedef struct _USBD_INTERFACE_INFORMATION *PUSBD_INTERFACE_INFORMATION;
+
+typedef struct _USBD_ISO_PACKET_DESCRIPTOR {
+ ULONG Offset;
+ ULONG Length;
+ USBD_STATUS Status;
+} USBD_ISO_PACKET_DESCRIPTOR;
+typedef struct _USBD_ISO_PACKET_DESCRIPTOR *PUSBD_ISO_PACKET_DESCRIPTOR;
+
+struct _URB_HCD_AREA {
+ PVOID Reserved8[8];
+};
+
+struct _URB_HEADER {
+ USHORT Length;
+ USHORT Function;
+ USBD_STATUS Status;
+ PVOID UsbdDeviceHandle;
+ ULONG UsbdFlags;
+};
+
+struct _URB_SELECT_INTERFACE {
+ struct _URB_HEADER Hdr;
+ USBD_CONFIGURATION_HANDLE ConfigurationHandle;
+ USBD_INTERFACE_INFORMATION Interface;
+};
+
+struct _URB_SELECT_CONFIGURATION {
+ struct _URB_HEADER Hdr;
+ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+ USBD_CONFIGURATION_HANDLE ConfigurationHandle;
+ USBD_INTERFACE_INFORMATION Interface;
+};
+
+struct _URB_PIPE_REQUEST {
+ struct _URB_HEADER Hdr;
+ USBD_PIPE_HANDLE PipeHandle;
+ ULONG Reserved;
+};
+
+struct _URB_FRAME_LENGTH_CONTROL {
+ struct _URB_HEADER Hdr;
+};
+
+struct _URB_GET_FRAME_LENGTH {
+ struct _URB_HEADER Hdr;
+ ULONG FrameLength;
+ ULONG FrameNumber;
+};
+
+struct _URB_SET_FRAME_LENGTH {
+ struct _URB_HEADER Hdr;
+ LONG FrameLengthDelta;
+};
+
+struct _URB_GET_CURRENT_FRAME_NUMBER {
+ struct _URB_HEADER Hdr;
+ ULONG FrameNumber;
+};
+
+struct _URB_CONTROL_TRANSFER {
+ struct _URB_HEADER Hdr;
+ USBD_PIPE_HANDLE PipeHandle;
+ ULONG TransferFlags;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ UCHAR SetupPacket[8];
+};
+
+struct _URB_BULK_OR_INTERRUPT_TRANSFER {
+ struct _URB_HEADER Hdr;
+ USBD_PIPE_HANDLE PipeHandle;
+ ULONG TransferFlags;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+};
+
+struct _URB_ISOCH_TRANSFER {
+ struct _URB_HEADER Hdr;
+ USBD_PIPE_HANDLE PipeHandle;
+ ULONG TransferFlags;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ ULONG StartFrame;
+ ULONG NumberOfPackets;
+ ULONG ErrorCount;
+ USBD_ISO_PACKET_DESCRIPTOR IsoPacket[1];
+};
+
+struct _URB_CONTROL_DESCRIPTOR_REQUEST {
+ struct _URB_HEADER Hdr;
+ PVOID Reserved;
+ ULONG Reserved0;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ USHORT Reserved1;
+ UCHAR Index;
+ UCHAR DescriptorType;
+ USHORT LanguageId;
+ USHORT Reserved2;
+};
+
+struct _URB_CONTROL_GET_STATUS_REQUEST {
+ struct _URB_HEADER Hdr;
+ PVOID Reserved;
+ ULONG Reserved0;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ UCHAR Reserved1[4];
+ USHORT Index;
+ USHORT Reserved2;
+};
+
+struct _URB_CONTROL_FEATURE_REQUEST {
+ struct _URB_HEADER Hdr;
+ PVOID Reserved;
+ ULONG Reserved2;
+ ULONG Reserved3;
+ PVOID Reserved4;
+ PMDL Reserved5;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ USHORT Reserved0;
+ USHORT FeatureSelector;
+ USHORT Index;
+ USHORT Reserved1;
+};
+
+struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST {
+ struct _URB_HEADER Hdr;
+ PVOID Reserved;
+ ULONG TransferFlags;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ UCHAR RequestTypeReservedBits;
+ UCHAR Request;
+ USHORT Value;
+ USHORT Index;
+ USHORT Reserved1;
+};
+
+struct _URB_CONTROL_GET_INTERFACE_REQUEST {
+ struct _URB_HEADER Hdr;
+ PVOID Reserved;
+ ULONG Reserved0;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ UCHAR Reserved1[4];
+ USHORT Interface;
+ USHORT Reserved2;
+};
+
+struct _URB_CONTROL_GET_CONFIGURATION_REQUEST {
+ struct _URB_HEADER Hdr;
+ PVOID Reserved;
+ ULONG Reserved0;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ UCHAR Reserved1[8];
+};
+
+struct _URB_OS_FEATURE_DESCRIPTOR_REQUEST {
+ struct _URB_HEADER Hdr;
+ PVOID Reserved;
+ ULONG Reserved0;
+ ULONG TransferBufferLength;
+ PVOID TransferBuffer;
+ PMDL TransferBufferMDL;
+ struct _URB *UrbLink;
+ struct _URB_HCD_AREA hca;
+ UCHAR Recipient:5;
+ UCHAR Reserved1:3;
+ UCHAR Reserved2;
+ UCHAR InterfaceNumber;
+ UCHAR MS_PageIndex;
+ USHORT MS_FeatureDescriptorIndex;
+ USHORT Reserved3;
+};
+
+typedef struct _URB {
+ union {
+ struct _URB_HEADER UrbHeader;
+ struct _URB_SELECT_INTERFACE UrbSelectInterface;
+ struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration;
+ struct _URB_PIPE_REQUEST UrbPipeRequest;
+ struct _URB_FRAME_LENGTH_CONTROL UrbFrameLengthControl;
+ struct _URB_GET_FRAME_LENGTH UrbGetFrameLength;
+ struct _URB_SET_FRAME_LENGTH UrbSetFrameLength;
+ struct _URB_GET_CURRENT_FRAME_NUMBER UrbGetCurrentFrameNumber;
+ struct _URB_CONTROL_TRANSFER UrbControlTransfer;
+ struct _URB_BULK_OR_INTERRUPT_TRANSFER UrbBulkOrInterruptTransfer;
+ struct _URB_ISOCH_TRANSFER UrbIsochronousTransfer;
+ struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest;
+ struct _URB_CONTROL_GET_STATUS_REQUEST UrbControlGetStatusRequest;
+ struct _URB_CONTROL_FEATURE_REQUEST UrbControlFeatureRequest;
+ struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST UrbControlVendorClassRequest;
+ struct _URB_CONTROL_GET_INTERFACE_REQUEST UrbControlGetInterfaceRequest;
+ struct _URB_CONTROL_GET_CONFIGURATION_REQUEST UrbControlGetConfigurationRequest;
+ struct _URB_OS_FEATURE_DESCRIPTOR_REQUEST UrbOSFeatureDescriptorRequest;
+ } DUMMYUNIONNAME;
+} URB;
+typedef struct _URB *PURB;
+
+#endif
diff --git a/include/ddk/usb100.h b/include/ddk/usb100.h
new file mode 100644
index 0000000..eac4399
--- /dev/null
+++ b/include/ddk/usb100.h
@@ -0,0 +1,99 @@
+/*
+ * 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
+ */
+
+#ifndef _USB100_
+#define _USB100_
+
+#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
+#define USB_STRING_DESCRIPTOR_TYPE 0x03
+#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
+#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
+#define USB_RESERVED_DESCRIPTOR_TYPE 0x06
+#define USB_CONFIG_POWER_DESCRIPTOR_TYPE 0x07
+#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 0x08
+
+#include <pshpack1.h>
+
+typedef struct _USB_DEVICE_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ USHORT bcdUSB;
+ UCHAR bDeviceClass;
+ UCHAR bDeviceSubClass;
+ UCHAR bDeviceProtocol;
+ UCHAR bMaxPacketSize0;
+ USHORT idVendor;
+ USHORT idProduct;
+ USHORT bcdDevice;
+ UCHAR iManufacturer;
+ UCHAR iProduct;
+ UCHAR iSerialNumber;
+ UCHAR bNumConfigurations;
+} USB_DEVICE_DESCRIPTOR;
+typedef struct _USB_DEVICE_DESCRIPTOR *PUSB_DEVICE_DESCRIPTOR;
+
+typedef struct _USB_ENDPOINT_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bEndpointAddress;
+ UCHAR bmAttributes;
+ USHORT wMaxPacketSize;
+ UCHAR bInterval;
+} USB_ENDPOINT_DESCRIPTOR;
+typedef struct _USB_ENDPOINT_DESCRIPTOR *PUSB_ENDPOINT_DESCRIPTOR;
+
+typedef struct _USB_CONFIGURATION_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ USHORT wTotalLength;
+ UCHAR bNumInterfaces;
+ UCHAR bConfigurationValue;
+ UCHAR iConfiguration;
+ UCHAR bmAttributes;
+ UCHAR MaxPower;
+} USB_CONFIGURATION_DESCRIPTOR;
+typedef struct _USB_CONFIGURATION_DESCRIPTOR *PUSB_CONFIGURATION_DESCRIPTOR;
+
+typedef struct _USB_INTERFACE_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bInterfaceNumber;
+ UCHAR bAlternateSetting;
+ UCHAR bNumEndpoints;
+ UCHAR bInterfaceClass;
+ UCHAR bInterfaceSubClass;
+ UCHAR bInterfaceProtocol;
+ UCHAR iInterface;
+} USB_INTERFACE_DESCRIPTOR;
+typedef struct _USB_INTERFACE_DESCRIPTOR *PUSB_INTERFACE_DESCRIPTOR;
+
+typedef struct _USB_STRING_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ WCHAR bString[1];
+} USB_STRING_DESCRIPTOR;
+typedef struct _USB_STRING_DESCRIPTOR *PUSB_STRING_DESCRIPTOR;
+
+typedef struct _USB_COMMON_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+} USB_COMMON_DESCRIPTOR;
+typedef struct _USB_COMMON_DESCRIPTOR *PUSB_COMMON_DESCRIPTOR;
+
+#include <poppack.h>
+
+#endif
diff --git a/include/ddk/usb200.h b/include/ddk/usb200.h
new file mode 100644
index 0000000..162f532
--- /dev/null
+++ b/include/ddk/usb200.h
@@ -0,0 +1,22 @@
+/*
+ * 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
+ */
+
+#ifndef _USB200_
+#define _USB200_
+
+#include "usb100.h"
+
+#endif
diff --git a/include/ddk/usbdlib.h b/include/ddk/usbdlib.h
new file mode 100644
index 0000000..ef9a773
--- /dev/null
+++ b/include/ddk/usbdlib.h
@@ -0,0 +1,26 @@
+/*
+ * 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
+ */
+
+#ifndef __USBDLIB_H__
+#define __USBDLIB_H__
+
+typedef struct _USBD_INTERFACE_LIST_ENTRY {
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ PUSBD_INTERFACE_INFORMATION Interface;
+} USBD_INTERFACE_LIST_ENTRY;
+typedef struct _USBD_INTERFACE_LIST_ENTRY *PUSBD_INTERFACE_LIST_ENTRY;
+
+#endif
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 931a130..bfbe0e9 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -28,6 +28,8 @@
#define POINTER_ALIGNMENT
#endif
+typedef LONG KPRIORITY;
+
typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
struct _KDPC;
@@ -84,6 +86,44 @@ typedef struct _KDEVICE_QUEUE {
BOOLEAN Busy;
} KDEVICE_QUEUE, *PKDEVICE_QUEUE, *RESTRICTED_POINTER PRKDEVICE_QUEUE;
+typedef struct _KMUTANT {
+ DISPATCHER_HEADER Header;
+ LIST_ENTRY MutantListEntry;
+ struct _KTHREAD *RESTRICTED_POINTER OwnerThread;
+ BOOLEAN Abandoned;
+ UCHAR ApcDisable;
+} KMUTANT, *PKMUTANT, *RESTRICTED_POINTER PRKMUTANT, KMUTEX, *PKMUTEX, *RESTRICTED_POINTER PRKMUTEX;
+
+typedef enum _KWAIT_REASON
+{
+ Executive,
+ FreePage,
+ PageIn,
+ PoolAllocation,
+ DelayExecution,
+ Suspended,
+ UserRequest,
+ WrExecutive,
+ WrFreePage,
+ WrPageIn,
+ WrDelayExecution,
+ WrSuspended,
+ WrUserRequest,
+ WrQueue,
+ WrLpcReceive,
+ WrLpcReply,
+ WrVirtualMemory,
+ WrPageOut,
+ WrRendezvous,
+ Spare2,
+ Spare3,
+ Spare4,
+ Spare5,
+ Spare6,
+ WrKernel,
+ MaximumWaitReason,
+} KWAIT_REASON;
+
typedef struct _IO_TIMER *PIO_TIMER;
typedef struct _ETHREAD *PETHREAD;
typedef struct _KTHREAD *PKTHREAD;
@@ -125,11 +165,90 @@ typedef struct _WAIT_CONTEXT_BLOCK {
PKDPC BufferChainingDpc;
} WAIT_CONTEXT_BLOCK, *PWAIT_CONTEXT_BLOCK;
+#define DO_BUFFERED_IO 0x00000004
+#define DO_EXCLUSIVE 0x00000008
+#define DO_DIRECT_IO 0x00000010
+#define DO_MAP_IO_BUFFER 0x00000020
+#define DO_DEVICE_INITIALIZING 0x00000080
+#define DO_SHUTDOWN_REGISTERED 0x00000800
+#define DO_BUS_ENUMERATED_DEVICE 0x00001000
+#define DO_POWER_PAGABLE 0x00002000
+#define DO_POWER_INRUSH 0x00004000
+
+#define IO_NO_INCREMENT 0
+#define IO_CD_ROM_INCREMENT 1
+#define IO_DISK_INCREMENT 1
+#define IO_KEYBOARD_INCREMENT 6
+#define IO_MAILSLOT_INCREMENT 2
+#define IO_MOUSE_INCREMENT 6
+#define IO_NAMED_PIPE_INCREMENT 2
+#define IO_NETWORK_INCREMENT 2
+#define IO_PARALLEL_INCREMENT 1
+#define IO_SERIAL_INCREMENT 2
+#define IO_SOUND_INCREMENT 8
+#define IO_VIDEO_INCREMENT 1
+
#ifndef DEVICE_TYPE
#define DEVICE_TYPE ULONG
#endif
-#define IRP_MJ_MAXIMUM_FUNCTION 0x1b
-#define IRP_MJ_DEVICE_CONTROL 0x0e
+#define IRP_MJ_MAXIMUM_FUNCTION 0x1b
+#define IRP_MJ_CREATE 0x00
+#define IRP_MJ_CREATE_NAMED_PIPE 0x01
+#define IRP_MJ_CLOSE 0x02
+#define IRP_MJ_READ 0x03
+#define IRP_MJ_WRITE 0x04
+#define IRP_MJ_QUERY_INFORMATION 0x05
+#define IRP_MJ_SET_INFORMATION 0x06
+#define IRP_MJ_QUERY_EA 0x07
+#define IRP_MJ_SET_EA 0x08
+#define IRP_MJ_FLUSH_BUFFERS 0x09
+#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
+#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b
+#define IRP_MJ_DIRECTORY_CONTROL 0x0c
+#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d
+#define IRP_MJ_DEVICE_CONTROL 0x0e
+#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
+#define IRP_MJ_SHUTDOWN 0x10
+#define IRP_MJ_LOCK_CONTROL 0x11
+#define IRP_MJ_CLEANUP 0x12
+#define IRP_MJ_CREATE_MAILSLOT 0x13
+#define IRP_MJ_QUERY_SECURITY 0x14
+#define IRP_MJ_SET_SECURITY 0x15
+#define IRP_MJ_POWER 0x16
+#define IRP_MJ_SYSTEM_CONTROL 0x17
+#define IRP_MJ_DEVICE_CHANGE 0x18
+#define IRP_MJ_QUERY_QUOTA 0x19
+#define IRP_MJ_SET_QUOTA 0x1a
+#define IRP_MJ_PNP 0x1b
+
+#define IRP_MN_START_DEVICE 0x00
+#define IRP_MN_QUERY_REMOVE_DEVICE 0x01
+#define IRP_MN_REMOVE_DEVICE 0x02
+#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03
+#define IRP_MN_STOP_DEVICE 0x04
+#define IRP_MN_QUERY_STOP_DEVICE 0x05
+#define IRP_MN_CANCEL_STOP_DEVICE 0x06
+#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07
+#define IRP_MN_QUERY_INTERFACE 0x08
+#define IRP_MN_QUERY_CAPABILITIES 0x09
+#define IRP_MN_QUERY_RESOURCES 0x0A
+#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B
+#define IRP_MN_QUERY_DEVICE_TEXT 0x0C
+#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
+#define IRP_MN_READ_CONFIG 0x0F
+#define IRP_MN_WRITE_CONFIG 0x10
+#define IRP_MN_EJECT 0x11
+#define IRP_MN_SET_LOCK 0x12
+#define IRP_MN_QUERY_ID 0x13
+#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14
+#define IRP_MN_QUERY_BUS_INFORMATION 0x15
+#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16
+#define IRP_MN_SURPRISE_REMOVAL 0x17
+
+#define IRP_QUOTA_CHARGED 0x01
+#define IRP_ALLOCATED_MUST_SUCCEED 0x02
+#define IRP_ALLOCATED_FIXED_SIZE 0x04
+#define IRP_LOOKASIDE_ALLOCATION 0x08
typedef struct _DEVICE_OBJECT {
CSHORT Type;
@@ -628,6 +747,11 @@ typedef NTSTATUS (WINAPI *PIO_COMPLETION_ROUTINE)(
IN struct _IRP *Irp,
IN PVOID Context);
+#define SL_PENDING_RETURNED 0x01
+#define SL_INVOKE_ON_CANCEL 0x20
+#define SL_INVOKE_ON_SUCCESS 0x40
+#define SL_INVOKE_ON_ERROR 0x80
+
#include <pshpack1.h>
typedef struct _IO_STACK_LOCATION {
UCHAR MajorFunction;
@@ -877,12 +1001,14 @@ PVOID WINAPI ExAllocatePoolWithQuotaTag(POOL_TYPE,SIZE_T,ULONG);
void WINAPI ExFreePool(PVOID);
void WINAPI ExFreePoolWithTag(PVOID,ULONG);
+PIRP WINAPI IoAllocateIrp(CCHAR, BOOLEAN);
NTSTATUS WINAPI IoCreateDevice(DRIVER_OBJECT*,ULONG,UNICODE_STRING*,DEVICE_TYPE,ULONG,BOOLEAN,DEVICE_OBJECT**);
NTSTATUS WINAPI IoCreateDriver(UNICODE_STRING*,PDRIVER_INITIALIZE);
NTSTATUS WINAPI IoCreateSymbolicLink(UNICODE_STRING*,UNICODE_STRING*);
void WINAPI IoDeleteDevice(DEVICE_OBJECT*);
void WINAPI IoDeleteDriver(DRIVER_OBJECT*);
NTSTATUS WINAPI IoDeleteSymbolicLink(UNICODE_STRING*);
+void WINAPI IoFreeIrp(IRP*);
PEPROCESS WINAPI IoGetCurrentProcess(void);
PKTHREAD WINAPI KeGetCurrentThread(void);
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 810464c..75777cd 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4281,6 +4281,33 @@ struct add_fd_completion_reply
};
+
+struct call_add_device_request
+{
+ struct request_header __header;
+ data_size_t drvname_len;
+ /* VARARG(drvname,unicode_str); */
+ /* VARARG(data,bytes); */
+};
+struct call_add_device_reply
+{
+ struct reply_header __header;
+};
+
+
+
+struct get_add_device_request_request
+{
+ struct request_header __header;
+ /* VARARG(drvname,unicode_str); */
+};
+struct get_add_device_request_reply
+{
+ struct reply_header __header;
+ /* VARARG(data,bytes); */
+};
+
+
enum request
{
REQ_new_process,
@@ -4516,6 +4543,8 @@ enum request
REQ_query_completion,
REQ_set_completion_info,
REQ_add_fd_completion,
+ REQ_call_add_device,
+ REQ_get_add_device_request,
REQ_NB_REQUESTS
};
@@ -4756,6 +4785,8 @@ union generic_request
struct query_completion_request query_completion_request;
struct set_completion_info_request set_completion_info_request;
struct add_fd_completion_request add_fd_completion_request;
+ struct call_add_device_request call_add_device_request;
+ struct get_add_device_request_request get_add_device_request_request;
};
union generic_reply
{
@@ -4994,8 +5025,10 @@ union generic_reply
struct query_completion_reply query_completion_reply;
struct set_completion_info_reply set_completion_info_reply;
struct add_fd_completion_reply add_fd_completion_reply;
+ struct call_add_device_reply call_add_device_reply;
+ struct get_add_device_request_reply get_add_device_request_reply;
};
-#define SERVER_PROTOCOL_VERSION 339
+#define SERVER_PROTOCOL_VERSION 340
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/programs/Makefile.in b/programs/Makefile.in
index cd84a36..08ab5eb 100644
--- a/programs/Makefile.in
+++ b/programs/Makefile.in
@@ -46,6 +46,7 @@ SUBDIRS = \
winemine \
winepath \
winetest \
+ wineusb \
winevdm \
winhlp32 \
winver \
@@ -92,6 +93,7 @@ INSTALLSUBDIRS = \
winemenubuilder \
winemine \
winepath \
+ wineusb \
winevdm \
winhlp32 \
winver \
diff --git a/programs/winedevice/Makefile.in b/programs/winedevice/Makefile.in
index 7effe56..5eaa31d 100644
--- a/programs/winedevice/Makefile.in
+++ b/programs/winedevice/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = winedevice.exe
APPMODE = -mwindows -municode
-IMPORTS = advapi32 ntoskrnl.exe kernel32 ntdll
+IMPORTS = advapi32 ntoskrnl.exe kernel32 ntdll wineusbhub
C_SRCS = \
device.c
diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c
index d48017a..6945f96 100644
--- a/programs/winedevice/device.c
+++ b/programs/winedevice/device.c
@@ -22,6 +22,10 @@
#include "wine/port.h"
#include <stdarg.h>
+#include <limits.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -31,13 +35,15 @@
#include "winreg.h"
#include "winnls.h"
#include "winsvc.h"
-#include "ddk/wdm.h"
+#include "ddk/ntddk.h"
#include "wine/unicode.h"
+#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(winedevice);
WINE_DECLARE_DEBUG_CHANNEL(relay);
+extern DEVICE_OBJECT *__wine_usbhub_get_pdo( ULONG pdonum, ULONG location, ULONG devnum );
extern NTSTATUS wine_ntoskrnl_main_loop( HANDLE stop_event );
static WCHAR *driver_name;
@@ -138,6 +144,7 @@ static NTSTATUS init_driver( HMODULE module, UNICODE_STRING *keyname )
WINE_TRACE( "- DriverInit = %p\n", driver_obj.DriverInit );
WINE_TRACE( "- DriverStartIo = %p\n", driver_obj.DriverStartIo );
WINE_TRACE( "- DriverUnload = %p\n", driver_obj.DriverUnload );
+ WINE_TRACE( "- AddDevice = %p\n", driver_extension.AddDevice );
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
WINE_TRACE( "- MajorFunction[%d] = %p\n", i, driver_obj.MajorFunction[i] );
@@ -255,10 +262,103 @@ static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
if (load_driver())
{
+ UNICODE_STRING drvname;
+ NTSTATUS ret = STATUS_SUCCESS;
+ UCHAR pnpFuncs[] = { IRP_MN_QUERY_LEGACY_BUS_INFORMATION,
+ IRP_MN_QUERY_RESOURCE_REQUIREMENTS,
+ IRP_MN_FILTER_RESOURCE_REQUIREMENTS,
+ IRP_MN_START_DEVICE,
+ IRP_MN_QUERY_CAPABILITIES,
+ IRP_MN_QUERY_PNP_DEVICE_STATE,
+ IRP_MN_QUERY_DEVICE_RELATIONS };
+ ULONG k;
+ IRP *irp;
+ IO_STACK_LOCATION *irpsp;
+ PDRIVER_DISPATCH dispatch;
+ DEVICE_CAPABILITIES cpbts;
+
status.dwCurrentState = SERVICE_RUNNING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SetServiceStatus( service_handle, &status );
+ RtlInitUnicodeString( &drvname, driver_name );
+
+ if (driver_extension.AddDevice)
+ {
+ NTSTATUS (*AddDevice)( PDRIVER_OBJECT, PDEVICE_OBJECT ) = driver_extension.AddDevice;
+ PDEVICE_OBJECT pdev_obj = NULL;
+ ULONG pdo_info[3];
+ data_size_t reply_size = 0;
+
+ while (!reply_size)
+ SERVER_START_REQ( get_add_device_request )
+ {
+ wine_server_add_data( req, drvname.Buffer, drvname.Length );
+ wine_server_set_reply( req, pdo_info, sizeof(pdo_info) );
+ ret = wine_server_call( req );
+ if (STATUS_SUCCESS == ret)
+ reply_size = wine_server_reply_size( reply );
+ }
+ SERVER_END_REQ;
+
+ pdev_obj = __wine_usbhub_get_pdo( pdo_info[0], pdo_info[1], pdo_info[2] );
+ if (pdev_obj)
+ {
+ WINE_TRACE( "calling AddDevice( %p, %p )\n", &driver_obj, pdev_obj );
+ ret = AddDevice( &driver_obj, pdev_obj );
+ if (STATUS_SUCCESS != ret)
+ WINE_ERR( "AddDevice failed: %x\n", ret );
+ }
+ else
+ {
+ ret = STATUS_UNSUCCESSFUL;
+ WINE_ERR( "wineusbhub error\n" );
+ }
+ }
+
+ for (k = 0; k < sizeof(pnpFuncs); ++k)
+ {
+ if (STATUS_SUCCESS != ret)
+ break;
+ if (driver_obj.MajorFunction[IRP_MJ_PNP])
+ {
+ irp = IoAllocateIrp( driver_obj.DeviceObject->StackSize, FALSE );
+ if (irp != NULL)
+ {
+ --irp->CurrentLocation;
+ irpsp = --irp->Tail.Overlay.s.u.CurrentStackLocation;
+
+ irp->RequestorMode = KernelMode;
+ irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED;
+
+ irpsp->MajorFunction = IRP_MJ_PNP;
+ irpsp->MinorFunction = pnpFuncs[k];
+ irpsp->DeviceObject = driver_obj.DeviceObject;
+
+ driver_obj.DeviceObject->CurrentIrp = irp;
+
+ if (IRP_MN_QUERY_CAPABILITIES == pnpFuncs[k])
+ {
+ RtlZeroMemory( &cpbts, sizeof(cpbts) );
+ cpbts.Size = 64;
+ cpbts.Version = 1;
+ cpbts.Address = ULONG_MAX;
+ cpbts.UINumber = ULONG_MAX;
+ irpsp->Parameters.DeviceCapabilities.Capabilities = &cpbts;
+ }
+
+ dispatch = driver_obj.MajorFunction[IRP_MJ_PNP];
+ ret = dispatch( driver_obj.DeviceObject, irp );
+ if (STATUS_SUCCESS != ret)
+ WINE_ERR( "MajorFunction[IRP_MJ_PNP] failed: %x\n", ret );
+
+ IoFreeIrp( irp );
+ }
+ else
+ ret = STATUS_UNSUCCESSFUL;
+ }
+ }
+
wine_ntoskrnl_main_loop( stop_event );
}
else WINE_ERR( "driver %s failed to load\n", wine_dbgstr_w(driver_name) );
diff --git a/programs/wineusb/Makefile.in b/programs/wineusb/Makefile.in
new file mode 100644
index 0000000..d985846
--- /dev/null
+++ b/programs/wineusb/Makefile.in
@@ -0,0 +1,15 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = wineusb.exe
+APPMODE = -mwindows -municode
+IMPORTS = advapi32 ntoskrnl.exe kernel32 ntdll setupapi
+EXTRALIBS = -lusb
+
+C_SRCS = \
+ main.c
+
+ на MAKE_PROG_RULES@
+
+ на DEPENDENCIES@ # everything below this line is overwritten by make depend
diff --git a/programs/wineusb/main.c b/programs/wineusb/main.c
new file mode 100644
index 0000000..c1a8476
--- /dev/null
+++ b/programs/wineusb/main.c
@@ -0,0 +1,217 @@
+/*
+ * Service process to call USB driver`s AddDevice routine
+ *
+ * Based on winedevice
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#include <usb.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "winternl.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "winsvc.h"
+#include "winuser.h"
+#include "setupapi.h"
+#include "ddk/wdm.h"
+#include "ddk/usb.h"
+#include "wine/unicode.h"
+#include "wine/server.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wineusb);
+
+static WCHAR service_nameW[] = {'w','i','n','e','u','s','b',0};
+static SERVICE_STATUS_HANDLE service_handle;
+static HANDLE stop_event;
+
+static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
+{
+ SERVICE_STATUS status;
+
+ status.dwServiceType = SERVICE_WIN32;
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ status.dwWin32ExitCode = 0;
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 0;
+ status.dwWaitHint = 0;
+
+ switch(ctrl)
+ {
+ case SERVICE_CONTROL_STOP:
+ case SERVICE_CONTROL_SHUTDOWN:
+ WINE_TRACE( "shutting down\n" );
+ status.dwCurrentState = SERVICE_STOP_PENDING;
+ status.dwControlsAccepted = 0;
+ SetServiceStatus( service_handle, &status );
+ SetEvent( stop_event );
+ return NO_ERROR;
+ default:
+ status.dwCurrentState = SERVICE_RUNNING;
+ SetServiceStatus( service_handle, &status );
+ return NO_ERROR;
+ }
+}
+
+static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
+{
+ HDEVINFO set;
+ GUID guid = {0x36FC9E60, 0xC465, 0x11CF, {0x80,0x56,0x44,0x45,0x53,0x54,0x00,0x00}};
+ SERVICE_STATUS status;
+
+ WINE_TRACE( "starting service\n" );
+
+ stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
+
+ service_handle = RegisterServiceCtrlHandlerExW( service_nameW, service_handler, NULL );
+ if (!service_handle)
+ return;
+
+ status.dwServiceType = SERVICE_WIN32;
+ status.dwCurrentState = SERVICE_START_PENDING;
+ status.dwControlsAccepted = 0;
+ status.dwWin32ExitCode = 0;
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 0;
+ status.dwWaitHint = 10000;
+ SetServiceStatus( service_handle, &status );
+
+ set = SetupDiGetClassDevsW( &guid, NULL, 0, 0 );
+ if (set != INVALID_HANDLE_VALUE)
+ {
+ UNICODE_STRING drvname;
+ ULONG pdo_info[3] = { 0, 0, 0 };
+ struct usb_device *dev;
+ struct usb_bus *bus;
+ SP_DEVINFO_DATA devInfo = { sizeof(devInfo), { 0 } };
+ DWORD size = 0, i = 0;
+ USHORT vid, pid;
+ char *str;
+ BYTE *buf;
+ BOOL ret;
+
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ while (SetupDiEnumDeviceInfo( set, i++, &devInfo ))
+ {
+ SetupDiGetDeviceRegistryPropertyA( set, &devInfo, SPDRP_HARDWAREID,
+ NULL, NULL, 0, &size );
+ buf = HeapAlloc( GetProcessHeap(), 0, size );
+ if (buf == NULL)
+ {
+ WINE_ERR( "insufficient memory\n" );
+ continue;
+ }
+ ret = SetupDiGetDeviceRegistryPropertyA( set, &devInfo, SPDRP_HARDWAREID,
+ NULL, buf, size, NULL );
+ if (!ret)
+ {
+ WINE_ERR( "SetupDiGetDeviceRegistryPropertyA failed\n" );
+ HeapFree( GetProcessHeap(), 0, buf );
+ continue;
+ }
+ str = strstr( (char *)buf, "Vid_" );
+ if (str != NULL)
+ {
+ str += 4;
+ vid = strtol( str, NULL, 16 );
+ str = strstr( str, "Pid_" );
+ }
+ if (str == NULL)
+ {
+ WINE_ERR( "bad hardware ID\n" );
+ HeapFree( GetProcessHeap(), 0, buf );
+ continue;
+ }
+ str += 4;
+ pid = strtol( str, NULL, 16 );
+ HeapFree( GetProcessHeap(), 0, buf );
+
+ for (bus = usb_busses; bus && ret; bus = bus->next)
+ for (dev = bus->devices; dev && ret; dev = dev->next)
+ if (dev->descriptor.idVendor == vid &&
+ dev->descriptor.idProduct == pid)
+ {
+ SetupDiGetDeviceRegistryPropertyW( set, &devInfo,
+ SPDRP_SERVICE, NULL, NULL, 0, &size );
+ buf = HeapAlloc( GetProcessHeap(), 0, size );
+ if (buf == NULL)
+ {
+ WINE_ERR( "insufficient memory\n" );
+ ret = FALSE;
+ break;
+ }
+ ret = SetupDiGetDeviceRegistryPropertyW( set, &devInfo,
+ SPDRP_SERVICE, NULL, buf, size, NULL );
+ if (!ret)
+ {
+ WINE_ERR( "SetupDiGetDeviceRegistryPropertyW failed\n" );
+ HeapFree( GetProcessHeap(), 0, buf );
+ break;
+ }
+ /* FIXME: check if driver is loaded */
+ RtlInitUnicodeString( &drvname, (PWSTR)buf );
+ pdo_info[1] = bus->location;
+ pdo_info[2] = dev->devnum;
+
+ SERVER_START_REQ( call_add_device )
+ {
+ req->drvname_len = drvname.Length;
+ wine_server_add_data( req, drvname.Buffer, drvname.Length );
+ wine_server_add_data( req, pdo_info, sizeof(pdo_info) );
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+
+ ++pdo_info[0];
+ HeapFree( GetProcessHeap(), 0, buf );
+ ret = FALSE;
+ break;
+ }
+ }
+ SetupDiDestroyDeviceInfoList( set );
+ }
+ else
+ WINE_ERR( "SetupDiGetClassDevsW failed\n" );
+
+ status.dwCurrentState = SERVICE_STOPPED;
+ status.dwControlsAccepted = 0;
+ SetServiceStatus( service_handle, &status );
+ WINE_TRACE( "service stopped\n" );
+}
+
+int wmain( int argc, WCHAR *argv[] )
+{
+ SERVICE_TABLE_ENTRYW service_table[2];
+
+ service_table[0].lpServiceName = service_nameW;
+ service_table[0].lpServiceProc = ServiceMain;
+ service_table[1].lpServiceName = NULL;
+ service_table[1].lpServiceProc = NULL;
+
+ StartServiceCtrlDispatcherW( service_table );
+ return 0;
+}
diff --git a/server/device.c b/server/device.c
index abf0ac5..eb1b593 100644
--- a/server/device.c
+++ b/server/device.c
@@ -32,6 +32,7 @@
#include "file.h"
#include "handle.h"
#include "request.h"
+#include "unicode.h"
struct ioctl_call
{
@@ -160,6 +161,41 @@ static const struct fd_ops device_fd_ops =
};
+static struct list add_dev_requests_list = LIST_INIT(add_dev_requests_list);
+
+struct add_dev_request
+{
+ struct object obj; /* object header */
+ struct unicode_str drvname; /* driver name */
+ void *data; /* driver specific data */
+ data_size_t size; /* driver specific data size */
+ struct list entry; /* entry in add_dev_requests_list */
+};
+
+static void add_dev_req_dump( struct object *obj, int verbose );
+static void add_dev_req_destroy( struct object *obj );
+
+static const struct object_ops add_dev_requests_ops =
+{
+ sizeof(struct add_dev_request), /* size */
+ add_dev_req_dump, /* dump */
+ no_get_type, /* get_type */
+ no_add_queue, /* add_queue */
+ NULL, /* remove_queue */
+ NULL, /* signaled */
+ no_satisfied, /* satisfied */
+ no_signal, /* signal */
+ no_get_fd, /* get_fd */
+ no_map_access, /* map_access */
+ default_get_sd, /* get_sd */
+ default_set_sd, /* set_sd */
+ no_lookup_name, /* lookup_name */
+ no_open_file, /* open_file */
+ no_close_handle, /* close_handle */
+ add_dev_req_destroy /* destroy */
+};
+
+
static void ioctl_call_dump( struct object *obj, int verbose )
{
struct ioctl_call *ioctl = (struct ioctl_call *)obj;
@@ -425,6 +461,27 @@ static struct device_manager *create_device_manager(void)
}
+static void add_dev_req_dump( struct object *obj, int verbose )
+{
+ struct add_dev_request *add_dev_req = (struct add_dev_request *)obj;
+ struct unicode_str *drvname = &add_dev_req->drvname;
+
+ fprintf( stderr, "AddDevice " );
+ if (drvname)
+ dump_strW( drvname->str, drvname->len / sizeof(WCHAR), stderr, "" );
+ fputc( '\n', stderr );
+}
+
+static void add_dev_req_destroy( struct object *obj )
+{
+ struct add_dev_request *add_dev_req = (struct add_dev_request *)obj;
+
+ list_remove( &add_dev_req->entry );
+ /* data and drvname.str are in the same memory block pointed to by drvname.str */
+ free( (void *)add_dev_req->drvname.str );
+}
+
+
/* create a device manager */
DECL_HANDLER(create_device_manager)
{
@@ -554,3 +611,57 @@ DECL_HANDLER(get_ioctl_result)
}
release_object( device );
}
+
+
+DECL_HANDLER(call_add_device)
+{
+ void *p;
+ struct add_dev_request *add_dev_req;
+ data_size_t size;
+
+ size = get_req_data_size();
+ p = mem_alloc( size );
+ if (p)
+ {
+ add_dev_req = alloc_object( &add_dev_requests_ops );
+ if (add_dev_req)
+ {
+ memcpy( p, get_req_data(), size );
+ add_dev_req->drvname.len = req->drvname_len;
+ add_dev_req->drvname.str = p;
+ add_dev_req->data = (char *)p + req->drvname_len;
+ add_dev_req->size = size - req->drvname_len;
+ list_add_tail( &add_dev_requests_list, &add_dev_req->entry );
+ }
+ else
+ free( p );
+ }
+}
+
+
+DECL_HANDLER(get_add_device_request)
+{
+ struct unicode_str drvname;
+ struct add_dev_request *add_dev_req;
+ int found = 0;
+
+ get_req_unicode_str( &drvname );
+ LIST_FOR_EACH_ENTRY( add_dev_req, &add_dev_requests_list, struct add_dev_request, entry )
+ {
+ struct unicode_str *p = &add_dev_req->drvname;
+
+ if (p->len != drvname.len) continue;
+ if (!strncmpiW( drvname.str, p->str, p->len/sizeof(WCHAR) ))
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ {
+ set_reply_data( add_dev_req->data, add_dev_req->size );
+ release_object( add_dev_req );
+ }
+ else
+ set_reply_data( NULL, 0 );
+}
diff --git a/server/protocol.def b/server/protocol.def
index 01d94d2..239a9c4 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3066,3 +3066,19 @@ enum message_type
unsigned int status; /* completion status */
unsigned long information; /* IO_STATUS_BLOCK Information */
@END
+
+
+/* Call AddDevice function in driver */
+ на REQ(call_add_device)
+ data_size_t drvname_len; /* driver name length */
+ VARARG(drvname,unicode_str); /* driver name */
+ VARARG(data,bytes); /* driver specific data */
+ на END
+
+
+/* Check if it should call AddDevice function */
+ на REQ(get_add_device_request)
+ VARARG(drvname,unicode_str); /* driver name */
+ на REPLY
+ VARARG(data,bytes); /* driver specific data */
+ на END
diff --git a/server/request.h b/server/request.h
index 496c5ff..e9864e8 100644
--- a/server/request.h
+++ b/server/request.h
@@ -344,6 +344,8 @@ DECL_HANDLER(remove_completion);
DECL_HANDLER(query_completion);
DECL_HANDLER(set_completion_info);
DECL_HANDLER(add_fd_completion);
+DECL_HANDLER(call_add_device);
+DECL_HANDLER(get_add_device_request);
#ifdef WANT_REQUEST_HANDLERS
@@ -583,6 +585,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_query_completion,
(req_handler)req_set_completion_info,
(req_handler)req_add_fd_completion,
+ (req_handler)req_call_add_device,
+ (req_handler)req_get_add_device_request,
};
#endif /* WANT_REQUEST_HANDLERS */
diff --git a/server/trace.c b/server/trace.c
index bbae524..1fd2cf9 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3782,6 +3782,28 @@ static void dump_add_fd_completion_request( const struct add_fd_completion_reque
fprintf( stderr, " information=%lx", req->information );
}
+static void dump_call_add_device_request( const struct call_add_device_request *req )
+{
+ fprintf( stderr, " drvname_len=%u,", req->drvname_len );
+ fprintf( stderr, " drvname=" );
+ dump_varargs_unicode_str( cur_size );
+ fputc( ',', stderr );
+ fprintf( stderr, " data=" );
+ dump_varargs_bytes( cur_size );
+}
+
+static void dump_get_add_device_request_request( const struct get_add_device_request_request *req )
+{
+ fprintf( stderr, " drvname=" );
+ dump_varargs_unicode_str( cur_size );
+}
+
+static void dump_get_add_device_request_reply( const struct get_add_device_request_reply *req )
+{
+ fprintf( stderr, " data=" );
+ dump_varargs_bytes( cur_size );
+}
+
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
@@ -4016,6 +4038,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_query_completion_request,
(dump_func)dump_set_completion_info_request,
(dump_func)dump_add_fd_completion_request,
+ (dump_func)dump_call_add_device_request,
+ (dump_func)dump_get_add_device_request_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -4252,6 +4276,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_query_completion_reply,
(dump_func)0,
(dump_func)0,
+ (dump_func)0,
+ (dump_func)dump_get_add_device_request_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4488,6 +4514,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"query_completion",
"set_completion_info",
"add_fd_completion",
+ "call_add_device",
+ "get_add_device_request",
};
static const struct
diff --git a/tools/wine.inf.in b/tools/wine.inf.in
index e5028e0..989c9f9 100644
--- a/tools/wine.inf.in
+++ b/tools/wine.inf.in
@@ -80,10 +80,12 @@ AddReg=\
[DefaultInstall.Services]
AddService=MountMgr,0x800,MountMgrService
AddService=Spooler,0,SpoolerService
+AddService=Wineusb,0,WineusbService
[DefaultInstall.NT.Services]
AddService=MountMgr,0x800,MountMgrService
AddService=Spooler,0,SpoolerService
+AddService=Wineusb,0,WineusbService
[Strings]
MciExtStr="Software\Microsoft\Windows NT\CurrentVersion\MCI Extensions"
@@ -2701,6 +2703,14 @@ StartType=4
ErrorControl=1
LoadOrderGroup="SpoolerGroup"
+[WineusbService]
+Description="WineUSB"
+DisplayName="WineUSB"
+ServiceBinary="%11%\wineusb.exe"
+ServiceType=0x10
+StartType=2
+ErrorControl=1
+
[Services]
HKLM,"System\CurrentControlSet\Services\VxD\MSTCP",,,""
--
1.5.4.5.GIT
Подробная информация о списке рассылки Wine-devel