CLSID clsid;
};
+static struct list registered_psclsid_list = LIST_INIT(registered_psclsid_list);
+
+static CRITICAL_SECTION cs_registered_psclsid_list;
+static CRITICAL_SECTION_DEBUG psclsid_cs_debug =
+{
+ 0, 0, &cs_registered_psclsid_list,
+ { &psclsid_cs_debug.ProcessLocksList, &psclsid_cs_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": cs_registered_psclsid_list") }
+};
+static CRITICAL_SECTION cs_registered_psclsid_list = { &psclsid_cs_debug, -1, 0, 0, 0, 0 };
+
/*
* This is a marshallable object exposing registered local servers.
* IServiceProvider is used only because it happens meet requirements
list_init(&apt->proxies);
list_init(&apt->stubmgrs);
- list_init(&apt->psclsids);
list_init(&apt->loaded_dlls);
apt->ipidc = 0;
apt->refs = 1;
LeaveCriticalSection( &csRegisteredClassList );
}
+static void revoke_registered_psclsids(void)
+{
+ struct registered_psclsid *psclsid, *psclsid2;
+
+ EnterCriticalSection( &cs_registered_psclsid_list );
+
+ LIST_FOR_EACH_ENTRY_SAFE(psclsid, psclsid2, ®istered_psclsid_list, struct registered_psclsid, entry)
+ {
+ list_remove(&psclsid->entry);
+ HeapFree(GetProcessHeap(), 0, psclsid);
+ }
+
+ LeaveCriticalSection( &cs_registered_psclsid_list );
+}
+
/******************************************************************************
* Implementation of the manual reset event object. (CLSID_ManualResetEvent)
*/
stub_manager_int_release(stubmgr);
}
- LIST_FOR_EACH_SAFE(cursor, cursor2, &apt->psclsids)
- {
- struct registered_psclsid *registered_psclsid =
- LIST_ENTRY(cursor, struct registered_psclsid, entry);
-
- list_remove(®istered_psclsid->entry);
- HeapFree(GetProcessHeap(), 0, registered_psclsid);
- }
-
/* if this assert fires, then another thread took a reference to a
* stub manager without taking a reference to the containing
* apartment, which it must do. */
{
TRACE("() - Releasing the COM libraries\n");
+ revoke_registered_psclsids();
RunningObjectTableImpl_UnInitialize();
}
else if (lCOMRefCnt<1) {
if (!pclsid)
return E_INVALIDARG;
- EnterCriticalSection(&apt->cs);
+ EnterCriticalSection(&cs_registered_psclsid_list);
- LIST_FOR_EACH_ENTRY(registered_psclsid, &apt->psclsids, struct registered_psclsid, entry)
+ LIST_FOR_EACH_ENTRY(registered_psclsid, ®istered_psclsid_list, struct registered_psclsid, entry)
if (IsEqualIID(®istered_psclsid->iid, riid))
{
*pclsid = registered_psclsid->clsid;
- LeaveCriticalSection(&apt->cs);
+ LeaveCriticalSection(&cs_registered_psclsid_list);
return S_OK;
}
- LeaveCriticalSection(&apt->cs);
+ LeaveCriticalSection(&cs_registered_psclsid_list);
data.cbSize = sizeof(data);
if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
*
* 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.
*
return CO_E_NOTINITIALIZED;
}
- EnterCriticalSection(&apt->cs);
+ EnterCriticalSection(&cs_registered_psclsid_list);
- LIST_FOR_EACH_ENTRY(registered_psclsid, &apt->psclsids, struct registered_psclsid, entry)
+ LIST_FOR_EACH_ENTRY(registered_psclsid, ®istered_psclsid_list, struct registered_psclsid, entry)
if (IsEqualIID(®istered_psclsid->iid, riid))
{
registered_psclsid->clsid = *rclsid;
- LeaveCriticalSection(&apt->cs);
+ LeaveCriticalSection(&cs_registered_psclsid_list);
return S_OK;
}
registered_psclsid = HeapAlloc(GetProcessHeap(), 0, sizeof(struct registered_psclsid));
if (!registered_psclsid)
{
- LeaveCriticalSection(&apt->cs);
+ LeaveCriticalSection(&cs_registered_psclsid_list);
return E_OUTOFMEMORY;
}
registered_psclsid->iid = *riid;
registered_psclsid->clsid = *rclsid;
- list_add_head(&apt->psclsids, ®istered_psclsid->entry);
+ list_add_head(®istered_psclsid_list, ®istered_psclsid->entry);
- LeaveCriticalSection(&apt->cs);
+ LeaveCriticalSection(&cs_registered_psclsid_list);
return S_OK;
}
LONG len = sizeof(szClsidNew);
TRACE("(%s,%p)\n", debugstr_guid(clsidOld), clsidNew);
+
+ if (!clsidOld || !clsidNew)
+ return E_INVALIDARG;
+
*clsidNew = *clsidOld; /* copy over old value */
res = COM_OpenKeyForCLSID(clsidOld, wszTreatAs, KEY_READ, &hkey);