[ros-diffs] [hpoussin] 24365: Implement CMP_WaitNoPendingInstallEvents Wait for Pnp manager to finish its job before displaying the 2nd stage setup Thanks Filip for his precious help on the umpnpmgr.exe side (not thread-safe as Single linked list functions are not implemented in ntdll)

hpoussin at svn.reactos.org hpoussin at svn.reactos.org
Mon Oct 2 20:46:39 CEST 2006


Author: hpoussin
Date: Mon Oct  2 22:46:39 2006
New Revision: 24365

URL: http://svn.reactos.org/svn/reactos?rev=24365&view=rev
Log:
Implement CMP_WaitNoPendingInstallEvents
Wait for Pnp manager to finish its job before displaying the 2nd stage setup
Thanks Filip for his precious help on the umpnpmgr.exe side (not thread-safe as Single linked list functions are not implemented in ntdll)

Modified:
    trunk/reactos/base/services/umpnpmgr/umpnpmgr.c
    trunk/reactos/dll/win32/setupapi/cfgmgr.c
    trunk/reactos/dll/win32/setupapi/setupapi.spec
    trunk/reactos/dll/win32/syssetup/install.c

Modified: trunk/reactos/base/services/umpnpmgr/umpnpmgr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/umpnpmgr/umpnpmgr.c?rev=24365&r1=24364&r2=24365&view=diff
==============================================================================
--- trunk/reactos/base/services/umpnpmgr/umpnpmgr.c (original)
+++ trunk/reactos/base/services/umpnpmgr/umpnpmgr.c Mon Oct  2 22:46:39 2006
@@ -26,6 +26,7 @@
  */
 
 /* INCLUDES *****************************************************************/
+//#define HAVE_SLIST_ENTRY_IMPLEMENTED
 #define WIN32_NO_STATUS
 #include <windows.h>
 #include <cmtypes.h>
@@ -61,7 +62,24 @@
 
 static HANDLE hUserToken = NULL;
 static HANDLE hInstallEvent = NULL;
-
+static HANDLE hNoPendingInstalls = NULL;
+
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+static SLIST_HEADER DeviceInstallListHead;
+#else
+static LIST_ENTRY DeviceInstallListHead;
+#endif
+static HANDLE hDeviceInstallListNotEmpty;
+
+typedef struct
+{
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+    SLIST_ENTRY ListEntry;
+#else
+    LIST_ENTRY ListEntry;
+#endif
+    WCHAR DeviceIds[1];
+} DeviceInstallParams;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -1437,6 +1455,51 @@
 }
 
 
+/* Loop to install all queued devices installations */
+static DWORD WINAPI
+DeviceInstallThread(LPVOID lpParameter)
+{
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+    PSLIST_ENTRY ListEntry;
+#else
+    PLIST_ENTRY ListEntry;
+#endif
+    DeviceInstallParams* Params;
+    BOOL setupActive;
+
+    setupActive = SetupIsActive();
+
+    SetEnvironmentVariable(L"USERPROFILE", L"."); /* FIXME: why is it needed? */
+
+    while (TRUE)
+    {
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+        ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead);
+#else
+        if (IsListEmpty(&DeviceInstallListHead))
+            ListEntry = NULL;
+        else
+            ListEntry = RemoveHeadList(&DeviceInstallListHead);
+#endif
+        if (ListEntry == NULL)
+        {
+            SetEvent(hNoPendingInstalls);
+            DPRINT1("*** EVENT SETTED\n");
+            WaitForSingleObject(hDeviceInstallListNotEmpty, INFINITE);
+        }
+        else
+        {
+            ResetEvent(hNoPendingInstalls);
+            DPRINT1("*** EVENT RESETTED\n");
+            Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry);
+            InstallDevice(Params->DeviceIds, setupActive);
+        }
+    }
+
+    return 0;
+}
+
+
 static DWORD WINAPI
 PnpEventThread(LPVOID lpParameter)
 {
@@ -1444,14 +1507,11 @@
     ULONG PnpEventSize;
     NTSTATUS Status;
     RPC_STATUS RpcStatus;
-    BOOL setupActive;
 
     PnpEventSize = 0x1000;
     PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
     if (PnpEvent == NULL)
         return ERROR_OUTOFMEMORY;
-
-    setupActive = SetupIsActive();
 
     for (;;)
     {
@@ -1476,19 +1536,35 @@
             break;
         }
 
+        /* Process the pnp event */
         DPRINT("Received PnP Event\n");
         if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
         {
+            DeviceInstallParams* Params;
+            DWORD len;
+
             DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
-            InstallDevice(PnpEvent->TargetDevice.DeviceIds, setupActive);
+
+            /* Queue device install (will be dequeued by DeviceInstallThread */
+            len = FIELD_OFFSET(DeviceInstallParams, DeviceIds)
+                + wcslen(PnpEvent->TargetDevice.DeviceIds) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+            Params = HeapAlloc(GetProcessHeap(), 0, len);
+            if (Params)
+            {
+                wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+                InterlockedPushEntrySList(&DeviceInstallListHead, &Params->ListEntry);
+#else
+                InsertTailList(&DeviceInstallListHead, &Params->ListEntry);
+#endif
+                SetEvent(hDeviceInstallListNotEmpty);
+            }
         }
         else
         {
             DPRINT1("Unknown event\n");
         }
 
-        /* FIXME: Process the pnp event */
-
         /* Dequeue the current pnp event and signal the next one */
         NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
     }
