services: Load root PnP drivers on startup.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Zebediah Figura 2019-06-22 10:12:34 -05:00 committed by Alexandre Julliard
parent 00e7134632
commit 887a57fadd
2 changed files with 29 additions and 2 deletions

View File

@ -1,5 +1,5 @@
MODULE = services.exe
IMPORTS = rpcrt4 advapi32 userenv
IMPORTS = rpcrt4 advapi32 userenv setupapi
EXTRADLLFLAGS = -mconsole -mno-cygwin

View File

@ -27,6 +27,7 @@
#include <winsvc.h>
#include <rpc.h>
#include <userenv.h>
#include <setupapi.h>
#include "wine/debug.h"
#include "wine/heap.h"
@ -423,25 +424,50 @@ static BOOL schedule_delayed_autostart(struct service_entry **services, unsigned
return TRUE;
}
static BOOL is_root_pnp_service(const struct service_entry *service, HDEVINFO set)
{
SP_DEVINFO_DATA device = {sizeof(device)};
WCHAR name[MAX_SERVICE_NAME];
unsigned int i;
for (i = 0; SetupDiEnumDeviceInfo(set, i, &device); ++i)
{
if (SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_SERVICE, NULL,
(BYTE *)name, sizeof(name), NULL)
&& !wcsicmp(name, service->name))
{
return TRUE;
}
}
return FALSE;
}
static void scmdatabase_autostart_services(struct scmdatabase *db)
{
static const WCHAR rootW[] = {'R','O','O','T',0};
struct service_entry **services_list;
unsigned int i = 0;
unsigned int size = 32;
unsigned int delayed_cnt = 0;
struct service_entry *service;
HDEVINFO set;
services_list = HeapAlloc(GetProcessHeap(), 0, size * sizeof(services_list[0]));
if (!services_list)
return;
if ((set = SetupDiGetClassDevsW( NULL, rootW, NULL, DIGCF_ALLCLASSES )) == INVALID_HANDLE_VALUE)
WINE_ERR("Failed to enumerate devices, error %#x.\n", GetLastError());
scmdatabase_lock(db);
LIST_FOR_EACH_ENTRY(service, &db->services, struct service_entry, entry)
{
if (service->config.dwStartType == SERVICE_BOOT_START ||
service->config.dwStartType == SERVICE_SYSTEM_START ||
service->config.dwStartType == SERVICE_AUTO_START)
service->config.dwStartType == SERVICE_AUTO_START ||
(set != INVALID_HANDLE_VALUE && is_root_pnp_service(set, service)))
{
if (i+1 >= size)
{
@ -482,6 +508,7 @@ static void scmdatabase_autostart_services(struct scmdatabase *db)
if (!delayed_cnt || !schedule_delayed_autostart(services_list, delayed_cnt))
heap_free(services_list);
SetupDiDestroyDeviceInfoList(set);
}
static void scmdatabase_wait_terminate(struct scmdatabase *db)