[PATCH v4 2/2] ieframe: Add stub implementation of InternetExplorerManager.

Zebediah Figura zfigura at codeweavers.com
Fri Sep 15 00:43:07 CDT 2017


v4: various fixes
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/ieframe/ieframe.h         |   5 +-
 dlls/ieframe/ieframe_main.c    |  35 ++++--------
 dlls/ieframe/iexplore.c        | 117 ++++++++++++++++++++++++++++++++++++++---
 dlls/ieframe/tests/ie.c        |  24 +++++++++
 programs/iexplore/iexplore.inf |   3 ++
 5 files changed, 151 insertions(+), 33 deletions(-)

diff --git a/dlls/ieframe/ieframe.h b/dlls/ieframe/ieframe.h
index d1f1c5daf2..3e6ac6c6be 100644
--- a/dlls/ieframe/ieframe.h
+++ b/dlls/ieframe/ieframe.h
@@ -312,13 +312,16 @@ TID_LIST
 } tid_t;
 
 HRESULT get_typeinfo(tid_t,ITypeInfo**) DECLSPEC_HIDDEN;
-HRESULT register_class_object(BOOL) DECLSPEC_HIDDEN;
 
 HRESULT WINAPI CUrlHistory_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
 HRESULT WINAPI InternetExplorer_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
 HRESULT WINAPI InternetShortcut_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
 HRESULT WINAPI WebBrowser_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
 HRESULT WINAPI WebBrowserV1_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
