Signed-off-by: Zebediah Figura z.figura12@gmail.com --- loader/Makefile.in | 1 + loader/wine.inf.in | 1 + loader/winebus.inf.in | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 loader/winebus.inf.in
diff --git a/loader/Makefile.in b/loader/Makefile.in index 3ada656408b..11a476103c1 100644 --- a/loader/Makefile.in +++ b/loader/Makefile.in @@ -10,6 +10,7 @@ SOURCES = \ wine.man.in \ wine.pl.UTF-8.man.in \ wine_info.plist.in \ + winebus.inf.in \ winehid.inf.in
PROGRAMS = $(WINELOADER_PROGRAMS) diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 9f97b346f93..0da7eeef7d8 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -3682,4 +3682,5 @@ inf_section = 17 l_intl.nls
[inf_section] +winebus.inf winehid.inf diff --git a/loader/winebus.inf.in b/loader/winebus.inf.in new file mode 100644 index 00000000000..3950c3dfc4e --- /dev/null +++ b/loader/winebus.inf.in @@ -0,0 +1,22 @@ +[Version] +Signature="$CHICAGO$" +ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} +Class=System + +[Manufacturer] +Wine=mfg_section + +[mfg_section] +Wine HID bus driver=device_section,root\winebus + +[device_section.Services] +AddService = winebus,0x2,svc_section + +[svc_section] +Description="Wine HID bus driver" +DisplayName="Wine HID bus" +ServiceBinary="%12%\winebus.sys" +LoadOrderGroup="WinePlugPlay" +ServiceType=1 +StartType=3 +ErrorControl=1
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winebus.sys/main.c | 65 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 3616ebe8152..34f0490fc0c 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -66,6 +66,9 @@ static const WORD PID_XBOX_CONTROLLERS[] = {
static DRIVER_OBJECT *driver_obj;
+/* The root-enumerated device stack. */ +static DEVICE_OBJECT *bus_pdo, *bus_fdo; + HANDLE driver_key;
struct pnp_device @@ -464,7 +467,33 @@ static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp) return status; }
-static NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) +static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); + NTSTATUS ret; + + switch (irpsp->MinorFunction) + { + case IRP_MN_START_DEVICE: + case IRP_MN_SURPRISE_REMOVAL: + irp->IoStatus.u.Status = STATUS_SUCCESS; + break; + case IRP_MN_REMOVE_DEVICE: + irp->IoStatus.u.Status = STATUS_SUCCESS; + IoSkipCurrentIrpStackLocation(irp); + ret = IoCallDriver(bus_pdo, irp); + IoDetachDevice(bus_pdo); + IoDeleteDevice(device); + return ret; + default: + FIXME("Unhandled minor function %#x.\n", irpsp->MinorFunction); + } + + IoSkipCurrentIrpStackLocation(irp); + return IoCallDriver(bus_pdo, irp); +} + +static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) { NTSTATUS status = irp->IoStatus.u.Status; IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); @@ -493,6 +522,13 @@ static NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) return status; }
+static NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) +{ + if (device == bus_fdo) + return fdo_pnp_dispatch(device, irp); + return pdo_pnp_dispatch(device, irp); +} + static NTSTATUS deliver_last_report(struct device_extension *ext, DWORD buffer_length, BYTE* buffer, ULONG_PTR *out_length) { if (buffer_length < ext->last_report_size) @@ -517,6 +553,12 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
TRACE("(%p, %p)\n", device, irp);
+ if (device == bus_fdo) + { + IoSkipCurrentIrpStackLocation(irp); + return IoCallDriver(bus_pdo, irp); + } + switch (irpsp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_HID_GET_DEVICE_ATTRIBUTES: @@ -759,6 +801,26 @@ BOOL is_xbox_gamepad(WORD vid, WORD pid) return FALSE; }
+static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *pdo) +{ + NTSTATUS ret; + + TRACE("driver %p, pdo %p.\n", driver, pdo); + + if ((ret = IoCreateDevice(driver, 0, NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &bus_fdo))) + { + ERR("Failed to create FDO, status %#x.\n", ret); + return ret; + } + + IoAttachDeviceToDeviceStack(bus_fdo, pdo); + bus_pdo = pdo; + + bus_fdo->Flags &= ~DO_DEVICE_INITIALIZING; + + return STATUS_SUCCESS; +} + static void WINAPI driver_unload(DRIVER_OBJECT *driver) { udev_driver_unload(); @@ -786,6 +848,7 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path )
driver->MajorFunction[IRP_MJ_PNP] = common_pnp_dispatch; driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = hid_internal_dispatch; + driver->DriverExtension->AddDevice = driver_add_device; driver->DriverUnload = driver_unload;
if (check_bus_option(&SDL_enabled, 1))
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- There does not seem to be a way to trigger root PnP device installation from e.g. an INF file [in particular, InstallHinfSection() will not install root PnP devices].
programs/wineboot/Makefile.in | 2 +- programs/wineboot/wineboot.c | 55 +++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in index f6da0f9df65..42ae420cebc 100644 --- a/programs/wineboot/Makefile.in +++ b/programs/wineboot/Makefile.in @@ -1,7 +1,7 @@ MODULE = wineboot.exe APPMODE = -mconsole IMPORTS = uuid advapi32 -DELAYIMPORTS = shell32 shlwapi version user32 +DELAYIMPORTS = shell32 shlwapi version user32 setupapi newdev
C_SRCS = \ shutdown.c \ diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c index defd12627d6..4b5ec738bc9 100644 --- a/programs/wineboot/wineboot.c +++ b/programs/wineboot/wineboot.c @@ -82,6 +82,8 @@ #include <shobjidl.h> #include <shlwapi.h> #include <shellapi.h> +#include <setupapi.h> +#include <newdev.h> #include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL(wineboot); @@ -1090,6 +1092,57 @@ static HANDLE start_rundll32( const char *inf_path, BOOL wow64 ) return pi.hProcess; }
+static void install_root_pnp_devices(void) +{ + static const struct + { + const char *name; + const char *hardware_id; + const char *infpath; + } + root_devices[] = + { + {"root\wine\winebus", "root\winebus\0", "C:\windows\inf\winebus.inf"}, + }; + SP_DEVINFO_DATA device = {sizeof(device)}; + unsigned int i; + HDEVINFO set; + + if ((set = SetupDiCreateDeviceInfoList( NULL, NULL )) == INVALID_HANDLE_VALUE) + { + WINE_ERR("Failed to create device info list, error %#x.\n", GetLastError()); + return; + } + + for (i = 0; i < ARRAY_SIZE(root_devices); ++i) + { + if (!SetupDiCreateDeviceInfoA( set, root_devices[i].name, &GUID_NULL, NULL, NULL, 0, &device)) + { + if (GetLastError() != ERROR_DEVINST_ALREADY_EXISTS) + WINE_ERR("Failed to create device %s, error %#x.\n", debugstr_a(root_devices[i].name), GetLastError()); + continue; + } + + if (!SetupDiSetDeviceRegistryPropertyA(set, &device, SPDRP_HARDWAREID, + (const BYTE *)root_devices[i].hardware_id, (strlen(root_devices[i].hardware_id) + 2) * sizeof(WCHAR))) + { + WINE_ERR("Failed to set hardware id for %s, error %#x.\n", debugstr_a(root_devices[i].name), GetLastError()); + continue; + } + + if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, set, &device)) + { + WINE_ERR("Failed to register device %s, error %#x.\n", debugstr_a(root_devices[i].name), GetLastError()); + continue; + } + + if (!UpdateDriverForPlugAndPlayDevicesA(NULL, root_devices[i].hardware_id, root_devices[i].infpath, 0, NULL)) + WINE_ERR("Failed to install drivers for %s, error %#x.\n", debugstr_a(root_devices[i].name), GetLastError()); + } + + SetupDiDestroyDeviceInfoList(set); +} + /* execute rundll32 on the wine.inf file if necessary */ static void update_wineprefix( BOOL force ) { @@ -1133,6 +1186,8 @@ static void update_wineprefix( BOOL force ) } DestroyWindow( hwnd ); } + install_root_pnp_devices(); + WINE_MESSAGE( "wine: configuration in '%s' has been updated.\n", config_dir ); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- loader/wine.inf.in | 12 ------------ 1 file changed, 12 deletions(-)
diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 0da7eeef7d8..a435282d33e 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -134,7 +134,6 @@ AddService=FontCache3.0.0.0,0,WPFFontCacheService AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService -AddService=WineBus,0,WineBusService AddService=Winmgmt,0,WinmgmtService
[DefaultInstall.NT.Services] @@ -150,7 +149,6 @@ AddService=FontCache3.0.0.0,0,WPFFontCacheService AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService -AddService=WineBus,0,WineBusService AddService=Winmgmt,0,WinmgmtService
[DefaultInstall.ntamd64.Services] @@ -166,7 +164,6 @@ AddService=FontCache3.0.0.0,0,WPFFontCacheService AddService=LanmanServer,0,LanmanServerService AddService=FontCache,0,FontCacheService AddService=Schedule,0,TaskSchedulerService -AddService=WineBus,0,WineBusService AddService=Winmgmt,0,WinmgmtService
[Strings] @@ -3454,15 +3451,6 @@ ServiceType=32 StartType=3 ErrorControl=1
-[WineBusService] -Description="Wine Platform Bus Kernel" -DisplayName="Platform Bus Kernel" -ServiceBinary="%12%\winebus.sys" -LoadOrderGroup="WinePlugPlay" -ServiceType=1 -StartType=2 -ErrorControl=1 - [SpoolerService] AddReg=SpoolerServiceKeys Description="Loads files to memory for later printing"
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- As of the next patch this will be necessary.
dlls/winebus.sys/main.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 34f0490fc0c..3139833db7a 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -469,16 +469,31 @@ static NTSTATUS handle_IRP_MN_QUERY_ID(DEVICE_OBJECT *device, IRP *irp)
static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) { + static const WCHAR SDL_enabledW[] = {'E','n','a','b','l','e',' ','S','D','L',0}; + static const UNICODE_STRING SDL_enabled = {sizeof(SDL_enabledW) - sizeof(WCHAR), sizeof(SDL_enabledW), (WCHAR*)SDL_enabledW}; IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); NTSTATUS ret;
switch (irpsp->MinorFunction) { case IRP_MN_START_DEVICE: + if (check_bus_option(&SDL_enabled, 1)) + { + if (sdl_driver_init() == STATUS_SUCCESS) + return STATUS_SUCCESS; + } + udev_driver_init(); + iohid_driver_init(); + irp->IoStatus.u.Status = STATUS_SUCCESS; + break; case IRP_MN_SURPRISE_REMOVAL: irp->IoStatus.u.Status = STATUS_SUCCESS; break; case IRP_MN_REMOVE_DEVICE: + udev_driver_unload(); + iohid_driver_unload(); + sdl_driver_unload(); + irp->IoStatus.u.Status = STATUS_SUCCESS; IoSkipCurrentIrpStackLocation(irp); ret = IoCallDriver(bus_pdo, irp); @@ -823,16 +838,11 @@ static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *p
static void WINAPI driver_unload(DRIVER_OBJECT *driver) { - udev_driver_unload(); - iohid_driver_unload(); - sdl_driver_unload(); NtClose(driver_key); }
NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) { - static const WCHAR SDL_enabledW[] = {'E','n','a','b','l','e',' ','S','D','L',0}; - static const UNICODE_STRING SDL_enabled = {sizeof(SDL_enabledW) - sizeof(WCHAR), sizeof(SDL_enabledW), (WCHAR*)SDL_enabledW}; OBJECT_ATTRIBUTES attr = {0}; NTSTATUS ret;
@@ -851,13 +861,5 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) driver->DriverExtension->AddDevice = driver_add_device; driver->DriverUnload = driver_unload;
- if (check_bus_option(&SDL_enabled, 1)) - { - if (sdl_driver_init() == STATUS_SUCCESS) - return STATUS_SUCCESS; - } - udev_driver_init(); - iohid_driver_init(); - return STATUS_SUCCESS; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 8 ++- dlls/ntoskrnl.exe/ntoskrnl_private.h | 6 ++ dlls/ntoskrnl.exe/pnp.c | 86 ++++++++++++++++++++++++---- dlls/winebus.sys/bus.h | 1 + dlls/winebus.sys/bus_iohid.c | 2 +- dlls/winebus.sys/bus_sdl.c | 2 +- dlls/winebus.sys/bus_udev.c | 2 +- dlls/winebus.sys/main.c | 11 ++-- 8 files changed, 97 insertions(+), 21 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index d9122a7aade..b006ef58631 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -1470,6 +1470,7 @@ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size, { static const WCHAR auto_format[] = {'\','D','e','v','i','c','e','\','%','0','8','x',0}; NTSTATUS status; + struct wine_device *wine_device; DEVICE_OBJECT *device; HANDLE manager = get_device_manager(); static unsigned int auto_idx = 0; @@ -1478,11 +1479,12 @@ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size, TRACE( "(%p, %u, %s, %u, %x, %u, %p)\n", driver, ext_size, debugstr_us(name), type, characteristics, exclusive, ret_device );
- if (!(device = alloc_kernel_object( IoDeviceObjectType, NULL, sizeof(DEVICE_OBJECT) + ext_size, 1 ))) + if (!(wine_device = alloc_kernel_object( IoDeviceObjectType, NULL, sizeof(struct wine_device) + ext_size, 1 ))) return STATUS_NO_MEMORY; + device = &wine_device->device_obj;
device->DriverObject = driver; - device->DeviceExtension = device + 1; + device->DeviceExtension = wine_device + 1; device->DeviceType = type; device->StackSize = 1;
@@ -1548,9 +1550,11 @@ void WINAPI IoDeleteDevice( DEVICE_OBJECT *device )
if (status == STATUS_SUCCESS) { + struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj); DEVICE_OBJECT **prev = &device->DriverObject->DeviceObject; while (*prev && *prev != device) prev = &(*prev)->NextDevice; if (*prev) *prev = (*prev)->NextDevice; + ExFreePool( wine_device->children ); ObDereferenceObject( device ); } } diff --git a/dlls/ntoskrnl.exe/ntoskrnl_private.h b/dlls/ntoskrnl.exe/ntoskrnl_private.h index b5244ef1641..256e945e6f3 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl_private.h +++ b/dlls/ntoskrnl.exe/ntoskrnl_private.h @@ -86,4 +86,10 @@ static const WCHAR servicesW[] = {'\','R','e','g','i','s','t','r','y', '\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', '\','S','e','r','v','i','c','e','s', '\',0}; + +struct wine_device +{ + DEVICE_OBJECT device_obj; + DEVICE_RELATIONS *children; +}; #endif diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c index 4ec8aaaed27..2ca7b43e4c2 100644 --- a/dlls/ntoskrnl.exe/pnp.c +++ b/dlls/ntoskrnl.exe/pnp.c @@ -387,25 +387,18 @@ static void start_device( DEVICE_OBJECT *device, HDEVINFO set, SP_DEVINFO_DATA * } }
-static void handle_bus_relations( DEVICE_OBJECT *device ) +static void enumerate_new_device( DEVICE_OBJECT *device, HDEVINFO set ) { static const WCHAR infpathW[] = {'I','n','f','P','a','t','h',0};
SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; WCHAR device_instance_id[MAX_DEVICE_ID_LEN]; BOOL need_driver = TRUE; - HDEVINFO set; HKEY key;
- /* We could (should?) do a full IRP_MN_QUERY_DEVICE_RELATIONS query, - * but we don't have to, we have the DEVICE_OBJECT of the new device - * so we can simply handle the process here */ - if (get_device_instance_id( device, device_instance_id )) return;
- set = SetupDiCreateDeviceInfoList( NULL, NULL ); - if (!SetupDiCreateDeviceInfoW( set, device_instance_id, &GUID_NULL, NULL, NULL, 0, &sp_device ) && !SetupDiOpenDeviceInfoW( set, device_instance_id, NULL, 0, &sp_device )) { @@ -433,19 +426,92 @@ static void handle_bus_relations( DEVICE_OBJECT *device ) }
start_device( device, set, &sp_device ); - - SetupDiDestroyDeviceInfoList( set ); }
static void remove_device( DEVICE_OBJECT *device ) { + struct wine_device *wine_device = CONTAINING_RECORD(device, struct wine_device, device_obj); + TRACE("Removing device %p.\n", device);
+ if (wine_device->children) + { + ULONG i; + for (i = 0; i < wine_device->children->Count; ++i) + remove_device( wine_device->children->Objects[i] ); + } + send_power_irp( device, PowerDeviceD3 ); send_pnp_irp( device, IRP_MN_SURPRISE_REMOVAL ); send_pnp_irp( device, IRP_MN_REMOVE_DEVICE ); }
+static BOOL device_in_list( const DEVICE_RELATIONS *list, const DEVICE_OBJECT *device ) +{ + ULONG i; + for (i = 0; i < list->Count; ++i) + { + if (list->Objects[i] == device) + return TRUE; + } + return FALSE; +} + +static void handle_bus_relations( DEVICE_OBJECT *parent ) +{ + struct wine_device *wine_parent = CONTAINING_RECORD(parent, struct wine_device, device_obj); + SP_DEVINFO_DATA sp_device = {sizeof(sp_device)}; + DEVICE_RELATIONS *relations; + IO_STATUS_BLOCK irp_status; + IO_STACK_LOCATION *irpsp; + NTSTATUS status; + HDEVINFO set; + IRP *irp; + ULONG i; + + TRACE( "(%p)\n", parent ); + + set = SetupDiCreateDeviceInfoList( NULL, NULL ); + + parent = IoGetAttachedDevice( parent ); + + if (!(irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, parent, NULL, 0, NULL, NULL, &irp_status ))) + { + SetupDiDestroyDeviceInfoList( set ); + return; + } + + irpsp = IoGetNextIrpStackLocation( irp ); + irpsp->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS; + irpsp->Parameters.QueryDeviceRelations.Type = BusRelations; + if ((status = send_device_irp( parent, irp, (ULONG_PTR *)&relations ))) + { + ERR("Failed to enumerate child devices, status %#x.\n", status); + SetupDiDestroyDeviceInfoList( set ); + return; + } + + TRACE("Got %u devices.\n", relations->Count); + + for (i = 0; i < relations->Count; ++i) + { + DEVICE_OBJECT *child = relations->Objects[i]; + + TRACE("%p, %p\n", wine_parent, wine_parent->children); + + if (!wine_parent->children || !device_in_list( wine_parent->children, child )) + { + TRACE("Adding new device %p.\n", child); + enumerate_new_device( child, set ); + } + } + + ExFreePool( wine_parent->children ); + wine_parent->children = relations; + + SetupDiDestroyDeviceInfoList( set ); +} + /*********************************************************************** * IoInvalidateDeviceRelations (NTOSKRNL.EXE.@) */ diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index de8ddf7ad9d..a2508784899 100644 --- a/dlls/winebus.sys/bus.h +++ b/dlls/winebus.sys/bus.h @@ -54,3 +54,4 @@ DWORD check_bus_option(const UNICODE_STRING *option, DWORD default_value) DECLSP BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
HANDLE driver_key DECLSPEC_HIDDEN; +DEVICE_OBJECT *bus_pdo DECLSPEC_HIDDEN; diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c index 7933374007e..e992db8376b 100644 --- a/dlls/winebus.sys/bus_iohid.c +++ b/dlls/winebus.sys/bus_iohid.c @@ -357,7 +357,7 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void * struct platform_private *private = impl_from_DEVICE_OBJECT(device); private->device = IOHIDDevice; private->buffer = NULL; - IoInvalidateDeviceRelations(device, BusRelations); + IoInvalidateDeviceRelations(bus_pdo, BusRelations); } }
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c index d24e21cff83..781deda7670 100644 --- a/dlls/winebus.sys/bus_sdl.c +++ b/dlls/winebus.sys/bus_sdl.c @@ -988,7 +988,7 @@ static void try_add_device(SDL_JoystickID index) HeapFree(GetProcessHeap(), 0, serial); return; } - IoInvalidateDeviceRelations(device, BusRelations); + IoInvalidateDeviceRelations(bus_pdo, BusRelations); } else { diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c index a3255dfc856..c2edade23c9 100644 --- a/dlls/winebus.sys/bus_udev.c +++ b/dlls/winebus.sys/bus_udev.c @@ -1241,7 +1241,7 @@ static void try_add_device(struct udev_device *dev) return; } #endif - IoInvalidateDeviceRelations(device, BusRelations); + IoInvalidateDeviceRelations(bus_pdo, BusRelations); } else { diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c index 3139833db7a..2e5cd93b933 100644 --- a/dlls/winebus.sys/main.c +++ b/dlls/winebus.sys/main.c @@ -67,7 +67,8 @@ static const WORD PID_XBOX_CONTROLLERS[] = { static DRIVER_OBJECT *driver_obj;
/* The root-enumerated device stack. */ -static DEVICE_OBJECT *bus_pdo, *bus_fdo; +DEVICE_OBJECT *bus_pdo; +static DEVICE_OBJECT *bus_fdo;
HANDLE driver_key;
@@ -476,6 +477,9 @@ static NTSTATUS fdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
switch (irpsp->MinorFunction) { + case IRP_MN_QUERY_DEVICE_RELATIONS: + irp->IoStatus.u.Status = handle_IRP_MN_QUERY_DEVICE_RELATIONS(irp); + break; case IRP_MN_START_DEVICE: if (check_bus_option(&SDL_enabled, 1)) { @@ -515,11 +519,6 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
switch (irpsp->MinorFunction) { - case IRP_MN_QUERY_DEVICE_RELATIONS: - TRACE("IRP_MN_QUERY_DEVICE_RELATIONS\n"); - status = handle_IRP_MN_QUERY_DEVICE_RELATIONS(irp); - irp->IoStatus.u.Status = status; - break; case IRP_MN_QUERY_ID: TRACE("IRP_MN_QUERY_ID\n"); status = handle_IRP_MN_QUERY_ID(device, irp);