mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 21:01:54 +00:00
[UMPNPMGR][USETUP] Fix the way device-install events are queued and dequeued. Fixes CORE-16103.
Dedicated to the hard work of Joachim Henze! xD This reverts part of commit043a98dd
(see also commitb2aeafca
). Contrary to what I assumed in commit043a98dd
(and was also assumed in the older commitb2aeafca
), we cannot use the singled-linked lists to queue and dequeue the PnP device-install events, because: - the events must be treated from the oldest to the newest ones, for consistency, otherwise this creates problems, as shown by e.g. CORE-16103; - the system singled-linked lists only offer access to the top of the list (like a stack) instead of to both the top and the bottom of the list, as would be required for a queue. Using the SLISTs would mean that only the newest-received events would be treated first, while the oldest (which were the first received) events would be treated last, and this is wrong. Therefore one must use e.g. the standard doubly-linked list. Also, using locked operations (insertion & removal) on the list of device-install events is necessary, because these operations are done concurrently by two different threads: PnpEventThread() and DeviceInstallThread(). Since the interlocked linked list functions are not available in user-mode, we need to use instead locking access through e.g. a mutex.
This commit is contained in:
parent
828a65f470
commit
ffc96d26ec
4 changed files with 93 additions and 42 deletions
|
@ -22,7 +22,7 @@
|
|||
* FILE: base/services/umpnpmgr/install.c
|
||||
* PURPOSE: Device installer
|
||||
* PROGRAMMER: Eric Kohl (eric.kohl@reactos.org)
|
||||
* Hervé Poussineau (hpoussin@reactos.org)
|
||||
* Hervé Poussineau (hpoussin@reactos.org)
|
||||
* Colin Finck (colin@reactos.org)
|
||||
*/
|
||||
|
||||
|
@ -40,7 +40,9 @@ HANDLE hUserToken = NULL;
|
|||
HANDLE hInstallEvent = NULL;
|
||||
HANDLE hNoPendingInstalls = NULL;
|
||||
|
||||
SLIST_HEADER DeviceInstallListHead;
|
||||
/* Device-install event list */
|
||||
HANDLE hDeviceInstallListMutex;
|
||||
LIST_ENTRY DeviceInstallListHead;
|
||||
HANDLE hDeviceInstallListNotEmpty;
|
||||
|
||||
|
||||
|
@ -354,7 +356,7 @@ DWORD
|
|||
WINAPI
|
||||
DeviceInstallThread(LPVOID lpParameter)
|
||||
{
|
||||
PSLIST_ENTRY ListEntry;
|
||||
PLIST_ENTRY ListEntry;
|
||||
DeviceInstallParams* Params;
|
||||
BOOL showWizard;
|
||||
|
||||
|
@ -366,7 +368,11 @@ DeviceInstallThread(LPVOID lpParameter)
|
|||
|
||||
while (TRUE)
|
||||
{
|
||||
ListEntry = InterlockedPopEntrySList(&DeviceInstallListHead);
|
||||
/* Dequeue the next oldest device-install event */
|
||||
WaitForSingleObject(hDeviceInstallListMutex, INFINITE);
|
||||
ListEntry = (IsListEmpty(&DeviceInstallListHead)
|
||||
? NULL : RemoveHeadList(&DeviceInstallListHead));
|
||||
ReleaseMutex(hDeviceInstallListMutex);
|
||||
|
||||
if (ListEntry == NULL)
|
||||
{
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
SLIST_ENTRY ListEntry;
|
||||
WCHAR DeviceIds[1];
|
||||
LIST_ENTRY ListEntry;
|
||||
WCHAR DeviceIds[ANYSIZE_ARRAY];
|
||||
} DeviceInstallParams;
|
||||
|
||||
/* install.c */
|
||||
|
@ -45,7 +45,9 @@ extern HANDLE hUserToken;
|
|||
extern HANDLE hInstallEvent;
|
||||
extern HANDLE hNoPendingInstalls;
|
||||
|
||||
extern SLIST_HEADER DeviceInstallListHead;
|
||||
/* Device-install event list */
|
||||
extern HANDLE hDeviceInstallListMutex;
|
||||
extern LIST_ENTRY DeviceInstallListHead;
|
||||
extern HANDLE hDeviceInstallListNotEmpty;
|
||||
|
||||
BOOL
|
||||
|
|
|
@ -104,13 +104,18 @@ PnpEventThread(LPVOID lpParameter)
|
|||
DeviceIdLength = lstrlenW(PnpEvent->TargetDevice.DeviceIds);
|
||||
if (DeviceIdLength)
|
||||
{
|
||||
/* Queue device install (will be dequeued by DeviceInstallThread) */
|
||||
/* Allocate a new device-install event */
|
||||
len = FIELD_OFFSET(DeviceInstallParams, DeviceIds) + (DeviceIdLength + 1) * sizeof(WCHAR);
|
||||
Params = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (Params)
|
||||
{
|
||||
wcscpy(Params->DeviceIds, PnpEvent->TargetDevice.DeviceIds);
|
||||
InterlockedPushEntrySList(&DeviceInstallListHead, &Params->ListEntry);
|
||||
|
||||
/* Queue the event (will be dequeued by DeviceInstallThread) */
|
||||
WaitForSingleObject(hDeviceInstallListMutex, INFINITE);
|
||||
InsertTailList(&DeviceInstallListHead, &Params->ListEntry);
|
||||
ReleaseMutex(hDeviceInstallListMutex);
|
||||
|
||||
SetEvent(hDeviceInstallListNotEmpty);
|
||||
}
|
||||
}
|
||||
|
@ -413,14 +418,6 @@ InitializePnPManager(VOID)
|
|||
return dwError;
|
||||
}
|
||||
|
||||
hDeviceInstallListNotEmpty = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (hDeviceInstallListNotEmpty == NULL)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("Could not create the Event! (Error %lu)\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
|
||||
hNoPendingInstalls = CreateEventW(NULL,
|
||||
TRUE,
|
||||
FALSE,
|
||||
|
@ -428,11 +425,30 @@ InitializePnPManager(VOID)
|
|||
if (hNoPendingInstalls == NULL)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("Could not create the Event! (Error %lu)\n", dwError);
|
||||
DPRINT1("Could not create the Pending-Install Event! (Error %lu)\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
|
||||
InitializeSListHead(&DeviceInstallListHead);
|
||||
/*
|
||||
* Initialize the device-install event list
|
||||
*/
|
||||
|
||||
hDeviceInstallListNotEmpty = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (hDeviceInstallListNotEmpty == NULL)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("Could not create the List Event! (Error %lu)\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
|
||||
hDeviceInstallListMutex = CreateMutexW(NULL, FALSE, NULL);
|
||||
if (hDeviceInstallListMutex == NULL)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
DPRINT1("Could not create the List Mutex! (Error %lu)\n", dwError);
|
||||
return dwError;
|
||||
}
|
||||
InitializeListHead(&DeviceInstallListHead);
|
||||
|
||||
/* Query the SuppressUI registry value and cache it for our whole lifetime */
|
||||
GetBooleanRegValue(HKEY_LOCAL_MACHINE,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue