From 12faa738563bf668c6e6aa1fc9b5b1fbef00325f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Tue, 21 Oct 2014 19:57:03 +0000 Subject: [PATCH] [WIN32K] - Fix a few usages of UserSetCursor - Defer the actual freeing of cursor resources to when the object is freed for real. CORE-7575 svn path=/trunk/; revision=64879 --- reactos/win32ss/user/ntuser/cursoricon.h | 2 ++ reactos/win32ss/user/ntuser/cursoricon_new.c | 17 +++++++++++++++-- reactos/win32ss/user/ntuser/defwnd.c | 8 ++++++-- reactos/win32ss/user/ntuser/desktop.c | 6 ++++++ reactos/win32ss/user/ntuser/display.c | 3 ++- reactos/win32ss/user/ntuser/object.c | 4 ++-- reactos/win32ss/user/ntuser/object.h | 2 ++ 7 files changed, 35 insertions(+), 7 deletions(-) diff --git a/reactos/win32ss/user/ntuser/cursoricon.h b/reactos/win32ss/user/ntuser/cursoricon.h index d62453f2b9d..16a466144d6 100644 --- a/reactos/win32ss/user/ntuser/cursoricon.h +++ b/reactos/win32ss/user/ntuser/cursoricon.h @@ -47,6 +47,8 @@ IntDestroyCurIconObject(PVOID Object); VOID FASTCALL IntCleanupCurIconCache(PPROCESSINFO Win32Process); +void FreeCurIconObject(PVOID Object); + #else typedef struct tagCURICON_PROCESS diff --git a/reactos/win32ss/user/ntuser/cursoricon_new.c b/reactos/win32ss/user/ntuser/cursoricon_new.c index 9beedbaab22..436021715a8 100644 --- a/reactos/win32ss/user/ntuser/cursoricon_new.c +++ b/reactos/win32ss/user/ntuser/cursoricon_new.c @@ -150,7 +150,19 @@ IntCreateCurIconHandle(BOOLEAN Animated) } BOOLEAN -IntDestroyCurIconObject(PVOID Object) +IntDestroyCurIconObject( + _In_ PVOID Object) +{ + PCURICON_OBJECT CurIcon = Object; + + /* We just mark the handle as being destroyed. + * Deleting all the stuff will be deferred to the actual struct free. */ + return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR); +} + +void +FreeCurIconObject( + _In_ PVOID Object) { PCURICON_OBJECT CurIcon = Object; @@ -220,7 +232,8 @@ IntDestroyCurIconObject(PVOID Object) } } - return TRUE; + /* Finally free the thing */ + FreeProcMarkObject(CurIcon); } VOID FASTCALL diff --git a/reactos/win32ss/user/ntuser/defwnd.c b/reactos/win32ss/user/ntuser/defwnd.c index c9b0799e17f..1fbd21a7757 100644 --- a/reactos/win32ss/user/ntuser/defwnd.c +++ b/reactos/win32ss/user/ntuser/defwnd.c @@ -675,13 +675,17 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam) { UserShowCursor( FALSE ); #ifdef NEW_CURSORICON - UserSetCursor(OldCursor, FALSE); + OldCursor = UserSetCursor(OldCursor, FALSE); #else IntSetCursor( hOldCursor ); #endif } #ifdef NEW_CURSORICON - UserDereferenceObject(DragCursor); + /* It could be that the cursor was already changed while we were proceeding, + * so we must unreference whatever cursor was current at the time we restored the old one. + * Maybe it is DragCursor, but maybe it is another one and DragCursor got already freed. + */ + UserDereferenceObject(OldCursor); #else IntDestroyCursor( hDragCursor, FALSE ); #endif diff --git a/reactos/win32ss/user/ntuser/desktop.c b/reactos/win32ss/user/ntuser/desktop.c index a8f0277ca0a..2f7838b99e3 100644 --- a/reactos/win32ss/user/ntuser/desktop.c +++ b/reactos/win32ss/user/ntuser/desktop.c @@ -662,9 +662,15 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lRe { return TRUE; } +#ifdef NEW_CURSORICON + pcurNew->CURSORF_flags |= CURSORF_CURRENT; +#endif pcurOld = UserSetCursor(pcurNew, FALSE); if (pcurOld) { +#ifdef NEW_CURSORICON + pcurOld->CURSORF_flags &= ~CURSORF_CURRENT; +#endif UserDereferenceObject(pcurOld); } return TRUE; diff --git a/reactos/win32ss/user/ntuser/display.c b/reactos/win32ss/user/ntuser/display.c index f6f1c3d6bf4..4705199766b 100644 --- a/reactos/win32ss/user/ntuser/display.c +++ b/reactos/win32ss/user/ntuser/display.c @@ -761,7 +761,8 @@ UserChangeDisplaySettings( ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm); /* Restore mouse pointer, no hooks called */ - UserSetCursor(pvOldCursor, TRUE); + pvOldCursor = UserSetCursor(pvOldCursor, TRUE); + ASSERT(pvOldCursor == NULL); /* Check for failure */ if (!ulResult) diff --git a/reactos/win32ss/user/ntuser/object.c b/reactos/win32ss/user/ntuser/object.c index a598807bcb5..39633146a5d 100644 --- a/reactos/win32ss/user/ntuser/object.c +++ b/reactos/win32ss/user/ntuser/object.c @@ -168,7 +168,7 @@ static PVOID AllocProcMarkObject( return ObjHead; } -static void FreeProcMarkObject( +void FreeProcMarkObject( _In_ PVOID Object) { PPROCESSINFO ppi = ((PPROCMARKHEAD)Object)->ppi; @@ -221,7 +221,7 @@ static const struct #ifndef NEW_CURSORICON { AllocProcMarkObject, /*UserCursorCleanup*/NULL, FreeProcMarkObject }, /* TYPE_CURSOR */ #else - { AllocProcMarkObject, IntDestroyCurIconObject, FreeProcMarkObject }, /* TYPE_CURSOR */ + { AllocProcMarkObject, IntDestroyCurIconObject, FreeCurIconObject }, /* TYPE_CURSOR */ #endif { AllocSysObject, /*UserSetWindowPosCleanup*/NULL, FreeSysObject }, /* TYPE_SETWINDOWPOS */ { AllocDeskThreadObject, IntRemoveHook, FreeDeskThreadObject }, /* TYPE_HOOK */ diff --git a/reactos/win32ss/user/ntuser/object.h b/reactos/win32ss/user/ntuser/object.h index 2270fc75f9f..1ed672b8700 100644 --- a/reactos/win32ss/user/ntuser/object.h +++ b/reactos/win32ss/user/ntuser/object.h @@ -56,4 +56,6 @@ UserDerefObjectCo(PVOID obj) UserDereferenceObject(obj); } +void FreeProcMarkObject(_In_ PVOID Object); + /* EOF */