From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com --- 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();