SHDOCVW: download the Mozilla Active X control on demand

Mike McCormack mike at codeweavers.com
Wed Sep 22 04:50:55 CDT 2004


This patch downloads the mozilla active control on demand.  It needs the 
following registry key to be present to function correctly:

[Software\\Wine\\Mozilla Control] 1089668326
"Url"="http://crossover.codeweavers.com/redirect/mozcontrol"
"Prog"="%TEMP%\\MozillaControl16.exe"

Mike


ChangeLog:
* download the Mozilla Active X control on demand
-------------- next part --------------
? dlls/shdocvw/shdocvw.rc
? dlls/shdocvw/shdocvw.res
Index: dlls/shdocvw/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/shdocvw/Makefile.in,v
retrieving revision 1.13
diff -u -r1.13 Makefile.in
--- dlls/shdocvw/Makefile.in	27 Jan 2004 00:11:16 -0000	1.13
+++ dlls/shdocvw/Makefile.in	22 Sep 2004 08:09:38 -0000
@@ -4,7 +4,7 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = shdocvw.dll
-IMPORTS   = ole32 user32 advapi32 kernel32
+IMPORTS   = urlmon ole32 user32 advapi32 kernel32
 EXTRALIBS = -luuid
 
 C_SRCS = \
@@ -18,7 +18,7 @@
 	shdocvw_main.c \
 	webbrowser.c
 
-RC_SRCS = version.rc
+RC_SRCS = shdocvw.rc version.rc
 
 @MAKE_DLL_RULES@
 
Index: dlls/shdocvw/shdocvw_main.c
===================================================================
RCS file: /home/wine/wine/dlls/shdocvw/shdocvw_main.c,v
retrieving revision 1.20
diff -u -r1.20 shdocvw_main.c
--- dlls/shdocvw/shdocvw_main.c	25 Aug 2004 17:33:47 -0000	1.20
+++ dlls/shdocvw/shdocvw_main.c	22 Sep 2004 08:09:39 -0000
@@ -2,6 +2,7 @@
  * SHDOCVW - Internet Explorer Web Control
  *
  * Copyright 2001 John R. Sheets (for CodeWeavers)
+ * Copyright 2004 Mike McCormack (for CodeWeavers)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -34,6 +35,7 @@
 
 #include "shdocvw.h"
 #include "uuids.h"
+#include "urlmon.h"
 
 #include "wine/unicode.h"
 #include "wine/debug.h"
@@ -42,8 +44,10 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
 
-#define MOZILLA_ACTIVEX_MESSAGE "You need to install the Mozilla ActiveX control to\n" \
-                                "use Wine's builtin CLSID_WebBrowser from SHDOCVW.DLL"
+static const WCHAR szMozDlPath[] = {
+    'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
+    'M','o','z','i','l','l','a',' ','C','o','n','t','r','o','l',0
+}; 
 
 DEFINE_GUID( CLSID_MozillaBrowser, 0x1339B54C,0x3453,0x11D2,0x93,0xB9,0x00,0x00,0x00,0x00,0x00,0x00);
 
@@ -125,26 +129,278 @@
     return S_FALSE;
 }
 
+/*************************************************************************
+ *              SHDOCVW_TryDownloadMozillaControl
+ */
+typedef struct _IBindStatusCallbackImpl {
+    IBindStatusCallbackVtbl *vtbl;
+    DWORD ref;
+    HWND hDialog;
+    BOOL *pbCancelled;
+} IBindStatusCallbackImpl;
+
+static HRESULT WINAPI
+dlQueryInterface( IBindStatusCallback* This, REFIID riid, void** ppvObject )
+{
+    if( IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IBindStatusCallback))
+    {
+        IBindStatusCallback_AddRef( This );
+        *ppvObject = This;
+        return S_OK;
+    }
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dlAddRef( IBindStatusCallback* iface )
+{
+    IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface;
+    return InterlockedIncrement( &This->ref );
+}
 
