[PATCH 1/3] combase: Move local proxy-stub registration functions.

Nikolay Sivov nsivov at codeweavers.com
Thu Aug 20 02:34:40 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---

Both internal functions will go away once relevant parts are moved to one place.
InternalIsInitialized() is equivalent to combase.InternalIsProcessInitialized, that we could
introduce is ole32 will need to such test.

 dlls/combase/combase.c    | 177 ++++++++++++++++++++++++++++
 dlls/combase/combase.spec |   5 +-
 dlls/ole32/compobj.c      | 235 +++-----------------------------------
 dlls/ole32/ole32.spec     |   5 +-
 4 files changed, 197 insertions(+), 225 deletions(-)

diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c
index 96c6a9bb817..516e8c9fd40 100644
--- a/dlls/combase/combase.c
+++ b/dlls/combase/combase.c
@@ -59,6 +59,18 @@ struct comclassredirect_data
     DWORD miscstatusdocprint;
 };
 
+struct ifacepsredirect_data
+{
+    ULONG size;
+    DWORD mask;
+    GUID  iid;
+    ULONG nummethods;
+    GUID  tlbid;
+    GUID  base;
+    ULONG name_len;
+    ULONG name_offset;
+};
+
 struct progidredirect_data
 {
     ULONG size;
@@ -73,6 +85,26 @@ struct init_spy
     unsigned int id;
 };
 
