https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7e138837236e9267f8abf…
commit 7e138837236e9267f8abffe1342ecee0099417c2
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Apr 18 08:23:18 2022 +0900
Commit: GitHub <noreply(a)github.com>
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)