https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7e138837236e9267f8abffe1342ecee0099417c2

commit 7e138837236e9267f8abffe1342ecee0099417c2
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Mon Apr 18 08:23:18 2022 +0900
Commit:     GitHub <[email protected]>
CommitDate: Mon Apr 18 08:23:18 2022 +0900

    [NTUSER] Do assignment lock pti->spDefaultImc (#4456)
    
    According to JIRA user simonelombardo, there was crash in exiting a thread.
    - Add UserAssignmentLock, and UserAssignmentUnlock helper functions.
    - Lock and unlock pti->spDefaultImc by using those helper functions.
    CORE-18044
---
 win32ss/user/ntuser/ime.c    |  4 +---
 win32ss/user/ntuser/main.c   |  2 ++
 win32ss/user/ntuser/object.c | 36 ++++++++++++++++++++++++++++++++++++
 win32ss/user/ntuser/object.h |  2 ++
 4 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c
index 7b6c06b9f94..6b6e17391ef 100644
--- a/win32ss/user/ntuser/ime.c
+++ b/win32ss/user/ntuser/ime.c
@@ -1362,9 +1362,7 @@ PIMC FASTCALL UserCreateInputContext(ULONG_PTR 
dwClientImcData)
     else // First time. It's the default IMC.
     {
         // Add the first one (default) to the list.
-        if (pti->spDefaultImc)
-            UserDereferenceObject(pti->spDefaultImc);
-        pti->spDefaultImc = pIMC;
+        UserAssignmentLock((PVOID*)&pti->spDefaultImc, pIMC);
         pIMC->pImcNext = NULL;
     }
 
diff --git a/win32ss/user/ntuser/main.c b/win32ss/user/ntuser/main.c
index dfdf2d64c0b..1010d7970ef 100644
--- a/win32ss/user/ntuser/main.c
+++ b/win32ss/user/ntuser/main.c
@@ -696,6 +696,7 @@ error:
 VOID
 UserDisplayNotifyShutdown(PPROCESSINFO ppiCurrent);
 
+// Win: xxxDestroyThreadInfo
 NTSTATUS
 NTAPI
 ExitThreadCallback(PETHREAD Thread)
@@ -783,6 +784,7 @@ ExitThreadCallback(PETHREAD Thread)
             ASSERT(FALSE);
             return STATUS_UNSUCCESSFUL;
         }
+        UserAssignmentUnlock((PVOID*)&ptiCurrent->spDefaultImc);
 
         if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && 
!ptiCurrent->ptiSibling &&
             ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED)
diff --git a/win32ss/user/ntuser/object.c b/win32ss/user/ntuser/object.c
index cc2bebdb8bc..492d4ab2b6b 100644
--- a/win32ss/user/ntuser/object.c
+++ b/win32ss/user/ntuser/object.c
@@ -801,3 +801,39 @@ CLEANUP:
    UserLeave();
    END_CLEANUP;
 }
+
+// Win: HMAssignmentLock
+PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
+{
+    PVOID pvOld = *ppvObj;
+    *ppvObj = pvNew;
+
+    if (pvOld && pvOld == pvNew)
+        return pvOld;
+
+    if (pvNew)
+        UserReferenceObject(pvNew);
+
+    if (pvOld)
+    {
+        if (UserDereferenceObject(pvOld))
+            pvOld = NULL;
+    }
+
+    return pvOld;
+}
+
+// Win: HMAssignmentUnlock
+PVOID FASTCALL UserAssignmentUnlock(PVOID *ppvObj)
+{
+    PVOID pvOld = *ppvObj;
+    *ppvObj = NULL;
+
+    if (pvOld)
+    {
+        if (UserDereferenceObject(pvOld))
+            pvOld = NULL;
+    }
+
+    return pvOld;
+}
diff --git a/win32ss/user/ntuser/object.h b/win32ss/user/ntuser/object.h
index 9fb1b7f6637..0d6bc6dda88 100644
--- a/win32ss/user/ntuser/object.h
+++ b/win32ss/user/ntuser/object.h
@@ -20,6 +20,8 @@ void DbgUserDumpHandleTable();
 PVOID FASTCALL ValidateHandle(HANDLE handle, HANDLE_TYPE type);
 BOOLEAN UserDestroyObjectsForOwner(PUSER_HANDLE_TABLE Table, PVOID Owner);
 BOOL FASTCALL UserMarkObjectDestroy(PVOID);
+PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew);
+PVOID FASTCALL UserAssignmentUnlock(PVOID *ppvObj);
 
 static __inline VOID
 UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)

Reply via email to