+static ULONG WINAPI dlRelease( IBindStatusCallback* iface )
+{
+    IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface;
+    DWORD ref = InterlockedDecrement( &This->ref );
+    if( !ref )
+    {
+        DestroyWindow( This->hDialog );
+        HeapFree( GetProcessHeap(), 0, This );
+    }
+    return ref;
+}
+
+static HRESULT WINAPI
+dlOnStartBinding( IBindStatusCallback* iface, DWORD dwReserved, IBinding* pib)
+{
+    ERR("\n");
+    return S_OK;
+}
+
+static HRESULT WINAPI
+dlGetPriority( IBindStatusCallback* iface, LONG* pnPriority)
+{
+    ERR("\n");
+    return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnLowResource( IBindStatusCallback* iface, DWORD reserved)
+{
+    ERR("\n");
+    return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnProgress( IBindStatusCallback* iface, ULONG ulProgress,
+              ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
+{
+    IBindStatusCallbackImpl *This = (IBindStatusCallbackImpl *) iface;
+    HWND hItem;
+    LONG r;
+
+    hItem = GetDlgItem( This->hDialog, 1000 );
+    if( hItem && ulProgressMax )
+        SendMessageW(hItem,PBM_SETPOS,(ulProgress*100)/ulProgressMax,0);
+
+    hItem = GetDlgItem(This->hDialog, 104);
+    if( hItem )
+        SendMessageW(hItem,WM_SETTEXT, 0, (LPARAM) szStatusText);
+
+    SetLastError(0);
+    r = GetWindowLongW( This->hDialog, GWL_USERDATA );
+    if( r || GetLastError() )
+    {
+        *This->pbCancelled = TRUE;
+        ERR("Cancelled\n");
+        return E_ABORT;
+    }
+
+    return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnStopBinding( IBindStatusCallback* iface, HRESULT hresult, LPCWSTR szError)
+{
+    ERR("\n");
+    return S_OK;
+}
+
+static HRESULT WINAPI
+dlGetBindInfo( IBindStatusCallback* iface, DWORD* grfBINDF, BINDINFO* pbindinfo)
+{
+    ERR("\n");
+    return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnDataAvailable( IBindStatusCallback* iface, DWORD grfBSCF,
+                   DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
+{
+    ERR("\n");
+    return S_OK;
+}
+
+static HRESULT WINAPI
+dlOnObjectAvailable( IBindStatusCallback* iface, REFIID riid, IUnknown* punk)
+{
+    ERR("\n");
+    return S_OK;
+}
+
+struct IBindStatusCallbackVtbl dlVtbl =
+{
+    dlQueryInterface,
+    dlAddRef,
+    dlRelease,
+    dlOnStartBinding,
+    dlGetPriority,
+    dlOnLowResource,
+    dlOnProgress,
+    dlOnStopBinding,
+    dlGetBindInfo,
+    dlOnDataAvailable,
+    dlOnObjectAvailable
+};
+
+static IBindStatusCallback* create_dl(HWND dlg, BOOL *pbCancelled)
+{
+    IBindStatusCallbackImpl *This;
+
+    This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
+    This->vtbl = &dlVtbl;
+    This->ref = 1;
+    This->hDialog = dlg;
+    This->pbCancelled = pbCancelled;
+
+    return (IBindStatusCallback*) This;
+}
+
+static DWORD WINAPI ThreadFunc( LPVOID info )
+{
+    IBindStatusCallback *dl;
+    static const WCHAR szUrlVal[] = {'U','r','l',0};
+    static const WCHAR szProgVal[] = {'P','r','o','g',0};
+    WCHAR szProg[MAX_PATH], path[MAX_PATH], szUrl[MAX_PATH];
+    STARTUPINFOW si;
+    PROCESS_INFORMATION pi;
+    HWND hDlg = info;
+    DWORD r, sz, type;
+    HKEY hkey;
+    BOOL bCancelled = FALSE;
+
+    /* find the name of the thing to download */
+    szProg[0] = 0;
+    szUrl[0] = 0;
+    r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szMozDlPath, &hkey );
+    if( r == ERROR_SUCCESS )
+    {
+        sz = MAX_PATH;
+        r = RegQueryValueExW( hkey, szProgVal, NULL, &type, (LPBYTE)szProg, &sz );
+        if( r == ERROR_SUCCESS )
+        {
+            sz = MAX_PATH;
+            r = RegQueryValueExW( hkey, szUrlVal, NULL, &type, (LPBYTE)szUrl, &sz );
+        }
+        RegCloseKey( hkey );
+    }
+    if( r != ERROR_SUCCESS )
+        goto end;
+    r = ExpandEnvironmentStringsW( szProg, path, MAX_PATH );
+    if( !r )
+        goto end;
+    
+    /* download it */
+    dl = create_dl(info, &bCancelled);
+    r = URLDownloadToFileW( NULL, szUrl, path, 0, dl );
+    if( dl )
+        IBindStatusCallback_Release( dl );
+    if( (r != S_OK) || bCancelled )
+        goto end;
+
+    /* run it */
+    memset( &si, 0, sizeof si );
+    si.cb = sizeof si;
+    r = CreateProcessW( path, NULL, NULL, NULL, 0, 0, NULL, NULL, &si, &pi );
+    if( !r )
+        goto end;
+    WaitForSingleObject( pi.hProcess, INFINITE );
+
+end:
+    EndDialog( hDlg, 0 );
+    return 0;
+}
+
+static INT_PTR CALLBACK
+dlProc ( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    HANDLE hThread;
+    DWORD ThreadId;
+    HWND hItem;
+
+    switch (uMsg)
+    {
+    case WM_INITDIALOG:
+        SetWindowLongW( hwndDlg, GWL_USERDATA, 0 );
+        hItem = GetDlgItem(hwndDlg, 1000);
+        if( hItem )
+        {
+            SendMessageW(hItem,PBM_SETRANGE,0,MAKELPARAM(0,100));
+            SendMessageW(hItem,PBM_SETPOS,0,0);
+        }
+        hThread = CreateThread(NULL,0,ThreadFunc,hwndDlg,0,&ThreadId);
+        if (!hThread)
+            return FALSE;
+        return TRUE;
+    case WM_COMMAND:
+        if( wParam == IDCANCEL )
+            SetWindowLongW( hwndDlg, GWL_USERDATA, 1 );
+        return FALSE;
+    default:
+        return FALSE;
+    }
+}
+
+static BOOL SHDOCVW_TryDownloadMozillaControl()
+{
+    DWORD r;
+    WCHAR buf[0x100];
+    static const WCHAR szWine[] = { 'W','i','n','e',0 };
+
+    LoadStringW( shdocvw_hinstance, 1001, buf, sizeof buf/sizeof(WCHAR) );
+    r = MessageBoxW(NULL, buf, szWine, MB_YESNO | MB_ICONQUESTION);
+    if( r != IDYES )
+        return FALSE;
+
+    DialogBoxW(shdocvw_hinstance, MAKEINTRESOURCEW(100), 0, dlProc);
+    
+    return TRUE;
+}
+ 
 static BOOL SHDOCVW_TryLoadMozillaControl()
 {
     WCHAR szPath[MAX_PATH];
+    BOOL bTried = FALSE;
 
     if( hMozCtl != (HMODULE)~0UL )
         return hMozCtl ? TRUE : FALSE;
 
-    if( !SHDOCVW_GetMozctlPath( szPath, sizeof szPath ) )
+    while( 1 )
     {
-        MESSAGE(MOZILLA_ACTIVEX_MESSAGE "\n");
-        MessageBoxA(NULL, MOZILLA_ACTIVEX_MESSAGE, "Wine", MB_OK | MB_ICONEXCLAMATION);
-        hMozCtl = 0;
-        return FALSE;
-    }
-    hMozCtl = LoadLibraryExW(szPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
-    if( !hMozCtl )
-    {
-        ERR("Can't load the Mozilla ActiveX control\n");
-        return FALSE;
+        if( SHDOCVW_GetMozctlPath( szPath, sizeof szPath ) )
+        {
+            hMozCtl = LoadLibraryExW(szPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+            if( hMozCtl )
+                return TRUE;
+        }
+        if( bTried )
+        {
+            MESSAGE("You need to install the Mozilla ActiveX control to\n");
+            MESSAGE("use Wine's builtin CLSID_WebBrowser from SHDOCVW.DLL\n");
+            return FALSE;
+        }
+        SHDOCVW_TryDownloadMozillaControl();
+        bTried = TRUE;
     }
     return TRUE;
 }
--- /dev/null	1994-07-18 08:46:18.000000000 +0900
+++ dlls/shdocvw/shdocvw.rc	2004-09-22 18:38:41.000000000 +0900
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2004 Mike McCormack 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "windef.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "commctrl.h"
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+100 DIALOG LOADONCALL MOVEABLE DISCARDABLE  0, 0, 220, 62
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Downloading the Mozilla Active X control"
+FONT 8, "Helv"
+{
+ CONTROL "Progress1",1000,"msctls_progress32",WS_BORDER|PBS_SMOOTH,10,10,200,12
+ LTEXT "", 104, 10, 30, 200, 10, SS_CENTER
+ PUSHBUTTON "Cancel", IDCANCEL, 85, 44, 50, 15, WS_GROUP | WS_TABSTOP
+}
+
+STRINGTABLE
+BEGIN
+ 1001	"This application is requesting an ActiveX browser object\n" \
+        "but the Mozilla Active X control is currently not installed." \
+        "Do you wish to download and install it?"
+END


More information about the wine-patches mailing list