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