[NTUSER][USER32] Rewrite GetAncestor (#7978)

JIRA issue: N/A
- Set the last error.
- Check message window.
- Modify user32.spec.
This commit is contained in:
Katayama Hirofumi MZ 2025-05-16 19:41:01 +09:00 committed by GitHub
parent 53685ada35
commit 9e1f2b035f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 97 additions and 110 deletions

View file

@ -2138,8 +2138,8 @@ NtUserGetAltTabInfo(
HWND
NTAPI
NtUserGetAncestor(
HWND hWnd,
UINT Flags);
_In_ HWND hWnd,
_In_ UINT uType);
DWORD
NTAPI

View file

@ -3351,99 +3351,98 @@ Exit:
return Ret;
}
/*
* @implemented
*/
PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type)
/* @implemented */
PWND FASTCALL
UserGetAncestor(_In_ PWND pWnd, _In_ UINT uType)
{
PWND WndAncestor, Parent;
PWND WndAncestor, Parent, pwndMessage;
PDESKTOP pDesktop;
PWND pwndDesktop;
if (UserHMGetHandle(Wnd) == IntGetDesktopWindow())
{
return NULL;
}
pDesktop = pWnd->head.rpdesk;
ASSERT(pDesktop);
ASSERT(pDesktop->pDeskInfo);
switch (Type)
{
case GA_PARENT:
{
WndAncestor = Wnd->spwndParent;
break;
}
pwndDesktop = pDesktop->pDeskInfo->spwnd;
if (pWnd == pwndDesktop)
return NULL;
case GA_ROOT:
{
WndAncestor = Wnd;
Parent = NULL;
pwndMessage = pDesktop->spwndMessage;
if (pWnd == pwndMessage)
return NULL;
for(;;)
Parent = pWnd->spwndParent;
if (!Parent)
return NULL;
switch (uType)
{
case GA_PARENT:
return Parent;
case GA_ROOT:
WndAncestor = pWnd;
if (Parent == pwndDesktop)
break;
do
{
if(!(Parent = WndAncestor->spwndParent))
{
break;
}
if(IntIsDesktopWindow(Parent))
{
break;
}
if (Parent == pwndMessage)
break;
WndAncestor = Parent;
WndAncestor = Parent;
pDesktop = Parent->head.rpdesk;
ASSERT(pDesktop);
ASSERT(pDesktop->pDeskInfo);
Parent = Parent->spwndParent;
} while (Parent != pDesktop->pDeskInfo->spwnd);
break;
case GA_ROOTOWNER:
WndAncestor = pWnd;
for (PWND pwndNode = IntGetParent(pWnd); pwndNode; pwndNode = IntGetParent(pwndNode))
{
WndAncestor = pwndNode;
}
break;
}
case GA_ROOTOWNER:
{
WndAncestor = Wnd;
for (;;)
{
Parent = IntGetParent(WndAncestor);
if (!Parent)
{
break;
}
WndAncestor = Parent;
}
break;
}
default:
{
default:
return NULL;
}
}
}
return WndAncestor;
return WndAncestor;
}
/*
* @implemented
*/
/* @implemented */
HWND APIENTRY
NtUserGetAncestor(HWND hWnd, UINT Type)
NtUserGetAncestor(_In_ HWND hWnd, _In_ UINT uType)
{
PWND Window, Ancestor;
HWND Ret = NULL;
PWND Window, pwndAncestor;
HWND hwndAncestor = NULL;
TRACE("Enter NtUserGetAncestor\n");
UserEnterExclusive();
TRACE("Enter NtUserGetAncestor\n");
UserEnterShared();
Window = UserGetWindowObject(hWnd);
if (Window)
{
Ancestor = UserGetAncestor(Window, Type);
/* fixme: can UserGetAncestor ever return NULL for a valid window? */
Window = UserGetWindowObject(hWnd);
if (!Window)
goto Quit;
Ret = (Ancestor ? UserHMGetHandle(Ancestor) : NULL);
}
if (!uType || uType > GA_ROOTOWNER)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
goto Quit;
}
TRACE("Leave NtUserGetAncestor, ret=%p\n", Ret);
UserLeave();
return Ret;
pwndAncestor = UserGetAncestor(Window, uType);
if (pwndAncestor)
hwndAncestor = UserHMGetHandle(pwndAncestor);
Quit:
UserLeave();
TRACE("Leave NtUserGetAncestor returning %p\n", hwndAncestor);
return hwndAncestor;
}
////

View file

@ -249,7 +249,7 @@
@ stdcall GetAltTabInfo(long long ptr ptr long) GetAltTabInfoA
@ stdcall GetAltTabInfoA(long long ptr ptr long)
@ stdcall GetAltTabInfoW(long long ptr ptr long)
@ stdcall GetAncestor(long long) ; Direct call NtUserGetAncestor
@ stdcall GetAncestor(ptr long) ; Direct call NtUserGetAncestor
@ stdcall GetAppCompatFlags(long)
@ stdcall GetAppCompatFlags2(long)
@ stdcall GetAsyncKeyState(long)

View file

@ -924,52 +924,40 @@ GetAltTabInfoW(HWND hwnd,
return NtUserGetAltTabInfo(hwnd,iItem,pati,pszItemText,cchItemText,FALSE);
}
/*
* @implemented
*/
/* @implemented */
HWND WINAPI
GetAncestor(HWND hwnd, UINT gaFlags)
GetAncestor(_In_ HWND hwnd, _In_ UINT uType)
{
HWND Ret = NULL;
PWND Ancestor, Wnd;
Wnd = ValidateHwnd(hwnd);
if (!Wnd)
PWND pWnd = ValidateHwnd(hwnd);
if (!pWnd || pWnd == GetThreadDesktopWnd())
return NULL;
_SEH2_TRY
/* Special handling optimized for speed */
if (uType == GA_PARENT)
{
Ancestor = NULL;
switch (gaFlags)
HWND hwndAncestor = NULL;
_SEH2_TRY
{
case GA_PARENT:
if (Wnd->spwndParent != NULL)
Ancestor = DesktopPtrToUser(Wnd->spwndParent);
break;
default:
/* FIXME: Call win32k for now */
Wnd = NULL;
break;
if (pWnd->spwndParent && pWnd->fnid != FNID_MESSAGEWND)
{
PWND pwndAncestor = DesktopPtrToUser(pWnd->spwndParent);
if (pwndAncestor)
hwndAncestor = UserHMGetHandle(pwndAncestor);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Do nothing */
}
_SEH2_END;
if (Ancestor != NULL)
Ret = UserHMGetHandle(Ancestor);
return hwndAncestor;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Do nothing */
}
_SEH2_END;
if (!Wnd) /* Fall back */
Ret = NtUserGetAncestor(hwnd, gaFlags);
return Ret;
return NtUserGetAncestor(hwnd, uType);
}
/*
* @implemented
*/