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/cursoricon_new.c?rev=64912&r1=64911&r2=64912&view=diff
==============================================================================
--- 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);
     }


Reply via email to