[PATCH] ole32: Store proxy/stub CLSIDs per process, not per apartment.
Zebediah Figura
zfigura at codeweavers.com
Tue Aug 1 16:27:29 CDT 2017
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
dlls/ole32/compobj.c | 23 ++++++++++++++++-------
dlls/ole32/compobj_private.h | 1 -
dlls/ole32/tests/compobj.c | 32 ++++++++++++++++++++++++++++++--
3 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 60244485249..f650549da09 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -170,8 +170,11 @@ struct registered_psclsid
struct list entry;
IID iid;
CLSID clsid;
+ OXID apartment_id;
};
+static struct list RegisteredPSCLSIDList = LIST_INIT(RegisteredPSCLSIDList);
+
/*
* This is a marshallable object exposing registered local servers.
* IServiceProvider is used only because it happens meet requirements
@@ -622,7 +625,6 @@ static APARTMENT *apartment_construct(DWORD model)
list_init(&apt->proxies);
list_init(&apt->stubmgrs);
- list_init(&apt->psclsids);
list_init(&apt->loaded_dlls);
apt->ipidc = 0;
apt->refs = 1;
@@ -1173,13 +1175,16 @@ DWORD apartment_release(struct apartment *apt)
stub_manager_int_release(stubmgr);
}
- LIST_FOR_EACH_SAFE(cursor, cursor2, &apt->psclsids)
+ LIST_FOR_EACH_SAFE(cursor, cursor2, &RegisteredPSCLSIDList)
{
struct registered_psclsid *registered_psclsid =
LIST_ENTRY(cursor, struct registered_psclsid, entry);
- list_remove(®istered_psclsid->entry);
- HeapFree(GetProcessHeap(), 0, registered_psclsid);
+ if (registered_psclsid->apartment_id == apt->oxid)
+ {
+ list_remove(®istered_psclsid->entry);
+ HeapFree(GetProcessHeap(), 0, registered_psclsid);
+ }
}
/* if this assert fires, then another thread took a reference to a
@@ -2582,7 +2587,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
EnterCriticalSection(&apt->cs);
- LIST_FOR_EACH_ENTRY(registered_psclsid, &apt->psclsids, struct registered_psclsid, entry)
+ LIST_FOR_EACH_ENTRY(registered_psclsid, &RegisteredPSCLSIDList, struct registered_psclsid, entry)
if (IsEqualIID(®istered_psclsid->iid, riid))
{
*pclsid = registered_psclsid->clsid;
@@ -2635,6 +2640,9 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
*
* NOTES
*
+ * Unlike CoRegisterClassObject(), CLSIDs registered with CoRegisterPSClsid()
+ * will be returned from other apartments in the same process.
+ *
* This function does not add anything to the registry and the effects are
* limited to the lifetime of the current process.
*
@@ -2656,7 +2664,7 @@ HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
EnterCriticalSection(&apt->cs);
- LIST_FOR_EACH_ENTRY(registered_psclsid, &apt->psclsids, struct registered_psclsid, entry)
+ LIST_FOR_EACH_ENTRY(registered_psclsid, &RegisteredPSCLSIDList, struct registered_psclsid, entry)
if (IsEqualIID(®istered_psclsid->iid, riid))
{
registered_psclsid->clsid = *rclsid;
@@ -2673,7 +2681,8 @@ HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
registered_psclsid->iid = *riid;
registered_psclsid->clsid = *rclsid;
- list_add_head(&apt->psclsids, ®istered_psclsid->entry);
+ registered_psclsid->apartment_id = apt->oxid;
+ list_add_head(&RegisteredPSCLSIDList, ®istered_psclsid->entry);
LeaveCriticalSection(&apt->cs);
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 64b67826bef..fd88ed981b4 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -137,7 +137,6 @@ struct apartment
struct list stubmgrs; /* stub managers for exported objects (CS cs) */
BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
- struct list psclsids; /* list of registered PS CLSIDs (CS cs) */
struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */
DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */
HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c
index feb1d72eace..728398ca947 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -1158,12 +1158,31 @@ static const CLSID CLSID_WineTestPSFactoryBuffer =
{0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
}; /* 52011640-8164-4fd0-a1a2-5d5a3654d3bd */
+static DWORD CALLBACK register_ps_clsid_thread(void *context)
+{
+ HRESULT hr;
+ CLSID clsid = {0};
+
+ pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+
+ hr = CoGetPSClsid(&IID_IWineTest, &clsid);
+ ok_ole_success(hr, "CoGetPSClsid");
+ ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
+ wine_dbgstr_guid(&CLSID_WineTestPSFactoryBuffer), wine_dbgstr_guid(&clsid));
+
+ CoUninitialize();
+
+ return hr;
+}
+
static void test_CoRegisterPSClsid(void)
{
HRESULT hr;
DWORD dwRegistrationKey;
IStream *stream;
CLSID clsid;
+ HANDLE thread;
+ DWORD tid;
hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
ok(hr == CO_E_NOTINITIALIZED, "CoRegisterPSClsid should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr);
@@ -1177,6 +1196,15 @@ static void test_CoRegisterPSClsid(void)
hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
ok_ole_success(hr, "CoRegisterPSClsid");
+ hr = CoGetPSClsid(&IID_IWineTest, &clsid);
+ ok_ole_success(hr, "CoGetPSClsid");
+ ok(IsEqualGUID(&clsid, &CLSID_WineTestPSFactoryBuffer), "expected %s, got %s\n",
+ wine_dbgstr_guid(&CLSID_WineTestPSFactoryBuffer), wine_dbgstr_guid(&clsid));
+
+ thread = CreateThread(NULL, 0, register_ps_clsid_thread, NULL, 0, &tid);
+ ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
+ ok(!WaitForSingleObject(thread, 10000), "wait timed out\n");
+
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
ok_ole_success(hr, "CreateStreamOnHGlobal");
@@ -1196,11 +1224,11 @@ static void test_CoRegisterPSClsid(void)
SET_EXPECT(CreateStub);
hr = CoMarshalInterface(stream, &IID_IEnumOLEVERB, (IUnknown*)&EnumOLEVERB, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
- ok(hr == S_OK, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr);
+ ok(hr == S_OK, "CoMarshalInterface should have returned S_OK instead of 0x%08x\n", hr);
CHECK_CALLED(CreateStub);
hr = CoMarshalInterface(stream, &IID_IEnumOLEVERB, &Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
- ok(hr == S_OK, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08x\n", hr);
+ ok(hr == S_OK, "CoMarshalInterface should have returned S_OK instead of 0x%08x\n", hr);
IStream_Release(stream);
IPSFactoryBuffer_Release(ps_factory_buffer);
--
2.13.3
More information about the wine-patches
mailing list