Skip to content

Commit 9e1f2b0

Browse files
authored
[NTUSER][USER32] Rewrite GetAncestor (reactos#7978)
JIRA issue: N/A - Set the last error. - Check message window. - Modify user32.spec.
1 parent 53685ad commit 9e1f2b0

File tree

4 files changed

+93
-106
lines changed

4 files changed

+93
-106
lines changed

win32ss/include/ntuser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,8 +2138,8 @@ NtUserGetAltTabInfo(
21382138
HWND
21392139
NTAPI
21402140
NtUserGetAncestor(
2141-
HWND hWnd,
2142-
UINT Flags);
2141+
_In_ HWND hWnd,
2142+
_In_ UINT uType);
21432143

21442144
DWORD
21452145
NTAPI

win32ss/user/ntuser/window.c

Lines changed: 68 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3351,99 +3351,98 @@ NtUserFindWindowEx(HWND hwndParent,
33513351
return Ret;
33523352
}
33533353

3354-
3355-
/*
3356-
* @implemented
3357-
*/
3358-
PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type)
3354+
/* @implemented */
3355+
PWND FASTCALL
3356+
UserGetAncestor(_In_ PWND pWnd, _In_ UINT uType)
33593357
{
3360-
PWND WndAncestor, Parent;
3358+
PWND WndAncestor, Parent, pwndMessage;
3359+
PDESKTOP pDesktop;
3360+
PWND pwndDesktop;
33613361

3362-
if (UserHMGetHandle(Wnd) == IntGetDesktopWindow())
3363-
{
3364-
return NULL;
3365-
}
3362+
pDesktop = pWnd->head.rpdesk;
3363+
ASSERT(pDesktop);
3364+
ASSERT(pDesktop->pDeskInfo);
33663365

3367-
switch (Type)
3368-
{
3369-
case GA_PARENT:
3370-
{
3371-
WndAncestor = Wnd->spwndParent;
3372-
break;
3373-
}
3366+
pwndDesktop = pDesktop->pDeskInfo->spwnd;
3367+
if (pWnd == pwndDesktop)
3368+
return NULL;
33743369

3375-
case GA_ROOT:
3376-
{
3377-
WndAncestor = Wnd;
3378-
Parent = NULL;
3370+
pwndMessage = pDesktop->spwndMessage;
3371+
if (pWnd == pwndMessage)
3372+
return NULL;
33793373

3380-
for(;;)
3381-
{
3382-
if(!(Parent = WndAncestor->spwndParent))
3383-
{
3384-
break;
3385-
}
3386-
if(IntIsDesktopWindow(Parent))
3387-
{
3388-
break;
3389-
}
3374+
Parent = pWnd->spwndParent;
3375+
if (!Parent)
3376+
return NULL;
33903377

3391-
WndAncestor = Parent;
3392-
}
3393-
break;
3394-
}
3378+
switch (uType)
3379+
{
3380+
case GA_PARENT:
3381+
return Parent;
33953382

3396-
case GA_ROOTOWNER:
3397-
{
3398-
WndAncestor = Wnd;
3383+
case GA_ROOT:
3384+
WndAncestor = pWnd;
3385+
if (Parent == pwndDesktop)
3386+
break;
33993387

3400-
for (;;)
3388+
do
34013389
{
3402-
Parent = IntGetParent(WndAncestor);
3390+
if (Parent == pwndMessage)
3391+
break;
34033392

3404-
if (!Parent)
3405-
{
3406-
break;
3407-
}
3393+
WndAncestor = Parent;
3394+
3395+
pDesktop = Parent->head.rpdesk;
3396+
ASSERT(pDesktop);
3397+
ASSERT(pDesktop->pDeskInfo);
3398+
3399+
Parent = Parent->spwndParent;
3400+
} while (Parent != pDesktop->pDeskInfo->spwnd);
3401+
break;
34083402

3409-
WndAncestor = Parent;
3403+
case GA_ROOTOWNER:
3404+
WndAncestor = pWnd;
3405+
for (PWND pwndNode = IntGetParent(pWnd); pwndNode; pwndNode = IntGetParent(pwndNode))
3406+
{
3407+
WndAncestor = pwndNode;
34103408
}
34113409
break;
3412-
}
34133410

3414-
default:
3415-
{
3411+
default:
34163412
return NULL;
3417-
}
3418-
}
3413+
}
34193414

3420-
return WndAncestor;
3415+
return WndAncestor;
34213416
}
34223417

