[NTUSER] Improve NtUserSetWindowPlacement (#7096)

Splitted from #7082. Correct behavior of
NtUserSetWindowPlacement function.
JIRA issue: N/A
- Check gptiCurrent->dwExpWinVer in
  NtUserSetWindowPlacement function.
- Fix the last error.
This commit is contained in:
Katayama Hirofumi MZ 2024-07-09 07:42:56 +09:00 committed by GitHub
parent bf4c09b331
commit ef3e27e2c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -553,7 +553,6 @@ WinPosInitInternalPos(PWND Wnd, RECTL *RestoreRect)
} }
} }
// Win: _GetWindowPlacement
BOOL BOOL
FASTCALL FASTCALL
IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl) IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
@ -562,6 +561,7 @@ IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
if(lpwndpl->length != sizeof(WINDOWPLACEMENT)) if(lpwndpl->length != sizeof(WINDOWPLACEMENT))
{ {
ERR("length mismatch: %u\n", lpwndpl->length);
return FALSE; return FALSE;
} }
@ -3398,9 +3398,7 @@ NtUserGetWindowPlacement(HWND hWnd,
UserEnterShared(); UserEnterShared();
if (!(Wnd = UserGetWindowObject(hWnd))) if (!(Wnd = UserGetWindowObject(hWnd)))
{
goto Exit; // Return FALSE goto Exit; // Return FALSE
}
Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT)); Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -3409,6 +3407,7 @@ NtUserGetWindowPlacement(HWND hWnd,
goto Exit; // Return FALSE goto Exit; // Return FALSE
} }
// This function doesn't check the length. Just overwrite it
Safepl.length = sizeof(WINDOWPLACEMENT); Safepl.length = sizeof(WINDOWPLACEMENT);
IntGetWindowPlacement(Wnd, &Safepl); IntGetWindowPlacement(Wnd, &Safepl);
@ -3709,16 +3708,10 @@ NtUserSetWindowPlacement(HWND hWnd,
TRACE("Enter NtUserSetWindowPlacement\n"); TRACE("Enter NtUserSetWindowPlacement\n");
UserEnterExclusive(); UserEnterExclusive();
if (!(Wnd = UserGetWindowObject(hWnd)) ||
UserIsDesktopWindow(Wnd) || UserIsMessageWindow(Wnd))
{
goto Exit; // Return FALSE
}
_SEH2_TRY _SEH2_TRY
{ {
ProbeForRead(lpwndpl, sizeof(WINDOWPLACEMENT), 1); ProbeForRead(lpwndpl, sizeof(*lpwndpl), 1);
RtlCopyMemory(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT)); Safepl = *lpwndpl;
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -3727,17 +3720,28 @@ NtUserSetWindowPlacement(HWND hWnd,
} }
_SEH2_END _SEH2_END
if(Safepl.length != sizeof(WINDOWPLACEMENT)) /* Backwards-compatibility: Win 3.x doesn't check the length */
if (LOWORD(gptiCurrent->dwExpWinVer) < WINVER_WINNT4)
Safepl.length = sizeof(Safepl);
if (Safepl.length != sizeof(Safepl))
{ {
goto Exit; // Return FALSE EngSetLastError(ERROR_INVALID_PARAMETER);
goto Exit;
} }
Flags = PLACE_MAX | PLACE_RECT; Flags = PLACE_MAX | PLACE_RECT;
if (Safepl.flags & WPF_SETMINPOSITION) Flags |= PLACE_MIN; if (Safepl.flags & WPF_SETMINPOSITION)
Flags |= PLACE_MIN;
Wnd = UserGetWindowObject(hWnd);
if (!Wnd)
goto Exit; // Return FALSE
UserRefObjectCo(Wnd, &Ref); UserRefObjectCo(Wnd, &Ref);
IntSetWindowPlacement(Wnd, &Safepl, Flags); if (!UserIsDesktopWindow(Wnd) && !UserIsMessageWindow(Wnd))
Ret = IntSetWindowPlacement(Wnd, &Safepl, Flags);
UserDerefObjectCo(Wnd); UserDerefObjectCo(Wnd);
Ret = TRUE;
Exit: Exit:
TRACE("Leave NtUserSetWindowPlacement, ret=%i\n", Ret); TRACE("Leave NtUserSetWindowPlacement, ret=%i\n", Ret);