Nikolay Sivov : combase: Set a flag on thread id initialization.

Alexandre Julliard julliard at winehq.org
Thu Nov 19 16:10:22 CST 2020


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Nov 19 13:40:31 2020 +0000

combase: Set a flag on thread id initialization.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/combase/combase.c         |  3 ++
 dlls/combase/combase_private.h | 15 ++++---
 dlls/ole32/compobj_private.h   | 36 ++++++++--------
 dlls/ole32/tests/compobj.c     | 96 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 127 insertions(+), 23 deletions(-)

diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c
index 7a85b95a19b..72ff6cc31f9 100644
--- a/dlls/combase/combase.c
+++ b/dlls/combase/combase.c
@@ -2547,7 +2547,10 @@ HRESULT WINAPI CoGetCurrentLogicalThreadId(GUID *id)
         return hr;
 
     if (IsEqualGUID(&tlsdata->causality_id, &GUID_NULL))
+    {
         CoCreateGuid(&tlsdata->causality_id);
+        tlsdata->flags |= OLETLS_UUIDINITIALIZED;
+    }
 
     *id = tlsdata->causality_id;
 
diff --git a/dlls/combase/combase_private.h b/dlls/combase/combase_private.h
index 55ce02d06f0..46a7c7f655d 100644
--- a/dlls/combase/combase_private.h
+++ b/dlls/combase/combase_private.h
@@ -63,17 +63,22 @@ HRESULT open_appidkey_from_clsid(REFCLSID clsid, REGSAM access, HKEY *subkey) DE
 
 #define CHARS_IN_GUID 39
 
+enum tlsdata_flags
+{
+    OLETLS_UUIDINITIALIZED = 0x2,
+};
+
 /* this is what is stored in TEB->ReservedForOle */
 struct tlsdata
 {
     struct apartment *apt;
     IErrorInfo       *errorinfo;
-    DWORD             thread_seqid;/* returned with CoGetCurrentProcess */
-    DWORD             apt_mask;    /* apartment mask (+0Ch on x86) */
+    DWORD             thread_seqid;  /* returned with CoGetCurrentProcess */
+    DWORD             flags;         /* tlsdata_flags (+0Ch on x86) */
     void             *unknown0;
-    DWORD             inits;        /* number of times CoInitializeEx called */
-    DWORD             ole_inits;    /* number of times OleInitialize called */
-    GUID              causality_id; /* unique identifier for each COM call */
+    DWORD             inits;         /* number of times CoInitializeEx called */
+    DWORD             ole_inits;     /* number of times OleInitialize called */
+    GUID              causality_id;  /* unique identifier for each COM call */
     LONG              pending_call_count_client; /* number of client calls pending */
     LONG              pending_call_count_server; /* number of server calls pending */
     DWORD             unknown;
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 4ec22d51f45..3c0e338127c 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -45,24 +45,24 @@ DEFINE_OLEGUID( CLSID_DfMarshal, 0x0000030b, 0, 0 );
 struct oletls
 {
     struct apartment *apt;
-    IErrorInfo       *errorinfo;   /* see errorinfo.c */
-    DWORD             thread_seqid;/* returned with CoGetCurrentProcess */
-    DWORD             apt_mask;    /* apartment mask (+0Ch on x86) */
-    void            *unknown0;
-    DWORD            inits;        /* number of times CoInitializeEx called */
-    DWORD            ole_inits;    /* number of times OleInitialize called */
-    GUID             causality_id; /* unique identifier for each COM call */
-    LONG             pending_call_count_client; /* number of client calls pending */
-    LONG             pending_call_count_server; /* number of server calls pending */
-    DWORD            unknown;
-    IObjContext     *context_token; /* (+38h on x86) */
-    IUnknown        *call_state;    /* current call context (+3Ch on x86) */
-    DWORD            unknown2[46];
-    IUnknown        *cancel_object; /* cancel object set by CoSetCancelObject (+F8h on x86) */
-    IUnknown        *state;       /* see CoSetState */
-    struct list      spies;         /* Spies installed with CoRegisterInitializeSpy */
-    DWORD            spies_lock;
-    DWORD            cancelcount;
+    IErrorInfo       *errorinfo;     /* see errorinfo.c */
+    DWORD             thread_seqid;  /* returned with CoGetCurrentProcess */
+    DWORD             flags;         /* tlsdata_flags (+0Ch on x86) */
+    void             *unknown0;
+    DWORD             inits;         /* number of times CoInitializeEx called */
+    DWORD             ole_inits;     /* number of times OleInitialize called */
+    GUID              causality_id;  /* unique identifier for each COM call */
+    LONG              pending_call_count_client; /* number of client calls pending */
+    LONG              pending_call_count_server; /* number of server calls pending */
+    DWORD             unknown;
+    IObjContext      *context_token; /* (+38h on x86) */
+    IUnknown         *call_state;    /* current call context (+3Ch on x86) */
+    DWORD             unknown2[46];
+    IUnknown         *cancel_object; /* cancel object set by CoSetCancelObject (+F8h on x86) */
+    IUnknown         *state;         /* see CoSetState */
+    struct list       spies;         /* Spies installed with CoRegisterInitializeSpy */
+    DWORD             spies_lock;
+    DWORD             cancelcount;
 };
 
 /* Global Interface Table Functions */
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c
index 0d7f3d8adee..c79e379f92a 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -36,6 +36,7 @@
 #include "ctxtcall.h"
 
 #include "wine/test.h"
+#include "winternl.h"
 #include "initguid.h"
 
 #define DEFINE_EXPECT(func) \
@@ -4245,6 +4246,100 @@ static void test_call_cancellation(void)
     ok(hr == CO_E_CANCEL_DISABLED, "Unexpected hr %#x.\n", hr);
 }
 
