mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 05:26:58 +00:00
[0.4.9][WIN32K:NTUSER] Fix CORE-12243 OS-freezing when closing nLite
This fixes CORE-12243 and allows .NET applications like nLite 1.4.9.3 to exit properly without freezing the whole OS. The actual fix was picked from 0.4.11-dev-78-g4d48b88bfb
"[WIN32K:NTUSER] co_UserDestroyWindow(): Simplify the destruction of the owned windows." but it made sense to also pick the related 0.4.11-dev-77-ge286c4c520
"[WIN32K:NTUSER] Optimize IntWinListOwnedPopups() a little bit. Improve a trace." and 0.4.11-dev-76-gf644a50cd7
"[WIN32K:NTUSER] Code formatting only."
This commit is contained in:
parent
2a9249b546
commit
bf8cbe2769
|
@ -254,29 +254,69 @@ IntEnableWindow( HWND hWnd, BOOL bEnable )
|
||||||
HWND* FASTCALL
|
HWND* FASTCALL
|
||||||
IntWinListChildren(PWND Window)
|
IntWinListChildren(PWND Window)
|
||||||
{
|
{
|
||||||
PWND Child;
|
PWND Child;
|
||||||
HWND *List;
|
HWND *List;
|
||||||
UINT Index, NumChildren = 0;
|
UINT Index, NumChildren = 0;
|
||||||
|
|
||||||
if (!Window) return NULL;
|
if (!Window) return NULL;
|
||||||
|
|
||||||
for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
|
for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
|
||||||
++NumChildren;
|
{
|
||||||
|
++NumChildren;
|
||||||
|
}
|
||||||
|
|
||||||
List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), USERTAG_WINDOWLIST);
|
List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), USERTAG_WINDOWLIST);
|
||||||
if(!List)
|
if(!List)
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate memory for children array\n");
|
ERR("Failed to allocate memory for children array\n");
|
||||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (Child = Window->spwndChild, Index = 0;
|
|
||||||
Child != NULL;
|
|
||||||
Child = Child->spwndNext, ++Index)
|
|
||||||
List[Index] = Child->head.h;
|
|
||||||
List[Index] = NULL;
|
|
||||||
|
|
||||||
return List;
|
Index = 0;
|
||||||
|
for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
|
||||||
|
{
|
||||||
|
List[Index++] = Child->head.h;
|
||||||
|
}
|
||||||
|
List[Index] = NULL;
|
||||||
|
|
||||||
|
return List;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND* FASTCALL
|
||||||
|
IntWinListOwnedPopups(PWND Window)
|
||||||
|
{
|
||||||
|
PWND Child, Desktop;
|
||||||
|
HWND *List;
|
||||||
|
UINT Index, NumOwned = 0;
|
||||||
|
|
||||||
|
Desktop = co_GetDesktopWindow(Window);
|
||||||
|
if (!Desktop)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (Child = Desktop->spwndChild; Child; Child = Child->spwndNext)
|
||||||
|
{
|
||||||
|
if (Child->spwndOwner == Window)
|
||||||
|
++NumOwned;
|
||||||
|
}
|
||||||
|
|
||||||
|
List = ExAllocatePoolWithTag(PagedPool, (NumOwned + 1) * sizeof(HWND), USERTAG_WINDOWLIST);
|
||||||
|
if (!List)
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate memory for children array\n");
|
||||||
|
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Index = 0;
|
||||||
|
for (Child = Desktop->spwndChild; Child; Child = Child->spwndNext)
|
||||||
|
{
|
||||||
|
if (Child->spwndOwner == Window)
|
||||||
|
List[Index++] = Child->head.h;
|
||||||
|
}
|
||||||
|
List[Index] = NULL;
|
||||||
|
|
||||||
|
return List;
|
||||||
}
|
}
|
||||||
|
|
||||||
PWND FASTCALL
|
PWND FASTCALL
|
||||||
|
@ -2572,7 +2612,7 @@ BOOLEAN co_UserDestroyWindow(PVOID Object)
|
||||||
hWnd = Window->head.h;
|
hWnd = Window->head.h;
|
||||||
ti = PsGetCurrentThreadWin32Thread();
|
ti = PsGetCurrentThreadWin32Thread();
|
||||||
|
|
||||||
TRACE("co_UserDestroyWindow \n");
|
TRACE("co_UserDestroyWindow(Window = 0x%p, hWnd = 0x%p)\n", Window, hWnd);
|
||||||
|
|
||||||
/* Check for owner thread */
|
/* Check for owner thread */
|
||||||
if ( Window->head.pti != PsGetCurrentThreadWin32Thread())
|
if ( Window->head.pti != PsGetCurrentThreadWin32Thread())
|
||||||
|
@ -2632,7 +2672,7 @@ BOOLEAN co_UserDestroyWindow(PVOID Object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust last active.
|
/* Adjust last active */
|
||||||
if ((pwndTemp = Window->spwndOwner))
|
if ((pwndTemp = Window->spwndOwner))
|
||||||
{
|
{
|
||||||
while (pwndTemp->spwndOwner)
|
while (pwndTemp->spwndOwner)
|
||||||
|
@ -2683,58 +2723,41 @@ BOOLEAN co_UserDestroyWindow(PVOID Object)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recursively destroy owned windows */
|
/* Recursively destroy owned windows */
|
||||||
|
if (!(Window->style & WS_CHILD))
|
||||||
|
{
|
||||||
|
HWND* List;
|
||||||
|
HWND* phWnd;
|
||||||
|
PWND pWnd;
|
||||||
|
|
||||||
if (! (Window->style & WS_CHILD))
|
List = IntWinListOwnedPopups(Window);
|
||||||
{
|
if (List)
|
||||||
for (;;)
|
{
|
||||||
{
|
for (phWnd = List; *phWnd; ++phWnd)
|
||||||
BOOL GotOne = FALSE;
|
|
||||||
HWND *Children;
|
|
||||||
HWND *ChildHandle;
|
|
||||||
PWND Child, Desktop;
|
|
||||||
|
|
||||||
Desktop = IntIsDesktopWindow(Window) ? Window :
|
|
||||||
UserGetWindowObject(IntGetDesktopWindow());
|
|
||||||
Children = IntWinListChildren(Desktop);
|
|
||||||
|
|
||||||
if (Children)
|
|
||||||
{
|
|
||||||
for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
|
|
||||||
{
|
{
|
||||||
Child = UserGetWindowObject(*ChildHandle);
|
pWnd = ValidateHwndNoErr(*phWnd);
|
||||||
if (Child == NULL)
|
if (pWnd == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (Child->spwndOwner != Window)
|
ASSERT(pWnd->spwndOwner == Window);
|
||||||
{
|
ASSERT(pWnd != Window);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IntWndBelongsToThread(Child, PsGetCurrentThreadWin32Thread()))
|
|
||||||
{
|
|
||||||
USER_REFERENCE_ENTRY ChildRef;
|
|
||||||
UserRefObjectCo(Child, &ChildRef); // Temp HACK?
|
|
||||||
co_UserDestroyWindow(Child);
|
|
||||||
UserDerefObjectCo(Child); // Temp HACK?
|
|
||||||
|
|
||||||
GotOne = TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Child->spwndOwner != NULL)
|
|
||||||
{
|
|
||||||
Child->spwndOwner = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
pWnd->spwndOwner = NULL;
|
||||||
|
if (IntWndBelongsToThread(pWnd, PsGetCurrentThreadWin32Thread()))
|
||||||
|
{
|
||||||
|
USER_REFERENCE_ENTRY Ref;
|
||||||
|
UserRefObjectCo(pWnd, &Ref); // Temp HACK?
|
||||||
|
co_UserDestroyWindow(pWnd);
|
||||||
|
UserDerefObjectCo(pWnd); // Temp HACK?
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERR("IntWndBelongsToThread(0x%p) is FALSE, ignoring.\n", pWnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ExFreePoolWithTag(Children, USERTAG_WINDOWLIST);
|
|
||||||
}
|
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
|
||||||
if (! GotOne)
|
}
|
||||||
{
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate mouse move message for the next window */
|
/* Generate mouse move message for the next window */
|
||||||
msg.message = WM_MOUSEMOVE;
|
msg.message = WM_MOUSEMOVE;
|
||||||
|
|
Loading…
Reference in a new issue