+struct registered_ps
+{
+    struct list entry;
+    IID iid;
+    CLSID clsid;
+};
+
+static struct list registered_proxystubs = LIST_INIT(registered_proxystubs);
+
+static CRITICAL_SECTION cs_registered_ps;
+static CRITICAL_SECTION_DEBUG psclsid_cs_debug =
+{
+    0, 0, &cs_registered_ps,
+    { &psclsid_cs_debug.ProcessLocksList, &psclsid_cs_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": cs_registered_psclsid_list") }
+};
+static CRITICAL_SECTION cs_registered_ps = { &psclsid_cs_debug, -1, 0, 0, 0, 0 };
+
+extern BOOL WINAPI InternalIsInitialized(void);
+
 static struct init_spy *get_spy_entry(struct tlsdata *tlsdata, unsigned int id)
 {
     struct init_spy *spy;
@@ -1721,3 +1753,148 @@ HRESULT WINAPI CoRegisterMessageFilter(IMessageFilter *filter, IMessageFilter **
 
     return S_OK;
 }
+
+void WINAPI InternalRevokeAllPSClsids(void)
+{
+    struct registered_ps *cur, *cur2;
+
+    EnterCriticalSection(&cs_registered_ps);
+
+    LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &registered_proxystubs, struct registered_ps, entry)
+    {
+        list_remove(&cur->entry);
+        heap_free(cur);
+    }
+
+    LeaveCriticalSection(&cs_registered_ps);
+}
+
+static HRESULT get_ps_clsid_from_registry(const WCHAR* path, REGSAM access, CLSID *pclsid)
+{
+    WCHAR value[CHARS_IN_GUID];
+    HKEY hkey;
+    DWORD len;
+
+    access |= KEY_READ;
+
+    if (open_classes_key(HKEY_CLASSES_ROOT, path, access, &hkey))
+        return REGDB_E_IIDNOTREG;
+
+    len = sizeof(value);
+    if (ERROR_SUCCESS != RegQueryValueExW(hkey, NULL, NULL, NULL, (BYTE *)value, &len))
+        return REGDB_E_IIDNOTREG;
+    RegCloseKey(hkey);
+
+    if (CLSIDFromString(value, pclsid) != NOERROR)
+        return REGDB_E_IIDNOTREG;
+
+    return S_OK;
+}
+
+/*****************************************************************************
+ *             CoGetPSClsid        (combase.@)
+ */
+HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
+{
+    static const WCHAR interfaceW[] = L"Interface\\";
+    static const WCHAR psW[] = L"\\ProxyStubClsid32";
+    WCHAR path[ARRAY_SIZE(interfaceW) - 1 + CHARS_IN_GUID - 1 + ARRAY_SIZE(psW)];
+    ACTCTX_SECTION_KEYED_DATA data;
+    struct registered_ps *cur;
+    REGSAM opposite = (sizeof(void*) > sizeof(int)) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
+    BOOL is_wow64;
+    HRESULT hr;
+
+    TRACE("%s, %p\n", debugstr_guid(riid), pclsid);
+
+    if (!InternalIsInitialized())
+    {
+        ERR("apartment not initialised\n");
+        return CO_E_NOTINITIALIZED;
+    }
+
+    if (!pclsid)
+        return E_INVALIDARG;
+
+    EnterCriticalSection(&cs_registered_ps);
+
+    LIST_FOR_EACH_ENTRY(cur, &registered_proxystubs, struct registered_ps, entry)
+    {
+        if (IsEqualIID(&cur->iid, riid))
+        {
+            *pclsid = cur->clsid;
+            LeaveCriticalSection(&cs_registered_ps);
+            return S_OK;
+        }
+    }
+
+    LeaveCriticalSection(&cs_registered_ps);
+
+    data.cbSize = sizeof(data);
+    if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
+            riid, &data))
+    {
+        struct ifacepsredirect_data *ifaceps = (struct ifacepsredirect_data *)data.lpData;
+        *pclsid = ifaceps->iid;
+        return S_OK;
+    }
+
+    /* Interface\\{string form of riid}\\ProxyStubClsid32 */
+    lstrcpyW(path, interfaceW);
+    StringFromGUID2(riid, path + ARRAY_SIZE(interfaceW) - 1, CHARS_IN_GUID);
+    lstrcpyW(path + ARRAY_SIZE(interfaceW) - 1 + CHARS_IN_GUID - 1, psW);
+
+    hr = get_ps_clsid_from_registry(path, 0, pclsid);
+    if (FAILED(hr) && (opposite == KEY_WOW64_32KEY || (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)))
+        hr = get_ps_clsid_from_registry(path, opposite, pclsid);
+
+    if (hr == S_OK)
+        TRACE("() Returning CLSID %s\n", debugstr_guid(pclsid));
+    else
+        WARN("No PSFactoryBuffer object is registered for IID %s\n", debugstr_guid(riid));
+
+    return hr;
+}
+
+/*****************************************************************************
+ *             CoRegisterPSClsid    (combase.@)
+ */
+HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
+{
+    struct registered_ps *cur;
+
+    TRACE("%s, %s\n", debugstr_guid(riid), debugstr_guid(rclsid));
+
+    if (!InternalIsInitialized())
+    {
+        ERR("apartment not initialised\n");
+        return CO_E_NOTINITIALIZED;
+    }
+
+    EnterCriticalSection(&cs_registered_ps);
+
+    LIST_FOR_EACH_ENTRY(cur, &registered_proxystubs, struct registered_ps, entry)
+    {
+        if (IsEqualIID(&cur->iid, riid))
+        {
+            cur->clsid = *rclsid;
+            LeaveCriticalSection(&cs_registered_ps);
+            return S_OK;
+        }
+    }
+
+    cur = heap_alloc(sizeof(*cur));
+    if (!cur)
+    {
+        LeaveCriticalSection(&cs_registered_ps);
+        return E_OUTOFMEMORY;
+    }
+
+    cur->iid = *riid;
+    cur->clsid = *rclsid;
+    list_add_head(&registered_proxystubs, &cur->entry);
+
+    LeaveCriticalSection(&cs_registered_ps);
+
+    return S_OK;
+}
diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec
index bb7eaf69f9d..02004852aa8 100644
--- a/dlls/combase/combase.spec
+++ b/dlls/combase/combase.spec
@@ -115,7 +115,7 @@
 @ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long)
 @ stub CoGetModuleType
 @ stdcall CoGetObjectContext(ptr ptr)
