Author: hbelusca
Date: Tue Aug 2 16:02:54 2016
New Revision: 72093
URL:
http://svn.reactos.org/svn/reactos?rev=72093&view=rev
Log:
[WIN32K]
- Deduplicate NtUserScrollWindowEx / IntScrollWindowEx by making NtUserScrollWindowEx
properly call IntScrollWindowEx instead.
- Fix potential memory leaks in failure paths in IntScrollWindowEx.
Modified:
trunk/reactos/win32ss/user/ntuser/scrollex.c
Modified: trunk/reactos/win32ss/user/ntuser/scrollex.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/scroll…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/scrollex.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/scrollex.c [iso-8859-1] Tue Aug 2 16:02:54 2016
@@ -238,8 +238,8 @@
LPRECT prcUpdate,
UINT flags)
{
+ INT Result;
RECTL rcScroll, rcClip, rcCaret;
- INT Result;
PWND CaretWnd;
HDC hDC;
PREGION RgnUpdate = NULL, RgnTemp, RgnWinupd = NULL;
@@ -248,19 +248,20 @@
int rdw_flags;
USER_REFERENCE_ENTRY CaretRef;
+ if (!Window || !IntIsWindowDrawable(Window))
+ {
+ return ERROR;
+ }
+
IntGetClientRect(Window, &rcClip);
if (prcScroll)
- {
RECTL_bIntersectRect(&rcScroll, &rcClip, prcScroll);
- }
else
rcScroll = rcClip;
if (prcClip)
- {
RECTL_bIntersectRect(&rcClip, &rcClip, prcClip);
- }
if (rcClip.right <= rcClip.left || rcClip.bottom <= rcClip.top ||
(dx == 0 && dy == 0))
@@ -283,7 +284,8 @@
if (!RgnTemp)
{
EngSetLastError(ERROR_INVALID_HANDLE);
- return ERROR;
+ Result = ERROR;
+ goto Cleanup;
}
IntGdiCombineRgn(RgnUpdate, RgnTemp, NULL, RGN_COPY);
REGION_UnlockRgn(RgnTemp);
@@ -311,7 +313,8 @@
if (!hDC)
{
/* FIXME: SetLastError? */
- return ERROR;
+ Result = ERROR;
+ goto Cleanup;
}
rdw_flags = (flags & SW_ERASE) && (flags & SW_INVALIDATE) ?
RDW_INVALIDATE | RDW_ERASE : RDW_INVALIDATE ;
@@ -339,7 +342,8 @@
if (!RgnTemp)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return ERROR;
+ Result = ERROR;
+ goto Cleanup;
}
if (co_IntGetUpdateRgn(Window, RgnTemp, FALSE) != NULLREGION)
@@ -349,7 +353,8 @@
{
if (hrgnUpdate)
{
- RgnWinupd = IntSysCreateRectpRgn( 0, 0, 0, 0);
+ RgnWinupd = IntSysCreateRectpRgn(0, 0, 0, 0);
+ // FIXME: What to do if RgnWinupd == NULL??
IntGdiCombineRgn( RgnWinupd, RgnTemp, 0, RGN_COPY);
}
@@ -381,10 +386,7 @@
for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
{
rcChild = Child->rcWindow;
- rcChild.left -= ClientOrigin.x;
- rcChild.top -= ClientOrigin.y;
- rcChild.right -= ClientOrigin.x;
- rcChild.bottom -= ClientOrigin.y;
+ RECTL_vOffsetRect(&rcChild, -ClientOrigin.x, -ClientOrigin.y);
if (!prcScroll || RECTL_bIntersectRect(&rcDummy, &rcChild,
&rcScroll))
{
@@ -396,9 +398,9 @@
lParam = MAKELONG(rcChild.left + dx, rcChild.top + dy);
/* wine sends WM_POSCHANGING, WM_POSCHANGED messages */
- /* windows sometimes a WM_MOVE */
+ /* windows sometimes a WM_MOVE */
co_IntSendMessage(UserHMGetHandle(Child), WM_MOVE, 0, lParam);
-
+
UserDerefObjectCo(Child);
}
}
@@ -436,6 +438,7 @@
REGION_UnlockRgn(RgnTemp);
}
+Cleanup:
if (RgnWinupd)
{
REGION_Delete(RgnWinupd);
@@ -478,9 +481,9 @@
LPRECT prcUnsafeUpdate)
{
DECLARE_RETURN(DWORD);
+ DWORD Result;
+ NTSTATUS Status = STATUS_SUCCESS;
RECTL rcScroll, rcClip, rcUpdate;
- NTSTATUS Status = STATUS_SUCCESS;
- DWORD Result;
TRACE("Enter NtUserScrollDC\n");
UserEnterExclusive();
@@ -506,7 +509,8 @@
{
Status = _SEH2_GetExceptionCode();
}
- _SEH2_END
+ _SEH2_END;
+
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
@@ -516,14 +520,14 @@
Result = UserScrollDC( hDC,
dx,
dy,
- prcUnsafeScroll? &rcScroll : 0,
- prcUnsafeClip? &rcClip : 0,
+ prcUnsafeScroll ? &rcScroll : NULL,
+ prcUnsafeClip ? &rcClip : NULL,
hrgnUpdate,
NULL,
- prcUnsafeUpdate? &rcUpdate : NULL);
+ prcUnsafeUpdate ? &rcUpdate : NULL);
if(Result == ERROR)
{
- /* FIXME: Only if hRgnUpdate is invalid we should
SetLastError(ERROR_INVALID_HANDLE) */
+ /* FIXME: Only if hRgnUpdate is invalid we should
SetLastError(ERROR_INVALID_HANDLE) */
RETURN(FALSE);
}
@@ -537,7 +541,8 @@
{
Status = _SEH2_GetExceptionCode();
}
- _SEH2_END
+ _SEH2_END;
+
if (!NT_SUCCESS(Status))
{
/* FIXME: SetLastError? */
@@ -572,17 +577,12 @@
LPRECT prcUnsafeUpdate,
UINT flags)
{
- RECTL rcScroll, rcClip, rcCaret, rcUpdate;
+ DECLARE_RETURN(DWORD);
INT Result;
- PWND Window = NULL, CaretWnd;
- HDC hDC;
- PREGION RgnUpdate = NULL, RgnTemp, RgnWinupd = NULL;
- HWND hwndCaret;
- DWORD dcxflags = 0;
- int rdw_flags;
NTSTATUS Status = STATUS_SUCCESS;
- DECLARE_RETURN(DWORD);
- USER_REFERENCE_ENTRY Ref, CaretRef;
+ PWND Window = NULL;
+ RECTL rcScroll, rcClip, rcUpdate;
+ USER_REFERENCE_ENTRY Ref;
TRACE("Enter NtUserScrollWindowEx\n");
UserEnterExclusive();
@@ -591,33 +591,29 @@
if (!Window || !IntIsWindowDrawable(Window))
{
Window = NULL; /* prevent deref at cleanup */
- RETURN( ERROR);
+ RETURN(ERROR);
}
UserRefObjectCo(Window, &Ref);
- IntGetClientRect(Window, &rcClip);
-
_SEH2_TRY
{
if (prcUnsafeScroll)
{
ProbeForRead(prcUnsafeScroll, sizeof(*prcUnsafeScroll), 1);
- RECTL_bIntersectRect(&rcScroll, &rcClip, prcUnsafeScroll);
- }
- else
- rcScroll = rcClip;
+ rcScroll = *prcUnsafeScroll;
+ }
if (prcUnsafeClip)
{
ProbeForRead(prcUnsafeClip, sizeof(*prcUnsafeClip), 1);
- RECTL_bIntersectRect(&rcClip, &rcClip, prcUnsafeClip);
+ rcClip = *prcUnsafeClip;
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
- _SEH2_END
+ _SEH2_END;
if (!NT_SUCCESS(Status))
{
@@ -625,166 +621,13 @@
RETURN(ERROR);
}
- if (rcClip.right <= rcClip.left || rcClip.bottom <= rcClip.top ||
- (dx == 0 && dy == 0))
- {
- RETURN(NULLREGION);
- }
-
- /* We must use a copy of the region, as we can't hold an exclusive lock
- * on it while doing callouts to user-mode */
- RgnUpdate = IntSysCreateRectpRgn(0, 0, 0, 0);
- if(!RgnUpdate)
- {
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- RETURN(ERROR);
- }
-
- if (hrgnUpdate)
- {
- RgnTemp = REGION_LockRgn(hrgnUpdate);
- if (!RgnTemp)
- {
- EngSetLastError(ERROR_INVALID_HANDLE);
- RETURN(ERROR);
- }
- IntGdiCombineRgn(RgnUpdate, RgnTemp, NULL, RGN_COPY);
- REGION_UnlockRgn(RgnTemp);
- }
-
- /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */
- if (flags & SW_SCROLLWNDDCE)
- {
- dcxflags = DCX_USESTYLE;
-
- if (!(Window->pcls->style & (CS_OWNDC|CS_CLASSDC)))
- dcxflags |= DCX_CACHE; // AH??? wine~ If not Powned or with Class go Cheap!
-
- if (flags & SW_SCROLLCHILDREN && Window->style &
WS_CLIPCHILDREN)
- dcxflags |= DCX_CACHE|DCX_NOCLIPCHILDREN;
- }
- else
- {
- /* So in this case ScrollWindowEx uses Cache DC. */
- dcxflags = DCX_CACHE|DCX_USESTYLE;
- if (flags & SW_SCROLLCHILDREN) dcxflags |= DCX_NOCLIPCHILDREN;
- }
-
- hDC = UserGetDCEx(Window, 0, dcxflags);
- if (!hDC)
- {
- /* FIXME: SetLastError? */
- RETURN(ERROR);
- }
-
- rdw_flags = (flags & SW_ERASE) && (flags & SW_INVALIDATE) ?
RDW_INVALIDATE | RDW_ERASE : RDW_INVALIDATE ;
-
- rcCaret = rcScroll;
- hwndCaret = co_IntFixCaret(Window, &rcCaret, flags);
-
- Result = UserScrollDC( hDC,
- dx,
- dy,
- &rcScroll,
- &rcClip,
- NULL,
- RgnUpdate,
- prcUnsafeUpdate? &rcUpdate : NULL);
-
- UserReleaseDC(Window, hDC, FALSE);
-
- /*
- * Take into account the fact that some damage may have occurred during
- * the scroll. Keep a copy in hrgnWinupd to be added to hrngUpdate at the end.
- */
-
- RgnTemp = IntSysCreateRectpRgn(0, 0, 0, 0);
- if (!RgnTemp)
- {
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- RETURN(ERROR);
- }
-
- if (co_IntGetUpdateRgn(Window, RgnTemp, FALSE) != NULLREGION)
- {
- PREGION RgnClip = IntSysCreateRectpRgnIndirect(&rcClip);
- if (RgnClip)
- {
- if (hrgnUpdate)
- {
- RgnWinupd = IntSysCreateRectpRgn( 0, 0, 0, 0);
- IntGdiCombineRgn( RgnWinupd, RgnTemp, 0, RGN_COPY);
- }
-
- REGION_bOffsetRgn(RgnTemp, dx, dy);
-
- IntGdiCombineRgn(RgnTemp, RgnTemp, RgnClip, RGN_AND);
-
- if (hrgnUpdate)
- IntGdiCombineRgn( RgnWinupd, RgnWinupd, RgnTemp, RGN_OR );
-
- co_UserRedrawWindow(Window, NULL, RgnTemp, rdw_flags );
-
- REGION_Delete(RgnClip);
- }
- }
- REGION_Delete(RgnTemp);
-
- if (flags & SW_SCROLLCHILDREN)
- {
- PWND Child;
- RECTL rcChild;
- POINT ClientOrigin;
- USER_REFERENCE_ENTRY WndRef;
- RECTL rcDummy;
- LPARAM lParam;
-
- IntGetClientOrigin(Window, &ClientOrigin);
-
- for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
- {
- rcChild = Child->rcWindow;
- rcChild.left -= ClientOrigin.x;
- rcChild.top -= ClientOrigin.y;
- rcChild.right -= ClientOrigin.x;
- rcChild.bottom -= ClientOrigin.y;
-
- if (!prcUnsafeScroll || RECTL_bIntersectRect(&rcDummy, &rcChild,
&rcScroll))
- {
- UserRefObjectCo(Child, &WndRef);
-
- if (Window->spwndParent == UserGetDesktopWindow()) //
Window->spwndParent->fnid == FNID_DESKTOP )
- lParam = MAKELONG(Child->rcClient.left, Child->rcClient.top);
- else
- lParam = MAKELONG(rcChild.left + dx, rcChild.top + dy);
-
- /* wine sends WM_POSCHANGING, WM_POSCHANGED messages */
- /* windows sometimes a WM_MOVE */
- co_IntSendMessage(UserHMGetHandle(Child), WM_MOVE, 0, lParam);
-
- UserDerefObjectCo(Child);
- }
- }
- }
-
- if (flags & (SW_INVALIDATE | SW_ERASE))
- {
- co_UserRedrawWindow( Window,
- NULL,
- RgnUpdate,
- rdw_flags | /* HACK
*/
- ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN :
RDW_NOCHILDREN) );
- }
-
- if (hwndCaret && (CaretWnd = UserGetWindowObject(hwndCaret)))
- {
- UserRefObjectCo(CaretWnd, &CaretRef);
-
- co_IntSetCaretPos(rcCaret.left + dx, rcCaret.top + dy);
- co_UserShowCaret(CaretWnd);
-
- UserDerefObjectCo(CaretWnd);
- }
+ Result = IntScrollWindowEx(Window,
+ dx, dy,
+ prcUnsafeScroll ? &rcScroll : NULL,
+ prcUnsafeClip ? &rcClip : NULL,
+ hrgnUpdate,
+ prcUnsafeUpdate ? &rcUpdate : NULL,
+ flags);
if (prcUnsafeUpdate)
{
@@ -798,7 +641,7 @@
{
Status = _SEH2_GetExceptionCode();
}
- _SEH2_END
+ _SEH2_END;
if (!NT_SUCCESS(Status))
{
@@ -810,29 +653,6 @@
RETURN(Result);
CLEANUP:
- if (hrgnUpdate && (_ret_ != ERROR))
- {
- /* Give everything back to the caller */
- RgnTemp = REGION_LockRgn(hrgnUpdate);
- /* The handle should still be valid */
- ASSERT(RgnTemp);
- if (RgnWinupd)
- IntGdiCombineRgn(RgnTemp, RgnUpdate, RgnWinupd, RGN_OR);
- else
- IntGdiCombineRgn(RgnTemp, RgnUpdate, NULL, RGN_COPY);
- REGION_UnlockRgn(RgnTemp);
- }
-
- if (RgnWinupd)
- {
- REGION_Delete(RgnWinupd);
- }
-
- if (RgnUpdate)
- {
- REGION_Delete(RgnUpdate);
- }
-
if (Window)
UserDerefObjectCo(Window);
@@ -841,5 +661,4 @@
END_CLEANUP;
}
-
/* EOF */