From 02ceb94351d20a615b75dba016a4053ffb408bc3 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Sat, 23 Jul 2011 18:40:54 +0200 Subject: [PATCH] ieframe: Moved InternetShortcut implementation to ieframe.dll. --- configure | 2 +- configure.ac | 2 +- dlls/ieframe/Makefile.in | 5 +- dlls/ieframe/ieframe.h | 90 ++++++++++++++++++++++++++++ dlls/ieframe/ieframe.spec | 1 + dlls/ieframe/ieframe_main.c | 69 ++++++++++++++++++--- dlls/{shdocvw => ieframe}/intshcut.c | 81 ++++++++++++------------- dlls/shdocvw/Makefile.in | 3 +- dlls/shdocvw/factory.c | 22 ++++++- dlls/shdocvw/shdocvw.h | 5 +- dlls/shdocvw/shdocvw.spec | 2 +- dlls/shdocvw/shdocvw_main.c | 14 +++++ 12 files changed, 233 insertions(+), 63 deletions(-) create mode 100644 dlls/ieframe/ieframe.h rename dlls/{shdocvw => ieframe}/intshcut.c (94%) diff --git a/configure b/configure index 702388fdc6..bf6540fea8 100755 --- a/configure +++ b/configure @@ -14854,7 +14854,7 @@ wine_fn_config_dll hnetcfg enable_hnetcfg wine_fn_config_dll httpapi enable_httpapi wine_fn_config_dll iccvid enable_iccvid po wine_fn_config_dll icmp enable_icmp -wine_fn_config_dll ieframe enable_ieframe +wine_fn_config_dll ieframe enable_ieframe implib wine_fn_config_dll ifsmgr.vxd enable_win16 wine_fn_config_dll imaadp32.acm enable_imaadp32_acm wine_fn_config_dll imagehlp enable_imagehlp implib diff --git a/configure.ac b/configure.ac index 0eb3ac8c85..481090b68c 100644 --- a/configure.ac +++ b/configure.ac @@ -2527,7 +2527,7 @@ WINE_CONFIG_DLL(hnetcfg) WINE_CONFIG_DLL(httpapi) WINE_CONFIG_DLL(iccvid,,[po]) WINE_CONFIG_DLL(icmp) -WINE_CONFIG_DLL(ieframe) +WINE_CONFIG_DLL(ieframe,,[implib]) WINE_CONFIG_DLL(ifsmgr.vxd,enable_win16) WINE_CONFIG_DLL(imaadp32.acm) WINE_CONFIG_DLL(imagehlp,,[implib]) diff --git a/dlls/ieframe/Makefile.in b/dlls/ieframe/Makefile.in index 77b5e2910a..129aab1bd8 100644 --- a/dlls/ieframe/Makefile.in +++ b/dlls/ieframe/Makefile.in @@ -1,6 +1,9 @@ MODULE = ieframe.dll +IMPORTLIB = ieframe +IMPORTS = uuid urlmon shell32 ole32 advapi32 C_SRCS = \ - ieframe_main.c + ieframe_main.c \ + intshcut.c @MAKE_DLL_RULES@ diff --git a/dlls/ieframe/ieframe.h b/dlls/ieframe/ieframe.h new file mode 100644 index 0000000000..e44b9c1a8d --- /dev/null +++ b/dlls/ieframe/ieframe.h @@ -0,0 +1,90 @@ +/* + * Header includes for shdocvw.dll + * + * Copyright 2011 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +#include "ole2.h" + +#include "wine/unicode.h" + +HRESULT WINAPI InternetShortcut_Create(IClassFactory*,IUnknown*,REFIID,void**); + +extern LONG module_ref DECLSPEC_HIDDEN; + +static inline void lock_module(void) { + InterlockedIncrement(&module_ref); +} + +static inline void unlock_module(void) { + InterlockedDecrement(&module_ref); +} + +static inline void *heap_alloc(size_t len) +{ + return HeapAlloc(GetProcessHeap(), 0, len); +} + +static inline void *heap_alloc_zero(size_t len) +{ + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); +} + +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} + +static inline LPWSTR co_strdupW(LPCWSTR str) +{ + WCHAR *ret = CoTaskMemAlloc((strlenW(str) + 1)*sizeof(WCHAR)); + if (ret) + lstrcpyW(ret, str); + return ret; +} + +static inline LPWSTR co_strdupAtoW(LPCSTR str) +{ + INT len; + WCHAR *ret; + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = CoTaskMemAlloc(len*sizeof(WCHAR)); + if (ret) + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + return ret; +} + +static inline LPSTR co_strdupWtoA(LPCWSTR str) +{ + INT len; + CHAR *ret; + len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, 0, 0); + ret = CoTaskMemAlloc(len); + if (ret) + WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, 0, 0); + return ret; +} diff --git a/dlls/ieframe/ieframe.spec b/dlls/ieframe/ieframe.spec index b16365d0c9..b022078640 100644 --- a/dlls/ieframe/ieframe.spec +++ b/dlls/ieframe/ieframe.spec @@ -2,3 +2,4 @@ @ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() +@ stdcall OpenURL(long long str long) diff --git a/dlls/ieframe/ieframe_main.c b/dlls/ieframe/ieframe_main.c index 53c40cfa15..225c33b5aa 100644 --- a/dlls/ieframe/ieframe_main.c +++ b/dlls/ieframe/ieframe_main.c @@ -16,19 +16,65 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "config.h" +#include "ieframe.h" -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" +#include "isguids.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ieframe); +LONG module_ref = 0; + +static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv); + *ppv = iface; + }else if(IsEqualGUID(&IID_IClassFactory, riid)) { + TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv); + *ppv = iface; + } + + if(*ppv) { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) +{ + TRACE("(%p)\n", iface); + return 2; +} + +static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) +{ + TRACE("(%p)\n", iface); + return 1; +} + +static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock) +{ + TRACE("(%p)->(%x)\n", iface, fLock); + return S_OK; +} + +static const IClassFactoryVtbl InternetShortcutFactoryVtbl = { + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + InternetShortcut_Create, + ClassFactory_LockServer +}; + +static IClassFactory InternetShortcutFactory = { &InternetShortcutFactoryVtbl }; + /****************************************************************** * DllMain (ieframe.@) */ @@ -53,6 +99,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) */ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { + if(IsEqualGUID(rclsid, &CLSID_InternetShortcut)) { + TRACE("(CLSID_InternetShortcut %s %p)\n", debugstr_guid(riid), ppv); + return IClassFactory_QueryInterface(&InternetShortcutFactory, riid, ppv); + } + FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); return CLASS_E_CLASSNOTAVAILABLE; } @@ -62,8 +113,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) */ HRESULT WINAPI DllCanUnloadNow(void) { - FIXME("()\n"); - return S_FALSE; + TRACE("()\n"); + return module_ref ? S_FALSE : S_OK; } /*********************************************************************** diff --git a/dlls/shdocvw/intshcut.c b/dlls/ieframe/intshcut.c similarity index 94% rename from dlls/shdocvw/intshcut.c rename to dlls/ieframe/intshcut.c index f83aa5222c..846e133143 100644 --- a/dlls/shdocvw/intshcut.c +++ b/dlls/ieframe/intshcut.c @@ -27,20 +27,21 @@ * The installer for the Zuma Deluxe Popcap game is good for testing. */ -#include #include -#define NONAMELESSUNION -#include "wine/debug.h" -#include "shdocvw.h" -#include "objidl.h" +#include "ieframe.h" + +#include "shlobj.h" #include "shobjidl.h" #include "intshcut.h" #include "shellapi.h" #include "winreg.h" #include "shlwapi.h" +#include "shlguid.h" -WINE_DEFAULT_DEBUG_CHANNEL(shdocvw); +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ieframe); typedef struct { @@ -133,7 +134,7 @@ static BOOL StartLinkProcessor( LPCOLESTR szLink ) if( !buffer ) return FALSE; - wsprintfW( buffer, szFormat, szLink ); + sprintfW( buffer, szFormat, szLink ); ret = run_winemenubuilder( buffer ); heap_free( buffer ); return ret; @@ -191,7 +192,7 @@ static ULONG Unknown_Release(InternetShortcut *This) CoTaskMemFree(This->currentFile); IPropertySetStorage_Release(This->property_set_storage); heap_free(This); - SHDOCVW_UnlockModule(); + unlock_module(); } return count; } @@ -815,7 +816,7 @@ static InternetShortcut *create_shortcut(void) newshortcut->IUniformResourceLocatorW_iface.lpVtbl = &uniformResourceLocatorWVtbl; newshortcut->IPersistFile_iface.lpVtbl = &persistFileVtbl; newshortcut->IPropertySetStorage_iface.lpVtbl = &propertySetStorageVtbl; - newshortcut->refCount = 0; + newshortcut->refCount = 1; hr = StgCreateStorageEx(NULL, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, STGFMT_STORAGE, 0, NULL, NULL, &IID_IPropertySetStorage, (void **) &newshortcut->property_set_storage); if FAILED(hr) @@ -839,64 +840,58 @@ static InternetShortcut *create_shortcut(void) return newshortcut; } -HRESULT InternetShortcut_Create(IUnknown *pOuter, REFIID riid, void **ppv) +HRESULT WINAPI InternetShortcut_Create(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) { InternetShortcut *This; - HRESULT hr; + HRESULT hres; - TRACE("(%p, %s, %p)\n", pOuter, debugstr_guid(riid), ppv); + TRACE("(%p, %s, %p)\n", outer, debugstr_guid(riid), ppv); *ppv = NULL; - if(pOuter) + if(outer) return CLASS_E_NOAGGREGATION; This = create_shortcut(); - if (This) - { - hr = Unknown_QueryInterface(This, riid, ppv); - if (SUCCEEDED(hr)) - SHDOCVW_LockModule(); - else - heap_free(This); - return hr; - } - else + if(!This) return E_OUTOFMEMORY; + + hres = Unknown_QueryInterface(This, riid, ppv); + Unknown_Release(This); + return hres; } /********************************************************************** - * OpenURL (SHDOCVW.@) + * OpenURL (ieframe.@) */ void WINAPI OpenURL(HWND hWnd, HINSTANCE hInst, LPCSTR lpcstrUrl, int nShowCmd) { InternetShortcut *shortcut; WCHAR* urlfilepath = NULL; + int len; + shortcut = create_shortcut(); - if (shortcut) - { - int len; + if(!shortcut) + return; - len = MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, NULL, 0); - urlfilepath = heap_alloc(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, urlfilepath, len); + len = MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, NULL, 0); + urlfilepath = heap_alloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpcstrUrl, -1, urlfilepath, len); - if(SUCCEEDED(IPersistFile_Load(&shortcut->IPersistFile_iface, urlfilepath, 0))) - { - URLINVOKECOMMANDINFOW ici; + if(SUCCEEDED(IPersistFile_Load(&shortcut->IPersistFile_iface, urlfilepath, 0))) { + URLINVOKECOMMANDINFOW ici; - memset( &ici, 0, sizeof ici ); - ici.dwcbSize = sizeof ici; - ici.dwFlags = IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB; - ici.hwndParent = hWnd; + memset( &ici, 0, sizeof ici ); + ici.dwcbSize = sizeof ici; + ici.dwFlags = IURL_INVOKECOMMAND_FL_USE_DEFAULT_VERB; + ici.hwndParent = hWnd; - if(FAILED(UniformResourceLocatorW_InvokeCommand(&shortcut->IUniformResourceLocatorW_iface, (PURLINVOKECOMMANDINFOW) &ici))) - TRACE("failed to open URL: %s\n", debugstr_a(lpcstrUrl)); - } - - heap_free(shortcut); - heap_free(urlfilepath); + if(FAILED(UniformResourceLocatorW_InvokeCommand(&shortcut->IUniformResourceLocatorW_iface, (PURLINVOKECOMMANDINFOW) &ici))) + TRACE("failed to open URL: %s\n", debugstr_a(lpcstrUrl)); } + + heap_free(urlfilepath); + Unknown_Release(shortcut); } diff --git a/dlls/shdocvw/Makefile.in b/dlls/shdocvw/Makefile.in index fe85d48377..d5dad46584 100644 --- a/dlls/shdocvw/Makefile.in +++ b/dlls/shdocvw/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -D_SHDOCVW_ MODULE = shdocvw.dll IMPORTLIB = shdocvw IMPORTS = uuid shell32 comctl32 shlwapi user32 gdi32 advapi32 -DELAYIMPORTS = version urlmon ole32 oleaut32 +DELAYIMPORTS = version urlmon ole32 oleaut32 ieframe C_SRCS = \ classinfo.c \ @@ -13,7 +13,6 @@ C_SRCS = \ frame.c \ ie.c \ iexplore.c \ - intshcut.c \ navigate.c \ oleobject.c \ persist.c \ diff --git a/dlls/shdocvw/factory.c b/dlls/shdocvw/factory.c index 71d1e7e419..d8a4b1193e 100644 --- a/dlls/shdocvw/factory.c +++ b/dlls/shdocvw/factory.c @@ -128,6 +128,25 @@ static const IClassFactoryVtbl WBCF_Vtbl = WBCF_LockServer }; +static HRESULT get_ieframe_object(REFCLSID rclsid, REFIID riid, void **ppv) +{ + HINSTANCE ieframe_instance; + + static HRESULT (WINAPI *ieframe_DllGetClassObject)(REFCLSID,REFIID,void**); + + if(!ieframe_DllGetClassObject) { + ieframe_instance = get_ieframe_instance(); + if(!ieframe_instance) + return CLASS_E_CLASSNOTAVAILABLE; + + ieframe_DllGetClassObject = (void*)GetProcAddress(ieframe_instance, "DllGetClassObject"); + if(!ieframe_DllGetClassObject) + return CLASS_E_CLASSNOTAVAILABLE; + } + + return ieframe_DllGetClassObject(rclsid, riid, ppv); +} + /************************************************************************* * DllGetClassObject (SHDOCVW.@) */ @@ -136,7 +155,6 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) static IClassFactoryImpl WB1ClassFactory = {{&WBCF_Vtbl}, WebBrowserV1_Create}; static IClassFactoryImpl WB2ClassFactory = {{&WBCF_Vtbl}, WebBrowserV2_Create}; static IClassFactoryImpl CUHClassFactory = {{&WBCF_Vtbl}, CUrlHistory_Create}; - static IClassFactoryImpl ISCClassFactory = {{&WBCF_Vtbl}, InternetShortcut_Create}; static IClassFactoryImpl TBLClassFactory = {{&WBCF_Vtbl}, TaskbarList_Create}; TRACE("\n"); @@ -151,7 +169,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) return IClassFactory_QueryInterface(&CUHClassFactory.IClassFactory_iface, riid, ppv); if(IsEqualGUID(&CLSID_InternetShortcut, rclsid)) - return IClassFactory_QueryInterface(&ISCClassFactory.IClassFactory_iface, riid, ppv); + return get_ieframe_object(rclsid, riid, ppv); if(IsEqualGUID(&CLSID_TaskbarList, rclsid)) return IClassFactory_QueryInterface(&TBLClassFactory.IClassFactory_iface, riid, ppv); diff --git a/dlls/shdocvw/shdocvw.h b/dlls/shdocvw/shdocvw.h index 6dfa6cd425..bd65551542 100644 --- a/dlls/shdocvw/shdocvw.h +++ b/dlls/shdocvw/shdocvw.h @@ -259,9 +259,6 @@ void InternetExplorer_WebBrowser_Init(InternetExplorer*) DECLSPEC_HIDDEN; void released_obj(void) DECLSPEC_HIDDEN; HRESULT CUrlHistory_Create(IUnknown*,REFIID,void**) DECLSPEC_HIDDEN; - -HRESULT InternetShortcut_Create(IUnknown*,REFIID,void**) DECLSPEC_HIDDEN; - HRESULT TaskbarList_Create(IUnknown*,REFIID,void**) DECLSPEC_HIDDEN; /********************************************************************** @@ -276,6 +273,8 @@ extern void register_iewindow_class(void) DECLSPEC_HIDDEN; extern void unregister_iewindow_class(void) DECLSPEC_HIDDEN; extern HRESULT update_ie_statustext(InternetExplorer*, LPCWSTR) DECLSPEC_HIDDEN; +HINSTANCE get_ieframe_instance(void) DECLSPEC_HIDDEN; + HRESULT register_class_object(BOOL) DECLSPEC_HIDDEN; HRESULT get_typeinfo(ITypeInfo**) DECLSPEC_HIDDEN; DWORD register_iexplore(BOOL) DECLSPEC_HIDDEN; diff --git a/dlls/shdocvw/shdocvw.spec b/dlls/shdocvw/shdocvw.spec index 672c7faa94..1cdeff43bb 100644 --- a/dlls/shdocvw/shdocvw.spec +++ b/dlls/shdocvw/shdocvw.spec @@ -122,7 +122,7 @@ @ stub IEWriteErrorLog @ stdcall ImportPrivacySettings(wstr ptr ptr) @ stub InstallReg_RunDLL -@ stdcall OpenURL(long long str long) +@ stdcall OpenURL(long long str long) ieframe.OpenURL @ stub SHGetIDispatchForFolder @ stdcall SetQueryNetSessionCount(long) @ stub SoftwareUpdateMessageBox diff --git a/dlls/shdocvw/shdocvw_main.c b/dlls/shdocvw/shdocvw_main.c index 9bf2fa788f..b9c8bae00b 100644 --- a/dlls/shdocvw/shdocvw_main.c +++ b/dlls/shdocvw/shdocvw_main.c @@ -92,6 +92,18 @@ const char *debugstr_variant(const VARIANT *v) } } +static HINSTANCE ieframe_instance; + +HINSTANCE get_ieframe_instance(void) +{ + static const WCHAR ieframe_dllW[] = {'i','e','f','r','a','m','e','.','d','l','l',0}; + + if(!ieframe_instance) + ieframe_instance = LoadLibraryW(ieframe_dllW); + + return ieframe_instance; +} + /************************************************************************* * SHDOCVW DllMain */ @@ -109,6 +121,8 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad) unregister_iewindow_class(); if(wb_typeinfo) ITypeInfo_Release(wb_typeinfo); + if(ieframe_instance) + FreeLibrary(ieframe_instance); break; } return TRUE;