[NTOSKRNL]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 11 Nov 2013 18:52:59 +0000 (18:52 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 11 Nov 2013 18:52:59 +0000 (18:52 +0000)
Fix PsSetProcessWin32Process and PsSetThreadWin32Thread

svn path=/trunk/; revision=60947

reactos/include/ndk/psfuncs.h
reactos/ntoskrnl/ntoskrnl.spec
reactos/ntoskrnl/ps/process.c
reactos/ntoskrnl/ps/thread.c
reactos/win32ss/user/ntuser/main.c

index 40d200f..3629a1f 100644 (file)
@@ -56,19 +56,21 @@ PsGetProcessWin32Process(
 );
 
 NTKERNELAPI
-VOID
+NTSTATUS
 NTAPI
 PsSetProcessWin32Process(
     _Inout_ PEPROCESS Process,
-    _In_ PVOID Win32Process
+    _In_opt_ PVOID Win32Process,
+    _In_opt_ PVOID OldWin32Process
 );
 
 NTKERNELAPI
-VOID
+PVOID
 NTAPI
 PsSetThreadWin32Thread(
     _Inout_ PETHREAD Thread,
-    PVOID Win32Thread
+    _In_ PVOID Win32Thread,
+    _In_ PVOID OldWin32Thread
 );
 
 NTKERNELAPI
index 605f59a..51ad5f5 100644 (file)
 @ stdcall PsSetProcessPriorityByClass(ptr ptr)
 @ stdcall PsSetProcessPriorityClass(ptr long)
 @ stdcall PsSetProcessSecurityPort(ptr ptr)
-@ stdcall PsSetProcessWin32Process(ptr ptr)
+@ stdcall PsSetProcessWin32Process(ptr ptr ptr)
 @ stdcall PsSetProcessWindowStation(ptr ptr)
 @ stdcall PsSetThreadHardErrorsAreDisabled(ptr long)
-@ stdcall PsSetThreadWin32Thread(ptr ptr)
+@ stdcall PsSetThreadWin32Thread(ptr ptr ptr)
 @ stdcall PsTerminateSystemThread(long)
 @ extern PsThreadType _PsThreadType
 ;PsWrapApcWow64Thread
index bd9746b..9036982 100644 (file)
@@ -1240,12 +1240,58 @@ PsSetProcessSecurityPort(PEPROCESS Process,
 /*
  * @implemented
  */
-VOID
-NTAPI
-PsSetProcessWin32Process(PEPROCESS Process,
-                         PVOID Win32Process)
+NTSTATUS 
+NTAPI 
+PsSetProcessWin32Process(
+    _Inout_ PEPROCESS Process, 
+    _In_opt_ PVOID Win32Process, 
+    _In_opt_ PVOID OldWin32Process)
 {
-    Process->Win32Process = Win32Process;
+    NTSTATUS Status;
+
+    /* Assume success */
+    Status = STATUS_SUCCESS;
+
+    /* Lock the process */
+    KeEnterCriticalRegion();
+    ExAcquirePushLockExclusive(&Process->ProcessLock);
+
+    /* Check if we set a new win32 process */
+    if (Win32Process != NULL)
+    {
+        /* Check if the process is in the right state */
+        if (((Process->Flags & PSF_PROCESS_DELETE_BIT) == 0) &&
+            (Process->Win32Process == NULL))
+        {
+            /* Set the new win32 process */
+            Process->Win32Process = Win32Process;
+        }
+        else
+        {
+            /* Otherwise fail */
+            Status = STATUS_PROCESS_IS_TERMINATING;
+        }
+    }
+    else
+    {
+        /* Reset the win32 process, did the caller specify the correct old value? */
+        if (Process->Win32Process == OldWin32Process)
+        {
+            /* Yes, so reset the win32 process to NULL */
+            Process->Win32Process = 0;
+        }
+        else
+        {
+            /* Otherwise fail */
+            Status = STATUS_UNSUCCESSFUL;
+        }
+    }
+
+    /* Unlock the process */
+    ExReleasePushLockExclusive(&Process->ProcessLock);
+    KeLeaveCriticalRegion();
+
+    return Status;
 }
 
 /*
index 3bc9469..84e7aa3 100644 (file)
@@ -904,12 +904,27 @@ PsSetThreadHardErrorsAreDisabled(IN PETHREAD Thread,
 /*
  * @implemented
  */
-VOID
+PVOID
 NTAPI
-PsSetThreadWin32Thread(IN PETHREAD Thread,
-                       IN PVOID Win32Thread)
+PsSetThreadWin32Thread(
+    _Inout_ PETHREAD Thread,
+    _In_ PVOID Win32Thread,
+    _In_ PVOID OldWin32Thread)
 {
-    Thread->Tcb.Win32Thread = Win32Thread;
+    /* Are we setting the win32 process? */
+    if (Win32Thread != NULL)
+    {
+        /* Just exchange it */
+        return InterlockedExchangePointer(&Thread->Tcb.Win32Thread,
+                                          Win32Thread);
+    }
+    else
+    {
+        /* We are resetting, only exchange when the old win32 thread matches */
+        return InterlockedCompareExchangePointer(&Thread->Tcb.Win32Thread,
+                                                 Win32Thread,
+                                                 OldWin32Thread);
+    }
 }
 
 NTSTATUS
index 3753d59..44c0692 100644 (file)
@@ -85,7 +85,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
 
         RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO));
 
-        PsSetProcessWin32Process(Process, ppiCurrent);
+        PsSetProcessWin32Process(Process, ppiCurrent, NULL);
 
 #if DBG
         DbgInitDebugChannels();
@@ -237,7 +237,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
 #endif
 
         /* Free the PROCESSINFO */
-        PsSetProcessWin32Process(Process, NULL);
+        PsSetProcessWin32Process(Process, NULL, ppiCurrent);
         ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
     }
 
@@ -280,7 +280,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
 
     /* Initialize the THREADINFO */
 
-    PsSetThreadWin32Thread(Thread, ptiCurrent);
+    PsSetThreadWin32Thread(Thread, ptiCurrent, NULL);
     IntReferenceThreadInfo(ptiCurrent);
     ptiCurrent->pEThread = Thread;
     ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
@@ -463,7 +463,7 @@ UserDeleteW32Thread(PTHREADINFO pti)
 
        IntSetThreadDesktop(NULL, TRUE);
 
-       PsSetThreadWin32Thread(pti->pEThread, NULL);
+       PsSetThreadWin32Thread(pti->pEThread, NULL, pti);
        ExFreePoolWithTag(pti, USERTAG_THREADINFO);
     }
 }