Author: fireball
Date: Fri Jul 24 23:00:17 2009
New Revision: 42181
URL: 
http://svn.reactos.org/svn/reactos?rev=42181&view=rev
Log:
- Implement desktop_close_handle. It is the second place in winstation.c which directly
relies on ETHREAD's internal members for enumerating threads of a process. Should be
reimplemented in a more compatible way, but so far it works in ReactOS and Windows 2003.
- Sticked // FIXME where appropriate.
Modified:
    branches/arwinss/reactos/subsystems/win32/win32k/wine/winstation.c
Modified: branches/arwinss/reactos/subsystems/win32/win32k/wine/winstation.c
URL:
http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win3…
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/wine/winstation.c [iso-8859-1]
(original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/wine/winstation.c [iso-8859-1] Fri
Jul 24 23:00:17 2009
@@ -249,18 +249,45 @@
 static int desktop_close_handle( struct object *obj, PPROCESSINFO process, obj_handle_t
handle )
 {
-#if 0
-    struct thread *thread;
+    PLIST_ENTRY ListHead, Entry;
+    PETHREAD FoundThread = NULL;
+    PTHREADINFO ThreadInfo;
     /* check if the handle is currently used by the process or one of its threads */
     if (process->desktop == handle) return 0;
-    LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry
)
-        if (thread->desktop == handle) return 0;
+
+    // FIXME: This code relies on ETHREAD internals!
+
+    /* Lock the process */
+    KeEnterCriticalRegion();
+    ExfAcquirePushLockShared(&process->peProcess->ProcessLock);
+
+    Entry = process->peProcess->ThreadListHead.Flink;
+
+    ListHead = &process->peProcess->ThreadListHead;
+    while (ListHead != Entry)
+    {
+        /* Get the Thread */
+        FoundThread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
+        ThreadInfo = PsGetThreadWin32Thread(FoundThread);
+        if (ThreadInfo && ThreadInfo->desktop == handle)
+        {
+            /* Unlock the process */
+            ExfReleasePushLockShared(&process->peProcess->ProcessLock);
+            KeLeaveCriticalRegion();
+
+            return 0;
+        }
+
+        /* Go to the next thread */
+        Entry = Entry->Flink;
+    }
+
+    /* Unlock the process */
+    ExfReleasePushLockShared(&process->peProcess->ProcessLock);
+    KeLeaveCriticalRegion();
+
     return 1;
-#else
-    UNIMPLEMENTED;
-    return 1;
-#endif
 }
 static void desktop_destroy( struct object *obj )
@@ -306,6 +333,8 @@
     if (!(old_desktop = get_desktop_obj( process, process->desktop, 0 )))
clear_error();
     process->desktop = handle;
+
+    // FIXME: This code relies on ETHREAD internals!
     /* Lock the process */
     KeEnterCriticalRegion();