winedevice: Introduce a custom service control to reënumerate root PnP devices.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-04-02 10:53:35 -05:00 committed by Alexandre Julliard
parent 6977b81807
commit 73bfe36eab
5 changed files with 29 additions and 6 deletions

View File

@ -3824,7 +3824,7 @@ NTSTATUS WINAPI ZwLoadDriver( const UNICODE_STRING *service_name )
driver = WINE_RB_ENTRY_VALUE( entry, struct wine_driver, entry );
driver->service_handle = service_handle;
pnp_manager_enumerate_root_devices( service_name->Buffer + wcslen( servicesW ) );
wine_enumerate_root_devices( service_name->Buffer + wcslen( servicesW ) );
set_service_status( service_handle, SERVICE_RUNNING,
SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN );

View File

@ -1686,3 +1686,4 @@
# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
@ cdecl wine_ntoskrnl_main_loop(long)
@ cdecl wine_enumerate_root_devices(wstr)

View File

@ -101,11 +101,12 @@ struct wine_driver
void ObReferenceObject( void *obj ) DECLSPEC_HIDDEN;
void pnp_manager_enumerate_root_devices( const WCHAR *driver_name ) DECLSPEC_HIDDEN;
void pnp_manager_start(void) DECLSPEC_HIDDEN;
void pnp_manager_stop_driver( struct wine_driver *driver ) DECLSPEC_HIDDEN;
void pnp_manager_stop(void) DECLSPEC_HIDDEN;
void CDECL wine_enumerate_root_devices( const WCHAR *driver_name );
struct wine_driver *get_driver( const WCHAR *name ) DECLSPEC_HIDDEN;
static const WCHAR servicesW[] = {'\\','R','e','g','i','s','t','r','y',

View File

@ -1047,13 +1047,14 @@ void pnp_manager_stop(void)
RpcBindingFree( &plugplay_binding_handle );
}
void pnp_manager_enumerate_root_devices( const WCHAR *driver_name )
void CDECL wine_enumerate_root_devices( const WCHAR *driver_name )
{
static const WCHAR driverW[] = {'\\','D','r','i','v','e','r','\\',0};
static const WCHAR rootW[] = {'R','O','O','T',0};
WCHAR buffer[MAX_SERVICE_NAME + ARRAY_SIZE(driverW)], id[MAX_DEVICE_ID_LEN];
SP_DEVINFO_DATA sp_device = {sizeof(sp_device)};
struct root_pnp_device *pnp_device;
struct list new_list = LIST_INIT(new_list);
struct root_pnp_device *pnp_device, *next;
struct wine_driver *driver;
DEVICE_OBJECT *device;
NTSTATUS status;
@ -1082,8 +1083,13 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name )
SetupDiGetDeviceInstanceIdW( set, &sp_device, id, ARRAY_SIZE(id), NULL );
if (find_root_pnp_device( driver, id ))
if ((pnp_device = find_root_pnp_device( driver, id )))
{
TRACE("Found device %s already enumerated.\n", debugstr_w(id));
list_remove( &pnp_device->entry );
list_add_tail( &new_list, &pnp_device->entry );
continue;
}
TRACE("Adding new root-enumerated device %s.\n", debugstr_w(id));
@ -1097,10 +1103,19 @@ void pnp_manager_enumerate_root_devices( const WCHAR *driver_name )
pnp_device = device->DeviceExtension;
wcscpy( pnp_device->id, id );
pnp_device->device = device;
list_add_tail( &driver->root_pnp_devices, &pnp_device->entry );
list_add_tail( &new_list, &pnp_device->entry );
start_device( device, set, &sp_device );
}
LIST_FOR_EACH_ENTRY_SAFE( pnp_device, next, &driver->root_pnp_devices, struct root_pnp_device, entry )
{
TRACE("Removing device %s.\n", debugstr_w(pnp_device->id));
remove_device( pnp_device->device );
}
list_move_head( &driver->root_pnp_devices, &new_list );
SetupDiDestroyDeviceInfoList(set);
}

View File

@ -35,6 +35,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(winedevice);
static const WCHAR servicesW[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
extern NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event );
extern void CDECL wine_enumerate_root_devices( const WCHAR *driver_name );
static WCHAR winedeviceW[] = L"winedevice";
static SERVICE_STATUS_HANDLE service_handle;
@ -55,6 +56,8 @@ static void set_service_status( SERVICE_STATUS_HANDLE handle, DWORD state, DWORD
SetServiceStatus( handle, &status );
}
#define SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES 128
static DWORD device_handler( DWORD ctrl, const WCHAR *driver_name )
{
UNICODE_STRING service_name;
@ -78,6 +81,9 @@ static DWORD device_handler( DWORD ctrl, const WCHAR *driver_name )
result = RtlNtStatusToDosError(ZwUnloadDriver( &service_name ));
break;
case SERVICE_CONTROL_REENUMERATE_ROOT_DEVICES:
wine_enumerate_root_devices( driver_name );
default:
FIXME( "got driver ctrl %x for %s\n", ctrl, wine_dbgstr_w(driver_name) );
break;