diff --git a/dlls/ieframe/ieframe.h b/dlls/ieframe/ieframe.h index d1f1c5daf24..3e6ac6c6be1 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 c6eaa845167..a862f9afe5a 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 const IClassFactoryVtbl InternetExplorerManagerFactoryVtbl = { + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + InternetExplorerManager_Create, + ClassFactory_LockServer +}; - 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); - } - - return CoRevokeClassObject(cookie); -} +IClassFactory InternetExplorerManagerFactory = { &InternetExplorerManagerFactoryVtbl }; /*********************************************************************** * DllCanUnloadNow (ieframe.@) diff --git a/dlls/ieframe/iexplore.c b/dlls/ieframe/iexplore.c index 378f7369900..23d61f9fe42 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 hr; +} + 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, ®_cookie); + else + hres = CoRegisterClassObject(&CLSID_InternetExplorer, + (IUnknown*)&InternetExplorerFactory, CLSCTX_SERVER, + REGCLS_MULTIPLEUSE, ®_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 9ddd25c35a1..ac055e248de 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 a8538d8883b..1886352b282 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}"