mirror of
https://github.com/reactos/reactos.git
synced 2024-08-12 06:06:27 +00:00
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) svn path=/trunk/; revision=24365
This commit is contained in:
parent
4cfbdb6f63
commit
b2aeafcad4
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
//#define HAVE_SLIST_ENTRY_IMPLEMENTED
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <cmtypes.h>
|
#include <cmtypes.h>
|
||||||
|
@ -61,7 +62,24 @@ static HKEY hClassKey = NULL;
|
||||||
|
|
||||||
static HANDLE hUserToken = NULL;
|
static HANDLE hUserToken = NULL;
|
||||||
static HANDLE hInstallEvent = 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 *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -1437,6 +1455,51 @@ cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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
|
static DWORD WINAPI
|
||||||
PnpEventThread(LPVOID lpParameter)
|
PnpEventThread(LPVOID lpParameter)
|
||||||
{
|
{
|
||||||
|
@ -1444,15 +1507,12 @@ PnpEventThread(LPVOID lpParameter)
|
||||||
ULONG PnpEventSize;
|
ULONG PnpEventSize;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
RPC_STATUS RpcStatus;
|
RPC_STATUS RpcStatus;
|
||||||
BOOL setupActive;
|
|
||||||
|
|
||||||
PnpEventSize = 0x1000;
|
PnpEventSize = 0x1000;
|
||||||
PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
|
PnpEvent = HeapAlloc(GetProcessHeap(), 0, PnpEventSize);
|
||||||
if (PnpEvent == NULL)
|
if (PnpEvent == NULL)
|
||||||
return ERROR_OUTOFMEMORY;
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
setupActive = SetupIsActive();
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
DPRINT("Calling NtGetPlugPlayEvent()\n");
|
DPRINT("Calling NtGetPlugPlayEvent()\n");
|
||||||
|
@ -1476,19 +1536,35 @@ PnpEventThread(LPVOID lpParameter)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Process the pnp event */
|
||||||
DPRINT("Received PnP Event\n");
|
DPRINT("Received PnP Event\n");
|
||||||
if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
|
if (UuidEqual(&PnpEvent->EventGuid, (UUID*)&GUID_DEVICE_ARRIVAL, &RpcStatus))
|
||||||
{
|
{
|
||||||
|
DeviceInstallParams* Params;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
|
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
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("Unknown event\n");
|
DPRINT1("Unknown event\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Process the pnp event */
|
|
||||||
|
|
||||||
/* Dequeue the current pnp event and signal the next one */
|
/* Dequeue the current pnp event and signal the next one */
|
||||||
NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
|
NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
|
||||||
}
|
}
|
||||||
|
@ -1507,6 +1583,11 @@ ServiceMain(DWORD argc, LPTSTR *argv)
|
||||||
|
|
||||||
DPRINT("ServiceMain() called\n");
|
DPRINT("ServiceMain() called\n");
|
||||||
|
|
||||||
|
hNoPendingInstalls = CreateEventW(NULL,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
L"Global\\PnP_No_Pending_Install_Events");
|
||||||
|
|
||||||
hThread = CreateThread(NULL,
|
hThread = CreateThread(NULL,
|
||||||
0,
|
0,
|
||||||
PnpEventThread,
|
PnpEventThread,
|
||||||
|
@ -1516,6 +1597,15 @@ ServiceMain(DWORD argc, LPTSTR *argv)
|
||||||
if (hThread != NULL)
|
if (hThread != NULL)
|
||||||
CloseHandle(hThread);
|
CloseHandle(hThread);
|
||||||
|
|
||||||
|
hThread = CreateThread(NULL,
|
||||||
|
0,
|
||||||
|
DeviceInstallThread,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&dwThreadId);
|
||||||
|
if (hThread != NULL)
|
||||||
|
CloseHandle(hThread);
|
||||||
|
|
||||||
hThread = CreateThread(NULL,
|
hThread = CreateThread(NULL,
|
||||||
0,
|
0,
|
||||||
RpcServerThread,
|
RpcServerThread,
|
||||||
|
@ -1544,6 +1634,20 @@ main(int argc, char *argv[])
|
||||||
return dwError;
|
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,
|
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||||
L"System\\CurrentControlSet\\Enum",
|
L"System\\CurrentControlSet\\Enum",
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -76,6 +76,25 @@ static BOOL GuidToString(LPGUID Guid, LPWSTR String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CMP_Init_Detection [SETUPAPI.@]
|
* CMP_Init_Detection [SETUPAPI.@]
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
@ stub CMP_RegisterNotification
|
@ stub CMP_RegisterNotification
|
||||||
@ stdcall CMP_Report_LogOn(long long)
|
@ stdcall CMP_Report_LogOn(long long)
|
||||||
@ stub CMP_UnregisterNotification
|
@ stub CMP_UnregisterNotification
|
||||||
@ stub CMP_WaitNoPendingInstallEvents
|
@ stdcall CMP_WaitNoPendingInstallEvents(long)
|
||||||
@ stub CMP_WaitServicesAvailable
|
@ stub CMP_WaitServicesAvailable
|
||||||
@ stdcall CM_Add_Empty_Log_Conf(ptr ptr long long)
|
@ stdcall CM_Add_Empty_Log_Conf(ptr ptr long long)
|
||||||
@ stdcall CM_Add_Empty_Log_Conf_Ex(ptr ptr long long ptr)
|
@ stdcall CM_Add_Empty_Log_Conf_Ex(ptr ptr long long ptr)
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
|
DWORD WINAPI
|
||||||
|
CMP_WaitNoPendingInstallEvents(DWORD dwTimeout);
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
|
@ -656,6 +658,12 @@ InstallReactOS (HINSTANCE hInstance)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CMP_WaitNoPendingInstallEvents(INFINITE) != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
DebugPrint("CMP_WaitNoPendingInstallEvents() failed!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
InstallWizard();
|
InstallWizard();
|
||||||
|
|
||||||
SetupCloseInfFile(hSysSetupInf);
|
SetupCloseInfFile(hSysSetupInf);
|
||||||
|
|
Loading…
Reference in a new issue