Gabriel Ivăncescu : msctf: Clear the corresponding DocumentMgr pointers for Associated Focus Windows on destruction.

Alexandre Julliard julliard at winehq.org
Thu Jan 16 15:36:56 CST 2020


Module: wine
Branch: master
Commit: 6393edb71425283c23eea59c71ecad3f153f5ede
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6393edb71425283c23eea59c71ecad3f153f5ede

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Wed Jan 15 18:02:03 2020 +0200

msctf: Clear the corresponding DocumentMgr pointers for Associated Focus Windows on destruction.

Fixes a regression introduced by d541087079a8770bb02bae830c56a6d3c0b6424e.

AssociateFocus does not grab ownership of the Document Manager, but it does
return it in the "prev" output parameter with an increased refcount. So,
if the docmgr gets destroyed and AssociateFocus is called again, its "prev"
parameter will refer to freed memory. Windows sets it to NULL in such case.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48469
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msctf/tests/inputprocessor.c | 15 +++++++++++++--
 dlls/msctf/threadmgr.c            | 14 ++++++++++++--
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index 38c591ea40..f8ec492f7f 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -2287,6 +2287,7 @@ static void test_AssociateFocus(void)
     ITfDocumentMgr *dm1, *dm2, *olddm, *dmcheck, *dmorig;
     HWND wnd1, wnd2, wnd3;
     HRESULT hr;
+    ULONG ref;
 
     ITfThreadMgr_GetFocus(g_tm, &dmorig);
     test_CurrentFocus = NULL;
@@ -2428,10 +2429,20 @@ static void test_AssociateFocus(void)
     processPendingMessages();
     SetFocus(wnd1);
     processPendingMessages();
-    test_OnSetFocus = SINK_UNEXPECTED;
+
+    hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,dm2,&olddm);
+    ok(SUCCEEDED(hr),"AssociateFocus failed\n");
+
+    /* Vista doesn't return NULL */
+    if (olddm) ITfDocumentMgr_Release(olddm);
+    ref = ITfDocumentMgr_Release(dm2);
+    ok(ref == 0, "incorrect DocumentMgr ref %d\n", ref);
+
+    hr = ITfThreadMgr_AssociateFocus(g_tm,wnd2,NULL,&olddm);
+    ok(SUCCEEDED(hr),"AssociateFocus failed\n");
+    ok(olddm == NULL, "incorrect old DocumentMgr returned\n");
 
     ITfDocumentMgr_Release(dm1);
-    ITfDocumentMgr_Release(dm2);
 
     test_CurrentFocus = dmorig;
     test_PrevFocus = FOCUS_IGNORE;
diff --git a/dlls/msctf/threadmgr.c b/dlls/msctf/threadmgr.c
index 2c208fbc04..77cf47ca4f 100644
--- a/dlls/msctf/threadmgr.c
+++ b/dlls/msctf/threadmgr.c
@@ -1530,6 +1530,8 @@ void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *iface, ITfDocumentMgr *mgr
 {
     ThreadMgr *This = impl_from_ITfThreadMgrEx((ITfThreadMgrEx *)iface);
     struct list *cursor;
+    BOOL found = FALSE;
+
     LIST_FOR_EACH(cursor, &This->CreatedDocumentMgrs)
     {
         DocumentMgrEntry *mgrentry = LIST_ENTRY(cursor,DocumentMgrEntry,entry);
@@ -1537,8 +1539,16 @@ void ThreadMgr_OnDocumentMgrDestruction(ITfThreadMgr *iface, ITfDocumentMgr *mgr
         {
             list_remove(cursor);
             HeapFree(GetProcessHeap(),0,mgrentry);
-            return;
+            found = TRUE;
+            break;
         }
     }
-    FIXME("ITfDocumentMgr %p not found in this thread\n",mgr);
+    if (!found) FIXME("ITfDocumentMgr %p not found in this thread\n",mgr);
+
+    LIST_FOR_EACH(cursor, &This->AssociatedFocusWindows)
+    {
+        AssociatedWindow *wnd = LIST_ENTRY(cursor,AssociatedWindow,entry);
+        if (wnd->docmgr == mgr)
+            wnd->docmgr = NULL;
+    }
 }




More information about the wine-cvs mailing list