+HRESULT WINAPI InternetExplorerManager_Create(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
+
+extern IClassFactory InternetExplorerFactory DECLSPEC_HIDDEN;
+extern IClassFactory InternetExplorerManagerFactory DECLSPEC_HIDDEN;
 
 extern LONG module_ref DECLSPEC_HIDDEN;
 extern HINSTANCE ieframe_instance DECLSPEC_HIDDEN;
diff --git a/dlls/ieframe/ieframe_main.c b/dlls/ieframe/ieframe_main.c
index c6eaa84516..a862f9afe5 100644
--- a/dlls/ieframe/ieframe_main.c
+++ b/dlls/ieframe/ieframe_main.c
@@ -18,9 +18,11 @@
 
 #include "ieframe.h"
 
+#include "initguid.h"
 #include "rpcproxy.h"
 #include "shlguid.h"
 #include "isguids.h"
+#include "ieautomation.h"
 
 #include "wine/debug.h"
 
@@ -238,32 +240,17 @@ static const IClassFactoryVtbl InternetExplorerFactoryVtbl = {
     ClassFactory_LockServer
 };
 
-static IClassFactory InternetExplorerFactory = { &InternetExplorerFactoryVtbl };
+IClassFactory InternetExplorerFactory = { &InternetExplorerFactoryVtbl };
 
-HRESULT register_class_object(BOOL do_reg)
-{
-    HRESULT hres;
-
-    static DWORD cookie;
-
-    if(do_reg) {
-        hres = CoRegisterClassObject(&CLSID_InternetExplorer,
-                (IUnknown*)&InternetExplorerFactory, CLSCTX_SERVER,
-                REGCLS_MULTIPLEUSE|REGCLS_SUSPENDED, &cookie);
-        if (FAILED(hres)) {
-            ERR("failed to register object %08x\n", hres);
-            return hres;
-        }
-
-        hres = CoResumeClassObjects();
-        if(SUCCEEDED(hres))
-            return hres;
-
-        ERR("failed to resume object %08x\n", hres);
-    }
+static const IClassFactoryVtbl InternetExplorerManagerFactoryVtbl = {
+    ClassFactory_QueryInterface,
+    ClassFactory_AddRef,
+    ClassFactory_Release,
+    InternetExplorerManager_Create,
+    ClassFactory_LockServer
+};
 
-    return CoRevokeClassObject(cookie);
-}
+IClassFactory InternetExplorerManagerFactory = { &InternetExplorerManagerFactoryVtbl };
 
 /***********************************************************************
  *          DllCanUnloadNow (ieframe.@)
diff --git a/dlls/ieframe/iexplore.c b/dlls/ieframe/iexplore.c
index 378f736990..61a8c5d6b4 100644
--- a/dlls/ieframe/iexplore.c
+++ b/dlls/ieframe/iexplore.c
@@ -39,6 +39,7 @@
 #include "shlwapi.h"
 #include "intshcut.h"
 #include "ddeml.h"
+#include "ieautomation.h"
 
 #include "wine/debug.h"
 
@@ -839,6 +840,92 @@ HRESULT WINAPI InternetExplorer_Create(IClassFactory *iface, IUnknown *pOuter, R
     return S_OK;
 }
 
+/******************************************************************
+ *      IInternetExplorerManager implementation
+ */
+struct InternetExplorerManager {
+    IInternetExplorerManager IInternetExplorerManager_iface;
+    LONG ref;
+};
+
+static inline InternetExplorerManager *impl_from_IInternetExplorerManager(IInternetExplorerManager *iface)
+{
+    return CONTAINING_RECORD(iface, InternetExplorerManager, IInternetExplorerManager_iface);
+}
+
+static HRESULT WINAPI InternetExplorerManager_QueryInterface(IInternetExplorerManager *iface, REFIID riid, void **out)
+{
+    TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), out);
+
+    if (IsEqualGUID(riid, &IID_IInternetExplorerManager) || IsEqualGUID(riid, &IID_IUnknown))
+    {
+        IInternetExplorerManager_AddRef(iface);
+        *out = iface;
+        return S_OK;
+    }
+
+    FIXME("interface %s not implemented\n", debugstr_guid(riid));
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI InternetExplorerManager_AddRef(IInternetExplorerManager *iface)
+{
+    InternetExplorerManager *This = impl_from_IInternetExplorerManager(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) increasing refcount to %u\n", iface, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI InternetExplorerManager_Release(IInternetExplorerManager *iface)
+{
+    InternetExplorerManager *This = impl_from_IInternetExplorerManager(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) decreasing refcount to %u\n", iface, ref);
+
+    if (ref == 0)
+        HeapFree(GetProcessHeap(), 0, This);
+
+    return ref;
+}
+
+static HRESULT WINAPI InternetExplorerManager_CreateObject(IInternetExplorerManager *iface, DWORD config, LPCWSTR url, REFIID riid, void **ppv)
+{
+    FIXME("(%p)->(0x%x, %s, %s, %p) stub!\n", iface, config, debugstr_w(url), debugstr_guid(riid), ppv);
+
+    return E_NOTIMPL;
+}
+
+static const IInternetExplorerManagerVtbl InternetExplorerManager_vtbl =
+{
+    InternetExplorerManager_QueryInterface,
+    InternetExplorerManager_AddRef,
+    InternetExplorerManager_Release,
+    InternetExplorerManager_CreateObject,
+};
+
+HRESULT WINAPI InternetExplorerManager_Create(IClassFactory *iface, IUnknown *pOuter, REFIID riid, void **ppv)
+{
+    InternetExplorerManager *ret;
+    HRESULT hr;
+
+    TRACE("(%p %s %p)\n", pOuter, debugstr_guid(riid), ppv);
+
+    if (!(ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret))))
+        return E_OUTOFMEMORY;
+
+    ret->IInternetExplorerManager_iface.lpVtbl = &InternetExplorerManager_vtbl;
+    ret->ref = 1;
+
+    hr = IInternetExplorerManager_QueryInterface(&ret->IInternetExplorerManager_iface, riid, ppv);
+    IInternetExplorerManager_Release(&ret->IInternetExplorerManager_iface);
+
+    return hres;
+}
+
 void released_obj(void)
 {
     if(!InterlockedDecrement(&obj_cnt))
@@ -1036,21 +1123,17 @@ DWORD WINAPI IEWinMain(const WCHAR *cmdline, int nShowWindow)
 {
     MSG msg;
     HRESULT hres;
-    BOOL embedding = FALSE, nohome = FALSE;
+    BOOL embedding = FALSE, nohome = FALSE, manager = FALSE;
+    DWORD reg_cookie;
 
     static const WCHAR embeddingW[] = {'-','e','m','b','e','d','d','i','n','g',0};
     static const WCHAR nohomeW[] = {'-','n','o','h','o','m','e',0};
+    static const WCHAR startmanagerW[] = {'-','s','t','a','r','t','m','a','n','a','g','e','r',0};
 
     TRACE("%s %d\n", debugstr_w(cmdline), nShowWindow);
 
     CoInitialize(NULL);
 
-    hres = register_class_object(TRUE);
-    if(FAILED(hres)) {
-        CoUninitialize();
-        ExitProcess(1);
-    }
-
     init_dde();
 
     while (*cmdline)
@@ -1066,12 +1149,30 @@ DWORD WINAPI IEWinMain(const WCHAR *cmdline, int nShowWindow)
             embedding = TRUE;
         else if (!strncmpiW(cmdline, nohomeW, length))
             nohome = TRUE;
+        else if (!strncmpiW(cmdline, startmanagerW, length))
+            manager = TRUE;
         else
             break;
 
         cmdline += length;
     }
 
+    if (manager)
+        hres = CoRegisterClassObject(&CLSID_InternetExplorerManager,
+            (IUnknown*)&InternetExplorerManagerFactory, CLSCTX_SERVER,
+            REGCLS_SINGLEUSE, &reg_cookie);
+    else
+        hres = CoRegisterClassObject(&CLSID_InternetExplorer,
+            (IUnknown*)&InternetExplorerFactory, CLSCTX_SERVER,
+            REGCLS_MULTIPLEUSE, &reg_cookie);
+
+    if (FAILED(hres))
+    {
+        ERR("failed to register CLSID_InternetExplorer%s: %08x\n", manager ? "Manager" : "", hres);
+        CoUninitialize();
+        ExitProcess(1);
+    }
+
     if (!embedding)
     {
         if(!create_ie_window(nohome, cmdline))
@@ -1088,7 +1189,7 @@ DWORD WINAPI IEWinMain(const WCHAR *cmdline, int nShowWindow)
         DispatchMessageW(&msg);
     }
 
-    register_class_object(FALSE);
+    CoRevokeClassObject(reg_cookie);
     release_dde();
 
     CoUninitialize();
diff --git a/dlls/ieframe/tests/ie.c b/dlls/ieframe/tests/ie.c
index 9ddd25c35a..ac055e248d 100644
--- a/dlls/ieframe/tests/ie.c
+++ b/dlls/ieframe/tests/ie.c
@@ -28,6 +28,8 @@
 #include "exdisp.h"
 #include "exdispid.h"
 #include "mshtml.h"
+#include "initguid.h"
+#include "ieautomation.h"
 
 #define DEFINE_EXPECT(func) \
     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@@ -275,10 +277,32 @@ static void test_InternetExplorer(void)
     ok(!ref, "object not destroyed, ref=%u\n", ref);
 }
 