-@ stdcall CoGetPSClsid(ptr ptr) ole32.CoGetPSClsid
+@ stdcall CoGetPSClsid(ptr ptr)
 @ stub CoGetProcessIdentifier
 @ stdcall CoGetStandardMarshal(ptr ptr long ptr long ptr) ole32.CoGetStandardMarshal
 @ stub CoGetStdMarshalEx
@@ -143,7 +143,7 @@
 @ stdcall CoRegisterInitializeSpy(ptr ptr)
 @ stdcall CoRegisterMallocSpy(ptr)
 @ stdcall CoRegisterMessageFilter(ptr ptr)
-@ stdcall CoRegisterPSClsid(ptr ptr) ole32.CoRegisterPSClsid
+@ stdcall CoRegisterPSClsid(ptr ptr)
 @ stdcall CoRegisterSurrogate(ptr) ole32.CoRegisterSurrogate
 @ stdcall CoRegisterSurrogateEx(ptr ptr) ole32.CoRegisterSurrogateEx
 @ stdcall CoReleaseMarshalData(ptr) ole32.CoReleaseMarshalData
@@ -268,6 +268,7 @@
 @ stub InternalNotifyDDStartOrStop
 @ stub InternalOleModalLoopBlockFn
 @ stub InternalRegisterWindowPropInterface
+@ stdcall InternalRevokeAllPSClsids()
 @ stub InternalReleaseMarshalObjRef
 @ stub InternalSTAInvoke
 @ stub InternalServerExceptionFilter
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index f02cdb8b53f..e8cc75c7de4 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -164,24 +164,6 @@ struct class_reg_data
     } u;
 };
 
-struct registered_psclsid
-{
-    struct list entry;
-    IID iid;
-    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
@@ -236,6 +218,8 @@ static CRITICAL_SECTION_DEBUG class_cs_debug =
 };
 static CRITICAL_SECTION csRegisteredClassList = { &class_cs_debug, -1, 0, 0, 0, 0 };
 
+extern void WINAPI InternalRevokeAllPSClsids(void);
+
 static inline enum comclass_miscfields dvaspect_to_miscfields(DWORD aspect)
 {
     switch (aspect)
@@ -776,21 +760,6 @@ static void COM_RevokeAllClasses(const struct apartment *apt)
   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, &registered_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)
  */
@@ -1997,7 +1966,7 @@ void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
   {
     TRACE("() - Releasing the COM libraries\n");
 
-    revoke_registered_psclsids();
+    InternalRevokeAllPSClsids();
     RunningObjectTableImpl_UnInitialize();
   }
   else if (lCOMRefCnt<1) {
@@ -2145,193 +2114,6 @@ HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey
     return S_OK;
 }
 
