[NTUSER] Do assignment lock pti->spDefaultImc (#4456)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Sun, 17 Apr 2022 23:23:18 +0000 (08:23 +0900)
committerGitHub <noreply@github.com>
Sun, 17 Apr 2022 23:23:18 +0000 (08:23 +0900)
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
win32ss/user/ntuser/main.c
win32ss/user/ntuser/object.c
win32ss/user/ntuser/object.h

index 7b6c06b..6b6e173 100644 (file)
@@ -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;
     }
 
index dfdf2d6..1010d79 100644 (file)
@@ -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)
index cc2bebd..492d4ab 100644 (file)
@@ -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;
+}
index 9fb1b7f..0d6bc6d 100644 (file)
@@ -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)