+static void test_InternetExplorerManager(void)
+{
+    IUnknown *unk;
+    ULONG ref;
+    HRESULT hres;
+
+    hres = CoCreateInstance(&CLSID_InternetExplorerManager, NULL, CLSCTX_LOCAL_SERVER,
+            &IID_IInternetExplorerManager, (void**)&unk);
+    ok(hres == S_OK || broken(hres == REGDB_E_CLASSNOTREG), "Could not create InternetExplorerManager instance: %08x\n", hres);
+
+    if(hres != S_OK)
+    {
+        win_skip("InternetExplorerManager not available\n");
+        return;
+    }
+
+    ref = IUnknown_Release(unk);
+    ok(!ref, "object not destroyed, ref=%u\n", ref);
+}
+
 START_TEST(ie)
 {
     CoInitialize(NULL);
 
+    test_InternetExplorerManager();
+
     test_InternetExplorer();
 
     CoUninitialize();
diff --git a/programs/iexplore/iexplore.inf b/programs/iexplore/iexplore.inf
index a8538d8883..1886352b28 100644
--- a/programs/iexplore/iexplore.inf
+++ b/programs/iexplore/iexplore.inf
@@ -22,6 +22,8 @@ HKCR,"CLSID\%CLSID_Internet%\Shell\OpenHomePage",,,"Open &Home Page"
 HKCR,"CLSID\%CLSID_Internet%\Shell\OpenHomePage\Command",,,"""%16422%\Internet Explorer\iexplore.exe"""
 HKCR,"CLSID\%CLSID_Internet%\ShellFolder",,2,"0x24"
 
+HKCR,"CLSID\%CLSID_InternetExplorerManager%\LocalServer32",,,"""%16422%\Internet Explorer\iexplore.exe"" -startmanager"
+
 
 [Settings.Reg]
 HKCU,"Software\Microsoft\Internet Explorer\Main","Start Page",2,"http://www.winehq.org"
@@ -42,3 +44,4 @@ HKLM,"Software\Microsoft\Internet Explorer","W2kVersion",,"9.0.8112.16421"
 [Strings]
 CLSID_InternetExplorer="{0002df01-0000-0000-c000-000000000046}"
 CLSID_Internet="{871c5380-42a0-1069-a2ea-08002b30309d}"
+CLSID_InternetExplorerManager="{df4fcc34-067a-4e0a-8352-4a1a5095346e}"
-- 
2.14.1




More information about the wine-patches mailing list