3423-
/*
3424-
* @implemented
3425-
*/
3418+
/* @implemented */
34263419
HWND APIENTRY
3427-
NtUserGetAncestor(HWND hWnd, UINT Type)
3420+
NtUserGetAncestor(_In_ HWND hWnd, _In_ UINT uType)
34283421
{
3429-
PWND Window, Ancestor;
3430-
HWND Ret = NULL;
3422+
PWND Window, pwndAncestor;
3423+
HWND hwndAncestor = NULL;
34313424

3432-
TRACE("Enter NtUserGetAncestor\n");
3433-
UserEnterExclusive();
3425+
TRACE("Enter NtUserGetAncestor\n");
3426+
UserEnterShared();
34343427

3435-
Window = UserGetWindowObject(hWnd);
3436-
if (Window)
3437-
{
3438-
Ancestor = UserGetAncestor(Window, Type);
3439-
/* fixme: can UserGetAncestor ever return NULL for a valid window? */
3428+
Window = UserGetWindowObject(hWnd);
3429+
if (!Window)
3430+
goto Quit;
34403431

3441-
Ret = (Ancestor ? UserHMGetHandle(Ancestor) : NULL);
3442-
}
3432+
if (!uType || uType > GA_ROOTOWNER)
3433+
{
3434+
EngSetLastError(ERROR_INVALID_PARAMETER);
3435+
goto Quit;
3436+
}
34433437

3444-
TRACE("Leave NtUserGetAncestor, ret=%p\n", Ret);
3445-
UserLeave();
3446-
return Ret;
3438+
pwndAncestor = UserGetAncestor(Window, uType);
3439+
if (pwndAncestor)
3440+
hwndAncestor = UserHMGetHandle(pwndAncestor);
3441+
3442+
Quit:
3443+
UserLeave();
3444+
TRACE("Leave NtUserGetAncestor returning %p\n", hwndAncestor);
3445+
return hwndAncestor;
34473446
}
34483447

34493448
////

win32ss/user/user32/user32.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@
249249
@ stdcall GetAltTabInfo(long long ptr ptr long) GetAltTabInfoA
250250
@ stdcall GetAltTabInfoA(long long ptr ptr long)
251251
@ stdcall GetAltTabInfoW(long long ptr ptr long)
252-
@ stdcall GetAncestor(long long) ; Direct call NtUserGetAncestor
252+
@ stdcall GetAncestor(ptr long) ; Direct call NtUserGetAncestor
253253
@ stdcall GetAppCompatFlags(long)
254254
@ stdcall GetAppCompatFlags2(long)
255255
@ stdcall GetAsyncKeyState(long)

win32ss/user/user32/windows/window.c

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -924,52 +924,40 @@ GetAltTabInfoW(HWND hwnd,
924924
return NtUserGetAltTabInfo(hwnd,iItem,pati,pszItemText,cchItemText,FALSE);
925925
}
926926

927-
928-
/*
929-
* @implemented
930-
*/
927+
/* @implemented */
931928
HWND WINAPI
932-
GetAncestor(HWND hwnd, UINT gaFlags)
929+
GetAncestor(_In_ HWND hwnd, _In_ UINT uType)
933930
{
934-
HWND Ret = NULL;
935-
PWND Ancestor, Wnd;
936-
937-
Wnd = ValidateHwnd(hwnd);
938-
if (!Wnd)
931+
PWND pWnd = ValidateHwnd(hwnd);
932+
if (!pWnd || pWnd == GetThreadDesktopWnd())
939933
return NULL;
940934

941-
_SEH2_TRY
935+
/* Special handling optimized for speed */
936+
if (uType == GA_PARENT)
942937
{
943-
Ancestor = NULL;
944-
switch (gaFlags)
945-
{
946-
case GA_PARENT:
947-
if (Wnd->spwndParent != NULL)
948-
Ancestor = DesktopPtrToUser(Wnd->spwndParent);
949-
break;
938+
HWND hwndAncestor = NULL;
950939

951-
default:
952-
/* FIXME: Call win32k for now */
953-
Wnd = NULL;
954-
break;
940+
_SEH2_TRY
941+
{
942+
if (pWnd->spwndParent && pWnd->fnid != FNID_MESSAGEWND)
943+
{
944+
PWND pwndAncestor = DesktopPtrToUser(pWnd->spwndParent);
945+
if (pwndAncestor)
946+
hwndAncestor = UserHMGetHandle(pwndAncestor);
947+
}
948+
}
949+
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
950+
{
951+
/* Do nothing */
955952
}
953+
_SEH2_END;
956954

957-
if (Ancestor != NULL)
958-
Ret = UserHMGetHandle(Ancestor);
955+
return hwndAncestor;
959956
}
960-
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
961-
{
962-
/* Do nothing */
963-
}
964-
_SEH2_END;
965957

966-
if (!Wnd) /* Fall back */
967-
Ret = NtUserGetAncestor(hwnd, gaFlags);
968-
969-
return Ret;
958+
return NtUserGetAncestor(hwnd, uType);
970959
}
971960

972-
973961
/*
974962
* @implemented
975963
*/

0 commit comments

Comments
 (0)