Hi,
Since some people have been complaining that MSHTML is a useless distraction in it's current form (there's some element of truth in that), here's a small patch to redirect calls to Mozilla's Active X control. You need to add a "mshtml"="builtin,native" override in the config file and download and install the control before this patch can try to use it:
http://www.iol.ie/~locka/mozilla/control.htm
This patch hasn't been tested too much... but it's better than the current implementation of MSHTML :)
Mike
You can remove dlls/mshtml/document.c from the CVS after applying this patch.
ChangeLog: * Try using the Mozilla Active X control in MSHTML
Index: dlls/mshtml/main.c =================================================================== RCS file: /home/wine/wine/dlls/mshtml/main.c,v retrieving revision 1.2 diff -u -r1.2 main.c --- dlls/mshtml/main.c 9 Sep 2003 19:39:32 -0000 1.2 +++ dlls/mshtml/main.c 16 Jan 2004 05:34:23 -0000 @@ -22,172 +22,135 @@ #include "config.h" #include <stdarg.h> +#include <stdio.h> #include "windef.h" #include "winbase.h" #include "winuser.h" +#include "winnls.h" +#include "winreg.h" #include "ole2.h" #include "uuids.h" +#include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(mshtml); -extern HRESULT HTMLDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj); +#include "initguid.h" -/* For the moment, do nothing here. */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) -{ - switch(fdwReason) { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hInstDLL); - break; - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} +DEFINE_GUID( CLSID_MozillaBrowser, 0x1339B54C,0x3453,0x11D2,0x93,0xB9,0x00,0x00,0x00,0x00,0x00,0x00); -/****************************************************************************** - * MSHTML ClassFactory - */ -typedef struct { - IClassFactory ITF_IClassFactory; - - DWORD ref; - HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); -} IClassFactoryImpl; +typedef HRESULT WINAPI (*fnGetClassObject)(REFCLSID rclsid, REFIID iid, LPVOID *ppv); +typedef BOOL WINAPI (*fnCanUnloadNow)(); -struct object_creation_info -{ - const CLSID *clsid; - LPCSTR szClassName; - HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); -}; +HMODULE hMozCtl; -static const struct object_creation_info object_creation[] = -{ - { &CLSID_HTMLDocument, "HTMLDocument", HTMLDocument_create }, -}; -static HRESULT WINAPI -HTMLCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) +/* convert a guid to a wide character string */ +static void MSHTML_guid2wstr( const GUID *guid, LPWSTR wstr ) { - ICOM_THIS(IClassFactoryImpl,iface); - - if (IsEqualGUID(riid, &IID_IUnknown) - || IsEqualGUID(riid, &IID_IClassFactory)) - { - IClassFactory_AddRef(iface); - *ppobj = This; - return S_OK; - } - - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); - return E_NOINTERFACE; -} - -static ULONG WINAPI HTMLCF_AddRef(LPCLASSFACTORY iface) { - ICOM_THIS(IClassFactoryImpl,iface); - return ++(This->ref); + char str[40]; + + sprintf(str, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] ); + MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, 40 ); } -static ULONG WINAPI HTMLCF_Release(LPCLASSFACTORY iface) { - ICOM_THIS(IClassFactoryImpl,iface); +static BOOL MSHTML_GetMozctlPath( LPWSTR szPath, DWORD sz ) +{ + DWORD r, type; + BOOL ret = FALSE; + HKEY hkey; + const WCHAR szPre[] = { + 'S','o','f','t','w','a','r','e','\\', + 'C','l','a','s','s','e','s','\\', + 'C','L','S','I','D','\\',0 }; + const WCHAR szPost[] = { + '\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2',0 }; + WCHAR szRegPath[(sizeof(szPre)+sizeof(szPost))/sizeof(WCHAR)+40]; - ULONG ref = --This->ref; + strcpyW( szRegPath, szPre ); + MSHTML_guid2wstr( &CLSID_MozillaBrowser, &szRegPath[strlenW(szRegPath)] ); + strcatW( szRegPath, szPost ); - if (ref == 0) - HeapFree(GetProcessHeap(), 0, This); + TRACE("key = %s\n", debugstr_w( szRegPath ) ); - return ref; -} + r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szRegPath, &hkey ); + if( r != ERROR_SUCCESS ) + return FALSE; + r = RegQueryValueExW( hkey, NULL, NULL, &type, (LPBYTE)szPath, &sz ); + ret = ( r == ERROR_SUCCESS ) && ( type == REG_SZ ); + RegCloseKey( hkey ); -static HRESULT WINAPI HTMLCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, - REFIID riid, LPVOID *ppobj) { - ICOM_THIS(IClassFactoryImpl,iface); - HRESULT hres; - LPUNKNOWN punk; - - TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); - - hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); - if (FAILED(hres)) { - *ppobj = NULL; - return hres; - } - hres = IUnknown_QueryInterface(punk, riid, ppobj); - if (FAILED(hres)) { - *ppobj = NULL; - return hres; - } - IUnknown_Release(punk); - return hres; -} - -static HRESULT WINAPI HTMLCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { - ICOM_THIS(IClassFactoryImpl,iface); - FIXME("(%p)->(%d),stub!\n",This,dolock); - return S_OK; + return ret; } -static ICOM_VTABLE(IClassFactory) HTMLCF_Vtbl = +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - HTMLCF_QueryInterface, - HTMLCF_AddRef, - HTMLCF_Release, - HTMLCF_CreateInstance, - HTMLCF_LockServer -}; + WCHAR szPath[MAX_PATH]; + switch(fdwReason) { + case DLL_PROCESS_ATTACH: + if( !MSHTML_GetMozctlPath( szPath, sizeof szPath ) ) + { + MESSAGE("You need to install the Mozilla ActiveX control to\n"); + MESSAGE("use Wine's builtin MSHTML dll.\n"); + return FALSE; + } + hMozCtl = LoadLibraryExW(szPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + if( !hMozCtl ) + { + ERR("Can't load the Mozilla ActiveX control\n"); + return FALSE; + } + break; + case DLL_PROCESS_DETACH: + FreeLibrary( hMozCtl ); + break; + } + return TRUE; +} HRESULT WINAPI MSHTML_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) { - int i; - IClassFactoryImpl *factory; + HRESULT r; + fnGetClassObject pGetClassObject; - TRACE("%s %s %p\n",debugstr_guid(rclsid), debugstr_guid(iid), ppv); - - if ( !IsEqualGUID( &IID_IClassFactory, iid ) - && ! IsEqualGUID( &IID_IUnknown, iid) ) - return E_NOINTERFACE; - - for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) - { - if (IsEqualGUID(object_creation[i].clsid, rclsid)) - break; - } + TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv ); - if (i == sizeof(object_creation)/sizeof(object_creation[0])) - { - FIXME("%s: no class found.\n", debugstr_guid(rclsid)); - return CLASS_E_CLASSNOTAVAILABLE; - } + if( !IsEqualGUID( &CLSID_HTMLDocument, rclsid ) ) + WARN("Unknown class %s\n", debugstr_guid(rclsid) ); - TRACE("Creating a class factory for %s\n",object_creation[i].szClassName); + pGetClassObject = (fnGetClassObject) GetProcAddress( hMozCtl, "DllGetClassObject" ); + if( !pGetClassObject ) + return CLASS_E_CLASSNOTAVAILABLE; + r = pGetClassObject( &CLSID_MozillaBrowser, iid, ppv ); - factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory)); - if (factory == NULL) return E_OUTOFMEMORY; + TRACE("r = %08lx *ppv = %p\n", r, *ppv ); - factory->ITF_IClassFactory.lpVtbl = &HTMLCF_Vtbl; - factory->ref = 1; + return S_OK; +} - factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; +BOOL WINAPI MSHTML_DllCanUnloadNow(void) +{ + fnCanUnloadNow pCanUnloadNow; + BOOL r; - *ppv = &(factory->ITF_IClassFactory); + TRACE("\n"); - TRACE("(%p) <- %p\n", ppv, &(factory->ITF_IClassFactory) ); + pCanUnloadNow = (fnCanUnloadNow) GetProcAddress( hMozCtl, "DllCanUnloadNow" ); + if( !pCanUnloadNow ) + return FALSE; + r = pCanUnloadNow(); - return S_OK; -} + TRACE("r = %d\n", r); -HRESULT WINAPI MSHTML_DllCanUnloadNow(void) -{ - FIXME("\n"); - return S_FALSE; + return r; } /* appears to have the same prototype as WinMain */