-static HRESULT get_ps_clsid_from_registry(const WCHAR* path, REGSAM access, CLSID *pclsid)
-{
-    HKEY hkey;
-    WCHAR value[CHARS_IN_GUID];
-    DWORD len;
-
-    access |= KEY_READ;
-
-    if (open_classes_key(HKEY_CLASSES_ROOT, path, access, &hkey))
-        return REGDB_E_IIDNOTREG;
-
-    len = sizeof(value);
-    if (ERROR_SUCCESS != RegQueryValueExW(hkey, NULL, NULL, NULL, (BYTE *)value, &len))
-        return REGDB_E_IIDNOTREG;
-    RegCloseKey(hkey);
-
-    if (CLSIDFromString(value, pclsid) != NOERROR)
-        return REGDB_E_IIDNOTREG;
-
-    return S_OK;
-}
-
-/*****************************************************************************
- *             CoGetPSClsid [OLE32.@]
- *
- * Retrieves the CLSID of the proxy/stub factory that implements
- * IPSFactoryBuffer for the specified interface.
- *
- * PARAMS
- *  riid   [I] Interface whose proxy/stub CLSID is to be returned.
- *  pclsid [O] Where to store returned proxy/stub CLSID.
- * 
- * RETURNS
- *   S_OK
- *   E_OUTOFMEMORY
- *   REGDB_E_IIDNOTREG if no PSFactoryBuffer is associated with the IID, or it could not be parsed
- *
- * NOTES
- *
- * The standard marshaller activates the object with the CLSID
- * returned and uses the CreateProxy and CreateStub methods on its
- * IPSFactoryBuffer interface to construct the proxies and stubs for a
- * given object.
- *
- * CoGetPSClsid determines this CLSID by searching the
- * HKEY_CLASSES_ROOT\Interface\{string form of riid}\ProxyStubClsid32
- * in the registry and any interface id registered by
- * CoRegisterPSClsid within the current process.
- *
- * BUGS
- *
- * Native returns S_OK for interfaces with a key in HKCR\Interface, but
- * without a ProxyStubClsid32 key and leaves garbage in pclsid. This should be
- * considered a bug in native unless an application depends on this (unlikely).
- *
- * SEE ALSO
- *  CoRegisterPSClsid.
- */
-HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
-{
-    static const WCHAR wszInterface[] = {'I','n','t','e','r','f','a','c','e','\\',0};
-    static const WCHAR wszPSC[] = {'\\','P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
-    WCHAR path[ARRAY_SIZE(wszInterface) - 1 + CHARS_IN_GUID - 1 + ARRAY_SIZE(wszPSC)];
-    APARTMENT *apt;
-    struct registered_psclsid *registered_psclsid;
-    ACTCTX_SECTION_KEYED_DATA data;
-    HRESULT hr;
-    REGSAM opposite = (sizeof(void*) > sizeof(int)) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
-    BOOL is_wow64;
-
-    TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid), pclsid);
-
-    if (!(apt = apartment_get_current_or_mta()))
-    {
-        ERR("apartment not initialised\n");
-        return CO_E_NOTINITIALIZED;
-    }
-    apartment_release(apt);
-
-    if (!pclsid)
-        return E_INVALIDARG;
-
-    EnterCriticalSection(&cs_registered_psclsid_list);
-
-    LIST_FOR_EACH_ENTRY(registered_psclsid, &registered_psclsid_list, struct registered_psclsid, entry)
-        if (IsEqualIID(&registered_psclsid->iid, riid))
-        {
-            *pclsid = registered_psclsid->clsid;
-            LeaveCriticalSection(&cs_registered_psclsid_list);
-            return S_OK;
-        }
-
-    LeaveCriticalSection(&cs_registered_psclsid_list);
-
-    data.cbSize = sizeof(data);
-    if (FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
-                              riid, &data))
-    {
-        struct ifacepsredirect_data *ifaceps = (struct ifacepsredirect_data*)data.lpData;
-        *pclsid = ifaceps->iid;
-        return S_OK;
-    }
-
-    /* Interface\\{string form of riid}\\ProxyStubClsid32 */
-    lstrcpyW(path, wszInterface);
-    StringFromGUID2(riid, path + ARRAY_SIZE(wszInterface) - 1, CHARS_IN_GUID);
-    lstrcpyW(path + ARRAY_SIZE(wszInterface) - 1 + CHARS_IN_GUID - 1, wszPSC);
-
-    hr = get_ps_clsid_from_registry(path, 0, pclsid);
-    if (FAILED(hr) && (opposite == KEY_WOW64_32KEY ||
-                       (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)))
-        hr = get_ps_clsid_from_registry(path, opposite, pclsid);
-
-    if (hr == S_OK)
-        TRACE ("() Returning CLSID=%s\n", debugstr_guid(pclsid));
-    else
-        WARN("No PSFactoryBuffer object is registered for IID %s\n", debugstr_guid(riid));
-
-    return hr;
-}
-
-/*****************************************************************************
- *             CoRegisterPSClsid [OLE32.@]
- *
- * Register a proxy/stub CLSID for the given interface in the current process
- * only.
- *
- * PARAMS
- *  riid   [I] Interface whose proxy/stub CLSID is to be registered.
- *  rclsid [I] CLSID of the proxy/stub.
- * 
- * RETURNS
- *   Success: S_OK
- *   Failure: E_OUTOFMEMORY
- *
- * 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.
- *
- * SEE ALSO
- *  CoGetPSClsid.
- */
-HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
-{
-    APARTMENT *apt;
-    struct registered_psclsid *registered_psclsid;
-
-    TRACE("(%s, %s)\n", debugstr_guid(riid), debugstr_guid(rclsid));
-
-    if (!(apt = apartment_get_current_or_mta()))
-    {
-        ERR("apartment not initialised\n");
-        return CO_E_NOTINITIALIZED;
-    }
-    apartment_release(apt);
-
-    EnterCriticalSection(&cs_registered_psclsid_list);
-
-    LIST_FOR_EACH_ENTRY(registered_psclsid, &registered_psclsid_list, struct registered_psclsid, entry)
-        if (IsEqualIID(&registered_psclsid->iid, riid))
-        {
-            registered_psclsid->clsid = *rclsid;
-            LeaveCriticalSection(&cs_registered_psclsid_list);
-            return S_OK;
-        }
-
-    registered_psclsid = HeapAlloc(GetProcessHeap(), 0, sizeof(struct registered_psclsid));
-    if (!registered_psclsid)
-    {
-        LeaveCriticalSection(&cs_registered_psclsid_list);
-        return E_OUTOFMEMORY;
-    }
-
-    registered_psclsid->iid = *riid;
-    registered_psclsid->clsid = *rclsid;
-    list_add_head(&registered_psclsid_list, &registered_psclsid->entry);
-
-    LeaveCriticalSection(&cs_registered_psclsid_list);
-
-    return S_OK;
-}
-
-
 /***
  * COM_GetRegisteredClassObject
  *
@@ -3872,6 +3654,17 @@ HRESULT WINAPI CoRegisterSurrogateEx(REFGUID guid, void *reserved)
     return E_NOTIMPL;
 }
 
+BOOL WINAPI InternalIsInitialized(void)
+{
+    struct apartment *apt;
+
+    if (!(apt = apartment_get_current_or_mta()))
+        return FALSE;
+    apartment_release(apt);
+
+    return TRUE;
+}
+
 typedef struct {
     IGlobalOptions IGlobalOptions_iface;
     LONG ref;
diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec
index ed5a958ce3c..02a8434d264 100644
--- a/dlls/ole32/ole32.spec
+++ b/dlls/ole32/ole32.spec
@@ -42,7 +42,7 @@
 @ stdcall CoGetMarshalSizeMax(ptr ptr ptr long ptr long) combase.CoGetMarshalSizeMax
 @ stdcall CoGetObject(wstr ptr ptr ptr)
 @ stdcall CoGetObjectContext(ptr ptr) combase.CoGetObjectContext
-@ stdcall CoGetPSClsid(ptr ptr)
+@ stdcall CoGetPSClsid(ptr ptr) combase.CoGetPSClsid
 @ stdcall CoGetStandardMarshal(ptr ptr long ptr long ptr)
 @ stdcall CoGetState(ptr)
 @ stub CoGetTIDFromIPID
@@ -69,7 +69,7 @@
 @ stdcall CoRegisterInitializeSpy(ptr ptr) combase.CoRegisterInitializeSpy
 @ stdcall CoRegisterMallocSpy(ptr) combase.CoRegisterMallocSpy
 @ stdcall CoRegisterMessageFilter(ptr ptr) combase.CoRegisterMessageFilter
-@ stdcall CoRegisterPSClsid(ptr ptr)
+@ stdcall CoRegisterPSClsid(ptr ptr) combase.CoRegisterPSClsid
 @ stdcall CoRegisterSurrogate(ptr)
 @ stdcall CoRegisterSurrogateEx(ptr ptr)
 @ stdcall CoReleaseMarshalData(ptr)
@@ -297,3 +297,4 @@
 @ stdcall WriteFmtUserTypeStg(ptr long ptr)
 @ stub WriteOleStg
 @ stub WriteStringStream
+@ stdcall InternalIsInitialized()
-- 
2.28.0




More information about the wine-devel mailing list