Zebediah Figura : services: Load root PnP drivers on startup.

Alexandre Julliard julliard at winehq.org
Tue Jun 25 17:25:52 CDT 2019


Module: wine
Branch: master
Commit: 887a57fadd00b39b266b421fe1a04ab09e0d917d
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=887a57fadd00b39b266b421fe1a04ab09e0d917d

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Sat Jun 22 10:12:34 2019 -0500

services: Load root PnP drivers on startup.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 programs/services/Makefile.in |  2 +-
 programs/services/services.c  | 29 ++++++++++++++++++++++++++++-
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/programs/services/Makefile.in b/programs/services/Makefile.in
index e06514c..560e277 100644
--- a/programs/services/Makefile.in
+++ b/programs/services/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = services.exe
-IMPORTS   = rpcrt4 advapi32 userenv
+IMPORTS   = rpcrt4 advapi32 userenv setupapi
 
 EXTRADLLFLAGS = -mconsole -mno-cygwin
 
diff --git a/programs/services/services.c b/programs/services/services.c
index ff5c4cb..67cd4fa 100644
--- a/programs/services/services.c
+++ b/programs/services/services.c
@@ -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)




More information about the wine-cvs mailing list