combase: Set a flag on thread id initialization.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-11-19 13:40:31 +00:00 committed by Alexandre Julliard
parent 07139b0be2
commit ffce592cc3
4 changed files with 127 additions and 23 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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();