+enum oletlsflags
+{
+    OLETLS_UUIDINITIALIZED = 0x2,
+    OLETLS_DISABLE_OLE1DDE = 0x40,
+    OLETLS_APARTMENTTHREADED = 0x80,
+    OLETLS_MULTITHREADED = 0x100,
+};
+
+struct oletlsdata
+{
+    void *threadbase;
+    void *smallocator;
+    DWORD id;
+    DWORD flags;
+};
+
+static DWORD get_oletlsflags(void)
+{
+    struct oletlsdata *data = NtCurrentTeb()->ReservedForOle;
+    return data ? data->flags : 0;
+}
+
+static DWORD CALLBACK oletlsdata_test_thread(void *arg)
+{
+    IUnknown *unk;
+    DWORD flags;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_InternetZoneManager, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    IUnknown_Release(unk);
+
+    /* Flag is not set for implicit MTA. */
+    flags = get_oletlsflags();
+    ok(!(flags & OLETLS_MULTITHREADED), "Unexpected flags %#x.\n", flags);
+
+    return 0;
+}
+
+static void test_oletlsdata(void)
+{
+    HANDLE thread;
+    DWORD flags;
+    HRESULT hr;
+    GUID guid;
+
+    /* STA */
+    hr = CoInitialize(NULL);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    flags = get_oletlsflags();
+todo_wine
+    ok(flags & OLETLS_APARTMENTTHREADED && !(flags & OLETLS_DISABLE_OLE1DDE), "Unexpected flags %#x.\n", flags);
+    CoUninitialize();
+    flags = get_oletlsflags();
+    ok(!(flags & (OLETLS_APARTMENTTHREADED | OLETLS_MULTITHREADED | OLETLS_DISABLE_OLE1DDE)), "Unexpected flags %#x.\n", flags);
+
+    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    flags = get_oletlsflags();
+todo_wine
+    ok(flags & OLETLS_APARTMENTTHREADED && flags & OLETLS_DISABLE_OLE1DDE, "Unexpected flags %#x.\n", flags);
+    CoUninitialize();
+    flags = get_oletlsflags();
+    ok(!(flags & (OLETLS_APARTMENTTHREADED | OLETLS_MULTITHREADED | OLETLS_DISABLE_OLE1DDE)), "Unexpected flags %#x.\n", flags);
+
+    /* MTA */
+    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    flags = get_oletlsflags();
+todo_wine
+    ok(flags & OLETLS_MULTITHREADED && flags & OLETLS_DISABLE_OLE1DDE, "Unexpected flags %#x.\n", flags);
+
+    /* Implicit case. */
+    thread = CreateThread(NULL, 0, oletlsdata_test_thread, NULL, 0, &flags);
+    ok(thread != NULL, "Failed to create a test thread, error %d.\n", GetLastError());
+    ok(!WaitForSingleObject(thread, 5000), "Wait timed out.\n");
+    CloseHandle(thread);
+
+    CoUninitialize();
+    flags = get_oletlsflags();
+    ok(!(flags & (OLETLS_APARTMENTTHREADED | OLETLS_MULTITHREADED | OLETLS_DISABLE_OLE1DDE)), "Unexpected flags %#x.\n", flags);
+
+    /* Thread ID. */
+    flags = get_oletlsflags();
+    ok(!(flags & OLETLS_UUIDINITIALIZED), "Unexpected flags %#x.\n", flags);
+
+    hr = CoGetCurrentLogicalThreadId(&guid);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    flags = get_oletlsflags();
+    ok(flags & OLETLS_UUIDINITIALIZED && !(flags & (OLETLS_APARTMENTTHREADED | OLETLS_MULTITHREADED)),
+            "Unexpected flags %#x.\n", flags);
+}
+
 START_TEST(compobj)
 {
     init_funcs();
@@ -4254,6 +4349,7 @@ START_TEST(compobj)
     lstrcatA(testlib, "\\testlib.dll");
     extract_resource("testlib.dll", "TESTDLL", testlib);
 
+    test_oletlsdata();
     test_ProgIDFromCLSID();
     test_CLSIDFromProgID();
     test_CLSIDFromString();




More information about the wine-cvs mailing list