@@ -1506,6 +1582,11 @@
     DWORD dwThreadId;
 
     DPRINT("ServiceMain() called\n");
+
+    hNoPendingInstalls = CreateEventW(NULL,
+                                      TRUE,
+                                      FALSE,
+                                      L"Global\\PnP_No_Pending_Install_Events");
 
     hThread = CreateThread(NULL,
                            0,
@@ -1518,6 +1599,15 @@
 
     hThread = CreateThread(NULL,
                            0,
+                           DeviceInstallThread,
+                           NULL,
+                           0,
+                           &dwThreadId);
+    if (hThread != NULL)
+        CloseHandle(hThread);
+
+    hThread = CreateThread(NULL,
+                           0,
                            RpcServerThread,
                            NULL,
                            0,
@@ -1544,6 +1634,20 @@
         return dwError;
     }
 
+    hDeviceInstallListNotEmpty = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (hDeviceInstallListNotEmpty == NULL)
+    {
+        dwError = GetLastError();
+        DPRINT1("Could not create the Event! (Error %lu)\n", dwError);
+        return dwError;
+    }
+
+#ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
+    InitializeSListHead(&DeviceInstallListHead);
+#else
+    InitializeListHead(&DeviceInstallListHead);
+#endif
+
     dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                             L"System\\CurrentControlSet\\Enum",
                             0,

Modified: trunk/reactos/dll/win32/setupapi/cfgmgr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/cfgmgr.c?rev=24365&r1=24364&r2=24365&view=diff
==============================================================================
--- trunk/reactos/dll/win32/setupapi/cfgmgr.c (original)
+++ trunk/reactos/dll/win32/setupapi/cfgmgr.c Mon Oct  2 22:46:39 2006
@@ -73,6 +73,25 @@
     RpcStringFree(&lpString);
 
     return TRUE;
+}
+
+
+/***********************************************************************
+ * CMP_WaitNoPendingInstallEvents [SETUPAPI.@]
+ */
+DWORD WINAPI CMP_WaitNoPendingInstallEvents(
+    DWORD dwTimeout)
+{
+    HANDLE hEvent;
+    DWORD ret;
+
+    hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
+    if (hEvent == NULL)
+       return WAIT_FAILED;
+
+    ret = WaitForSingleObject(hEvent, dwTimeout);
+    CloseHandle(hEvent);
+    return ret;
 }
 
 

Modified: trunk/reactos/dll/win32/setupapi/setupapi.spec
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/setupapi.spec?rev=24365&r1=24364&r2=24365&view=diff
==============================================================================
--- trunk/reactos/dll/win32/setupapi/setupapi.spec (original)
+++ trunk/reactos/dll/win32/setupapi/setupapi.spec Mon Oct  2 22:46:39 2006
@@ -7,7 +7,7 @@
 @ stub CMP_RegisterNotification
 @ stdcall CMP_Report_LogOn(long long)
 @ stub CMP_UnregisterNotification
-@ stub CMP_WaitNoPendingInstallEvents
+@ stdcall CMP_WaitNoPendingInstallEvents(long)
 @ stub CMP_WaitServicesAvailable
 @ stdcall CM_Add_Empty_Log_Conf(ptr ptr long long)
 @ stdcall CM_Add_Empty_Log_Conf_Ex(ptr ptr long long ptr)

Modified: trunk/reactos/dll/win32/syssetup/install.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/syssetup/install.c?rev=24365&r1=24364&r2=24365&view=diff
==============================================================================
--- trunk/reactos/dll/win32/syssetup/install.c (original)
+++ trunk/reactos/dll/win32/syssetup/install.c Mon Oct  2 22:46:39 2006
@@ -49,6 +49,8 @@
 #include "globals.h"
 #include "resource.h"
 
+DWORD WINAPI
+CMP_WaitNoPendingInstallEvents(DWORD dwTimeout);
 
 /* GLOBALS ******************************************************************/
 
@@ -656,6 +658,12 @@
     return 0;
   }
 
+  if (CMP_WaitNoPendingInstallEvents(INFINITE) != WAIT_OBJECT_0)
+  {
+    DebugPrint("CMP_WaitNoPendingInstallEvents() failed!\n");
+    return 0;
+  }
+
   InstallWizard();
 
   SetupCloseInfFile(hSysSetupInf);




More information about the Ros-diffs mailing list