Author: jgardou
Date: Thu Oct 23 09:32:39 2014
New Revision: 64912
URL:
http://svn.reactos.org/svn/reactos?rev=64912&view=rev
Log:
[WIN32K]
- Remove the cursor from the process cache when its handle is deleted, not after.
- Do not return an invalid handle in NtUserSetCursor.
CORE-7575
Modified:
trunk/reactos/win32ss/user/ntuser/cursoricon_new.c
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon_new.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursor…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] Thu Oct 23 09:32:39
2014
@@ -63,9 +63,9 @@
return NULL;
}
- if(UserObjectInDestroy(hCurIcon))
- {
- ERR("Requesting destroyed cursor.\n");
+ if (UserObjectInDestroy(hCurIcon))
+ {
+ WARN("Requesting invalid/destroyed cursor.\n");
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
return NULL;
}
@@ -155,71 +155,20 @@
{
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;
-
- if(!(CurIcon->CURSORF_flags & CURSORF_ACON))
- {
- HBITMAP bmpMask = CurIcon->hbmMask;
- HBITMAP bmpColor = CurIcon->hbmColor;
- HBITMAP bmpAlpha = CurIcon->hbmAlpha;
-
- /* Delete bitmaps */
- if (bmpMask)
- {
- GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(bmpMask);
- CurIcon->hbmMask = NULL;
- }
- if (bmpColor)
- {
- GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(bmpColor);
- CurIcon->hbmColor = NULL;
- }
- if (bmpAlpha)
- {
- GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(bmpAlpha);
- CurIcon->hbmAlpha = NULL;
- }
- }
- else
- {
- PACON AniCurIcon = (PACON)CurIcon;
- UINT i;
-
- for(i = 0; i < AniCurIcon->cpcur; i++)
- IntDestroyCurIconObject(AniCurIcon->aspcur[i]);
- ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
- }
-
+ /* Try finding it in its process cache */
if (CurIcon->CURSORF_flags & CURSORF_LRSHARED)
{
PPROCESSINFO ppi;
- if (!IS_INTRESOURCE(CurIcon->strName.Buffer))
- ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
- if (CurIcon->atomModName)
- RtlDeleteAtomFromAtomTable(gAtomTable, CurIcon->atomModName);
- CurIcon->strName.Buffer = NULL;
- CurIcon->atomModName = 0;
-
- /* Try finding it in its process cache */
ppi = CurIcon->head.ppi;
if (ppi->pCursorCache == CurIcon)
+ {
ppi->pCursorCache = CurIcon->pcurNext;
+ UserDereferenceObject(CurIcon);
+ }
else
{
- PCURICON_OBJECT CacheCurIcon= ppi->pCursorCache;
+ PCURICON_OBJECT CacheCurIcon = ppi->pCursorCache;
while (CacheCurIcon)
{
if (CacheCurIcon->pcurNext == CurIcon)
@@ -229,7 +178,68 @@
}
CacheCurIcon = CacheCurIcon->pcurNext;
}
- }
+
+ /* We must have found it! */
+ ASSERT(CacheCurIcon != NULL);
+ UserDereferenceObject(CurIcon);
+ }
+ }
+
+ /* 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;
+
+ if(!(CurIcon->CURSORF_flags & CURSORF_ACON))
+ {
+ HBITMAP bmpMask = CurIcon->hbmMask;
+ HBITMAP bmpColor = CurIcon->hbmColor;
+ HBITMAP bmpAlpha = CurIcon->hbmAlpha;
+
+ /* Delete bitmaps */
+ if (bmpMask)
+ {
+ GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(bmpMask);
+ CurIcon->hbmMask = NULL;
+ }
+ if (bmpColor)
+ {
+ GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(bmpColor);
+ CurIcon->hbmColor = NULL;
+ }
+ if (bmpAlpha)
+ {
+ GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(bmpAlpha);
+ CurIcon->hbmAlpha = NULL;
+ }
+ }
+ else
+ {
+ PACON AniCurIcon = (PACON)CurIcon;
+ UINT i;
+
+ for(i = 0; i < AniCurIcon->cpcur; i++)
+ IntDestroyCurIconObject(AniCurIcon->aspcur[i]);
+ ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
+ }
+
+ if (CurIcon->CURSORF_flags & CURSORF_LRSHARED)
+ {
+ if (!IS_INTRESOURCE(CurIcon->strName.Buffer))
+ ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
+ if (CurIcon->atomModName)
+ RtlDeleteAtomFromAtomTable(gAtomTable, CurIcon->atomModName);
+ CurIcon->strName.Buffer = NULL;
+ CurIcon->atomModName = 0;
}
/* Finally free the thing */
@@ -635,7 +645,7 @@
{
BOOL ret;
- TRACE("Enter NtUserDestroyCursorIcon\n");
+ TRACE("Enter NtUserDestroyCursorIcon (%p, %u)\n", hCurIcon, bForce);
UserEnterExclusive();
if (!bForce)
@@ -842,7 +852,7 @@
PCURICON_OBJECT pcurOld, pcurNew;
HCURSOR hOldCursor = NULL;
- TRACE("Enter NtUserSetCursor\n");
+ TRACE("Enter NtUserSetCursor: %p\n", hCursor);
UserEnterExclusive();
if (hCursor)
@@ -863,6 +873,10 @@
pcurOld = UserSetCursor(pcurNew, FALSE);
if (pcurOld)
{
+ hOldCursor = pcurOld->head.h;
+ /* See if it was destroyed in the meantime */
+ if (UserObjectInDestroy(hOldCursor))
+ hOldCursor = NULL;
pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
UserDereferenceObject(pcurOld);
}