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:
parent
6977b81807
commit
73bfe36eab
|
@ -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 );
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue