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/umpn... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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);