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/ump…
==============================================================================
--- 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.…
==============================================================================
--- 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/setupap…
==============================================================================
--- 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…
==============================================================================
--- 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);