Author: jgardou
Date: Sun Oct 28 14:45:35 2012
New Revision: 57641

URL: http://svn.reactos.org/svn/reactos?rev=57641&view=rev
Log:
[WIN32K]
- Properly handle deletion of cursor/Icon objects
- Gracefully change object owner when process closes
- Remove useless check in a macro

Modified:
    trunk/reactos/win32ss/gdi/ntgdi/misc.h
    trunk/reactos/win32ss/user/ntuser/cursoricon.c
    trunk/reactos/win32ss/user/ntuser/object.c
    trunk/reactos/win32ss/user/ntuser/object.h

Modified: trunk/reactos/win32ss/gdi/ntgdi/misc.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/misc.h?rev=57641&r1=57640&r2=57641&view=diff
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/misc.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/misc.h [iso-8859-1] Sun Oct 28 14:45:35 2012
@@ -163,6 +163,6 @@
 #define LIST_FOR_EACH_SAFE(cursor, cursor2, list, type, field) \
     for ((cursor) = CONTAINING_RECORD((list)->Flink, type, field), \
          (cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field); \
-         &(cursor)->field != (list) && ((&((cursor)->field)) != NULL); \
+         &(cursor)->field != (list); \
          (cursor) = (cursor2), \
          (cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field))

Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursoricon.c?rev=57641&r1=57640&r2=57641&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/cursoricon.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/cursoricon.c [iso-8859-1] Sun Oct 28 
14:45:35 2012
@@ -234,55 +234,54 @@
 }
 
 BOOLEAN FASTCALL
-IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOL ProcessCleanup)
+IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
 {
     PSYSTEM_CURSORINFO CurInfo;
     HBITMAP bmpMask, bmpColor;
-    BOOLEAN Ret;
+    BOOLEAN Ret, bListEmpty, bFound = FALSE;
     PCURICON_PROCESS Current = NULL;
-    PPROCESSINFO W32Process = PsGetCurrentProcessWin32Process();
-
-    /* Private objects can only be destroyed by their own process */
-    if (NULL == CurIcon->hModule)
-    {
-        ASSERT(CurIcon->ProcessList.Flink->Flink == &CurIcon->ProcessList);
-        Current = CONTAINING_RECORD(CurIcon->ProcessList.Flink, 
CURICON_PROCESS, ListEntry);
-        if (Current->Process != W32Process)
-        {
-            ERR("Trying to destroy private icon/cursor of another process\n");
-            return FALSE;
-        }
-    }
-    else if (! ProcessCleanup)
-    {
-        TRACE("Trying to destroy shared icon/cursor\n");
-        return FALSE;
-    }
+    
+    /* For handles created without any data (error handling) */
+    if(IsListEmpty(&CurIcon->ProcessList))
+        goto emptyList;
 
     /* Now find this process in the list of processes referencing this object 
and
        remove it from that list */
     LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
     {
-        if (Current->Process == W32Process)
-        {
-            RemoveEntryList(&Current->ListEntry);
+        if (Current->Process == ppi)
+        {
+            bFound = TRUE;
+            bListEmpty = RemoveEntryList(&Current->ListEntry);
             break;
         }
     }
+    
+    if(!bFound)
+    {
+        /* This object doesn't belong to this process */
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
 
     ExFreeToPagedLookasideList(pgProcessLookasideList, Current);
 
     /* If there are still processes referencing this object we can't destroy 
it yet */
-    if (! IsListEmpty(&CurIcon->ProcessList))
-    {
+    if (!bListEmpty)
+    {
+        if(CurIcon->head.ppi == ppi)
+        {
+            /* Set the first process of the list as owner */
+            Current = CONTAINING_RECORD(CurIcon->ProcessList.Flink, 
CURICON_PROCESS, ListEntry);
+            UserSetObjectOwner(CurIcon, otCursorIcon, Current->Process);
+        }
+        UserDereferenceObject(CurIcon);
         return TRUE;
     }
 
-
-    if (! ProcessCleanup)
-    {
-        RemoveEntryList(&CurIcon->ListEntry);
-    }
+emptyList:
+    /* Remove it from the list */
+    RemoveEntryList(&CurIcon->ListEntry);
 
     CurInfo = IntGetSysCursorInfo();
 
@@ -320,33 +319,13 @@
 IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
 {
     PCURICON_OBJECT CurIcon, tmp;
-    PCURICON_PROCESS ProcessData;
-
+
+    /* Run through the list of icon objects */
     LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
     {
         UserReferenceObject(CurIcon);
-        //    if(NT_SUCCESS(UserReferenceObjectByPointer(Object, 
otCursorIcon)))
-        {
-            LIST_FOR_EACH(ProcessData, &CurIcon->ProcessList, CURICON_PROCESS, 
ListEntry)
-            {
-                if (Win32Process == ProcessData->Process)
-                {
-                    RemoveEntryList(&CurIcon->ListEntry);
-                    IntDestroyCurIconObject(CurIcon, TRUE);
-                    CurIcon = NULL;
-                    break;
-                }
-            }
-
-//         UserDereferenceObject(Object);
-        }
-
-        if (CurIcon)
-        {
-            UserDereferenceObject(CurIcon);
-        }
-    }
-
+        IntDestroyCurIconObject(CurIcon, Win32Process);
+    }
 }
 
 
@@ -649,7 +628,7 @@
         RETURN(FALSE);
     }
 
-    ret = IntDestroyCurIconObject(CurIcon, FALSE);
+    ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
     /* Note: IntDestroyCurIconObject will remove our reference for us! */
 
     RETURN(ret);

Modified: trunk/reactos/win32ss/user/ntuser/object.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/object.c?rev=57641&r1=57640&r2=57641&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/object.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/object.c [iso-8859-1] Sun Oct 28 14:45:35 
2012
@@ -516,6 +516,38 @@
     return object;
 }
 
+VOID
+FASTCALL
+UserSetObjectOwner(PVOID obj, USER_OBJECT_TYPE type, PVOID owner)
+{
+    PUSER_HANDLE_ENTRY entry = handle_to_entry(gHandleTable, ((PHEAD)obj)->h );
+    PPROCESSINFO ppi, oldppi;
+    
+    /* This must be called with a valid object */
+    ASSERT(entry);
+    
+    /* For now, only supported for CursorIcon object */
+    switch(type)
+    {
+        case otCursorIcon:
+            ppi = (PPROCESSINFO)owner;
+            entry->pi = ppi;
+            oldppi = ((PPROCMARKHEAD)obj)->ppi;
+            ((PPROCMARKHEAD)obj)->ppi = ppi;
+            break;
+        default:
+            ASSERT(FALSE);
+            return;
+    }
+
+    oldppi->UserHandleCount--;
+    ppi->UserHandleCount++;
+#if DBG
+    oldppi->DbgHandleCount[type]--;
+    ppi->DbgHandleCount[type]++;
+#endif
+}
+
 /*
  * NtUserValidateHandleSecure
  *

Modified: trunk/reactos/win32ss/user/ntuser/object.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/object.h?rev=57641&r1=57640&r2=57641&view=diff
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/object.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/object.h [iso-8859-1] Sun Oct 28 14:45:35 
2012
@@ -40,6 +40,7 @@
 BOOL FASTCALL UserCreateHandleTable(VOID);
 BOOL FASTCALL UserObjectInDestroy(HANDLE);
 void DbgUserDumpHandleTable();
+VOID FASTCALL UserSetObjectOwner(PVOID obj, USER_OBJECT_TYPE type, PVOID 
owner);
 
 static __inline VOID
 UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)


Reply via email to